mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-20 01:04:22 +01:00
docs: sdk
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
import { Plugin } from "./index"
|
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 {
|
return {
|
||||||
permission: {},
|
permission: {},
|
||||||
async "chat.params"(input, output) {
|
async "chat.params"(_input, output) {
|
||||||
output.topP = 1
|
output.topP = 1
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
55
packages/sdk/js/example/example.ts
Normal file
55
packages/sdk/js/example/example.ts
Normal 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)
|
||||||
|
}),
|
||||||
|
)
|
||||||
@@ -26,7 +26,7 @@ Plugins are loaded from:
|
|||||||
### Basic structure
|
### Basic structure
|
||||||
|
|
||||||
```js title=".opencode/plugin/example.js"
|
```js title=".opencode/plugin/example.js"
|
||||||
export const MyPlugin = async ({ app, client, $ }) => {
|
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
|
||||||
console.log("Plugin initialized!")
|
console.log("Plugin initialized!")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -37,7 +37,9 @@ export const MyPlugin = async ({ app, client, $ }) => {
|
|||||||
|
|
||||||
The plugin function receives:
|
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.
|
- `client`: An opencode SDK client for interacting with the AI.
|
||||||
- `$`: Bun's [shell API](https://bun.com/docs/runtime/shell) for executing commands.
|
- `$`: 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}
|
```ts title="my-plugin.ts" {1}
|
||||||
import type { Plugin } from "@opencode-ai/plugin"
|
import type { Plugin } from "@opencode-ai/plugin"
|
||||||
|
|
||||||
export const MyPlugin: Plugin = async ({ app, client, $ }) => {
|
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
|
||||||
return {
|
return {
|
||||||
// Type-safe hook implementations
|
// 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:
|
Send notifications when certain events occur:
|
||||||
|
|
||||||
```js title=".opencode/plugin/notification.js"
|
```js title=".opencode/plugin/notification.js"
|
||||||
export const NotificationPlugin = async ({ client, $ }) => {
|
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
|
||||||
return {
|
return {
|
||||||
event: async ({ event }) => {
|
event: async ({ event }) => {
|
||||||
// Send notification on session completion
|
// 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:
|
Prevent opencode from reading `.env` files:
|
||||||
|
|
||||||
```javascript title=".opencode/plugin/env-protection.js"
|
```javascript title=".opencode/plugin/env-protection.js"
|
||||||
export const EnvProtection = async ({ client, $ }) => {
|
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
|
||||||
return {
|
return {
|
||||||
"tool.execute.before": async (input, output) => {
|
"tool.execute.before": async (input, output) => {
|
||||||
if (input.tool === "read" && output.args.filePath.includes(".env")) {
|
if (input.tool === "read" && output.args.filePath.includes(".env")) {
|
||||||
throw new Error("Do not read .env files")
|
throw new Error("Do not read .env files")
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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.
|
[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
|
## Install
|
||||||
@@ -66,7 +68,7 @@ server.close()
|
|||||||
#### Options
|
#### Options
|
||||||
|
|
||||||
| Option | Type | Description | Default |
|
| Option | Type | Description | Default |
|
||||||
| ---------- | -------------- | ------------------------------ | ------------- |
|
| ---------- | ------------- | ------------------------------ | ----------- |
|
||||||
| `hostname` | `string` | Server hostname | `127.0.0.1` |
|
| `hostname` | `string` | Server hostname | `127.0.0.1` |
|
||||||
| `port` | `number` | Server port | `4096` |
|
| `port` | `number` | Server port | `4096` |
|
||||||
| `signal` | `AbortSignal` | Abort signal for cancellation | `undefined` |
|
| `signal` | `AbortSignal` | Abort signal for cancellation | `undefined` |
|
||||||
@@ -80,7 +82,7 @@ The SDK includes TypeScript definitions for all API types. Import them directly:
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import type { Session, Message, Part } from "@opencode-ai/sdk"
|
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>.
|
All types are generated from the server's OpenAPI specification and available in the <a href={typesUrl}>types file</a>.
|
||||||
|
|
||||||
@@ -109,17 +111,62 @@ The SDK exposes all server APIs through a type-safe client interface.
|
|||||||
### App
|
### App
|
||||||
|
|
||||||
| Method | Description | Response |
|
| Method | Description | Response |
|
||||||
| ------------ | ------------------ | --------------------------------------- |
|
| -------------- | ------------------------- | ------------------------------------------- |
|
||||||
| `app.get()` | Get app info | <a href={typesUrl}><code>App</code></a> |
|
| `app.log()` | Write a log entry | `boolean` |
|
||||||
| `app.init()` | Initialize the app | `boolean` |
|
| `app.agents()` | List all available agents | <a href={typesUrl}><code>Agent[]</code></a> |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const app = await client.app.get()
|
// Log an entry
|
||||||
await client.app.init()
|
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.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.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.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.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.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> |
|
| `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()
|
const sessions = await client.session.list()
|
||||||
|
|
||||||
// Send messages
|
// Send messages
|
||||||
const message = await client.session.chat({
|
const message = await client.session.prompt({
|
||||||
id: session.id,
|
id: session.id,
|
||||||
|
model: {
|
||||||
providerID: "anthropic",
|
providerID: "anthropic",
|
||||||
modelID: "claude-3-5-sonnet-20241022",
|
modelID: "claude-3-5-sonnet-20241022",
|
||||||
|
},
|
||||||
parts: [{ type: "text", text: "Hello!" }],
|
parts: [{ type: "text", text: "Hello!" }],
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user