# Fisshing for OpenCode

Check on OpenCode and answer its questions from **Profile → Agent Desk** while
you fish. The plugin sends your answers back to OpenCode. You don’t need a
sidecar, and you still approve commands and file changes in OpenCode.

This version supports OpenCode 1.18.29. See the compatibility notes below for
the API details.

## Install

OpenCode loads local `.js` and `.ts` plugins from `.opencode/plugins/` or
`~/.config/opencode/plugins/`. Copy the entrypoint and its two local modules
from this directory to one of those locations:

```sh
curl -fsSLO https://fisshing.net/integrations/fisshing-opencode-plugin.tar.gz
tar -xzf fisshing-opencode-plugin.tar.gz
cd fisshing-opencode
mkdir -p ~/.config/opencode/plugins
cp fisshing.js fisshing-opencode.mjs fisshing-api.mjs ~/.config/opencode/plugins/
export FISSHING_API_KEY='your-key-from-Profile-API-Key'
opencode
```

`fisshing.js` is the only auto-loaded plugin. It exports one server plugin and
imports `fisshing-opencode.mjs`, which imports the shared `fisshing-api.mjs` client.

Use the key from the character you play. SSH and browser characters have
separate keys. Keep the key in the local environment.

## Data and limits

The plugin registers up to eight OpenCode sessions for one player. It stores
only the Agent Desk id and token in
`~/.local/state/fisshing/opencode` with private file permissions. Set
`FISSHING_PLUGIN_STATE_DIR` to use another private directory.

The plugin sends the agent name, project folder name, task status, and
questions with their choices. It limits the length of questions. It does not send transcripts, prompts,
file contents, command output, or secrets. Agent Desk question ids include the
OpenCode session, request, question index, and question text. A late reply
cannot answer a later question.

The poll interval is two seconds and status heartbeats are limited to one per
ten seconds. Questions wait for five minutes by default. Set
`FISSHING_QUESTION_TIMEOUT_MS` up to ten minutes or
`FISSHING_QUESTION_POLL_MS` when needed. On timeout or an unavailable desk,
the native OpenCode question stays available. If OpenCode or the player
answers first, the plugin stops its poll and sends no second answer.

Set `FISSHING_BASE_URL` to use another Fisshing server. HTTPS is required for
the Agent Desk; localhost HTTP is allowed for local development. When the
OpenCode server uses `OPENCODE_SERVER_PASSWORD`, the native fallback sends
the documented Basic Auth header using `OPENCODE_SERVER_USERNAME` or the
default `opencode` user.

## Compatibility notes

The supported target is OpenCode 1.18.29 with
`@opencode-ai/plugin` 1.18.29 and the versioned `@opencode-ai/sdk/v2`
question contract from the same release. The `v2` name is the SDK namespace;
the plugin uses the OpenCode 1.x server supplied by the harness. The route is
`POST /question/:requestID/reply` with an `answers` array. The plugin first
uses `client.question.reply` and `client.question.list` when the harness
exposes them. It otherwise uses the supplied `serverUrl` and these same native
routes. It checks the exact request id in the current pending-question list
before it posts an answer. It never starts a server.

The contract is documented in the official OpenCode sources:

- [Plugin API](https://dev.opencode.ai/docs/plugins/)
- [Plugin input and event hook](https://github.com/anomalyco/opencode/blob/v1.18.29/packages/plugin/src/index.ts)
- [SDK v2 client transport](https://github.com/anomalyco/opencode/blob/v1.18.29/packages/sdk/js/src/v2/client.ts)
- [Native question reply method](https://github.com/anomalyco/opencode/blob/v1.18.29/packages/sdk/js/src/v2/gen/sdk.gen.ts#L2896-L2994)
