Skip to content

Latest commit

 

History

History
137 lines (100 loc) · 4.58 KB

File metadata and controls

137 lines (100 loc) · 4.58 KB

Contributing

Prerequisites

  • Bun v1.0+
  • An opencode installation for manual testing

Getting started

git clone https://github.com/devtheops/opencode-plugin-otel
cd opencode-plugin-otel
bun install

Development workflow

Install dependencies in the checkout with bun install. In the project where you run OpenCode, create .opencode/plugins/otel/index.ts:

export { default } from "/path/to/opencode-plugin-otel/src/index.ts"

OpenCode V2 discovers the directory automatically and loads TypeScript via Bun, so there is no build step during development. A plugins entry pointing directly to an absolute .ts file is rejected by OpenCode 2.0.1.

Branching: main targets OpenCode V2. The OpenCode V1 plugin is maintained on the v1 branch (branched from the last 1.x tag) — open V1 bug/security fixes against v1, not main.

Commands

Command Description
bun run lint Run ESLint, including JSDoc formatting checks
bun run check:jsdoc-coverage Enforce minimum JSDoc coverage for exported API declarations
bun run typecheck Type-check all sources without emitting
bun test Run the test suite

Project structure

src/
├── index.ts              — Plugin entrypoint (V2 default export)
├── plugin.ts             — setup(): config, hooks, event subscription
├── state.ts              — shared OTel SDK + tracing state
├── types.ts              — Shared types (Level, HandlerContext, Instruments, etc.)
├── config.ts             — Environment config loading and log level resolution
├── otel.ts               — OTel SDK setup, resource construction, instrument creation
├── probe.ts              — TCP connectivity probe for the OTLP endpoint
├── util.ts               — Utility functions (errorSummary, setBoundedMap)
└── handlers/
    ├── session.ts        — session.created / session.execution.* / session.status
    ├── step.ts           — session.step.* (LLM spans + token/cost metrics)
    ├── tool.ts           — session.tool.* (tool spans, subagents, duration, commits)
    ├── permission.ts     — permission.asked / permission.replied
    └── chat-headers.ts   — context preview and model.request / WebSocket propagation

Testing locally with a collector

The easiest way to verify telemetry is being emitted is to run a local OpenTelemetry collector:

docker run --rm -p 4317:4317 \
  otel/opentelemetry-collector:latest

Then set OPENCODE_ENABLE_TELEMETRY=1 and start opencode. The collector will print received spans and metrics to stdout.

Commit messages

This project follows Conventional Commits. All commits must be structured as:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Types

Type When to use
feat A new feature (triggers a minor version bump)
fix A bug fix (triggers a patch version bump)
perf A performance improvement
refactor Code change that is neither a fix nor a feature
test Adding or updating tests
docs Documentation only changes
ci CI/CD configuration changes
chore Maintenance tasks (dependency updates, etc.)
build Changes to the build system

Breaking changes

Append ! after the type or add a BREAKING CHANGE: footer:

feat!: drop support for OTLP HTTP

BREAKING CHANGE: only OTLP/gRPC is supported going forward

Examples

feat(handlers): add support for file.edited event
fix(probe): handle malformed endpoint URL without throwing
docs: update Datadog configuration example
chore(deps): bump @opentelemetry/api to 1.10.0

Submitting changes

  1. Fork the repo and create a branch from main: git checkout -b feat/my-feature
  2. Make your changes and ensure bun run lint, bun run check:jsdoc-coverage, bun run typecheck, and bun test pass
  3. Commit using Conventional Commits format
  4. Open a pull request with a clear, human-readable title and link any related issues in the description

Releasing

Releases are handled via GitHub Actions. See the release workflow. To cut a release, push a version tag:

git tag v1.2.3
git push origin v1.2.3

The version bump should follow SemVer based on the commits since the last release:

  • fix commits → patch (1.0.x)
  • feat commits → minor (1.x.0)
  • BREAKING CHANGE commits → major (x.0.0)