Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e05b656
scaffold project with pnpm, posthog-node, and opencode plugin types
Quantumlyy Apr 5, 2026
e66f727
add types, utilities, and version module
Quantumlyy Apr 5, 2026
1fca5a9
add event builders for generation, span, and trace
Quantumlyy Apr 5, 2026
b191247
add plugin entry point with event router and state management
Quantumlyy Apr 5, 2026
5cf9ca8
add README with configuration, events, and privacy docs
Quantumlyy Apr 5, 2026
feca479
remove dead loop in session idle cleanup
Quantumlyy Apr 5, 2026
edfc0be
fix span parenting and string-level secret redaction
Quantumlyy Apr 5, 2026
a9003b5
add vitest tests for event builders and utilities
Quantumlyy Apr 5, 2026
60ab456
fix bearer token redaction, error field leaks, and per-step input con…
Quantumlyy Apr 5, 2026
5003b3f
use static import for posthog-node instead of dynamic import()
Quantumlyy Apr 5, 2026
3105794
redact tool output in step input, clean up per-message state, fix README
Quantumlyy Apr 5, 2026
c0348b5
set version to 0.0.1, add author, CI workflow, and reorder package.json
Quantumlyy Apr 5, 2026
700fc7d
add oxlint/oxfmt, license headers, derive version from package.json
Quantumlyy Apr 5, 2026
d63a62f
update README install instructions to match OpenCode plugin docs
Quantumlyy Apr 5, 2026
9c2358f
switch from pnpm to bun
Quantumlyy Apr 5, 2026
997063b
fix CI: replace pnpm with bun run in workflow steps
Quantumlyy Apr 5, 2026
6aafb71
fix step-input ordering and cache token property names
Quantumlyy Apr 5, 2026
df16bf9
configure package.json and tsconfig for npm publishing
Quantumlyy Apr 5, 2026
63b58df
only ship dist in npm package
Quantumlyy Apr 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
dist/
*.tsbuildinfo
.context/
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
# opencode-posthog
# opencode-posthog

PostHog LLM Analytics plugin for [OpenCode](https://opencode.ai). Captures LLM generations, tool executions, and conversation traces, sending them to PostHog as structured `$ai_*` events for the LLM Analytics dashboard.

## Installation

Add to your `opencode.json`:

```json
{
"plugin": ["opencode-posthog"]
}
```

Or for local development, copy `src/index.ts` to `.opencode/plugins/posthog.ts`.

## Configuration

All configuration is via environment variables:

| Variable | Default | Description |
|---|---|---|
| `POSTHOG_API_KEY` | _(required)_ | PostHog project API key |
| `POSTHOG_HOST` | `https://us.i.posthog.com` | PostHog instance URL |
| `POSTHOG_PRIVACY_MODE` | `false` | Redact all LLM input/output content when `true` |
| `POSTHOG_ENABLED` | `true` | Set `false` to disable |
| `POSTHOG_DISTINCT_ID` | machine hostname | The `distinct_id` for all events |
| `POSTHOG_PROJECT_NAME` | cwd basename | Project name in all events |
| `POSTHOG_TAGS` | _(none)_ | Custom tags: `key1:val1,key2:val2` |
| `POSTHOG_MAX_ATTRIBUTE_LENGTH` | `12000` | Max length for serialized tool input/output |

If `POSTHOG_API_KEY` is not set, the plugin is a no-op.

## Events

### `$ai_generation` — per LLM call

Emitted for each LLM roundtrip (step-finish part). Properties include:

- `$ai_model`, `$ai_provider` — model and provider identifiers
- `$ai_input_tokens`, `$ai_output_tokens`, `$ai_reasoning_tokens` — token counts
- `$ai_cache_read_input_tokens`, `$ai_cache_creation_input_tokens` — cache token counts
- `$ai_total_cost_usd` — cost in USD
- `$ai_latency` — not available per-step (use trace-level latency)
- `$ai_stop_reason` — `stop`, `tool_calls`, `error`, etc.
- `$ai_input`, `$ai_output_choices` — message content (null in privacy mode)
- `$ai_trace_id`, `$ai_span_id`, `$ai_session_id` — correlation IDs

### `$ai_span` — per tool execution

Emitted when a tool call completes or errors. Properties include:

- `$ai_span_name` — tool name (`read`, `write`, `bash`, `edit`, etc.)
- `$ai_latency` — execution time in seconds
- `$ai_input_state`, `$ai_output_state` — tool input/output (null in privacy mode)
- `$ai_parent_id` — span ID of the generation that triggered this tool
- `$ai_is_error`, `$ai_error` — error status

### `$ai_trace` — per user prompt

Emitted on `session.idle` (agent finished responding). Properties include:

- `$ai_trace_id`, `$ai_session_id` — correlation IDs
- `$ai_latency` — total trace time in seconds
- `$ai_total_input_tokens`, `$ai_total_output_tokens` — accumulated token counts
- `$ai_input_state`, `$ai_output_state` — user prompt and final response
- `$ai_is_error` — whether any step/tool errored

## Privacy

When `POSTHOG_PRIVACY_MODE=true`, all content fields (`$ai_input`, `$ai_output_choices`, `$ai_input_state`, `$ai_output_state`) are set to `null`. Token counts, costs, latency, and model metadata still flow.

Sensitive keys (matching `api_key`, `token`, `secret`, `password`, `authorization`, `credential`, `private_key`) are always redacted in tool inputs/outputs regardless of privacy mode.

## License

MIT
37 changes: 37 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "opencode-posthog",
"version": "0.1.0",
"description": "PostHog LLM Analytics plugin for OpenCode",
"type": "module",
"license": "MIT",
"main": "src/index.ts",
"keywords": [
"opencode-plugin",
"posthog",
"ai",
"llm",
"observability",
"tracing",
"analytics"
],
"packageManager": "pnpm@10.12.1",
"files": [
"src",
"!src/**/*.test.ts"
],
"dependencies": {
"posthog-node": "^5.0.0"
},
"peerDependencies": {
"@opencode-ai/plugin": "*"
},
"devDependencies": {
"@opencode-ai/plugin": "*",
"@opencode-ai/sdk": "*",
"@types/node": "^22.0.0",
"typescript": "^5.8.0"
},
"scripts": {
"typecheck": "tsc --noEmit"
}
}
139 changes: 139 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading