docs: sdk

This commit is contained in:
Dax Raad
2025-09-01 17:35:48 -04:00
parent 26f75d4e68
commit f6bc9238df
4 changed files with 137 additions and 25 deletions

View File

@@ -1,9 +1,15 @@
import { Plugin } from "./index"
export const ExamplePlugin: Plugin = async ({ client, $ }) => {
export const ExamplePlugin: Plugin = async ({
client: _client,
$: _shell,
project: _project,
directory: _directory,
worktree: _worktree,
}) => {
return {
permission: {},
async "chat.params"(input, output) {
async "chat.params"(_input, output) {
output.topP = 1
},
}

View File

@@ -0,0 +1,55 @@
import { createOpencodeClient, createOpencodeServer } from "@opencode-ai/sdk"
const server = await createOpencodeServer()
const client = createOpencodeClient({ baseUrl: server.url })
const input = await Array.fromAsync(new Bun.Glob("packages/core/*.ts").scan())
const tasks: Promise<void>[] = []
for await (const file of input) {
console.log("processing", file)
const session = await client.session.create()
tasks.push(
client.session.prompt({
path: { id: session.data.id },
body: {
parts: [
{
type: "file",
mime: "text/plain",
url: `file://${file}`,
},
{
type: "text",
text: `Write tests for every public function in this file.`,
},
],
},
}),
)
console.log("done", file)
}
await Promise.all(
input.map(async (file) => {
const session = await client.session.create()
console.log("processing", file)
await client.session.prompt({
path: { id: session.data.id },
body: {
parts: [
{
type: "file",
mime: "text/plain",
url: `file://${file}`,
},
{
type: "text",
text: `Write tests for every public function in this file.`,
},
],
},
})
console.log("done", file)
}),
)

View File

@@ -26,7 +26,7 @@ Plugins are loaded from:
### Basic structure
```js title=".opencode/plugin/example.js"
export const MyPlugin = async ({ app, client, $ }) => {
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
@@ -37,7 +37,9 @@ export const MyPlugin = async ({ app, client, $ }) => {
The plugin function receives:
- `app`: The opencode application instance.
- `project`: The current project information.
- `directory`: The current working directory.
- `worktree`: The git worktree path.
- `client`: An opencode SDK client for interacting with the AI.
- `$`: Bun's [shell API](https://bun.com/docs/runtime/shell) for executing commands.
@@ -50,7 +52,7 @@ For TypeScript plugins, you can import types from the plugin package:
```ts title="my-plugin.ts" {1}
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ app, client, $ }) => {
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
@@ -70,7 +72,7 @@ Here are some examples of plugins you can use to extend opencode.
Send notifications when certain events occur:
```js title=".opencode/plugin/notification.js"
export const NotificationPlugin = async ({ client, $ }) => {
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
// Send notification on session completion
@@ -91,13 +93,13 @@ We are using `osascript` to run AppleScript on macOS. Here we are using it to se
Prevent opencode from reading `.env` files:
```javascript title=".opencode/plugin/env-protection.js"
export const EnvProtection = async ({ client, $ }) => {
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "read" && output.args.filePath.includes(".env")) {
throw new Error("Do not read .env files")
}
}
},
}
}
```

View File

@@ -10,6 +10,8 @@ The opencode [JS/TS SDK](https://www.npmjs.com/package/@opencode-ai/sdk) provide
[Learn more](/docs/server) about how the opencode server works.
> **Note**: Many API endpoints now require a `directory` query parameter to specify the working directory context.
---
## Install
@@ -65,12 +67,12 @@ server.close()
#### Options
| Option | Type | Description | Default |
| ---------- | -------------- | ------------------------------ | ------------- |
| `hostname` | `string` | Server hostname | `127.0.0.1` |
| `port` | `number` | Server port | `4096` |
| `signal` | `AbortSignal` | Abort signal for cancellation | `undefined` |
| `timeout` | `number` | Timeout in ms for server start | `5000` |
| Option | Type | Description | Default |
| ---------- | ------------- | ------------------------------ | ----------- |
| `hostname` | `string` | Server hostname | `127.0.0.1` |
| `port` | `number` | Server port | `4096` |
| `signal` | `AbortSignal` | Abort signal for cancellation | `undefined` |
| `timeout` | `number` | Timeout in ms for server start | `5000` |
---
@@ -80,7 +82,7 @@ The SDK includes TypeScript definitions for all API types. Import them directly:
```typescript
import type { Session, Message, Part } from "@opencode-ai/sdk"
````
```
All types are generated from the server's OpenAPI specification and available in the <a href={typesUrl}>types file</a>.
@@ -108,18 +110,63 @@ The SDK exposes all server APIs through a type-safe client interface.
### App
| Method | Description | Response |
| ------------ | ------------------ | --------------------------------------- |
| `app.get()` | Get app info | <a href={typesUrl}><code>App</code></a> |
| `app.init()` | Initialize the app | `boolean` |
| Method | Description | Response |
| -------------- | ------------------------- | ------------------------------------------- |
| `app.log()` | Write a log entry | `boolean` |
| `app.agents()` | List all available agents | <a href={typesUrl}><code>Agent[]</code></a> |
---
#### Examples
```javascript
const app = await client.app.get()
await client.app.init()
// Log an entry
await client.app.log({
service: "my-app",
level: "info",
message: "Operation completed",
})
// List available agents
const agents = await client.app.agents()
```
---
### Project
| Method | Description | Response |
| ------------------- | ------------------- | --------------------------------------------- |
| `project.list()` | List all projects | <a href={typesUrl}><code>Project[]</code></a> |
| `project.current()` | Get current project | <a href={typesUrl}><code>Project</code></a> |
---
#### Examples
```javascript
// List all projects
const projects = await client.project.list()
// Get current project
const currentProject = await client.project.current()
```
---
### Path
| Method | Description | Response |
| ------------ | ---------------- | ---------------------------------------- |
| `path.get()` | Get current path | <a href={typesUrl}><code>Path</code></a> |
---
#### Examples
```javascript
// Get current path information
const pathInfo = await client.path.get()
```
---
@@ -159,7 +206,7 @@ const { providers, default: defaults } = await client.config.providers()
| `session.summarize({ id, providerID, modelID })` | Summarize session | Returns `boolean` |
| `session.messages({ id })` | List messages in a session | Returns `{ info: `<a href={typesUrl}><code>Message</code></a>`, parts: `<a href={typesUrl}><code>Part[]</code></a>`}[]` |
| `session.message({ id, messageID })` | Get message details | Returns `{ info: `<a href={typesUrl}><code>Message</code></a>`, parts: `<a href={typesUrl}><code>Part[]</code></a>`}` |
| `session.chat({ id, ...chatInput })` | Send chat message | Returns <a href={typesUrl}><code>Message</code></a> |
| `session.prompt({ id, ...promptInput })` | Send prompt message | Returns <a href={typesUrl}><code>Message</code></a> |
| `session.shell({ id, agent, command })` | Run a shell command | Returns <a href={typesUrl}><code>Message</code></a> |
| `session.revert({ id, messageID, partID? })` | Revert a message | Returns <a href={typesUrl}><code>Session</code></a> |
| `session.unrevert({ id })` | Restore reverted messages | Returns <a href={typesUrl}><code>Session</code></a> |
@@ -175,10 +222,12 @@ const session = await client.session.create({ title: "My session" })
const sessions = await client.session.list()
// Send messages
const message = await client.session.chat({
const message = await client.session.prompt({
id: session.id,
providerID: "anthropic",
modelID: "claude-3-5-sonnet-20241022",
model: {
providerID: "anthropic",
modelID: "claude-3-5-sonnet-20241022",
},
parts: [{ type: "text", text: "Hello!" }],
})
```