# @sketchi-app/opencode-excalidraw

OpenCode plugin for generating and manipulating Excalidraw diagrams via Sketchi.

## Quickstart

1. Add the plugin to your `opencode.jsonc`:

```jsonc
{
  "plugin": ["@sketchi-app/opencode-excalidraw"]
}
```

2. Install the package:

```bash
npm i @sketchi-app/opencode-excalidraw
```

3. Install Playwright browsers once per machine (required for `diagram_to_png`):

```bash
npx playwright install chromium
```

If browsers are missing, PNG-related tools fail fast with this install command. They do not auto-install browser binaries during execution.

## Usage

The plugin exposes tools:

- `diagram_from_prompt`
- `diagram_tweak`
- `diagram_restructure`
- `diagram_to_png`
- `diagram_grade`

`diagram_grade` is intentionally one-image-per-call. For multiple diagrams, invoke `diagram_grade` in separate follow-up messages.

When this plugin is loaded, it registers a `sketchi-diagram` subagent (without disabling built-in `build`/`plan`) and conditionally injects routing guidance only when the user request mentions `diagram`, `sketchi`, or `excalidraw`, so diagram requests route to `diagram_*` tools instead of defaulting to Mermaid (unless Mermaid is explicitly requested).

## Configuration

Optional env override:

- `SKETCHI_API_URL` (defaults to `https://www.sketchi.app`)
- `SKETCHI_ALLOW_UNSAFE_OUTPUT_PATH=1` to opt out of default output-path containment (power users only)

Authentication is required for diagram APIs. In OpenCode, select auth provider `sketchi`:

- `Sign in with Sketchi (device flow)`
- Open the verification URL, sign in, and approve the displayed device code

Optional env-based auth fallback (used when OpenCode auth is not configured):

- `SKETCHI_ACCESS_TOKEN` or `SKETCHI_BEARER_TOKEN` (OAuth bearer token)

## Output Paths

PNG outputs are session-scoped by default:

- root: `/.sketchi/sessions/<opencode-session-id>/png/`
- auto-generated files (`diagram_from_prompt`, `diagram_tweak`, `diagram_restructure`, `diagram_to_png`, `diagram_grade`) are written under this root
- tool-provided `outputPath` values are constrained to this root by default

Examples:

- `outputPath: "foo.png"` -> `/.sketchi/sessions/<sessionID>/png/foo.png`
- `outputPath: "exports/foo.png"` -> `/.sketchi/sessions/<sessionID>/png/exports/foo.png`

Traversal attempts and absolute paths outside the session root are rejected unless `SKETCHI_ALLOW_UNSAFE_OUTPUT_PATH=1` is set.

## Testing

- Fast package tests: `bun run test`
- Optional live integration scenario (calls Sketchi API and renders PNG): `bun run test:integration`

## Release Channels

Plugin publishing uses two channels:

- `next`: published for plugin iterations on `main` when a formal release was not created.
- `latest`: published only when release-please creates an actual release (after merging the release PR).

Practical flow:

1. Keep the release PR open while validating behavior via real OpenCode install/upgrade cycles.
2. Consume `next` builds for validation.
3. Merge the release PR when ready to promote that version to `latest`.

## Links

- npm: https://www.npmjs.com/package/@sketchi-app/opencode-excalidraw
- GitHub: https://github.com/shpitdev/sketchi/tree/main/packages/opencode-excalidraw
