Instructions for AI agents working in this repository.
Always run after making changes:
bun run typecheckThere is no build step. TypeScript source files are published directly and loaded natively by Bun.
bun testsrc/
├── index.ts — Plugin entrypoint
├── types.ts — Shared types
├── config.ts — Env config and log level
├── otel.ts — OTel SDK setup and instruments
├── probe.ts — OTLP endpoint TCP probe
├── util.ts — errorSummary, setBoundedMap
└── handlers/
├── session.ts — Session lifecycle events
├── message.ts — LLM message and tool part events
├── permission.ts — Tool permission events
└── activity.ts — File diffs and git commits
- Bun over Node — use
bun,bun test,bun run. Never usenode,npx,jest, orvitest. - No comments unless explicitly requested.
- No
sdk-node— the OTel Node SDK meta-package is intentionally excluded; use individual packages. HandlerContext— all event handlers receive aHandlerContext(defined insrc/types.ts). Do not importclientor OTel globals directly inside handlers; thread them through the context.setBoundedMap— always use this instead ofMap.setforpendingToolSpansandpendingPermissionsto prevent unbounded growth.- Single source of truth for tokens/cost — token and cost counters are incremented only in
message.updated(src/handlers/message.ts), never instep-finish. - Shutdown — OTel providers are flushed via
SIGTERM/SIGINT/beforeExit. Do not useprocess.on("exit")for async flushing. - All env vars are
OPENCODE_prefixed —OPENCODE_ENABLE_TELEMETRY,OPENCODE_OTLP_ENDPOINT,OPENCODE_OTLP_METRICS_INTERVAL,OPENCODE_OTLP_LOGS_INTERVAL,OPENCODE_METRIC_PREFIX,OPENCODE_OTLP_HEADERS,OPENCODE_RESOURCE_ATTRIBUTES. Never use bareOTEL_*names for plugin config.loadConfigcopiesOPENCODE_OTLP_HEADERS→OTEL_EXPORTER_OTLP_HEADERSandOPENCODE_RESOURCE_ATTRIBUTES→OTEL_RESOURCE_ATTRIBUTESbefore the SDK initializes. OPENCODE_ENABLE_TELEMETRY— all OTel instrumentation is gated on this env var. The plugin always loads regardless; only telemetry is disabled when unset.OPENCODE_METRIC_PREFIX— defaults toopencode.; set toclaude_code.for Claude Code dashboard compatibility.
All commits must follow Conventional Commits:
<type>[optional scope]: <description>
Common types: feat, fix, perf, refactor, test, docs, ci, chore, build.
Use ! or a BREAKING CHANGE: footer for breaking changes.
Examples:
feat(handlers): add support for file.edited event
fix(probe): handle malformed endpoint URL without throwing
chore(deps): bump @opentelemetry/api to 1.10.0