Files
agentlens/apps/web/src/app/docs/opencode-plugin/page.tsx

217 lines
10 KiB
TypeScript

import type { Metadata } from "next";
import { CodeBlock } from "@/components/code-block";
export const metadata: Metadata = {
title: "OpenCode Plugin",
description:
"Capture OpenCode sessions including tool calls, LLM calls, file edits, and git diffs with the AgentLens OpenCode plugin.",
};
export default function OpenCodePluginPage() {
return (
<div>
<h1 className="text-4xl font-bold tracking-tight mb-4">
OpenCode Plugin
</h1>
<p className="text-lg text-neutral-400 mb-10 leading-relaxed">
The AgentLens OpenCode plugin captures everything that happens during an
OpenCode coding session and sends it as structured traces to your
AgentLens instance.
</p>
<section className="mb-12">
<h2 className="text-2xl font-semibold mb-4">Installation</h2>
<CodeBlock title="terminal" language="bash">{`npm install opencode-agentlens`}</CodeBlock>
</section>
<section className="mb-12">
<h2 className="text-2xl font-semibold mb-4">Configuration</h2>
<p className="text-neutral-400 leading-relaxed mb-4">
Add the plugin to your <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">opencode.json</code> configuration file:
</p>
<CodeBlock title="opencode.json" language="json">{`{
"plugin": ["opencode-agentlens"]
}`}</CodeBlock>
<p className="text-neutral-400 leading-relaxed mt-4 mb-4">
Set the required environment variables:
</p>
<CodeBlock title="terminal" language="bash">{`export AGENTLENS_API_KEY="your-api-key"
export AGENTLENS_ENDPOINT="https://agentlens.vectry.tech"`}</CodeBlock>
<p className="text-neutral-400 leading-relaxed mt-4">
You can also add these to a <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">.env</code> file in your project root.
</p>
</section>
<section className="mb-12">
<h2 className="text-2xl font-semibold mb-4">What gets captured</h2>
<p className="text-neutral-400 leading-relaxed mb-6">
Every OpenCode session becomes a trace with nested spans and events
for each action taken during the session:
</p>
<div className="space-y-3">
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
AGENT span
</span>
<span className="text-sm font-medium text-neutral-200">
Sessions
</span>
</div>
<p className="text-sm text-neutral-500">
Each OpenCode session is captured as a top-level AGENT span.
Includes session ID, start time, end time, and overall status.
</p>
</div>
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
LLM_CALL span
</span>
<span className="text-sm font-medium text-neutral-200">
LLM calls
</span>
</div>
<p className="text-sm text-neutral-500">
Every call to an LLM provider (Claude, GPT, etc.) is recorded with
the full prompt, response, token counts, and cost.
</p>
</div>
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
TOOL_CALL span
</span>
<span className="text-sm font-medium text-neutral-200">
Tool calls
</span>
</div>
<p className="text-sm text-neutral-500">
Tool invocations including file reads, writes, shell commands,
search operations, and MCP tool calls. Captures input arguments
and outputs.
</p>
</div>
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
TOOL_SELECTION decision
</span>
<span className="text-sm font-medium text-neutral-200">
Permissions
</span>
</div>
<p className="text-sm text-neutral-500">
Permission requests and grants are captured as decision points,
showing what the agent asked to do and whether it was allowed.
</p>
</div>
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
CUSTOM span
</span>
<span className="text-sm font-medium text-neutral-200">
File edits
</span>
</div>
<p className="text-sm text-neutral-500">
Every file creation, modification, and deletion is tracked with
before/after content diffs.
</p>
</div>
<div className="p-4 rounded-lg border border-neutral-800/50 bg-neutral-900/30">
<div className="flex items-center gap-3 mb-2">
<span className="px-2 py-0.5 rounded text-xs font-mono bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
CUSTOM event
</span>
<span className="text-sm font-medium text-neutral-200">
Git diffs
</span>
</div>
<p className="text-sm text-neutral-500">
Git operations (commits, diffs, branch changes) are captured as
events with the full diff content.
</p>
</div>
</div>
</section>
<section className="mb-12">
<h2 className="text-2xl font-semibold mb-4">Trace structure</h2>
<p className="text-neutral-400 leading-relaxed mb-4">
A typical OpenCode session trace looks like this:
</p>
<CodeBlock>{`Trace: "opencode-session-abc123"
|
+-- Span: "session" (AGENT)
| +-- Span: "read-file: src/main.ts" (TOOL_CALL)
| +-- Span: "llm-call: claude-sonnet" (LLM_CALL)
| | Decision: TOOL_SELECTION -> chose "edit-file" over "write-file"
| +-- Span: "edit-file: src/main.ts" (TOOL_CALL)
| +-- Span: "llm-call: claude-sonnet" (LLM_CALL)
| +-- Span: "bash: npm test" (TOOL_CALL)
| +-- Event: "git-diff" (CUSTOM)
| +-- Span: "bash: git commit" (TOOL_CALL)`}</CodeBlock>
</section>
<section className="mb-12">
<h2 className="text-2xl font-semibold mb-4">Environment variables</h2>
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-neutral-800">
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">Variable</th>
<th className="text-left py-2 pr-4 text-neutral-400 font-medium">Required</th>
<th className="text-left py-2 text-neutral-400 font-medium">Description</th>
</tr>
</thead>
<tbody className="text-neutral-300">
<tr className="border-b border-neutral-800/50">
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_API_KEY</td>
<td className="py-2 pr-4 text-neutral-500">Yes</td>
<td className="py-2">API key for authentication</td>
</tr>
<tr className="border-b border-neutral-800/50">
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_ENDPOINT</td>
<td className="py-2 pr-4 text-neutral-500">Yes</td>
<td className="py-2">AgentLens server URL</td>
</tr>
<tr className="border-b border-neutral-800/50">
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_ENABLED</td>
<td className="py-2 pr-4 text-neutral-500">No</td>
<td className="py-2">Set to &quot;false&quot; to disable (default: &quot;true&quot;)</td>
</tr>
<tr>
<td className="py-2 pr-4 font-mono text-emerald-400 text-xs">AGENTLENS_SESSION_TAGS</td>
<td className="py-2 pr-4 text-neutral-500">No</td>
<td className="py-2">Comma-separated tags to add to all session traces</td>
</tr>
</tbody>
</table>
</div>
</section>
<section>
<h2 className="text-2xl font-semibold mb-4">Filtering sensitive data</h2>
<p className="text-neutral-400 leading-relaxed mb-4">
By default, the plugin captures full file contents and command outputs.
To filter sensitive data, set the <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">AGENTLENS_REDACT_PATTERNS</code> environment variable with a comma-separated list of regex patterns:
</p>
<CodeBlock title="terminal" language="bash">{`export AGENTLENS_REDACT_PATTERNS="password=.*,API_KEY=.*,Bearer .*"`}</CodeBlock>
<p className="text-neutral-400 leading-relaxed mt-4">
Matched content is replaced with <code className="text-emerald-400 font-mono text-xs bg-emerald-500/5 px-1.5 py-0.5 rounded">[REDACTED]</code> before
being sent to the server.
</p>
</section>
</div>
);
}