Skip to content
Open
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
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ Add the plugin to your [OpenCode config](https://opencode.ai/docs/config/):

### OpenCode V2

OpenCode V2 uses the new plugin API. You can load `opencode-pty/v2` and optionally configure options (such as a fixed web UI port):
OpenCode V2 uses the new plugin API. Load the package by its bare npm ref — the `.` entrypoint is a dual-mode export that serves both runtimes — and optionally configure options (such as a fixed web UI port):

```json
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"plugins": [
{
"package": "opencode-pty/v2",
"package": "opencode-pty",
"options": {
"port": 4200,
"hostname": "127.0.0.1",
Expand All @@ -61,6 +61,11 @@ OpenCode V2 uses the new plugin API. You can load `opencode-pty/v2` and optional
}
```

Notes for V2:

- V2 reads the `plugins` array (object form). The V1 `plugin` field is silently ignored — a V1-shaped array produces zero plugin loads.
- The previous `opencode-pty/v2` subpath ref does not install: the V2 loader parses subpath refs as npm install specs ([#67](https://github.com/shekohex/opencode-pty/issues/67)). The bare ref works via the dual-mode default export; the `./v2` subpath remains valid for direct-import consumers.

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `port` | `number` | `0` (ephemeral) | Fixed port for the PTY Web UI observer server |
Expand Down
15 changes: 15 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
import { Plugin } from './src/v2/index.ts'
import { PTYPlugin } from './src/plugin.ts'

export { PTYPlugin } from './src/plugin.ts'
export { PTYPlugin as server } from './src/plugin.ts'
export { Plugin } from './src/v2/index.ts'

// Dual-mode default export: opencode V1 (>= 1.18.29) resolves the object entrypoint and
// calls `server()`; V2 validates `{ id, setup }` and calls `setup()`. The bare npm ref
// therefore loads on both runtimes — necessary because the V2 loader parses the
// documented `opencode-pty/v2` subpath ref as an npm install spec and cannot install it
// (#67), and the previous `.` entrypoint carried no default export at all.
export default {
id: Plugin.id,
server: PTYPlugin,
setup: Plugin.setup,
}
25 changes: 25 additions & 0 deletions test/dual-mode-default.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from 'bun:test'
import defaults, { PTYPlugin } from '../index.ts'
import { Plugin } from '../src/v2/index.ts'

// The bare npm ref resolves the `.` entrypoint's default export on both runtimes:
// V1 (>= 1.18.29) calls `server()`, V2 validates `{ id, setup }` and calls `setup()`.
// Before the dual-mode export the `.` entrypoint had no default at all, so the bare
// ref schema-failed on V2 (#67) and the only working path was the `./v2` subpath —
// which the V2 loader cannot install (it parses subpath refs as npm install specs).
describe('dual-mode default export', () => {
it('carries the V2 id and setup', () => {
expect(defaults.id).toBe('opencode-pty')
expect(defaults.setup).toBe(Plugin.setup)
expect(typeof defaults.setup).toBe('function')
})

it('carries the V1 server entrypoint', () => {
expect(defaults.server).toBe(PTYPlugin)
expect(typeof defaults.server).toBe('function')
})

it('re-exports the V2 plugin by name', () => {
expect(Plugin.id).toBe('opencode-pty')
})
})