@prata.ma/anvil-opencode
v0.3.1
Published
OpenCode session ingestion and finalize integration for Anvil workspaces.
Readme
@prata.ma/anvil-opencode
OpenCode session ingestion and finalize integration for Anvil workspaces.
Overview
@prata.ma/anvil-opencode is Anvil's package boundary for OpenCode-specific session integration. It exports a native OpenCode plugin plus library helpers that resolve the owning Anvil workspace, normalize OpenCode local storage or markdown transcript artifacts into the canonical @prata.ma/anvil-sync session model, finalize sessions through the sync runtime, and optionally refresh summary and transcript indexes through @prata.ma/anvil-search without making derived refresh failure block canonical finalize success.
The current package surface focuses on:
- nearest-manifest workspace resolution from an OpenCode artifact path
- OpenCode markdown transcript normalization into canonical sync session input
- OpenCode local storage normalization from
~/.local/share/opencode/storage - fixture-backed ingest through
@prata.ma/anvil-sync - finalize plus deterministic projection export through
@prata.ma/anvil-sync - optional targeted summary and transcript reindexing through
@prata.ma/anvil-search, with refresh failure reported separately from canonical finalize success - a native OpenCode plugin that finalizes sessions when OpenCode emits
session.idle
Installation
Install from npm or consume it through a workspace dependency while developing inside this monorepo.
npm
pnpm add @prata.ma/anvil-opencodeWorkspace
{
"dependencies": {
"@prata.ma/anvil-opencode": "workspace:*"
}
}Usage
@prata.ma/anvil-opencode supports both direct OpenCode plugin loading and library-style integration flows.
OpenCode Plugin
Add the package to OpenCode config.
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@prata.ma/anvil-opencode"]
}The plugin listens for session.idle, waits briefly for OpenCode to flush local storage, reads the session from OpenCode's local storage, finalizes it through @prata.ma/anvil-sync, exports summary and transcript projections, and refreshes search by default.
Environment
| Variable | Purpose |
| ------------------------------------------------- | ------------------------------------------------------ |
| ANVIL_OPENCODE_REFRESH_SEARCH=false | Disable default summary and transcript search refresh. |
| ANVIL_OPENCODE_IDLE_DELAY_MS=1000 | Override the post-idle storage flush delay. |
| ANVIL_OPENCODE_STORAGE_ROOT=/path/to/storage | Override OpenCode local storage root. |
| ANVIL_SYNC_DATABASE_PATH=/path/to/sync.db | Override the canonical sync database path. |
| ANVIL_SYNC_PROJECTION_ROOT=/path/to/projections | Override the projection output root. |
| ANVIL_SEARCH_DATABASE_PATH=/path/to/search.db | Override the derived search database path. |
Library
import { finalizeOpenCodeStoredSession } from '@prata.ma/anvil-opencode'
const result = await finalizeOpenCodeStoredSession({
sessionId: 'ses_123',
refreshSearch: true,
summary: {
overview: 'Captured the package integration outcome.',
},
})
console.log(result.workspace.workspaceId)
console.log(result.finalize.session.status)Patterns
Common package flows include:
- resolving the owning workspace from the nearest
anvil.yaml - normalizing a transcript-shaped markdown artifact into canonical sync session input
- ingesting the transcript before finalization so the canonical session stays reconciled to the latest local artifact
- exporting deterministic summary and transcript projections and then optionally refreshing the corresponding search indexes
API
@prata.ma/anvil-opencode exposes one root library surface.
Exports
@prata.ma/anvil-opencode- root library surface@prata.ma/anvil-opencode/plugin- native OpenCode plugin entrypoint- workspace resolver
resolveOpenCodeWorkspace - normalizers
normalizeOpenCodeSessionFileandnormalizeOpenCodeStoredSession - runtime helpers
ingestOpenCodeSessionFile,finalizeOpenCodeSessionFile,finalizeOpenCodeStoredSession, andrefreshOpenCodeSessionSearch - integration factories
createAnvilOpenCodeIntegrationandcreateAnvilOpenCodePlugin - package types for workspace resolution, normalized sessions, ingest results, finalize results, and refresh results
Integration Contract
The public contract stays intentionally narrow:
- input: an OpenCode transcript artifact path plus optional workspace or runtime overrides
- input: an OpenCode local storage session id plus optional workspace or runtime overrides
- canonical output:
@prata.ma/anvil-syncsession ingest and finalize results - optional derived output:
@prata.ma/anvil-searchsummary and transcript refresh results - optional derived refresh failure:
searchRefreshErrorwhen reindexing fails after canonical finalize already succeeded
Raw OpenCode storage details remain internal implementation details behind the normalized sync-facing shape.
Development
Use the package-local scripts while working in @packages/anvil-opencode, and keep OpenCode-specific parsing here while delegating canonical storage and search ownership to the dedicated runtime packages.
Commands
pnpm --filter @prata.ma/anvil-opencode build
pnpm --filter @prata.ma/anvil-opencode lint
pnpm --filter @prata.ma/anvil-opencode test
pnpm --filter @prata.ma/anvil-opencode test:typeTesting
The current tests cover:
- workspace resolution from a transcript artifact path
- transcript normalization into canonical message and part shapes
- OpenCode local storage normalization and native plugin idle finalization
- canonical ingest through
@prata.ma/anvil-sync - finalize plus projection export
- optional targeted summary and transcript search refresh
Conventions
- keep OpenCode-specific parsing in this package rather than in
@prata.ma/anvil-sync - keep canonical writes routed only through the sync runtime
- keep search refresh optional and explicit rather than broad or background-driven
- keep canonical finalize success separate from best-effort derived refresh failure
- keep the native plugin thin over the same normalized runtime helpers used by library consumers
Status
This package is active and currently covers the first official fixture-backed OpenCode integration slice.
Maturity
@prata.ma/anvil-opencode is publish-prepared and validated as a package-owned integration layer over @prata.ma/anvil-sync and @prata.ma/anvil-search.
Scope
The current surface handles native OpenCode plugin loading, workspace resolution, local storage and markdown transcript normalization, canonical ingest, finalize, projection export, and targeted search refresh. When refresh fails, the package still returns the canonical finalize result and reports the derived refresh failure separately. Non-OpenCode integrations remain out of scope.
Notes
@prata.ma/anvil-opencodedepends on@prata.ma/anvil-syncfor canonical state and on@prata.ma/anvil-searchfor derived indexing; it does not own either concern itself.- The package uses OpenCode local storage for the native plugin path and keeps markdown transcript parsing as a direct library path.
- The plugin remains thin over the same package-owned runtime contract used by explicit library calls.
