summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/plugin/src/example.ts10
-rw-r--r--packages/sdk/js/example/example.ts55
-rw-r--r--packages/web/src/content/docs/docs/plugins.mdx14
-rw-r--r--packages/web/src/content/docs/docs/sdk.mdx83
4 files changed, 137 insertions, 25 deletions
diff --git a/packages/plugin/src/example.ts b/packages/plugin/src/example.ts
index a13c0fbac..04c48c918 100644
--- a/packages/plugin/src/example.ts
+++ b/packages/plugin/src/example.ts
@@ -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
},
}
diff --git a/packages/sdk/js/example/example.ts b/packages/sdk/js/example/example.ts
new file mode 100644
index 000000000..481fc4240
--- /dev/null
+++ b/packages/sdk/js/example/example.ts
@@ -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)
+ }),
+)
diff --git a/packages/web/src/content/docs/docs/plugins.mdx b/packages/web/src/content/docs/docs/plugins.mdx
index 22c78b0b3..071f1d427 100644
--- a/packages/web/src/content/docs/docs/plugins.mdx
+++ b/packages/web/src/content/docs/docs/plugins.mdx
@@ -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")
}
- }
+ },
}
}
```
diff --git a/packages/web/src/content/docs/docs/sdk.mdx b/packages/web/src/content/docs/docs/sdk.mdx
index 3b4353d82..1e537362f 100644
--- a/packages/web/src/content/docs/docs/sdk.mdx
+++ b/packages/web/src/content/docs/docs/sdk.mdx
@@ -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
+// 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
-const app = await client.app.get()
-await client.app.init()
+// 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!" }],
})
```