Bladeren bron

chore(repo): delete dev/ and context-findings/, archive docs/planning/

Remove unreferenced junk directories (toy dashboard project, opencode
research notes, orphaned draft plan) and move the 16 stale synthesis
docs from docs/planning/ to docs/archive/planning/ with an ARCHIVED
note on the index. Update the 7 remaining references (plugin README,
maintenance plan, canonical-refactor citations) to the archive path.
.claude-plugin/ untouched.

Task: canonical-refactor-05
darrenhinde 2 weken geleden
bovenliggende
commit
a274eb674a
46 gewijzigde bestanden met toevoegingen van 13 en 9215 verwijderingen
  1. 0 95
      context-findings/plan/context-system-implementation-plan.md
  2. 0 1273
      dev/ai-tools/opencode/building-plugins.md
  3. 0 1801
      dev/ai-tools/opencode/cheatsheet-context-symbols.md
  4. 0 1835
      dev/ai-tools/opencode/context/CONTEXT-DEEP-DIVE.md
  5. 0 416
      dev/ai-tools/opencode/context/how-context-works.md
  6. 0 1692
      dev/ai-tools/opencode/logging-and-session-storage.md
  7. 0 1007
      dev/ai-tools/opencode/plugins/Plugin-inspiration.md
  8. 0 538
      dev/ai-tools/opencode/slash-commands-and-subagents.md
  9. 0 12
      dev/dashboard-project/main.js
  10. 0 7
      dev/dashboard-project/package.json
  11. 0 23
      dev/dashboard-project/period/core.js
  12. 0 11
      dev/dashboard-project/period/index.js
  13. 0 0
      dev/dashboard-project/period/tests/period.test.js
  14. 0 0
      dev/dashboard-project/shared/index.js
  15. 0 25
      dev/dashboard-project/shared/utils.js
  16. 0 19
      dev/dashboard-project/star-sign/core.js
  17. 0 11
      dev/dashboard-project/star-sign/index.js
  18. 0 0
      dev/dashboard-project/star-sign/tests/star-sign.test.js
  19. 0 18
      dev/dashboard-project/time/core.js
  20. 0 11
      dev/dashboard-project/time/index.js
  21. 0 0
      dev/dashboard-project/time/tests/time.test.js
  22. 0 26
      dev/dashboard-project/ui/core.js
  23. 0 23
      dev/dashboard-project/ui/index.js
  24. 0 0
      dev/dashboard-project/ui/tests/ui.test.js
  25. 0 364
      dev/docs/context-reference-convention.md
  26. 1 1
      docs/architecture/canonical-refactor/00-INDEX.md
  27. 2 2
      docs/architecture/canonical-refactor/03-adapter-specs.md
  28. 2 2
      docs/architecture/canonical-refactor/06-REVIEW.md
  29. 6 1
      docs/archive/planning/00-INDEX.md
  30. 0 0
      docs/archive/planning/01-main-plan.md
  31. 0 0
      docs/archive/planning/02-quickstart-guide.md
  32. 0 0
      docs/archive/planning/03-critical-feedback.md
  33. 0 0
      docs/archive/planning/04-solo-developer-scenarios.md
  34. 0 0
      docs/archive/planning/05-team-lead-scenarios.md
  35. 0 0
      docs/archive/planning/07-content-creator-scenarios.md
  36. 0 0
      docs/archive/planning/08-open-source-maintainer-scenarios.md
  37. 0 0
      docs/archive/planning/09-SYNTHESIS.md
  38. 0 0
      docs/archive/planning/10-FINAL-REVIEW.md
  39. 0 0
      docs/archive/planning/11-json-config-system-SUMMARY.md
  40. 0 0
      docs/archive/planning/11-json-config-system.md
  41. 0 0
      docs/archive/planning/12-MASTER-SYNTHESIS.md
  42. 0 0
      docs/archive/planning/13-PROJECT-BREAKDOWN.md
  43. 0 0
      docs/archive/planning/14-PROVIDER-PATTERN-FINAL.md
  44. 0 0
      docs/archive/planning/mvp/00-MVP-PLAN.md
  45. 1 1
      docs/maintenance/REPOSITORY_MANAGEMENT_PLAN.md
  46. 1 1
      plugins/claude-code/README.md

+ 0 - 95
context-findings/plan/context-system-implementation-plan.md

@@ -1,95 +0,0 @@
-# Context System Implementation Plan
-
-Status: draft
-Owner: repository-manager
-Last Updated: 2026-02-14
-
-## Goal
-
-Make context management simple, reliable, and efficient by standardizing file governance, introducing ADR-style decision memory, and adding lightweight CLI/agent workflows with strict validation.
-
-## Scope
-
-This plan covers:
-- Context file standards and lifecycle governance
-- ADR migration from single decision log to index + per-record files
-- Simple command surface for creation, validation, and health checks
-- Agent workflow integration (ContextScout + TaskManager + DocWriter)
-- CI and local validation gates
-
-This plan does not make SQLite primary storage. Files remain source of truth.
-
-## Fundamental Principles
-
-1. File-first truth: markdown context files are canonical.
-2. Deterministic operations: same input files => same validation/index outcomes.
-3. Minimal Viable Information: concise, scannable, reference-heavy.
-4. Navigation-first retrieval: load index/navigation before deep files.
-5. Least privilege and conflict safety: explicit permissions and supersession rules.
-
-## Target Outcomes
-
-- Standardized metadata and structure across context files
-- ADR system in place with conflict/supersession protection
-- One-command validation for local + CI use
-- Reduced token load via index-first retrieval patterns
-- Clear ownership and freshness maintenance cadence
-
-## Workstreams
-
-### WS1: Standards Baseline
-- Define required metadata contract and file constraints
-- Align with existing context-system standards and MVI
-- Publish single operating standard doc
-
-### WS2: ADR Refactor
-- Create decisions index and ADR directory structure
-- Define ADR template and status lifecycle
-- Migrate key decisions from legacy decisions log
-- Enforce supersession updates for conflicting decisions
-
-### WS3: CLI + Workflow
-- Define `ctx` command set (add, validate, check, adr new, adr supersede, stale)
-- Integrate agent preflight (`ctx validate --changed`) for context edits
-- Keep backend file-based (no DB dependency required)
-
-### WS4: Validation + Governance
-- Add local validation script and CI gates
-- Validate metadata, links, line limits, navigation presence, ADR index integrity
-- Add review cadence and ownership coverage rules
-
-## Proposed Artifacts
-
-- `context-findings/plan/CONTEXT_OPERATING_STANDARD.md`
-- `context-findings/plan/ADR_STANDARD.md`
-- `context-findings/plan/CLI_COMMAND_SPEC.md`
-- `context-findings/plan/VALIDATION_CHECKLIST.md`
-- `context-findings/plan/ROLL_OUT_PLAN.md`
-
-## Acceptance Criteria
-
-1. Standards docs are complete and internally consistent.
-2. ADR model supports conflict-safe supersession flow.
-3. Validation checklist is executable in local and CI contexts.
-4. Command specs are clear enough for implementation without ambiguity.
-5. Rollout plan includes phases, owners, and measurable KPIs.
-
-## Initial KPI Set
-
-- 100% context files pass required metadata checks
-- 100% active folders include `navigation.md`
-- 0 unresolved ADR conflicts/supersession gaps
-- 100% critical/high context files reviewed within cadence window
-
-## Risks and Mitigations
-
-- Risk: Overly complex process
-  - Mitigation: keep command surface minimal and defaults opinionated.
-- Risk: Drift between standards and usage
-  - Mitigation: enforce CI validation and monthly drift review.
-- Risk: Agent confusion from conflicting ADRs
-  - Mitigation: strict supersession policy and index integrity checks.
-
-## Delegation Request (TaskManager)
-
-Break this plan into atomic execution subtasks with dependencies, owners, and acceptance criteria. Prioritize standards and validation first, then ADR migration, then workflow/command integration.

+ 0 - 1273
dev/ai-tools/opencode/building-plugins.md

@@ -1,1273 +0,0 @@
-# Building OpenCode Plugins
-
-## Introduction
-
-OpenCode plugins extend the functionality of the OpenCode AI agent system. Plugins can:
-
-- Monitor system events (messages, sessions, errors)
-- Add custom tools for agents to use
-- Modify LLM parameters dynamically
-- Intercept and transform messages
-- Control permissions and behavior
-- Track and manage context usage
-
-Plugins are written in TypeScript and registered via `opencode.json`.
-
----
-
-## Getting Started
-
-### Basic Plugin Structure
-
-Create a TypeScript file (e.g., `my-plugin.ts`):
-
-```typescript
-import { Plugin } from "@opencode-ai/plugin"
-
-export const MyPlugin: Plugin = async (ctx) => {
-  // Plugin initialization
-  // ctx provides: client, project, directory, worktree, $
-  
-  return {
-    // Your hooks go here
-    async event({ event }) {
-      // Handle system events
-    },
-    
-    tool: {
-      // Custom tools
-    },
-    
-    async config(config) {
-      // Load configuration
-    }
-  }
-}
-```
-
-### Plugin Registration
-
-Add to your `opencode.json`:
-
-```json
-{
-  "plugin": [
-    "file:///absolute/path/to/my-plugin.ts",
-    "file://./relative/path/to/plugin.ts"
-  ]
-}
-```
-
-**Path formats:**
-- Absolute: `file:///Users/name/plugins/my-plugin.ts`
-- Relative to config: `file://./plugins/my-plugin.ts`
-- Home directory: `file://~/opencode/plugins/my-plugin.ts`
-
-### Plugin Input Context (`PluginInput`)
-
-When your plugin initializes, you receive:
-
-```typescript
-{
-  client: OpencodeClient,    // Full SDK client for OpenCode APIs
-  project: Project,           // Current project metadata
-  directory: string,          // Working directory path
-  worktree: string,          // Git worktree root
-  $: BunShell                // Bun shell for executing commands
-}
-```
-
----
-
-## Core Plugin Hooks
-
-### 1. `event` Hook - System Event Monitoring
-
-Monitor all system events in real-time:
-
-```typescript
-async event({ event }) {
-  // Available event types:
-  
-  if (event.type === "session.created") {
-    const session = event.properties.info
-    console.log(`New session: ${session.id}`)
-  }
-  
-  if (event.type === "session.updated") {
-    // Session metadata changed
-  }
-  
-  if (event.type === "session.deleted") {
-    // Clean up tracking state
-  }
-  
-  if (event.type === "message.updated") {
-    const msg = event.properties.info
-    console.log(`Message tokens: ${msg.tokens.input}`)
-  }
-  
-  if (event.type === "message.removed") {
-    // Message was deleted
-  }
-  
-  if (event.type === "session.compacted") {
-    // Session context was compacted
-  }
-  
-  if (event.type === "session.diff") {
-    // File changes detected
-  }
-  
-  if (event.type === "session.error") {
-    // Error occurred
-  }
-}
-```
-
-**Key Events:**
-- `session.*` - Session lifecycle
-- `message.*` - Message lifecycle
-- `message.part.*` - Message part updates
-- `session.compacted` - Context compaction
-- `session.diff` - File changes
-- `session.error` - Errors
-
----
-
-### 2. `chat.message` Hook - Message Interception
-
-Intercept user messages before they're sent to the agent:
-
-```typescript
-async "chat.message"(input, output) {
-  // input: { message: UserMessage }
-  // output: { message: UserMessage, parts: MessagePart[] }
-  
-  // Example: Add metadata to messages
-  output.message.metadata = {
-    timestamp: Date.now(),
-    source: "plugin"
-  }
-  
-  // Example: Modify message parts
-  output.parts.forEach(part => {
-    if (part.type === "text") {
-      // Transform text content
-    }
-  })
-  
-  // Example: Validate before sending
-  if (output.message.content.length > 10000) {
-    console.warn("Large message detected")
-  }
-}
-```
-
----
-
-### 3. `chat.params` Hook - LLM Parameter Modification
-
-Modify LLM parameters dynamically:
-
-```typescript
-async "chat.params"(input, output) {
-  // input.model = Model being used
-  // input.provider = Provider info
-  // input.message = Current message
-  
-  // output.temperature = 0-1
-  // output.topP = 0-1
-  // output.options = Record<string, any>
-  
-  // Example: Adjust temperature based on task
-  if (input.message.content.includes("creative")) {
-    output.temperature = 0.8
-  } else {
-    output.temperature = 0.3
-  }
-  
-  // Example: Add custom model parameters
-  output.options = {
-    top_k: 40,
-    repetition_penalty: 1.1
-  }
-  
-  // Example: Model-specific settings
-  if (input.model.id.includes("claude")) {
-    output.options.thinking = {
-      type: "enabled",
-      budget_tokens: 2000
-    }
-  }
-}
-```
-
----
-
-### 4. `tool` Hook - Custom Tool Creation
-
-Add custom tools that agents can use:
-
-```typescript
-import { tool } from "@opencode-ai/plugin"
-
-export const MyPlugin: Plugin = async (ctx) => {
-  return {
-    tool: {
-      // Simple tool with no arguments
-      get_timestamp: tool({
-        description: "Get current timestamp",
-        args: {},
-        async execute() {
-          return new Date().toISOString()
-        }
-      }),
-      
-      // Tool with arguments
-      search_database: tool({
-        description: "Search the project database",
-        args: {
-          query: {
-            type: "string",
-            description: "Search query"
-          },
-          limit: {
-            type: "number",
-            description: "Maximum results",
-            default: 10
-          }
-        },
-        async execute({ query, limit }) {
-          const results = await searchDB(query, limit)
-          return JSON.stringify(results, null, 2)
-        }
-      }),
-      
-      // Tool with access to context
-      analyze_project: tool({
-        description: "Analyze current project structure",
-        args: {},
-        async execute() {
-          // Access plugin context
-          const files = await ctx.$`find ${ctx.worktree} -type f`.text()
-          return `Project has ${files.split('\n').length} files`
-        }
-      })
-    }
-  }
-}
-```
-
-**Tool Best Practices:**
-- Clear, descriptive names
-- Detailed descriptions (agent uses these to decide when to call)
-- Type-safe arguments with descriptions
-- Return strings or JSON-serializable data
-- Handle errors gracefully
-
----
-
-### 5. `tool.execute.before` / `tool.execute.after` - Tool Execution Hooks
-
-Hook into tool execution to track or modify behavior:
-
-```typescript
-async "tool.execute.before"(input, output) {
-  // input.tool = Tool name
-  // input.sessionID = Current session
-  // input.callID = Unique call ID
-  // output.args = Tool arguments (mutable)
-  
-  console.log(`Executing tool: ${input.tool}`)
-  
-  // Example: Modify arguments
-  if (input.tool === "bash" && output.args.command.includes("rm -rf")) {
-    throw new Error("Dangerous command blocked")
-  }
-  
-  // Example: Track usage
-  trackToolUsage(input.tool, input.sessionID)
-}
-
-async "tool.execute.after"(input, output) {
-  // output.title = Tool result title
-  // output.output = Tool result output
-  // output.metadata = Tool metadata
-  
-  console.log(`Tool ${input.tool} completed`)
-  
-  // Example: Log results
-  if (output.output.length > 5000) {
-    console.warn(`Tool ${input.tool} returned large output`)
-  }
-  
-  // Example: Track performance
-  const duration = output.metadata?.duration
-  if (duration > 5000) {
-    console.warn(`Tool ${input.tool} took ${duration}ms`)
-  }
-}
-```
-
----
-
-### 6. `config` Hook - Configuration Loading
-
-Load plugin configuration from `opencode.json`:
-
-```typescript
-async config(config) {
-  // Access user's opencode.json config
-  const mySettings = config.myPlugin || {}
-  
-  // Example: Load settings with defaults
-  const settings = {
-    enabled: mySettings.enabled ?? true,
-    threshold: mySettings.threshold ?? 100,
-    apiKey: mySettings.apiKey || process.env.MY_API_KEY
-  }
-  
-  console.log("Plugin configured:", settings)
-  
-  return settings
-}
-```
-
-**In `opencode.json`:**
-```json
-{
-  "plugin": ["file://./my-plugin.ts"],
-  "myPlugin": {
-    "enabled": true,
-    "threshold": 150,
-    "apiKey": "secret"
-  }
-}
-```
-
----
-
-### 7. `permission.ask` Hook - Permission Control
-
-Control what the agent can do:
-
-```typescript
-async "permission.ask"(input, output) {
-  // input = Permission request details
-  // output.status = "ask" | "deny" | "allow"
-  
-  // Example: Auto-approve safe operations
-  if (input.tool === "read" || input.tool === "list") {
-    output.status = "allow"
-    return
-  }
-  
-  // Example: Block dangerous operations
-  if (input.tool === "bash" && input.args?.command?.includes("rm -rf /")) {
-    output.status = "deny"
-    return
-  }
-  
-  // Example: Conditional approval
-  if (input.tool === "write") {
-    const path = input.args?.filePath
-    if (path?.startsWith("/tmp/")) {
-      output.status = "allow"
-    } else {
-      output.status = "ask"  // Prompt user
-    }
-  }
-}
-```
-
----
-
-## SDK Client Methods
-
-Available via `ctx.client`:
-
-### Session Management
-
-```typescript
-// Get session info
-const session = await ctx.client.session.get({
-  path: { id: sessionID }
-})
-
-// List all sessions
-const sessions = await ctx.client.session.list()
-
-// Get session messages
-const messages = await ctx.client.session.messages.list({
-  path: { id: sessionID }
-})
-
-// Fork session (preserve context)
-const newSession = await ctx.client.session.fork({
-  path: { id: sessionID }
-})
-
-// Delete session
-await ctx.client.session.delete({
-  path: { id: sessionID }
-})
-
-// Execute command in session
-await ctx.client.session.command({
-  path: { id: sessionID },
-  body: {
-    command: "compact",
-    arguments: "",
-    agent: "build",
-    model: "anthropic/claude-3.5-sonnet"
-  }
-})
-```
-
-### Event Publishing
-
-```typescript
-// Publish UI events (toasts)
-await ctx.client.events.publish({
-  body: {
-    type: "tui.toast.show",
-    properties: {
-      title: "Alert",
-      message: "Something happened",
-      variant: "info" | "warning" | "error" | "success",
-      duration: 5000
-    }
-  }
-})
-```
-
-### Shell Commands
-
-```typescript
-// Execute shell commands via Bun
-const output = await ctx.$`ls -la ${ctx.worktree}`.text()
-
-// With error handling
-try {
-  const result = await ctx.$`git status`.text()
-  console.log(result)
-} catch (error) {
-  console.error("Command failed:", error)
-}
-```
-
----
-
-## Best Practices
-
-### Error Handling
-
-Always handle errors gracefully - never let exceptions crash OpenCode:
-
-```typescript
-async event({ event }) {
-  try {
-    // Your logic here
-    await processEvent(event)
-  } catch (error) {
-    console.error("Plugin error:", error)
-    // Log but don't throw - let OpenCode continue
-  }
-}
-```
-
-### State Management
-
-Use Maps for efficient state tracking:
-
-```typescript
-const MyPlugin: Plugin = async (ctx) => {
-  // State persists across hook calls
-  const sessionState = new Map<string, {
-    created: number
-    messageCount: number
-  }>()
-  
-  return {
-    async event({ event }) {
-      if (event.type === "session.created") {
-        sessionState.set(event.properties.info.id, {
-          created: Date.now(),
-          messageCount: 0
-        })
-      }
-      
-      if (event.type === "session.deleted") {
-        // Always clean up!
-        sessionState.delete(event.properties.info.id)
-      }
-    }
-  }
-}
-```
-
-### Performance Considerations
-
-Keep hooks fast and non-blocking:
-
-```typescript
-async event({ event }) {
-  // ✅ Good: Fast checks first
-  if (event.type !== "message.updated") return
-  if (!shouldProcess(event)) return
-  
-  // ✅ Good: Async operations don't block
-  processEventAsync(event).catch(console.error)
-  
-  // ❌ Bad: Heavy computation blocks event loop
-  // await expensiveAnalysis()  // Don't do this
-}
-```
-
-### Cleanup Patterns
-
-Always clean up resources:
-
-```typescript
-const MyPlugin: Plugin = async (ctx) => {
-  const resources = new Map()
-  
-  return {
-    async event({ event }) {
-      if (event.type === "session.created") {
-        resources.set(event.properties.info.id, createResource())
-      }
-      
-      if (event.type === "session.deleted") {
-        const resource = resources.get(event.properties.info.id)
-        if (resource) {
-          await resource.cleanup()
-          resources.delete(event.properties.info.id)
-        }
-      }
-    }
-  }
-}
-```
-
----
-
-## Context-Aware Plugins
-
-Context-aware plugins monitor and manage the agent's context window to optimize token usage and prevent context overflow.
-
-### Understanding Context Data
-
-#### Token Tracking
-
-From `message.updated` events:
-
-```typescript
-msg.tokens = {
-  input: number,        // Context window tokens
-  output: number,       // Generated tokens
-  reasoning: number,    // Reasoning tokens (if applicable)
-  cache: {
-    read: number,       // Prompt cache hits
-    write: number       // Prompt cache writes
-  }
-}
-```
-
-**Key calculation:**
-```typescript
-// Actual context window usage
-const contextSize = msg.tokens.input + msg.tokens.cache.read
-```
-
-#### Message Parts
-
-Track different types of content:
-
-```typescript
-part.type =
-  | "text"           // Text content
-  | "file"           // File attachments
-  | "tool"           // Tool calls & results
-  | "step-start"     // Agent thinking step
-  | "step-finish"    // Step completion with token usage
-  | "snapshot"       // Code snapshot
-  | "patch"          // Code changes
-  | "reasoning"      // Model reasoning (if enabled)
-```
-
-**Tool results can be large:**
-```typescript
-if (part.type === "tool" && part.state.status === "completed") {
-  const outputSize = estimateTokens(part.state.output)
-  // Track this for context management
-}
-```
-
----
-
-### Example: Context Monitor Plugin
-
-A complete plugin that monitors context usage and warns when approaching limits:
-
-```typescript
-import { Plugin } from "@opencode-ai/plugin"
-
-export const ContextMonitor: Plugin = async (ctx) => {
-  // Track state per session
-  const sessionWarnings = new Map<string, {
-    warned80k: boolean
-    warned100k: boolean
-    lastTokenCount: number
-    history: Array<{ timestamp: number, tokens: number }>
-  }>()
-  
-  // Configuration
-  const config = {
-    warn80k: 80_000,
-    warn100k: 100_000,
-    autoCompact: false
-  }
-  
-  return {
-    async config(userConfig) {
-      // Load user settings
-      Object.assign(config, userConfig.contextMonitor || {})
-    },
-    
-    async event({ event }) {
-      // Monitor message updates for token usage
-      if (event.type === "message.updated") {
-        const msg = event.properties.info
-        
-        // Only process assistant messages with token data
-        if (msg.role === "assistant" && msg.tokens) {
-          const totalTokens = msg.tokens.input + msg.tokens.cache.read
-          const sessionID = msg.sessionID
-          
-          // Initialize tracking if needed
-          if (!sessionWarnings.has(sessionID)) {
-            sessionWarnings.set(sessionID, {
-              warned80k: false,
-              warned100k: false,
-              lastTokenCount: 0,
-              history: []
-            })
-          }
-          
-          const state = sessionWarnings.get(sessionID)!
-          
-          // Track history
-          state.history.push({
-            timestamp: Date.now(),
-            tokens: totalTokens
-          })
-          
-          // Keep only last 10 entries
-          if (state.history.length > 10) {
-            state.history.shift()
-          }
-          
-          // Calculate growth rate
-          const growthRate = calculateGrowthRate(state.history)
-          
-          // Warning at 80k tokens
-          if (totalTokens >= config.warn80k && !state.warned80k) {
-            state.warned80k = true
-            
-            await ctx.client.events.publish({
-              body: {
-                type: "tui.toast.show",
-                properties: {
-                  title: "Context Warning",
-                  message: `Context at ${totalTokens.toLocaleString()} tokens (${Math.round(totalTokens / 2000)}% of 200k limit)`,
-                  variant: "warning",
-                  duration: 8000
-                }
-              }
-            })
-            
-            console.log(`⚠️  Context at ${totalTokens} tokens - consider compacting soon`)
-          }
-          
-          // Critical warning at 100k tokens
-          if (totalTokens >= config.warn100k && !state.warned100k) {
-            state.warned100k = true
-            
-            await ctx.client.events.publish({
-              body: {
-                type: "tui.toast.show",
-                properties: {
-                  title: "Context Critical",
-                  message: `Context at ${totalTokens.toLocaleString()} tokens - compact recommended`,
-                  variant: "error",
-                  duration: 10000
-                }
-              }
-            })
-            
-            console.log(`🚨 Context at ${totalTokens} tokens - compact now!`)
-            
-            // Auto-compact if enabled
-            if (config.autoCompact) {
-              await ctx.client.session.command({
-                path: { id: sessionID },
-                body: {
-                  command: "compact",
-                  arguments: "",
-                  agent: "build",
-                  model: msg.model
-                }
-              })
-              console.log("✅ Auto-compaction triggered")
-            }
-          }
-          
-          // Log growth rate if concerning
-          if (growthRate > 10000) {
-            console.log(`📈 Rapid context growth: ${growthRate} tokens/min`)
-          }
-          
-          state.lastTokenCount = totalTokens
-        }
-      }
-      
-      // Reset warnings after compaction
-      if (event.type === "session.compacted") {
-        const sessionID = event.properties.info.id
-        const state = sessionWarnings.get(sessionID)
-        if (state) {
-          state.warned80k = false
-          state.warned100k = false
-          console.log("✅ Context compacted - warnings reset")
-        }
-      }
-      
-      // Clean up when session deleted
-      if (event.type === "session.deleted") {
-        sessionWarnings.delete(event.properties.info.id)
-      }
-    },
-    
-    // Add custom tool for checking context
-    tool: {
-      check_context: tool({
-        description: "Check current session context size and health",
-        args: {},
-        async execute() {
-          // Get current session (would need session ID in real implementation)
-          const sessions = await ctx.client.session.list()
-          const currentSession = sessions[0] // Simplified
-          
-          if (!currentSession) {
-            return "No active session"
-          }
-          
-          const state = sessionWarnings.get(currentSession.id)
-          if (!state) {
-            return "No context data available yet"
-          }
-          
-          const tokens = state.lastTokenCount
-          const percentage = Math.round((tokens / 200000) * 100)
-          const growthRate = calculateGrowthRate(state.history)
-          
-          return `Context Health Report:
-- Current tokens: ${tokens.toLocaleString()}
-- Percentage of 200k limit: ${percentage}%
-- Growth rate: ${growthRate.toLocaleString()} tokens/min
-- Status: ${tokens < 80000 ? "✅ Healthy" : tokens < 100000 ? "⚠️  Warning" : "🚨 Critical"}
-${tokens >= 80000 ? "\nRecommendation: Consider compacting context" : ""}`
-        }
-      })
-    }
-  }
-}
-
-// Helper function to calculate growth rate
-function calculateGrowthRate(history: Array<{ timestamp: number, tokens: number }>): number {
-  if (history.length < 2) return 0
-  
-  const first = history[0]
-  const last = history[history.length - 1]
-  
-  const tokenDiff = last.tokens - first.tokens
-  const timeDiff = (last.timestamp - first.timestamp) / 1000 / 60 // minutes
-  
-  if (timeDiff === 0) return 0
-  
-  return Math.round(tokenDiff / timeDiff)
-}
-
-// Helper function for token estimation
-function estimateTokens(text: string): number {
-  // Rough estimation: ~4 characters per token
-  return Math.ceil(text.length / 4)
-}
-```
-
-**Configuration in `opencode.json`:**
-```json
-{
-  "plugin": ["file://./context-monitor.ts"],
-  "contextMonitor": {
-    "warn80k": 80000,
-    "warn100k": 100000,
-    "autoCompact": false
-  }
-}
-```
-
----
-
-### Context Optimization Strategies
-
-#### 1. Monitor Context Growth Rate
-
-Track how fast context is growing to predict when compaction will be needed:
-
-```typescript
-const history: Array<{ timestamp: number, tokens: number }> = []
-
-async event({ event }) {
-  if (event.type === "message.updated" && event.properties.info.tokens) {
-    const tokens = event.properties.info.tokens.input + 
-                   event.properties.info.tokens.cache.read
-    
-    history.push({ timestamp: Date.now(), tokens })
-    
-    // Keep last 10 measurements
-    if (history.length > 10) history.shift()
-    
-    // Calculate tokens per minute
-    const rate = calculateGrowthRate(history)
-    
-    if (rate > 10000) {
-      console.warn(`⚠️  Rapid context growth: ${rate} tokens/min`)
-    }
-  }
-}
-```
-
-#### 2. Smart Compaction Triggers
-
-Don't just check total tokens - check token efficiency:
-
-```typescript
-const efficiency = outputTokens / inputTokens
-
-if (efficiency < 0.01 && inputTokens > 100_000) {
-  // Too much input for little output = should compact
-  console.warn("Low token efficiency - compaction recommended")
-}
-```
-
-#### 3. Predictive Warnings
-
-Warn before hitting the limit:
-
-```typescript
-async "chat.params"(input, output) {
-  const model = input.model
-  const modelLimit = model.limit.context
-  const currentTokens = await getCurrentContextSize(input.message.sessionID)
-  
-  // Estimate next turn will add ~5k tokens
-  const projectedGrowth = 5000
-  
-  if (currentTokens + projectedGrowth > modelLimit * 0.9) {
-    console.warn("⚠️  Will exceed limit soon - compact before next turn!")
-  }
-}
-```
-
-#### 4. Model-Specific Context Limits
-
-Adjust behavior based on model limits:
-
-```typescript
-async "chat.params"(input, output) {
-  const model = input.model
-  
-  // model.limit.context = Total context window
-  // model.limit.output = Max output tokens
-  
-  const available = model.limit.context - model.limit.output
-  const used = await getCurrentContextSize(input.message.sessionID)
-  const remaining = available - used
-  
-  if (remaining < 10_000) {
-    console.warn(`⚠️  Only ${remaining} tokens remaining!`)
-    
-    // Reduce temperature for more focused responses
-    output.temperature = 0.2
-  }
-}
-```
-
-#### 5. Adaptive Context Configuration
-
-Adjust agent behavior based on context size:
-
-```typescript
-async "chat.params"(input, output) {
-  const contextTokens = await getContextSize(input.message.sessionID)
-  
-  if (contextTokens > 100_000) {
-    // High context - optimize for focus
-    output.temperature = 0.3
-    output.topP = 0.9
-    
-    console.log("High context mode: reduced temperature for focus")
-  } else {
-    // Normal context - allow creativity
-    output.temperature = 0.7
-    output.topP = 0.95
-  }
-}
-```
-
-#### 6. Track Tool Impact on Context
-
-Monitor which tools add the most context:
-
-```typescript
-const toolImpact = new Map<string, number>()
-
-async "tool.execute.after"(input, output) {
-  const tokensAdded = estimateTokens(output.output)
-  
-  const current = toolImpact.get(input.tool) || 0
-  toolImpact.set(input.tool, current + tokensAdded)
-  
-  // Log top offenders
-  if (tokensAdded > 5000) {
-    console.log(`Tool ${input.tool} added ${tokensAdded} tokens`)
-  }
-}
-```
-
----
-
-### Understanding Compaction
-
-#### How Compaction Works
-
-OpenCode automatically compacts when:
-
-```typescript
-// System checks if overflow
-SessionCompaction.isOverflow({
-  tokens: msg.tokens,
-  model: currentModel
-})
-
-// Returns true when:
-// (input + cache.read + output) > (context_limit - output_limit)
-```
-
-**Key constants:**
-- `PRUNE_MINIMUM = 20_000` - Minimum tokens to prune
-- `PRUNE_PROTECT = 40_000` - Protect recent 40k tokens
-
-#### Compaction Process
-
-1. Keeps last 2 user turns fully
-2. Summarizes older messages
-3. Prunes old tool call outputs (marks as `compacted`)
-4. Emits `session.compacted` event
-
-#### Detecting Compacted State
-
-```typescript
-async event({ event }) {
-  if (event.type === "session.compacted") {
-    console.log("✅ Context was compacted")
-    // Reset your warnings/tracking
-  }
-}
-
-// Check if session has been compacted
-const messages = await ctx.client.session.messages.list({
-  path: { id: sessionID }
-})
-
-const hasCompacted = messages.some(m => 
-  m.info.role === "assistant" && m.info.summary === true
-)
-```
-
----
-
-### Complete Context-Aware Plugin Example
-
-Here's a production-ready context monitoring plugin with all optimizations:
-
-```typescript
-import { Plugin, tool } from "@opencode-ai/plugin"
-
-interface SessionState {
-  warned80k: boolean
-  warned100k: boolean
-  warned150k: boolean
-  lastTokenCount: number
-  history: Array<{ timestamp: number, tokens: number }>
-  toolImpact: Map<string, number>
-  compactionCount: number
-}
-
-export const AdvancedContextMonitor: Plugin = async (ctx) => {
-  const sessions = new Map<string, SessionState>()
-  
-  const config = {
-    warn80k: 80_000,
-    warn100k: 100_000,
-    warn150k: 150_000,
-    autoCompact: false,
-    adaptiveTemperature: true,
-    trackToolImpact: true
-  }
-  
-  function getOrCreateState(sessionID: string): SessionState {
-    if (!sessions.has(sessionID)) {
-      sessions.set(sessionID, {
-        warned80k: false,
-        warned100k: false,
-        warned150k: false,
-        lastTokenCount: 0,
-        history: [],
-        toolImpact: new Map(),
-        compactionCount: 0
-      })
-    }
-    return sessions.get(sessionID)!
-  }
-  
-  function calculateGrowthRate(history: Array<{ timestamp: number, tokens: number }>): number {
-    if (history.length < 2) return 0
-    const first = history[0]
-    const last = history[history.length - 1]
-    const tokenDiff = last.tokens - first.tokens
-    const timeDiff = (last.timestamp - first.timestamp) / 1000 / 60
-    return timeDiff === 0 ? 0 : Math.round(tokenDiff / timeDiff)
-  }
-  
-  function estimateTokens(text: string): number {
-    return Math.ceil(text.length / 4)
-  }
-  
-  return {
-    async config(userConfig) {
-      Object.assign(config, userConfig.advancedContextMonitor || {})
-      console.log("Advanced Context Monitor configured:", config)
-    },
-    
-    async event({ event }) {
-      try {
-        // Track message updates
-        if (event.type === "message.updated") {
-          const msg = event.properties.info
-          
-          if (msg.role === "assistant" && msg.tokens) {
-            const totalTokens = msg.tokens.input + msg.tokens.cache.read
-            const state = getOrCreateState(msg.sessionID)
-            
-            // Update history
-            state.history.push({ timestamp: Date.now(), tokens: totalTokens })
-            if (state.history.length > 10) state.history.shift()
-            
-            const growthRate = calculateGrowthRate(state.history)
-            
-            // Progressive warnings
-            if (totalTokens >= config.warn80k && !state.warned80k) {
-              state.warned80k = true
-              await ctx.client.events.publish({
-                body: {
-                  type: "tui.toast.show",
-                  properties: {
-                    title: "Context Notice",
-                    message: `${totalTokens.toLocaleString()} tokens (${Math.round(totalTokens/2000)}%)`,
-                    variant: "info",
-                    duration: 5000
-                  }
-                }
-              })
-            }
-            
-            if (totalTokens >= config.warn100k && !state.warned100k) {
-              state.warned100k = true
-              await ctx.client.events.publish({
-                body: {
-                  type: "tui.toast.show",
-                  properties: {
-                    title: "Context Warning",
-                    message: `${totalTokens.toLocaleString()} tokens - consider compacting`,
-                    variant: "warning",
-                    duration: 8000
-                  }
-                }
-              })
-            }
-            
-            if (totalTokens >= config.warn150k && !state.warned150k) {
-              state.warned150k = true
-              await ctx.client.events.publish({
-                body: {
-                  type: "tui.toast.show",
-                  properties: {
-                    title: "Context Critical",
-                    message: `${totalTokens.toLocaleString()} tokens - compact now!`,
-                    variant: "error",
-                    duration: 10000
-                  }
-                }
-              })
-              
-              if (config.autoCompact) {
-                await ctx.client.session.command({
-                  path: { id: msg.sessionID },
-                  body: {
-                    command: "compact",
-                    arguments: "",
-                    agent: "build",
-                    model: msg.model
-                  }
-                })
-                console.log("✅ Auto-compaction triggered")
-              }
-            }
-            
-            state.lastTokenCount = totalTokens
-          }
-        }
-        
-        // Track compaction
-        if (event.type === "session.compacted") {
-          const state = sessions.get(event.properties.info.id)
-          if (state) {
-            state.warned80k = false
-            state.warned100k = false
-            state.warned150k = false
-            state.compactionCount++
-            console.log(`✅ Compaction #${state.compactionCount} completed`)
-          }
-        }
-        
-        // Cleanup
-        if (event.type === "session.deleted") {
-          sessions.delete(event.properties.info.id)
-        }
-      } catch (error) {
-        console.error("Context monitor error:", error)
-      }
-    },
-    
-    async "tool.execute.after"(input, output) {
-      if (!config.trackToolImpact) return
-      
-      try {
-        const tokensAdded = estimateTokens(output.output || "")
-        const state = getOrCreateState(input.sessionID)
-        
-        const current = state.toolImpact.get(input.tool) || 0
-        state.toolImpact.set(input.tool, current + tokensAdded)
-        
-        if (tokensAdded > 5000) {
-          console.log(`📊 Tool ${input.tool} added ${tokensAdded.toLocaleString()} tokens`)
-        }
-      } catch (error) {
-        console.error("Tool tracking error:", error)
-      }
-    },
-    
-    async "chat.params"(input, output) {
-      if (!config.adaptiveTemperature) return
-      
-      try {
-        const msg = input.message
-        const state = sessions.get(msg.sessionID)
-        
-        if (state && state.lastTokenCount > 100_000) {
-          // High context - reduce temperature for focus
-          output.temperature = 0.3
-          console.log("🎯 Adaptive mode: reduced temperature (high context)")
-        }
-      } catch (error) {
-        console.error("Adaptive params error:", error)
-      }
-    },
-    
-    tool: {
-      context_health: tool({
-        description: "Get detailed context health report for current session",
-        args: {},
-        async execute() {
-          try {
-            const sessions_list = await ctx.client.session.list()
-            if (!sessions_list.length) return "No active sessions"
-            
-            const currentSession = sessions_list[0]
-            const state = sessions.get(currentSession.id)
-            
-            if (!state) return "No context data available yet"
-            
-            const tokens = state.lastTokenCount
-            const percentage = Math.round((tokens / 200000) * 100)
-            const growthRate = calculateGrowthRate(state.history)
-            
-            let report = `📊 Context Health Report\n\n`
-            report += `Current tokens: ${tokens.toLocaleString()}\n`
-            report += `Percentage of 200k limit: ${percentage}%\n`
-            report += `Growth rate: ${growthRate.toLocaleString()} tokens/min\n`
-            report += `Compactions: ${state.compactionCount}\n`
-            report += `Status: ${tokens < 80000 ? "✅ Healthy" : tokens < 100000 ? "⚠️  Warning" : "🚨 Critical"}\n`
-            
-            if (config.trackToolImpact && state.toolImpact.size > 0) {
-              report += `\n📈 Top Tools by Token Impact:\n`
-              const sorted = Array.from(state.toolImpact.entries())
-                .sort((a, b) => b[1] - a[1])
-                .slice(0, 5)
-              
-              sorted.forEach(([tool, tokens]) => {
-                report += `  - ${tool}: ${tokens.toLocaleString()} tokens\n`
-              })
-            }
-            
-            if (tokens >= 80000) {
-              report += `\n💡 Recommendation: Consider compacting context`
-            }
-            
-            return report
-          } catch (error) {
-            return `Error: ${error}`
-          }
-        }
-      })
-    }
-  }
-}
-```
-
----
-
-## Key Takeaways
-
-### For All Plugins:
-1. **Always handle errors** - Never crash OpenCode
-2. **Clean up state** - Delete tracking data when sessions end
-3. **Keep hooks fast** - Don't block the event loop
-4. **Use TypeScript** - Type safety prevents bugs
-5. **Test thoroughly** - Plugins run in production
-
-### For Context-Aware Plugins:
-1. **Monitor `message.updated` events** for token tracking
-2. **Calculate context as** `input + cache.read` tokens
-3. **Warn at 80-100k tokens** even if model supports more
-4. **Track `session.compacted` events** to reset warnings
-5. **Use adaptive strategies** - adjust behavior based on context size
-6. **Track tool impact** - identify which tools add most context
-7. **Provide tools** - let agents check their own context health
-8. **Test with real sessions** - generate lots of context to verify
-
-The plugin system provides complete visibility and control over OpenCode's behavior, enabling sophisticated context management and optimization strategies.

+ 0 - 1801
dev/ai-tools/opencode/cheatsheet-context-symbols.md

@@ -1,1801 +0,0 @@
-# OpenCode Context Reference Cheat Sheet
-
-> **Purpose**: Master reference for defining files, agents, and tools in prompts that work seamlessly with OpenCode's automatic tool resolution.
-
----
-
-## 🎯 Quick Reference Table
-
-| Type | Syntax | Auto-Loaded? | AI Action Required | When to Use |
-|------|--------|--------------|-------------------|-------------|
-| **File (Initial)** | `@file.md` | ✅ Yes | ❌ No | User's initial prompt |
-| **File (Nested)** | `@file.md` | ❌ No | ✅ Yes (read_file) | Inside loaded files |
-| **Directory** | `@src/components/` | ✅ Yes | ❌ No | Folder context |
-| **Sub-Agent (Context)** | `@agent-name` | ✅ Yes* | ❌ No | Reference agent info |
-| **Sub-Agent (Invoke)** | `task(subagent_type="name")` | ❌ No | ✅ Yes (task tool) | Delegate tasks |
-| **Shell Command** | `` !`command` `` | ✅ Yes | ❌ No | Inline command output |
-| **Config File** | `instructions: []` in `opencode.json` | ✅ Yes | ❌ No | Always-needed context |
-| **Agent (Markdown)** | `.opencode/agent/**/*.md` | ✅ Auto-registered | ❌ No | Define agents |
-
----
-
-
-## 🔑 Key Takeaways
-
-1. **@ in agent markdown** = Just informational text
-2. **@ in user prompt** = OpenCode processes it (loads files/metadata)
-3. **To invoke agents** = Always use `task` tool
-4. **Agent names** = Full path from `.opencode/agent/` directory
-5. **Don't use @ to list agents** in your prompt - it's confusing!
-
-The `@` symbol only has special meaning in **USER PROMPTS**, not in **AGENT SYSTEM PROMPTS**.
-
-------
-
-## 🔧 Shell Commands
-
-### Inline Shell Commands (Automatic Execution)
-
-Use the `` !`command` `` syntax to execute commands and inline their output into prompts:
-
-```markdown
-# Example: Include git information
-Current branch: !`git branch --show-current`
-Recent commits: !`git log --oneline -5`
-
-# Example: Include system information  
-Node version: !`node --version`
-Available memory: !`free -h | grep Mem`
-
-# Example: Include file contents
-Database schema: !`cat schema.sql`
-
-# Example: Include directory structure
-Project structure:
-!`tree -L 2 -I 'node_modules|dist'`
-```
-
-**How it works:**
-- ✅ Commands execute when prompt is processed
-- ✅ Output is inserted into the prompt text
-- ✅ Great for dynamic context (git status, file lists, system info)
-- ⚠️ Commands run in shell with current working directory
-
-### Shell Command Patterns
-
-#### Git Context
-
-```markdown
-## Current Work Context
-
-Branch: !`git branch --show-current`
-Modified files: !`git status --short`
-Last commit: !`git log -1 --pretty=format:'%h - %s'`
-Uncommitted changes:
-!`git diff --stat`
-```
-
-#### Project Structure
-
-```markdown
-## Project Layout
-
-!`find src -type f -name '*.ts' | head -20`
-
-## Component Structure  
-
-!`tree src/components -L 2`
-```
-
-#### Environment Information
-
-```markdown
-## Environment
-
-Node: !`node --version`
-npm: !`npm --version`
-OS: !`uname -a`
-```
-
-#### File Content Snippets
-
-```markdown
-## Configuration
-
-Current eslint rules:
-!`cat .eslintrc.json`
-
-Package scripts:
-!`cat package.json | jq .scripts`
-```
-
-### When to Use Shell Commands vs Tools
-
-| Scenario | Use Shell `!` Syntax | Use `run_terminal_cmd` Tool |
-|----------|---------------------|---------------------------|
-| **Static context in prompt** | ✅ | ❌ |
-| **Git information** | ✅ | ❌ |
-| **File contents** | ✅ | ❌ |
-| **Interactive AI execution** | ❌ | ✅ |
-| **Based on AI decisions** | ❌ | ✅ |
-| **Build/test commands** | ❌ | ✅ |
-| **Requires error handling** | ❌ | ✅ |
-
----
-
-## 📁 File References
-
-### Initial Prompt (Automatic)
-When **you** type this in your prompt:
-
-```markdown
-Follow guidelines in @GUIDELINES.md
-Use patterns from @src/patterns/
-```
-
-**OpenCode automatically:**
-- ✅ Reads `GUIDELINES.md`
-- ✅ Lists `src/patterns/` directory
-- ✅ Attaches content to AI context
-- ❌ Does NOT read nested @ references inside these files
-
-### Nested References (Requires AI Action)
-
-When `GUIDELINES.md` contains:
-
-```markdown
-Also see @CODE_STYLE.md and @TESTING.md
-```
-
-**OpenCode does:**
-- ❌ Does NOT automatically read these
-- ✅ AI sees them as plain text
-
-**To make AI read them, use explicit instructions:**
-
-```markdown
-# GUIDELINES.md
-
-⚠️ **CRITICAL**: Before proceeding, read these files using read_file:
-
-1. @CODE_STYLE.md - Coding standards (READ FIRST)
-2. @TESTING.md - Testing patterns (READ FIRST)  
-3. @ARCHITECTURE.md - System design (READ FIRST)
-
-[rest of your guidelines...]
-```
-
-**Key phrases that work:**
-- ✅ `READ FIRST`
-- ✅ `use read_file tool`
-- ✅ `CRITICAL: Read these files`
-- ✅ `Load immediately before proceeding`
-
----
-
-## 🤖 Sub-Agent References
-
-### ⚠️ CRITICAL: Agent Context vs Agent Invocation
-
-**IMPORTANT DISTINCTION: Agent Files vs Agent Names**
-
-#### Understanding the Difference
-
-**Agent File** (Documentation):
-- Path: `.opencode/agents/subagents/core/taskmanager.md`
-- This is a MARKDOWN FILE describing the agent
-- Use `@.opencode/agents/subagents/core/taskmanager.md` to load file content
-- Result: Loads documentation/instructions as text
-
-**Agent Name** (System Registration):
-- Name: `taskmanager` (registered in OpenCode)
-- This is the actual AGENT that can execute tasks
-- Use `task(subagent_type="taskmanager", ...)` to invoke
-- Result: Agent runs and performs work
-
-#### Scenario 1: Using `@agent-name` (USUALLY NOT RECOMMENDED)
-When you use `@agent-name` in **your initial prompt**:
-
-```markdown
-Use @reviewer agent for code review
-```
-
-**What happens:**
-1. ✅ OpenCode checks if it's a file at that path
-2. ❌ File doesn't exist → Checks if it's a registered agent
-3. ✅ If agent exists: Attaches agent **metadata** as context (name, description, tools)
-4. ❌ Does **NOT invoke/run** the agent
-5. ⚠️ This loads agent info but doesn't execute anything
-
-**Result:** AI knows the agent exists but doesn't execute it.
-
-**When to use:** Rarely needed. Only if you want to reference agent capabilities in context.
-
-#### Scenario 2: Agent Invocation (RECOMMENDED)
-To actually **run** an agent and execute tasks:
-
-```javascript
-// AI must explicitly call the task tool
-task(
-  subagent_type="CodeReviewer",
-  description="Review code",
-  prompt="Review the auth implementation for security issues"
-)
-```
-
-**Result:** Agent **executes** and returns results.
-
-**When to use:** Always - this is how you actually invoke agents.
-
-#### Scenario 3: Loading Agent Documentation Files
-If you have agent documentation files:
-
-```markdown
-# Initial prompt
-Follow guidelines in @.opencode/agents/subagents/core/taskmanager.md
-```
-
-**What happens:**
-1. ✅ Loads the **file** content as context
-2. ❌ Does NOT invoke the agent
-3. ✅ Good for loading agent usage instructions
-
-**When to use:** When you want to load documentation about how to use agents.
-
----
-
-### Best Practice: Clear Agent Instructions
-
-**❌ DON'T write this (confusing - uses @ for agents):**
-```markdown
-Use @reviewer to review code
-Review with @taskmanager agent
-```
-**Problems:**
-- Loads agent metadata, doesn't invoke
-- AI might be confused about how to use it
-- Mixing file syntax with agent invocation
-
-**✅ DO write this (clear and explicit):**
-
-**Option 1: If you have agent documentation files**
-```markdown
-# Load agent documentation (file)
-@.opencode/agents/subagents/core/taskmanager.md
-
-# Then instruct AI how to invoke (not using @)
-**Agent: `taskmanager`**
-- Purpose: Task planning and breakdown
-- Invoke with: task(subagent_type="taskmanager", description="Plan X", prompt="Break down feature Y")
-```
-
-**Option 2: Direct invocation instructions (no @ at all)**
-```markdown
-**Agent: `reviewer`** - Code review agent
-- Purpose: Review code for quality and security
-- When: After implementing features
-- Invoke with: task(subagent_type="CodeReviewer", description="Review X", prompt="Review Y for Z issues")
-
-**DO NOT use @reviewer** - This loads metadata, not invocation
-**ALWAYS use task tool** - This actually runs the agent
-```
-
----
-
-### Listing Sub-Agents
-
-```markdown
-# Available Sub-Agents
-
-⚠️ **IMPORTANT**: These agents are NOT loaded as context. You MUST invoke them using the `task` tool:
-
-## Code Agents
-
-**Agent: `tester`** (DO NOT use @tester as context reference)
-- **Purpose**: Test generation and execution
-- **When to invoke**: After implementing features, before commits
-- **Tool call**: 
-  ```javascript
-  task(
-    subagent_type="TestEngineer",
-    description="Test auth",
-    prompt="Write comprehensive tests for auth module with >80% coverage"
-  )
-  ```
-
-**Agent: `reviewer`** (DO NOT use @reviewer as context reference)
-- **Purpose**: Code review and quality checks  
-- **When to invoke**: After completing code changes
-- **Tool call**: 
-  ```javascript
-  task(
-    subagent_type="CodeReviewer",
-    description="Review changes",
-    prompt="Review the authentication implementation for security vulnerabilities, code quality, and best practices"
-  )
-  ```
-
-## Core Agents
-
-**Agent: `planner`** (DO NOT use @planner as context reference)
-- **Purpose**: Project planning and task breakdown
-- **When to invoke**: Starting large features or projects
-- **Tool call**: 
-  ```javascript
-  task(
-    subagent_type="planner",
-    description="Plan feature",
-    prompt="Break down the payment system feature into implementable tasks with dependencies"
-  )
-  ```
-```
-
-### Proactive Sub-Agent Invocation
-
-To make the AI **automatically** invoke sub-agents at appropriate times:
-
-```markdown
-## Agent Automation Rules
-
-**CRITICAL**: Agents are invoked via `task` tool, NOT by referencing them with @.
-
-**After completing code changes, ALWAYS:**
-1. Invoke the `tester` agent using `task` tool to write and run tests
-2. Invoke the `reviewer` agent using `task` tool to review code quality
-3. Report results back to the user
-
-**Example workflow:**
-1. User requests feature
-2. You implement the code
-3. Automatically call: 
-   ```javascript
-   task(subagent_type="TestEngineer", description="Test feature", prompt="Write tests for X")
-   ```
-4. Automatically call: 
-   ```javascript
-   task(subagent_type="CodeReviewer", description="Review feature", prompt="Review X for quality")
-   ```
-5. Summarize results for user
-
-**Important**: 
-- Sub-agents return results ONLY to you. You must summarize for the user.
-- DO NOT use `@agent-name` syntax to invoke agents
-- ALWAYS use the `task` tool for agent invocation
-```
-
----
-
-## 🛠️ Tool References
-
-### Built-in OpenCode Tools
-
-```markdown
-## Available Tools
-
-**File Operations**
-- `read_file` - Read file contents (supports line ranges)
-- `write_file` - Create or overwrite files  
-- `search_replace` - Edit files with precision
-- `list_dir` - List directory contents
-- `glob_file_search` - Find files by pattern
-
-**Code Operations**
-- `grep` - Search code with ripgrep
-- `codebase_search` - Semantic code search
-
-**Execution**
-- `run_terminal_cmd` - Execute shell commands
-- `task` - Invoke sub-agents
-
-**Planning**
-- `todo_write` - Create and manage task lists
-```
-
-### When to Reference Tools
-
-```markdown
-# Task Instructions
-
-When you need to find configuration files, use `glob_file_search` to locate them.
-
-When analyzing code patterns, use `codebase_search` for semantic understanding.
-
-When editing code, use `search_replace` for precision rather than rewriting entire files.
-```
-
----
-
-## 💡 Complete Example: Index File
-
-Here's a **production-ready index file** that works perfectly with OpenCode:
-
-```markdown
-# Project Context Index
-
-## 📋 Quick Start
-
-**CRITICAL INSTRUCTION**: Before proceeding with ANY task:
-1. Read the files marked `[READ FIRST]` using the `read_file` tool
-2. Review the available sub-agents below
-3. Follow the coding standards and patterns defined in these files
-
----
-
-## 📚 Core Documentation [READ FIRST]
-
-Load these files immediately using `read_file`:
-
-- @docs/CODING_STANDARDS.md - TypeScript/React coding patterns
-- @docs/TESTING_STRATEGY.md - Test requirements and patterns
-- @docs/ARCHITECTURE.md - System design and component structure
-- @.opencode/WORKFLOWS.md - Development workflows and CI/CD
-
----
-
-## 🤖 Available Sub-Agents
-
-Use the `task` tool to invoke these specialized agents:
-
-### Development Agents
-
-**@subagents/code/implementer** - Complex feature implementation
-```javascript
-task(
-  subagent_type="implementer",
-  description="Implement user auth",
-  prompt="Create complete authentication system with JWT tokens, including login, logout, and session management. Follow patterns in @docs/ARCHITECTURE.md"
-)
-```
-
-**@TestEngineer** - Test generation and execution
-```javascript
-task(
-  subagent_type="TestEngineer", 
-  description="Test auth system",
-  prompt="Write comprehensive unit and integration tests for the authentication module. Ensure >80% coverage. Run tests and report results."
-)
-```
-
-**@CodeReviewer** - Code quality and security review
-```javascript
-task(
-  subagent_type="CodeReviewer",
-  description="Review auth code",
-  prompt="Review the authentication implementation for security vulnerabilities, code quality, and adherence to @docs/CODING_STANDARDS.md. Provide specific improvement suggestions."
-)
-```
-
-### Documentation Agents
-
-**@subagents/docs/technical-writer** - API and code documentation
-```javascript
-task(
-  subagent_type="technical-writer",
-  description="Document auth API", 
-  prompt="Generate comprehensive API documentation for the authentication endpoints, including request/response examples and error codes."
-)
-```
-
-### Planning Agents
-
-**@subagents/core/architect** - System design and planning
-```javascript
-task(
-  subagent_type="architect",
-  description="Design payment system",
-  prompt="Design a payment processing system architecture that integrates with Stripe. Break down into implementable tasks. Consider scalability and error handling."
-)
-```
-
----
-
-## 🔄 Automated Workflows
-
-### After Implementing Code
-
-**ALWAYS execute this workflow:**
-
-1. **Test** - Invoke `@TestEngineer` to validate implementation
-2. **Review** - Invoke `@CodeReviewer` for quality check
-3. **Document** - Update relevant documentation
-4. **Report** - Summarize results to user with:
-   - What was implemented
-   - Test results and coverage
-   - Any issues found in review
-   - Next recommended steps
-
-### Before Starting Large Features
-
-**ALWAYS execute this workflow:**
-
-1. **Plan** - Invoke `@subagents/core/architect` for design
-2. **Load Context** - Read relevant documentation from @docs/
-3. **Break Down** - Create detailed TODO list with `todo_write`
-4. **Confirm** - Ask user to confirm approach
-
----
-
-## 📖 Additional Context Files
-
-### Code Patterns & Examples
-
-For specific implementation patterns, read these on-demand:
-
-- @examples/api-patterns.ts - REST API implementation patterns
-- @examples/component-patterns.tsx - React component patterns
-- @examples/test-patterns.test.ts - Testing patterns and fixtures
-- @examples/error-handling.ts - Error handling strategies
-
-### Configuration Files
-
-Reference these when setting up tools or CI/CD:
-
-- @.github/workflows/ - GitHub Actions workflows
-- @tsconfig.json - TypeScript configuration
-- @package.json - Project dependencies and scripts
-
----
-
-## 🎯 Tool Usage Guidelines
-
-### File Search Strategy
-
-1. **Known filename**: Use `read_file` directly
-2. **Pattern match**: Use `glob_file_search` (e.g., "*.test.ts")
-3. **Semantic search**: Use `codebase_search` (e.g., "authentication logic")
-4. **Text search**: Use `grep` for exact text matches
-
-### Editing Strategy
-
-1. **Small changes**: Use `search_replace` for precision
-2. **New files**: Use `write_file`
-3. **Large refactors**: Consider sub-agent with `task` tool
-
-### Execution Strategy
-
-1. **Simple commands**: Use `run_terminal_cmd`
-2. **Complex workflows**: Create shell scripts first
-3. **Multistep tasks**: Use sub-agents with `task` tool
-
----
-
-## ⚠️ Common Pitfalls to Avoid
-
-### ❌ DON'T DO THIS:
-
-```markdown
-# Bad: Using @ syntax for agent invocation
-Use @tester when needed
-Review with @reviewer after coding
-
-# Bad: Treating agents like files
-Read @tester for testing guidelines
-See @reviewer documentation
-
-# Bad: Vague agent reference
-Use the tester agent when needed
-
-# Bad: Assuming nested files are auto-loaded
-See @guidelines.md (which references @other.md)
-
-# Bad: Not specifying how to invoke
-Available agents: tester, reviewer, planner
-
-# Bad: Mixing context and invocation
-Use @agent-name to run the agent
-```
-
-### ✅ DO THIS:
-
-```markdown
-# Good: Explicit tool call for agent invocation
-**Agent: `tester`** - Invoke ONLY via task tool:
-task(subagent_type="TestEngineer", description="Test feature", prompt="Write comprehensive tests for X")
-
-# Good: Clear separation of concerns
-**File**: @docs/testing-guide.md - Load with read_file
-**Agent**: `tester` - Invoke with task tool
-
-# Good: Explicit read instruction for nested refs
-**CRITICAL**: Read @guidelines.md, then read all files it references using read_file
-
-# Good: Clear tool invocation
-Use the `codebase_search` tool to find authentication logic
-
-# Good: Proactive invocation instruction
-After implementing code, ALWAYS invoke the tester agent:
-task(subagent_type="TestEngineer", description="Test X", prompt="Write and run tests for X")
-```
-
----
-
-## 🚀 Quick Start Template
-
-Copy this template to create your own index:
-
-```markdown
-# [Project Name] Context Index
-
-## 🎯 Before Starting ANY Task
-
-**CRITICAL**: Load these files first using `read_file`:
-1. @[PATH_TO_GUIDELINES]
-2. @[PATH_TO_STANDARDS]
-3. @[PATH_TO_ARCHITECTURE]
-
----
-
-## 🤖 Sub-Agents (MUST use `task` tool to invoke)
-
-**Agent: `[AGENT_NAME]`** (DO NOT use @[AGENT_NAME] as context)
-- Purpose: [Description]
-- When to invoke: [When to invoke]
-- Tool call: 
-  ```javascript
-  task(
-    subagent_type="[AGENT_NAME]",
-    description="[SHORT_DESC]",
-    prompt="[DETAILED_TASK_INSTRUCTIONS]"
-  )
-  ```
-
----
-
-## 🔄 Standard Workflows
-
-### After Code Changes
-1. Invoke tester agent via `task` tool
-2. Invoke reviewer agent via `task` tool  
-3. Report results to user
-
-Example:
-```javascript
-// Step 1: Test
-task(subagent_type="[TESTER_AGENT]", description="Test feature", prompt="Write tests for X")
-
-// Step 2: Review
-task(subagent_type="[REVIEWER_AGENT]", description="Review feature", prompt="Review X for quality")
-
-// Step 3: Summarize results for user
-```
-
----
-
-## 📚 Reference Files (Load on-demand)
-
-- @[FILE_PATH] - [Description] (Read when: [TRIGGER])
-
----
-```
-
----
-
-## 🔍 Verification Checklist
-
-Before sharing your index file, verify:
-
-- [ ] All **file** references use `@` prefix
-- [ ] Agent references use `task` tool, NOT `@` syntax
-- [ ] Agent names are plain text (e.g., `tester`), not `@tester`
-- [ ] Nested file references have explicit "READ FIRST" instructions
-- [ ] Sub-agents have complete `task()` tool call examples
-- [ ] Sub-agents show when/why to invoke them
-- [ ] Clear distinction between files (@file.md) and agents (task tool)
-- [ ] Automated workflows use `task` tool for agents
-- [ ] Tool usage instructions are specific
-- [ ] No ambiguous or vague instructions
-- [ ] No mixing of @ syntax for agents
-
----
-
-## 📝 Quick Reference Notes
-
-- **Files**: Use `@path/to/file.md` in prompts (auto-loaded initially, nested require read_file)
-- **Agent Files**: Use `@.opencode/agents/subagents/core/agent.md` to load documentation
-- **Agent Invocation**: Use `task` tool, NOT `@agent-name` syntax
-- **Agent Names**: Plain text only (e.g., `taskmanager`), never `@taskmanager`
-- **Shell**: Use `` !`command` `` for automatic execution in prompts
-- **Key Rule**: `@` is for FILES only, `task` tool is for AGENTS
-- **Rare Exception**: `@agent-name` loads agent metadata (usually not needed)
-
----
-
-## 🎨 Advanced Patterns
-
-### Combining Multiple Context Types
-
-```markdown
-# Complete Feature Context
-
-## Files to Read [READ FIRST]
-@docs/auth-spec.md
-@src/auth/types.ts
-
-## Current Implementation
-!`find src/auth -type f -name '*.ts'`
-
-## Git Context
-Branch: !`git branch --show-current`
-Changes: !`git diff --name-only`
-
-## Environment
-Node: !`node --version`
-Dependencies: !`npm list --depth=0 | grep auth`
-
-## Sub-Agents Available
-
-**@subagents/code/implementer** - Use for implementation
-**@TestEngineer** - Use for testing
-
-## Task
-Implement the authentication flow following @docs/auth-spec.md
-```
-
-### Dynamic File Loading
-
-```markdown
-# Load All Test Files
-
-Test files in project:
-!`find . -name "*.test.ts" -o -name "*.spec.ts"`
-
-**INSTRUCTION**: Read all test files above using `read_file` to understand testing patterns.
-```
-
-### Conditional Context
-
-```markdown
-# Database Migration Context
-
-## Current Migration Status
-!`npm run db:status 2>&1`
-
-## Latest Migration
-!`ls -t migrations/ | head -1 | xargs cat`
-
-**If migrations are pending**: Read @docs/migration-guide.md
-**If migrations are up-to-date**: Proceed with schema changes
-```
-
-### Nested Shell Commands with File References
-
-```markdown
-# Component Analysis
-
-## All React Components
-!`find src -name "*.tsx" | grep -v test`
-
-## Component Guidelines
-@docs/component-patterns.md
-
-**CRITICAL**: 
-1. Review the component list above
-2. Read @docs/component-patterns.md using `read_file`
-3. Ensure new components follow established patterns
-```
-
----
-
-## 🔗 Shell Command Cheat Sheet
-
-### Git Commands
-
-```bash
-# Current branch
-!`git branch --show-current`
-
-# Recent commits
-!`git log --oneline -n 10`
-
-# Modified files
-!`git status --short`
-
-# Diff summary
-!`git diff --stat`
-
-# Authors
-!`git shortlog -sn --all`
-
-# Current commit hash
-!`git rev-parse HEAD`
-```
-
-### File System Commands
-
-```bash
-# List TypeScript files
-!`find src -name "*.ts" -type f`
-
-# Count lines of code
-!`find src -name "*.ts" | xargs wc -l | tail -1`
-
-# Recent files
-!`ls -lt src | head -10`
-
-# Directory tree
-!`tree -L 3 -I 'node_modules|dist|.git'`
-
-# File size summary
-!`du -sh src/*`
-```
-
-### Project Info Commands
-
-```bash
-# Package version
-!`cat package.json | jq -r .version`
-
-# Dependencies
-!`npm list --depth=0`
-
-# Scripts
-!`cat package.json | jq .scripts`
-
-# Node version
-!`node --version`
-
-# npm version
-!`npm --version`
-```
-
-### Search Commands
-
-```bash
-# Find TODO comments
-!`grep -r "TODO" src --include="*.ts"`
-
-# Find FIXME comments
-!`grep -r "FIXME" src --include="*.ts"`
-
-# Find specific function
-!`grep -rn "function authenticate" src`
-
-# Count test files
-!`find . -name "*.test.ts" | wc -l`
-```
-
-### System Commands
-
-```bash
-# OS info
-!`uname -a`
-
-# Memory usage
-!`free -h`
-
-# Disk usage
-!`df -h .`
-
-# Process list (filtered)
-!`ps aux | grep node`
-```
-
----
-
-## 🎯 Complete Real-World Example
-
-```markdown
-# Feature Implementation: User Authentication
-
-## Pre-Flight Context Loading
-
-### CRITICAL: Read These Files First
-1. @docs/CODING_STANDARDS.md
-2. @docs/AUTH_ARCHITECTURE.md  
-3. @src/auth/interfaces.ts
-4. @tests/auth/auth.test.ts
-
-### Current State
-
-**Branch**: !`git branch --show-current`
-
-**Modified Files**:
-!`git status --short`
-
-**Existing Auth Files**:
-!`find src/auth -name "*.ts" -type f`
-
-**Test Coverage**:
-!`npm run test:coverage -- src/auth 2>&1 | tail -5`
-
-### Dependencies
-
-**Current Auth Libraries**:
-!`npm list | grep -E "(passport|jwt|bcrypt)"`
-
-**Node Version**: !`node --version`
-
-## Sub-Agents Available
-
-**@subagents/code/implementer** - Feature implementation
-- Use when: Implementing new auth flows
-- Example: `task(subagent_type="implementer", description="OAuth flow", prompt="Implement OAuth2 flow with Google, following patterns in @docs/AUTH_ARCHITECTURE.md")`
-
-**@TestEngineer** - Test creation
-- Use when: After implementing auth features  
-- Example: `task(subagent_type="TestEngineer", description="Test OAuth", prompt="Write integration tests for OAuth2 flow with >90% coverage")`
-
-**@subagents/security/auditor** - Security review
-- Use when: Before deploying auth changes
-- Example: `task(subagent_type="auditor", description="Audit auth", prompt="Review auth implementation for security vulnerabilities, SQL injection, XSS, and CSRF")`
-
-## Implementation Workflow
-
-### Step 1: Context Loading
-1. Read all files marked [READ FIRST]
-2. Review current implementation: !`cat src/auth/auth.service.ts`
-3. Review existing tests: !`cat tests/auth/auth.test.ts`
-
-### Step 2: Implementation
-1. Implement feature following @docs/CODING_STANDARDS.md
-2. Follow patterns from @src/auth/interfaces.ts
-3. Update types in @src/auth/types.ts
-
-### Step 3: Testing
-1. Invoke tester agent via `task` tool for test creation
-   ```javascript
-   task(subagent_type="TestEngineer", description="Test auth", prompt="Write tests for auth module")
-   ```
-2. Run tests: Use `run_terminal_cmd` for `npm test`
-3. Verify coverage meets requirements
-
-### Step 4: Review
-1. Invoke security auditor agent via `task` tool
-   ```javascript
-   task(subagent_type="auditor", description="Security audit", prompt="Review auth for vulnerabilities")
-   ```
-2. Address any issues found
-3. Re-run tests after fixes
-
-### Step 5: Documentation
-1. Update @docs/AUTH_ARCHITECTURE.md with changes
-2. Add inline code documentation
-3. Update API documentation
-
-## Reference Files (Load on-demand)
-
-- @docs/api/auth-endpoints.md - API documentation
-- @examples/auth-examples.ts - Usage examples
-- @config/auth.config.ts - Configuration options
-
-## Additional Context
-
-**Database Schema**:
-!`cat migrations/latest_auth_schema.sql`
-
-**Environment Variables**:
-!`cat .env.example | grep AUTH`
-
----
-
-**REMEMBER**: 
-- Files: Use `@filename` (nested require read_file)
-- Agents: Use `task` tool, NOT `@agent-name`
-- Shell: `` !`cmd` `` executes automatically in prompt
-- Agent names are plain text (e.g., `tester`), never `@tester`
-```
-
----
-
-## 📝 Notes
-
-- **Auto-loaded**: Initial `@` references in YOUR prompt (files only)
-- **Requires tool call**: Nested `@` references in loaded files
-- **Agent as context**: `@agent-name` in initial prompt attaches agent info (not invocation)
-- **Agent invocation**: Always requires `task` tool call - NEVER use `@` syntax
-- **Shell commands**: `` !`command` `` syntax executes automatically in prompt processing
-- **Tool commands**: `run_terminal_cmd` for AI-driven execution during conversation
-- **Key distinction**: Files use `@`, Agents use `task` tool
-
----
-
-## 🎯 Quick Decision Tree
-
-**Need to load a file?**
-- Initial prompt → Use `@path/to/file.md`
-- Nested reference → Add "READ FIRST" instruction for AI to use `read_file`
-- Agent docs → Use `@.opencode/agents/subagents/core/agent.md` (file path)
-
-**Need to invoke an agent?**
-- ❌ **NEVER** use `@agent-name` syntax for invocation
-- ✅ AI must call `task(subagent_type="name", ...)`
-- ✅ Use plain agent names (e.g., `taskmanager`, not `@taskmanager`)
-- ✅ Add clear invocation instructions in your context
-- ⚠️ Using `@agent-name` only loads metadata (rarely useful)
-
-**Need to run a command?**
-- Static context → Use `` !`command` `` in prompt
-- AI-driven execution → AI uses `run_terminal_cmd` tool
-
-**Structure Example:**
-```
-Files (use @):          Agents (use task):
-@docs/guide.md          task(subagent_type="CodeReviewer", ...)
-@src/types.ts           task(subagent_type="TestEngineer", ...)
-@.opencode/agents/      [agent name without @]
-  taskmanager.md        
-```
-
----
-
----
-
-## 🎯 THE PERFECT PROMPT TEMPLATE
-
-Use this template to avoid ALL confusion and work seamlessly with OpenCode:
-
-### Template Structure
-
-```markdown
-# [Task Name]
-
-## 📋 Context Files (Load with read_file tool)
-
-**CRITICAL**: Read these files FIRST using the `read_file` tool:
-1. @docs/coding-standards.md
-2. @docs/architecture.md
-3. @src/types/core.ts
-
----
-
-## 📚 Additional Documentation (Auto-loaded)
-
-Current git status:
-Branch: !`git branch --show-current`
-Recent changes: !`git status --short`
-
-Project structure:
-!`find src -type d -maxdepth 2`
-
----
-
-## 🤖 Available Agents (Invoke via task tool ONLY)
-
-**IMPORTANT**: DO NOT use @ syntax for agents. Use the `task` tool to invoke.
-
-### Agent: `implementer`
-**Purpose**: Complex feature implementation
-**When to invoke**: When implementing new features or major refactors
-**How to invoke**:
-```javascript
-task(
-  subagent_type="implementer",
-  description="Implement feature X",
-  prompt="Create complete implementation of X following @docs/architecture.md patterns. Include error handling and validation."
-)
-```
-
-### Agent: `tester`
-**Purpose**: Test creation and execution
-**When to invoke**: After implementing features, before committing
-**How to invoke**:
-```javascript
-task(
-  subagent_type="TestEngineer",
-  description="Test feature X",
-  prompt="Write comprehensive tests for X with >80% coverage. Run tests and report results."
-)
-```
-
-### Agent: `reviewer`
-**Purpose**: Code review and quality checks
-**When to invoke**: After code changes, before finalizing
-**How to invoke**:
-```javascript
-task(
-  subagent_type="CodeReviewer",
-  description="Review feature X",
-  prompt="Review the implementation of X for code quality, security vulnerabilities, and adherence to @docs/coding-standards.md"
-)
-```
-
----
-
-## 🔄 Required Workflow
-
-**After implementing ANY code:**
-1. Invoke `tester` agent using task tool
-2. Invoke `reviewer` agent using task tool
-3. Summarize results to user
-
----
-
-## 🎯 Your Task
-
-[Describe the specific task here]
-
----
-
-## ⚠️ Important Reminders
-
-- Files: Use `@path/to/file.md` syntax
-- Agent invocation: Use `task(subagent_type="name", ...)` 
-- NEVER use `@agent-name` to invoke agents
-- Agent names are plain text: `tester`, `reviewer`, NOT `@tester`
-```
-
----
-
-### Real-World Example: Perfect Prompt
-
-```markdown
-# Implement User Authentication System
-
-## 📋 Context Files (Load FIRST)
-
-**CRITICAL**: Use `read_file` tool to load these before starting:
-1. @docs/CODING_STANDARDS.md - TypeScript coding patterns
-2. @docs/AUTH_ARCHITECTURE.md - Authentication design patterns
-3. @src/auth/types.ts - Existing auth type definitions
-4. @tests/auth/auth.test.ts - Existing test patterns
-
----
-
-## 📚 Current State (Auto-loaded)
-
-**Git Context**:
-Branch: !`git branch --show-current`
-Modified: !`git status --short`
-
-**Existing Auth Files**:
-!`find src/auth -name "*.ts" -type f`
-
-**Dependencies**:
-!`npm list | grep -E "(jwt|bcrypt|passport)"`
-
----
-
-## 🤖 Available Agents
-
-### Agent: `implementer`
-Purpose: Feature implementation
-Invoke with:
-```javascript
-task(
-  subagent_type="implementer",
-  description="Implement auth flow",
-  prompt="Create authentication system with JWT tokens, including login, logout, and session management. Follow patterns in @docs/AUTH_ARCHITECTURE.md. Include middleware, controllers, and services."
-)
-```
-
-### Agent: `tester`
-Purpose: Test creation
-Invoke with:
-```javascript
-task(
-  subagent_type="TestEngineer",
-  description="Test auth system",
-  prompt="Write unit and integration tests for authentication module. Cover login, logout, token refresh, and session management. Ensure >85% coverage. Run tests and report results."
-)
-```
-
-### Agent: `reviewer`
-Purpose: Security and quality review
-Invoke with:
-```javascript
-task(
-  subagent_type="CodeReviewer",
-  description="Review auth implementation",
-  prompt="Review authentication implementation for security vulnerabilities (SQL injection, XSS, CSRF), proper token handling, password security, and adherence to @docs/CODING_STANDARDS.md"
-)
-```
-
----
-
-## 🔄 Required Workflow
-
-**You MUST follow this workflow:**
-
-1. **Read Context**: Load all files marked [CRITICAL] above
-2. **Implement**: Create the authentication system
-3. **Test**: Invoke `tester` agent via task tool
-4. **Review**: Invoke `reviewer` agent via task tool
-5. **Report**: Summarize implementation, test results, and review findings
-
----
-
-## 🎯 Task Details
-
-Implement a complete authentication system with:
-- JWT-based authentication
-- Login/logout endpoints
-- Token refresh mechanism
-- Session management
-- Password hashing with bcrypt
-- Middleware for protected routes
-
-Requirements:
-- Follow patterns in @docs/AUTH_ARCHITECTURE.md
-- Adhere to @docs/CODING_STANDARDS.md
-- Integrate with existing user model in @src/models/user.ts
-- Add proper error handling
-- Include request validation
-
----
-
-## ⚠️ Important Rules
-
-- Load files with @ syntax: `@docs/file.md`
-- Invoke agents with task tool: `task(subagent_type="name", ...)`
-- NEVER use `@agent-name` to invoke agents
-- Agent names are plain text: `tester`, NOT `@tester`
-- Shell commands auto-execute: !`git status`
-```
-
----
-
-## 📝 Anti-Pattern Examples (What NOT To Do)
-
-### ❌ BAD PROMPT (Confusing)
-```markdown
-Use @tester and @reviewer agents to test the code.
-Follow @guidelines and implement authentication.
-```
-
-**Problems:**
-- Uses `@` for agents (only loads metadata, doesn't invoke)
-- No clear invocation instructions
-- Mixing file and agent syntax
-- No explicit workflow
-
-### ✅ GOOD PROMPT (Clear)
-```markdown
-# Implement Authentication
-
-## Context Files
-**Read these using read_file tool:**
-- @docs/guidelines.md
-
-## Agents
-**Agent: `tester`** - Invoke with task tool:
-task(subagent_type="TestEngineer", description="Test auth", prompt="...")
-
-**Agent: `reviewer`** - Invoke with task tool:
-task(subagent_type="CodeReviewer", description="Review auth", prompt="...")
-
-## Workflow
-1. Read @docs/guidelines.md
-2. Implement feature
-3. Invoke tester agent via task tool
-4. Invoke reviewer agent via task tool
-```
-
----
-
-## 🎨 Prompt Templates by Use Case
-
-### Template 1: Simple Feature Implementation
-```markdown
-# Implement [Feature Name]
-
-## Context
-Read: @docs/standards.md
-
-Git status: !`git status --short`
-
-## Task
-[Detailed description]
-
-## No Agents Needed
-(Simple task, no agents required)
-```
-
-### Template 2: Complex Feature with Agents
-```markdown
-# Implement [Complex Feature]
-
-## Context Files (Read FIRST)
-1. @docs/standards.md
-2. @docs/architecture.md
-
-## Current State
-!`git status --short`
-!`find src/[module] -name "*.ts"`
-
-## Available Agents
-
-**Agent: `implementer`**
-Invoke: task(subagent_type="implementer", description="...", prompt="...")
-
-**Agent: `tester`**
-Invoke: task(subagent_type="TestEngineer", description="...", prompt="...")
-
-## Workflow
-1. Read context files
-2. Implement feature
-3. Invoke tester agent
-4. Report results
-```
-
-### Template 3: Code Review Task
-```markdown
-# Review [Feature/Module]
-
-## Context
-Files to review:
-!`git diff --name-only main...HEAD`
-
-Recent changes:
-!`git log --oneline -5`
-
-## Agent
-
-**Agent: `reviewer`**
-Invoke immediately:
-task(
-  subagent_type="CodeReviewer",
-  description="Review recent changes",
-  prompt="Review all changes in current branch for code quality, security, and adherence to standards"
-)
-
-## Task
-Run code review and report findings.
-```
-
-### Template 4: Documentation Task
-```markdown
-# Document [Feature]
-
-## Context
-Implementation files:
-!`find src/[module] -name "*.ts"`
-
-## Agent
-
-**Agent: `documenter`**
-Invoke: task(subagent_type="documenter", description="Document X", prompt="...")
-
-## Task
-Generate comprehensive documentation for [feature].
-```
-
----
-
-## 🔑 Golden Rules for Perfect Prompts
-
-1. **Files**: Always use `@path/to/file.md`
-2. **Agents**: Always use `task(subagent_type="name", ...)`
-3. **Shell**: Always use `` !`command` `` for dynamic context
-4. **Clarity**: Separate files, agents, and tasks into clear sections
-5. **Workflow**: Always specify the execution order
-6. **Agent Names**: Plain text only - `tester`, never `@tester`
-7. **Context First**: Load all context before describing the task
-8. **Explicit Instructions**: Tell AI exactly when and how to invoke agents
-
----
-
-## 🎯 REAL-WORLD EXAMPLE: Your Agent Setup
-
-Based on your actual agent configurations (task-manager subagent + orchestration agent):
-
-### Your Agent Files Structure & Naming
-
-**CRITICAL**: Agents are defined in MARKDOWN files. The agent NAME comes from the FILE PATH!
-
-```
-.opencode/
-  agent/                          # All agents as markdown files
-    subagents/
-      core/
-        task-manager.md           # Agent name: "TaskManager"
-    orchestration-agent.md        # Agent name: "orchestration-agent"
-    code/
-      reviewer.md                 # Agent name: "code/reviewer"
-      tester.md                   # Agent name: "code/tester"
-```
-
-**Markdown Agent File Format:**
-```markdown
----
-description: "Brief description of agent"
-mode: subagent                    # or "primary" or "all"
-temperature: 0.2
-tools:
-  read: true
-  write: true
-  edit: true
-  bash: true
-  task: true
-permissions:
-  edit:
-    "**/*.secret": "deny"
-  bash:
-    "rm -rf *": "deny"
----
-
-# Agent Prompt Content Here
-
-Your agent instructions, personality, rules, etc.
-All the markdown content becomes the agent's system prompt.
-```
-
-**How OpenCode determines agent names (from source code):**
-1. Scans `.opencode/agent/**/*.md` files recursively
-2. Parses YAML frontmatter (between `---` markers) for config
-3. Uses markdown content as the agent's system prompt
-4. Agent name = file path from `agent/` directory (minus `.md`)
-
-**Examples:**
-- File: `.opencode/agent/task-manager.md` → Name: `task-manager`
-- File: `.opencode/agent/TaskManager.md` → Name: `TaskManager`
-- File: `.opencode/agent/code/reviewer.md` → Name: `code/reviewer`
-
-**No opencode.json needed!** Everything is in markdown.
-
-### ❌ WRONG: Confusing Prompt
-
-```markdown
-Use @task-manager to break down the feature
-Have @orchestration-agent coordinate the work
-```
-
-**Problems:**
-- Using `@` for agent invocation (only loads metadata)
-- AI won't actually invoke the agents
-- Wrong agent name - should include full path: `TaskManager`
-- Confusing agent files with agent invocation
-
-### ✅ CORRECT: Clear Prompt
-
-```markdown
-# Implement User Dashboard Feature
-
-## 📋 Context Files (Load FIRST)
-
-**Agent Documentation** (optional - only if you need to understand agent capabilities):
-- @.opencode/agent/orchestration-agent.md - Main agent guidelines
-- @.opencode/agent/TaskManager.md - Task breakdown process
-
-**Project Documentation**:
-- @docs/coding-standards.md
-- @docs/architecture.md
-
-**Current State**:
-Branch: !`git branch --show-current`
-Files: !`find src/dashboard -name "*.ts"`
-
----
-
-## 🤖 Available Agents
-
-### Agent: `TaskManager` (Subagent)
-
-**IMPORTANT**: Agent is defined in a MARKDOWN file. The agent name comes from the file path!
-
-**File location**: `.opencode/agent/TaskManager.md`
-**Agent name**: `TaskManager` (path from `agent/` directory)
-**Format**: Markdown with YAML frontmatter
-
-**File structure:**
-```markdown
----
-description: "Breaks down complex features into subtasks"
-mode: subagent
-temperature: 0.1
-tools: { read: true, write: true, ... }
----
-
-# Task Manager Agent Prompt
-[Your agent instructions here...]
-```
-
-**Purpose**: Break down complex features into atomic subtasks
-
-**When to invoke**: 
-- Feature has 4+ components
-- Need structured task breakdown
-- Complex dependencies exist
-
-**How to invoke**:
-```javascript
-task(
-  subagent_type="TaskManager",
-  description="Break down dashboard feature",
-  prompt="Break down the user dashboard feature into atomic subtasks. Feature includes: profile widget, activity feed, notification center, and settings panel. Create structured task files in /tasks/ directory following your two-phase workflow."
-)
-```
-
-**What it does**:
-1. Analyzes feature and creates subtask plan
-2. Waits for your approval
-3. Creates task files in `tasks/subtasks/{feature}/`
-4. Returns task sequence and dependencies
-
----
-
-## 🔄 Required Workflow
-
-**For complex features (4+ components):**
-
-1. **Invoke task-manager** to break down the feature
-   ```javascript
-   task(
-     subagent_type="TaskManager",
-     description="Break down dashboard",
-     prompt="Analyze and break down user dashboard feature with profile, activity, notifications, and settings components. Create task files with dependencies and acceptance criteria."
-   )
-   ```
-
-2. **Review the task plan** (agent will request approval)
-
-3. **Approve and let agent create files**
-
-4. **Implement tasks** sequentially based on dependencies
-
-5. **Validate each task** against acceptance criteria
-
----
-
-## 🎯 Your Task
-
-Implement a user dashboard feature with:
-- Profile widget (avatar, name, stats)
-- Activity feed (recent actions, timestamps)
-- Notification center (alerts, read/unread states)
-- Settings panel (preferences, theme toggle)
-
-Requirements:
-- Follow @docs/architecture.md patterns
-- Responsive design
-- Real-time updates for notifications
-- Accessibility compliant
-
-**Since this is complex (4+ components), invoke the task-manager agent first.**
-
----
-
-## ⚠️ Important Notes
-
-- **Agent files** (`.md` in `.opencode/agents/`): Use `@` to load as documentation
-- **Agent invocation**: Use `task(subagent_type="name", ...)` to actually run the agent
-- **Agent names**: Plain text - `task-manager`, NOT `@task-manager`
-- The orchestration agent is your primary agent (already active)
-- Invoke `task-manager` when you need feature breakdown
-```
-
----
-
-## 🎨 Prompt Templates for Your Specific Agents
-
-### Template 1: Complex Feature (Needs Task Breakdown)
-
-```markdown
-# Implement [Complex Feature Name]
-
-## 📋 Context
-
-**Read these files:**
-- @docs/coding-standards.md
-- @docs/architecture.md
-- @.opencode/context/core/workflows/delegation.md
-
-**Current state:**
-!`git status --short`
-!`find src/[module] -type f`
-
----
-
-## 🤖 Agent: TaskManager
-
-**Invoke immediately for task breakdown:**
-
-```javascript
-task(
-  subagent_type="TaskManager",
-  description="Break down [feature]",
-  prompt="Break down [feature description] into atomic subtasks. Include:
-  - Component 1: [details]
-  - Component 2: [details]
-  - Component 3: [details]
-  
-  Create task files in /tasks/ with dependencies, acceptance criteria, and test requirements. Follow your two-phase workflow (plan → approve → create files)."
-)
-```
-
----
-
-## 🎯 Task Details
-
-[Detailed feature requirements]
-
----
-
-## 🔄 Workflow
-
-1. Invoke task-manager for breakdown
-2. Review and approve task plan
-3. Implement tasks in dependency order
-4. Validate against acceptance criteria
-5. Report completion
-```
-
-### Template 2: Simple Task (Direct Execution)
-
-```markdown
-# [Simple Task Name]
-
-## 📋 Context
-
-**Read:**
-- @docs/coding-standards.md
-
-**Current state:**
-!`git status --short`
-
----
-
-## 🎯 Task
-
-[Task description - simple, 1-3 files]
-
----
-
-## ⚠️ Notes
-
-- Simple task, no task-manager needed
-- Execute directly
-- Follow coding standards from @docs/coding-standards.md
-```
-
-### Template 3: Coordination Task (Uses Orchestration Features)
-
-```markdown
-# Coordinate [Multi-Step Feature]
-
-## 📋 Context
-
-**Read orchestration guidelines:**
-- @.opencode/agents/orchestration-agent.md
-- @.opencode/context/core/workflows/delegation.md
-
-**Current state:**
-!`git status --short`
-
----
-
-## 🔄 Coordination Workflow
-
-This task requires coordination across multiple steps:
-
-1. **Break down** feature using task-manager
-2. **Implement** core components
-3. **Delegate** complex subsystems if needed
-4. **Validate** integration
-5. **Report** completion
-
----
-
-## 🤖 Agents Available
-
-**Agent: `TaskManager`** - For feature breakdown
-Invoke: task(subagent_type="TaskManager", description="...", prompt="...")
-
-**Agent: `general`** - For delegated complex work (if needed)
-Invoke: task(subagent_type="general", description="...", prompt="...")
-
----
-
-## 🎯 Task
-
-[Complex coordinated task description]
-
----
-
-## 📝 Orchestration Rules
-
-From @.opencode/agents/orchestration-agent.md:
-- Request approval before execution
-- Stop on failures (don't auto-fix)
-- Report → Propose → Approve → Fix
-- Confirm before cleanup
-```
-
----
-
-## 🎯 Key Insights for Your Setup
-
-### Your Orchestration Agent (Primary)
-- **Already active** - it's processing your prompts
-- **Has task delegation** capability
-- **Follows approval workflow**
-- **Can invoke task-manager** when needed
-
-### Your Task-Manager Subagent
-- **Invoked via task tool** when you need breakdown
-- **Two-phase workflow**: Plan → Approve → Create
-- **Creates files** in `tasks/subtasks/{feature}/`
-- **Returns structured** task plans
-
-### Critical Distinctions
-
-| What | File Syntax | Agent Invocation |
-|------|-------------|------------------|
-| Load agent docs | `@.opencode/agent/TaskManager.md` | N/A |
-| Invoke task-manager | N/A | `task(subagent_type="TaskManager", ...)` |
-| Reference in text | "the task-manager agent" or "TaskManager" | N/A |
-| Load project docs | `@docs/standards.md` | N/A |
-
-**KEY INSIGHT**: The agent name comes from the file path structure, NOT just the filename!
-
-### Decision Flow
-
-```
-Is it complex (4+ components)?
-  ↓ YES
-  Invoke task-manager → Get breakdown → Implement tasks
-  
-  ↓ NO
-  Execute directly (orchestration agent handles it)
-
-Need to understand agents?
-  ↓ YES
-  Load agent docs: @.opencode/agents/[agent].md
-  
-  ↓ NO
-  Skip - just invoke when needed
-```
-
----
-
----
-
-## 🤔 Design Philosophy: Why List Subagents?
-
-**You might ask**: "Why do I need to tell the AI about subagents in my prompt when the `task` tool already lists them?"
-
-**You're right - it's redundant!** Here's the reality:
-
-### The Ideal World (How It Should Work)
-```markdown
----
-tools:
-  task: true  # AI should figure out the rest
----
-
-# Your Agent
-Delegate complex work to specialized subagents.
-```
-
-The AI should:
-1. ✅ See the `task` tool
-2. ✅ Read the tool's description (which lists agents)
-3. ✅ Use it when appropriate
-
-### The Real World (Current AI Limitations)
-
-Current AI models don't always:
-- ❌ Read tool descriptions carefully
-- ❌ Remember to check available tools
-- ❌ Connect "complex task" → "delegate" → "use task tool"
-
-So we **compensate** by:
-- Explicitly mentioning agents in prompts
-- Providing invocation examples
-- Repeating instructions
-
-### Two Approaches
-
-**Option 1: Minimal (Trust the Tool)**
-```markdown
-For complex work, use the `task` tool to delegate to specialized subagents.
-Available agents are documented in the task tool description.
-```
-- ✅ Clean, minimal
-- ⚠️ AI might not delegate when it should
-
-**Option 2: Explicit (Be Redundant)**
-```markdown
-Available subagents via task tool:
-- TaskManager - For feature breakdown
-- TestEngineer - For testing
-
-Invoke with: task(subagent_type="...", description="...", prompt="...")
-```
-- ⚠️ Redundant with tool description
-- ✅ AI consistently delegates appropriately
-
-**Recommendation**:
-
-**Last Updated**: 2024-11-21
-**OpenCode Version**: Latest
-

+ 0 - 1835
dev/ai-tools/opencode/context/CONTEXT-DEEP-DIVE.md

@@ -1,1835 +0,0 @@
-# OpenCode Context Deep Dive: Complete Guide
-
-**Last verified:** Dec 7, 2025  
-**Source code verified:** `packages/opencode/src/session/system.ts`, `prompt.ts`, `transform.ts`
-
----
-
-## 🎯 Context in 60 Seconds
-
-Every time you send a message to OpenCode, it builds a **context** (like a brief for the AI). Think of it like preparing a sandwich:
-
-```
-🍞 Header         → "You are Claude" (if using Anthropic)            ~12 tokens
-🥬 Base Prompt    → Big instructions (1,300-3,900 words)              ~2,000 tokens
-🧀 Environment    → "You're in /Users/you/project, 50 files..."      ~200 tokens
-🥓 Your Rules     → AGENTS.md, CLAUDE.md (your custom instructions)  ~500 tokens
-🍖 Tools          → "You can read, write, edit..." (16 tools)         ~6,600 tokens
-🍞 Your Message   → "Fix the bug in auth.ts"                          ~10 tokens
-                                                           ─────────────────────────
-                                                           Total: ~9,322 tokens
-```
-
-### 💰 The Cost Story
-
-**Without Caching (Ollama, most models):**
-- Every request: 9,322 tokens × full price
-- Or FREE (local models like Ollama)
-- 🚨 Problem: Uses 50-100% of small context windows!
-
-**With Caching (Claude/Anthropic only):**
-- First request: 9,322 tokens × full price = $0.028
-- Next requests: 9,000 cached (10% price) + 322 new = $0.004
-- **Savings: 85% cheaper!** Cache lasts 5 minutes
-- Static parts (base prompt, tools) reused automatically
-
-**The TUI shows total tokens INCLUDING cached reads, so high numbers are actually GOOD for Claude!**
-
----
-
-## 🔄 How Caching Actually Works
-
-### What Gets Cached?
-
-**OpenCode caches specific messages automatically:**
-
-```typescript
-// From: packages/opencode/src/provider/transform.ts:23-63
-
-const system = msgs.filter((msg) => msg.role === "system").slice(0, 2)
-const final = msgs.filter((msg) => msg.role !== "system").slice(-2)
-```
-
-**Translation:** OpenCode marks these messages as cacheable:
-1. **First 2 system messages** (base prompt, environment+tools)
-2. **Last 2 conversation messages** (your previous question + AI's answer)
-
-**Visual example:**
-
-```
-Request 1: "Fix auth bug"
-├─ [System 1] Header + Base Prompt          [CACHEABLE ✅]
-├─ [System 2] Environment + Custom + Tools  [CACHEABLE ✅]
-├─ [User] "Fix auth bug"                    [NOT CACHED]
-└─ [Assistant] "Here's the fix..."          [NOT CACHED]
-
-Request 2: "Add tests"  
-├─ [System 1] Header + Base Prompt          [CACHE HIT! 💰]
-├─ [System 2] Environment + Custom + Tools  [CACHE HIT! 💰]
-├─ [User] "Fix auth bug"                    [CACHEABLE ✅]
-├─ [Assistant] "Here's the fix..."          [CACHEABLE ✅]
-├─ [User] "Add tests"                       [NOT CACHED]
-└─ [Assistant] "Here are the tests..."      [NOT CACHED]
-
-Request 3: "Explain the tests"
-├─ [System 1] Header + Base Prompt          [CACHE HIT! 💰]
-├─ [System 2] Environment + Custom + Tools  [CACHE HIT! 💰]
-├─ ... (earlier messages truncated)
-├─ [User] "Add tests"                       [CACHE HIT! 💰]
-├─ [Assistant] "Here are the tests..."      [CACHE HIT! 💰]
-├─ [User] "Explain the tests"               [NOT CACHED]
-└─ [Assistant] "The tests work by..."       [NOT CACHED]
-```
-
-### How It's Stored
-
-**Caching happens on the provider's servers (not locally):**
-
-1. **Anthropic receives your request** with special markers:
-   ```json
-   {
-     "messages": [
-       {
-         "role": "system",
-         "content": "You are Claude...",
-         "cache_control": { "type": "ephemeral" }  // ← Cache marker
-       }
-     ]
-   }
-   ```
-
-2. **Anthropic computes a hash** of the message content
-   - Same content = Same hash = Cache hit!
-   - One character change = Different hash = Cache miss
-
-3. **Cache is stored on Anthropic's servers** for your API key
-   - Keyed by: message content hash + your API key
-   - Not shared between users
-   - Not stored locally
-
-4. **OpenCode tracks cache status** in message metadata:
-   ```json
-   {
-     "tokens": {
-       "input": 1200,
-       "cache": {
-         "read": 8500,    // ← Anthropic says "I already have this"
-         "write": 0       // ← New content added to cache
-       }
-     }
-   }
-   ```
-
-### Cache Expiration & Refresh
-
-**Lifespan:** 5 minutes of inactivity
-
-```
-0:00 - Request 1: Cache written (full price)
-0:30 - Request 2: Cache hit! (10% price)
-1:00 - Request 3: Cache hit! (10% price)
-4:50 - Request 4: Cache hit! (10% price)
-... (silence for 5 minutes)
-10:00 - Request 5: Cache expired, rebuilt (full price)
-10:30 - Request 6: Cache hit again! (10% price)
-```
-
-**Auto-refresh:** Every cache hit resets the 5-minute timer
-
-### Which Providers Support Caching?
-
-**Source:** `packages/opencode/src/provider/transform.ts:65-74`
-
-```typescript
-export function message(msgs: ModelMessage[], providerID: string, modelID: string) {
-  if (providerID === "anthropic" || modelID.includes("anthropic") || modelID.includes("claude")) {
-    msgs = applyCaching(msgs, providerID)
-  }
-  return msgs
-}
-```
-
-**Verified Provider Support:**
-
-| Provider | Models | Caching Support | Cache Format | Notes |
-|----------|--------|-----------------|--------------|-------|
-| **Anthropic** | Claude 3.5 Sonnet<br/>Claude 3.5 Haiku<br/>Claude 3 Opus/Sonnet | ✅ **Yes** | `cacheControl: { type: "ephemeral" }` | Native support, best implementation |
-| **OpenRouter** | When routing to Claude | ✅ **Yes** | `cache_control: { type: "ephemeral" }` | Only if backend is Anthropic |
-| **AWS Bedrock** | Claude on Bedrock | ✅ **Yes** | `cachePoint: { type: "ephemeral" }` | AWS-specific format |
-| **OpenAI** | GPT-4, GPT-4 Turbo<br/>o1, o3, GPT-5 | ⚠️ **Different** | `promptCacheKey: sessionID` | Different system, not as effective |
-| **OpenCode API** | Big Pickle | ✅ **Yes** | Routes through Anthropic | Backend uses Anthropic, so caching works |
-| **Ollama** | All local models | ❌ **No** | N/A | Local models don't support caching |
-| **LM Studio** | All local models | ❌ **No** | N/A | Local server, no cloud cache |
-| **Together AI** | Qwen, Llama, etc. | ❌ **No** | N/A | No caching support |
-| **Google AI** | Gemini 1.5, 2.0 | ❌ **No** | N/A | Not supported by provider |
-| **Azure OpenAI** | GPT-4 on Azure | ⚠️ **Varies** | Depends on Azure config | Check your Azure setup |
-
-### How to Tell if Caching is Working
-
-**Method 1: Check Token Breakdown**
-
-```bash
-# View your session tokens
-cat ~/.local/share/opencode/storage/message/ses_YOUR_ID/*.json | jq '.tokens'
-
-# If you see this, caching is working:
-{
-  "cache": {
-    "read": 8500  // ← Non-zero = cache hit!
-  }
-}
-
-# If you see this, no caching:
-{
-  "cache": {
-    "read": 0     // ← Zero = no cache support
-  }
-}
-```
-
-**Method 2: TUI Display**
-
-```
-Context
-9,842 tokens   ← If this stays HIGH but cost stays LOW = caching works!
-```
-
-**Method 3: Cost Pattern**
-
-```
-Request 1: $0.028  (first request)
-Request 2: $0.004  (85% cheaper)
-Request 3: $0.004  (still cheap)
-```
-
-If costs drop dramatically after first request = caching works!
-
-### Why Some Models Show Cache But Shouldn't
-
-**Big Pickle Mystery Solved:**
-
-```
-Your Setup:
-├─ You select: "Big Pickle" (Ollama model)
-├─ OpenCode CLI sends to: OpenCode API
-└─ OpenCode API routes to: Anthropic Claude API
-                            ↑
-                      Cache happens here!
-```
-
-**That's why you see:**
-- `cache.read: 8500` tokens (from Anthropic)
-- Costs are charged (not free like local Ollama)
-- Same caching behavior as Claude
-
-**It's not really Ollama - it's Claude with a different name!**
-
-### Cache Optimization Tips
-
-**For Anthropic/Claude:**
-1. ✅ Keep long system prompts (they get cached)
-2. ✅ Enable all tools you might need (cached after first use)
-3. ✅ Long conversations benefit more (2+ messages)
-4. ✅ Work in bursts under 5 minutes (cache stays warm)
-5. ❌ Don't optimize context size (caching makes it cheap)
-
-**For Non-Caching Models:**
-1. ✅ Minimize system prompts aggressively
-2. ✅ Disable unused tools
-3. ✅ Remove custom instructions
-4. ✅ Use agent prompt overrides
-5. ❌ Don't rely on "cheaper subsequent requests"
-
-### Technical: Cache Control Application
-
-**Source:** `packages/opencode/src/provider/transform.ts:23-63`
-
-```typescript
-function applyCaching(msgs: ModelMessage[], providerID: string): ModelMessage[] {
-  const system = msgs.filter((msg) => msg.role === "system").slice(0, 2)
-  const final = msgs.filter((msg) => msg.role !== "system").slice(-2)
-
-  const providerOptions = {
-    anthropic: { cacheControl: { type: "ephemeral" } },
-    openrouter: { cache_control: { type: "ephemeral" } },
-    bedrock: { cachePoint: { type: "ephemeral" } },
-    openaiCompatible: { cache_control: { type: "ephemeral" } },
-  }
-
-  // Apply cache markers to eligible messages
-  for (const msg of unique([...system, ...final])) {
-    msg.providerOptions = {
-      ...msg.providerOptions,
-      ...providerOptions[providerID]
-    }
-  }
-  
-  return msgs
-}
-```
-
-**What this does:**
-1. Finds first 2 system messages
-2. Finds last 2 conversation messages  
-3. Adds provider-specific cache markers
-4. Provider sees markers and caches those messages
-
----
-
-## 📊 Visual Flow: How Context is Built
-
-```mermaid
-graph TD
-    A[You type message] --> B{OpenCode starts building context}
-    
-    B --> C[1️⃣ Add Header]
-    C --> C1[Anthropic: 'You are Claude'<br/>Others: Nothing]
-    
-    B --> D[2️⃣ Add Base Prompt]
-    D --> D1{Which model?}
-    D1 -->|Claude| D2[anthropic.txt<br/>1,335 words]
-    D1 -->|GPT-4| D3[beast.txt<br/>1,904 words]
-    D1 -->|GPT-5| D4[codex.txt<br/>3,940 words]
-    D1 -->|Gemini| D5[gemini.txt<br/>2,235 words]
-    D1 -->|Others/Ollama/Big Pickle| D6[qwen.txt<br/>1,596 words]
-    
-    B --> E[3️⃣ Add Environment]
-    E --> E1[Working directory<br/>Project tree<br/>Date & platform]
-    
-    B --> F[4️⃣ Search for Custom Instructions]
-    F --> F1{Find local files?}
-    F1 -->|Yes| F2[Load AGENTS.md<br/>or CLAUDE.md]
-    F1 -->|No| F3[Check global<br/>~/.claude/CLAUDE.md]
-    
-    B --> G[5️⃣ Add Tool Definitions]
-    G --> G1{Which tools enabled?}
-    G1 -->|Agent config| G2[Load descriptions<br/>for enabled tools]
-    G1 -->|All by default| G3[Load all 16 tools<br/>~6,600 tokens!]
-    
-    C1 & D2 & D3 & D4 & D5 & D6 & E1 & F2 & F3 & G2 & G3 --> H[6️⃣ Combine Everything]
-    
-    H --> I[7️⃣ Apply Caching]
-    I --> I1{Anthropic/Claude?}
-    I1 -->|Yes| I2[Mark first 2 system<br/>messages as cacheable]
-    I1 -->|No| I3[No caching]
-    
-    I2 & I3 --> J[8️⃣ Add Your Message]
-    
-    J --> K[Send to AI Model]
-    
-    K --> L{First request?}
-    L -->|Yes| M[Full cost:<br/>All tokens charged]
-    L -->|No + Cached| N[Discounted:<br/>90% cached at 10% cost]
-    
-    M & N --> O[AI Responds]
-    
-    style A fill:#e1f5ff
-    style K fill:#fff4e1
-    style M fill:#ffe1e1
-    style N fill:#e1ffe1
-    style O fill:#f0e1ff
-```
-
----
-
-## 🏗️ The Layer Cake Metaphor
-
-Think of OpenCode context like building a **layer cake** for the AI to "eat":
-
-### Layer 1: The Foundation (Header)
-- **What:** A tiny label saying who the AI is
-- **Size:** 0-12 tokens
-- **Example:** "You are Claude, made by Anthropic"
-- **Why:** Some models need this identity reminder
-
-### Layer 2: The Recipe Book (Base Prompt)
-- **What:** Detailed instructions on how to behave
-- **Size:** 1,300-3,900 words (1,700-5,100 tokens!)
-- **Example:** "Be concise. Use tools. Don't write malicious code..."
-- **Why:** Different models need different instruction styles
-- **🚨 Problem:** This layer is HUGE and different per model!
-
-### Layer 3: The Kitchen Tour (Environment)
-- **What:** Info about the project you're working in
-- **Size:** 40-600 tokens
-- **Example:** "You're in /project, here's the file tree with 50 files..."
-- **Why:** AI needs to know what files exist and where it is
-
-### Layer 4: The House Rules (Custom Instructions)
-- **What:** YOUR personal preferences and rules
-- **Size:** 0-5,000 tokens (highly variable)
-- **Files:** `AGENTS.md`, `CLAUDE.md`, or files in `config.instructions`
-- **Example:** "Always use TypeScript. Follow our style guide..."
-- **Why:** Customize AI behavior for your team/workflow
-
-### Layer 5: The Toolbox Manual (Tool Definitions)
-- **What:** Descriptions of what tools the AI can use
-- **Size:** 0-6,600 tokens (330-1,900 per tool)
-- **Example:** "read: Read file contents. write: Create new files..."
-- **Why:** AI needs to know what actions it can take
-- **🚨 Problem:** All 16 tools = 6,600 tokens by default!
-
-### Layer 6: Your Request (The Actual Question)
-- **What:** What you just typed
-- **Size:** ~1.3 tokens per word
-- **Example:** "Fix the authentication bug in auth.ts"
-- **Why:** This is what you want help with!
-
----
-
-## 💡 The Key Insight: Most Context is STATIC
-
-```
-┌─────────────────────────────────────────┐
-│ STATIC CONTENT (Same Every Request)     │ 8,000-10,000 tokens
-├─────────────────────────────────────────┤
-│ • Base Prompt      → 2,000 tokens       │ ← Huge!
-│ • Tool Definitions → 6,600 tokens       │ ← Wasteful if unused!
-│ • Environment      →   200 tokens       │
-│ • Custom Rules     →   500 tokens       │
-└─────────────────────────────────────────┘
-         ↓ This repeats EVERY request
-         
-┌─────────────────────────────────────────┐
-│ DYNAMIC CONTENT (Changes Each Request)  │ 10-100 tokens
-├─────────────────────────────────────────┤
-│ • Your Message     →    15 tokens       │
-└─────────────────────────────────────────┘
-```
-
-**Without caching:** You pay for all 8,000+ tokens every time!  
-**With caching (Anthropic):** You pay full price once, then 10% for the static parts!
-
----
-
-## 🎭 Different Models = Different Base Layers
-
-Here's why you see different token counts for different models:
-
-| Model | Base Prompt | Size | Why Different? |
-|-------|------------|------|----------------|
-| **Claude** | anthropic.txt | 1,736 tokens | Optimized for Claude's style |
-| **GPT-4** | beast.txt | 2,475 tokens | Detailed reasoning instructions |
-| **GPT-5** | codex.txt | 5,122 tokens | Advanced multi-step guidance |
-| **Gemini** | gemini.txt | 2,906 tokens | Google-specific format |
-| **Ollama/Big Pickle** | qwen.txt | 2,075 tokens | Open-source model format |
-
-**🚨 Key Point:** Your Ollama model gets the same 2,075-token prompt as GPT-4, even though it has a tiny 8k context window!
-
----
-
-## 🔄 How Caching Saves You Money
-
-**First Request (No Cache):**
-```
-Request 1: "Hi"
-├─ Base Prompt:        2,000 tokens × $3.00/1M  = $0.0060
-├─ Tools:              6,600 tokens × $3.00/1M  = $0.0198
-├─ Environment:          200 tokens × $3.00/1M  = $0.0006
-├─ Your Message:          10 tokens × $3.00/1M  = $0.0000
-└─ AI Response:          100 tokens × $15.00/1M = $0.0015
-                                    Total: $0.0279
-```
-
-**Second Request (With Cache):**
-```
-Request 2: "Thanks"
-├─ Base Prompt:        2,000 tokens × $0.30/1M  = $0.0006 (cached!)
-├─ Tools:              6,600 tokens × $0.30/1M  = $0.0020 (cached!)
-├─ Environment:          200 tokens × $0.30/1M  = $0.0001 (cached!)
-├─ Your Message:          10 tokens × $3.00/1M  = $0.0000
-└─ AI Response:          100 tokens × $15.00/1M = $0.0015
-                                    Total: $0.0042
-                                    
-Savings: 85% cheaper!
-```
-
-**🎁 Cache expires after 5 minutes of inactivity, then rebuilds automatically.**
-
----
-
-## 🎯 The Problem (And Solutions)
-
-### Problem 1: Local Models (Ollama) Waste Context
-
-```
-Ollama Model: 8,000 token context limit
-├─ Base Prompt:        2,075 tokens (26%!) 😱
-├─ Tools:              6,600 tokens (82%!) 😱😱
-└─ Remaining for you:  -675 tokens ❌ DOESN'T FIT!
-```
-
-**Solution:** Minimize everything (see optimization section below)
-
-### Problem 2: You Don't Control Base Prompts
-
-You can't easily change the 2,000+ token base prompt without editing source code.
-
-**Solution:** Override with agent `prompt:` field (explained below)
-
-### Problem 3: Tools Load By Default
-
-All 16 tools = 6,600 tokens, even if you only need 3.
-
-**Solution:** Explicitly disable unused tools (explained below)
-
----
-
-## 🚀 Quick Wins
-
-Before diving into the technical details, here are the fastest ways to reduce context:
-
-### For Claude/Anthropic (Use Full Context)
-```yaml
-# Don't optimize - caching makes it cheap!
-# Keep all tools and instructions
-```
-
-### For Ollama (Minimize Everything)
-```yaml
-# .opencode/agent/ollama.md
----
-description: "Ollama optimized"
-prompt: "Code assistant"  # ← Replaces 2,075 token base prompt!
-tools:
-  read: true
-  write: true
-  edit: true
-  # All others automatically false = Saves 5,900 tokens!
----
-```
-
-```bash
-# Remove custom instructions
-mv ~/.claude/CLAUDE.md ~/.claude/CLAUDE.md.disabled  # Saves 200-2,000 tokens
-
-# Result: 750 tokens instead of 8,000+ (91% reduction!)
-```
-
----
-
----
-
-## 🔍 How to Verify Context for Your Setup
-
-Before diving into details, here's how to check what context YOUR agents are using:
-
-### Method 1: Count Agent Tokens (Script)
-
-```bash
-# Run the token counting script
-cd /Users/darrenhinde/Documents/GitHub/opencode
-./script/count-agent-tokens.sh AGENT_NAME MODEL_ID PROVIDER
-
-# Examples:
-./script/count-agent-tokens.sh build claude-sonnet-4 anthropic
-./script/count-agent-tokens.sh ollama qwen2.5:latest ollama
-./script/count-agent-tokens.sh your-custom-agent big-pickle opencode
-
-# Output shows:
-# - Base prompt tokens
-# - Environment tokens
-# - Custom instruction files found
-# - Tool tokens
-# - Total estimated tokens
-```
-
-### Method 2: Check TUI During Session
-
-When you run OpenCode in TUI mode:
-
-```bash
-opencode  # Start TUI
-
-# Top right shows:
-Context
-9,842 tokens   ← Total tokens (includes cached!)
-12% used       ← % of context window
-$0.00 spent    ← Cost so far
-```
-
-**🎯 Key Insight:** The token count includes `cache.read` tokens, so:
-- **High number + Claude = GOOD** (90% of it is cached/cheap)
-- **High number + Ollama = BAD** (eating your limited context)
-
-### Method 3: Inspect Session Data (Advanced)
-
-```bash
-# Find your session ID in TUI (top of screen: "Session: ses_...")
-SESSION_ID="ses_YOUR_SESSION_ID_HERE"
-
-# View token breakdown
-cat ~/.local/share/opencode/storage/message/$SESSION_ID/*.json | \
-  jq '.tokens'
-
-# Example output:
-{
-  "input": 1200,        ← New tokens this request
-  "output": 150,        ← AI response tokens
-  "reasoning": 0,       ← Reasoning tokens (o1/o3 only)
-  "cache": {
-    "read": 8500,       ← Reused from cache (cheap!)
-    "write": 0          ← New cache writes
-  }
-}
-
-# Calculate real cost:
-# Cached: 8500 × $0.30/1M = $0.0026
-# Input:  1200 × $3.00/1M = $0.0036
-# Output:  150 × $15.00/1M = $0.0023
-# Total: $0.0085 (not $0.0285 without cache!)
-```
-
-### Method 4: Check What Files Are Loaded
-
-```bash
-# Find custom instruction files being loaded
-cd your-project
-find . -name "AGENTS.md" -o -name "CLAUDE.md" -o -name "CONTEXT.md" 2>/dev/null
-
-# Check global files
-ls -la ~/.config/opencode/AGENTS.md 2>/dev/null
-ls -la ~/.claude/CLAUDE.md 2>/dev/null
-
-# Count words in custom files
-wc -w .opencode/AGENTS.md ~/.claude/CLAUDE.md
-
-# Estimate tokens (words × 1.3)
-```
-
-### Method 5: List Enabled Tools
-
-```bash
-# Check your opencode.json
-cat opencode.json | jq '.tools'
-
-# Or check agent config
-cat .opencode/agent/your-agent.md | grep -A 20 "tools:"
-
-# Count enabled tools:
-# Each tool ≈ 200-1,800 tokens
-# All 16 tools ≈ 6,600 tokens total
-```
-
-### Quick Diagnostic Table
-
-| Symptom | Likely Cause | Fix |
-|---------|--------------|-----|
-| 8,000+ tokens on "Hi" | Base prompt + all tools loaded | Use minimal agent, disable tools |
-| Same tokens every request | No caching OR local model | Switch to Claude for caching |
-| 9k cache + 1k input | Perfect! Caching working | Nothing, this is optimal! |
-| Context 90% used (Ollama) | Too much context for small window | Minimize base prompt, disable tools |
-| Can't fit full context | Project too large + tools + prompt | Reduce tool count, use agent override |
-
-### Example Verification Session
-
-```bash
-# 1. Create minimal agent
-cat > .opencode/agent/test.md << 'EOF'
----
-description: "Test minimal context"
-prompt: "Code assistant"
-tools:
-  read: true
----
-EOF
-
-# 2. Count tokens
-./script/count-agent-tokens.sh test qwen2.5:latest ollama
-
-# 3. Compare before/after
-# Before: ~8,000 tokens
-# After: ~400 tokens
-# Savings: 95%!
-
-# 4. Test in TUI
-opencode --agent test
-# Type: "hi"
-# Check Context in top right
-```
-
----
-
-Now let's dive into the technical details...
-
----
-
-## Table of Contents
-
-1. [How Context is Built (Step-by-Step)](#how-context-is-built)
-2. [Model-Specific Prompts](#model-specific-prompts)
-3. [How Caching Works](#how-caching-works)
-4. [Custom Instruction Files](#custom-instruction-files)
-5. [Tool Loading](#tool-loading)
-6. [Optimization Strategies](#optimization-strategies)
-7. [Complete Token Breakdown Examples](#complete-token-breakdown-examples)
-
----
-
-## How Context is Built
-
-Every request to the AI follows this exact sequence. Here's the verified code flow:
-
-### Step 1: System Prompt Assembly
-
-**Source:** `packages/opencode/src/session/prompt.ts:492-512`
-
-```typescript
-async function resolveSystemPrompt(input: {
-  system?: string
-  agent: Agent.Info
-  providerID: string
-  modelID: string
-}) {
-  let system = SystemPrompt.header(input.providerID)          // Step 1
-  system.push(...(() => {                                     // Step 2
-    if (input.system) return [input.system]
-    if (input.agent.prompt) return [input.agent.prompt]
-    return SystemPrompt.provider(input.modelID)
-  })())
-  system.push(...(await SystemPrompt.environment()))          // Step 3
-  system.push(...(await SystemPrompt.custom()))               // Step 4
-  
-  // Combine into max 2 messages for caching
-  const [first, ...rest] = system
-  system = [first, rest.join("\n")]
-  return system
-}
-```
-
-### The 4 Components (In Order)
-
-#### 1️⃣ **Header** (Provider-Specific)
-
-**Source:** `packages/opencode/src/session/system.ts:20-23`
-
-```typescript
-export function header(providerID: string) {
-  if (providerID.includes("anthropic")) return [PROMPT_ANTHROPIC_SPOOF.trim()]
-  return []
-}
-```
-
-**What gets added:**
-- **Anthropic only:** "You are Claude, a large language model trained by Anthropic." (~9 words)
-- **All others:** Nothing
-
-**Token cost:**
-- Anthropic: ~12 tokens
-- Others: 0 tokens
-
----
-
-#### 2️⃣ **Base Model Prompt** (Model-Specific)
-
-**Source:** `packages/opencode/src/session/system.ts:25-31`
-
-```typescript
-export function provider(modelID: string) {
-  if (modelID.includes("gpt-5")) return [PROMPT_CODEX]
-  if (modelID.includes("gpt-") || modelID.includes("o1") || modelID.includes("o3")) 
-    return [PROMPT_BEAST]
-  if (modelID.includes("gemini-")) return [PROMPT_GEMINI]
-  if (modelID.includes("claude")) return [PROMPT_ANTHROPIC]
-  return [PROMPT_ANTHROPIC_WITHOUT_TODO]  // Default fallback
-}
-```
-
-**Override Priority:**
-1. If `--system "custom"` flag used → Use that
-2. If agent has `prompt:` field → Use agent prompt
-3. Otherwise → Select by model ID
-
-**Verified Prompt Files & Token Counts:**
-
-| Model Pattern | File | Words | Approx Tokens | Used By |
-|--------------|------|-------|---------------|---------|
-| `gpt-5` | codex.txt | 3,940 | ~5,122 | GPT-5, o1-pro, o1-2024-12-17 |
-| `gpt-*`, `o1`, `o3` | beast.txt | 1,904 | ~2,475 | GPT-4, o1, o3 |
-| `gemini-` | gemini.txt | 2,235 | ~2,906 | Gemini models |
-| `claude` | anthropic.txt | 1,335 | ~1,736 | Claude 3.5, 3, etc. |
-| **Default** | qwen.txt | 1,596 | **~2,075** | **Big Pickle, Ollama, DeepSeek, etc.** |
-
-**🔥 Key Insight:** Models that don't match specific patterns (like Big Pickle, Ollama models, most local models) get the **qwen.txt** prompt by default, which is ~2,075 tokens!
-
----
-
-#### 3️⃣ **Environment Context**
-
-**Source:** `packages/opencode/src/session/system.ts:33-56`
-
-```typescript
-export async function environment() {
-  const project = Instance.project
-  return [
-    [
-      `Here is some useful information about the environment you are running in:`,
-      `<env>`,
-      `  Working directory: ${Instance.directory}`,
-      `  Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`,
-      `  Platform: ${process.platform}`,
-      `  Today's date: ${new Date().toDateString()}`,
-      `</env>`,
-      `<project>`,
-      `  ${
-        project.vcs === "git"
-          ? await Ripgrep.tree({
-              cwd: Instance.directory,
-              limit: 200,  // ← Max 200 files shown
-            })
-          : ""
-      }`,
-      `</project>`,
-    ].join("\n"),
-  ]
-}
-```
-
-**What gets added:**
-1. Working directory path
-2. Git repo status
-3. Platform (darwin/linux/win32)
-4. Today's date
-5. **Project tree** (if git repo):
-   - Up to 200 files
-   - Shows directory structure
-   - ~3-5 tokens per file
-
-**Token cost:**
-- Base info: ~40 tokens
-- Project tree: ~3 tokens × number of files (max 200 files = ~600 tokens)
-- **Typical:** 40-400 tokens depending on project size
-
----
-
-#### 4️⃣ **Custom Instructions**
-
-**Source:** `packages/opencode/src/session/system.ts:58-115`
-
-This is the most misunderstood part! Let me show you exactly what gets loaded:
-
-```typescript
-const LOCAL_RULE_FILES = [
-  "AGENTS.md",
-  "CLAUDE.md",
-  "CONTEXT.md", // deprecated
-]
-
-const GLOBAL_RULE_FILES = [
-  path.join(Global.Path.config, "AGENTS.md"),        // ~/.config/opencode/AGENTS.md
-  path.join(os.homedir(), ".claude", "CLAUDE.md"),   // ~/.claude/CLAUDE.md
-]
-
-export async function custom() {
-  const config = await Config.get()
-  const paths = new Set<string>()
-
-  // 1. Search for LOCAL files (searches UP the directory tree)
-  for (const localRuleFile of LOCAL_RULE_FILES) {
-    const matches = await Filesystem.findUp(localRuleFile, Instance.directory, Instance.worktree)
-    if (matches.length > 0) {
-      matches.forEach((path) => paths.add(path))
-      break  // ← STOPS after finding first matching file
-    }
-  }
-
-  // 2. Check GLOBAL files (exact paths only)
-  for (const globalRuleFile of GLOBAL_RULE_FILES) {
-    if (await Bun.file(globalRuleFile).exists()) {
-      paths.add(globalRuleFile)
-      break  // ← STOPS after finding first global file
-    }
-  }
-
-  // 3. Load files from config.instructions (if specified)
-  if (config.instructions) {
-    for (let instruction of config.instructions) {
-      if (instruction.startsWith("~/")) {
-        instruction = path.join(os.homedir(), instruction.slice(2))
-      }
-      let matches: string[] = []
-      if (path.isAbsolute(instruction)) {
-        matches = await Array.fromAsync(
-          new Bun.Glob(path.basename(instruction)).scan({
-            cwd: path.dirname(instruction),
-            absolute: true,
-            onlyFiles: true,
-          }),
-        ).catch(() => [])
-      } else {
-        matches = await Filesystem.globUp(instruction, Instance.directory, Instance.worktree)
-          .catch(() => [])
-      }
-      matches.forEach((path) => paths.add(path))
-    }
-  }
-
-  return Promise.all(Array.from(paths).map(...))
-}
-```
-
-**Search Behavior (Critical!):**
-
-1. **Local Files** (searches UP from current directory):
-   - Looks for: `AGENTS.md`, `CLAUDE.md`, `CONTEXT.md`
-   - Searches: Current dir → Parent → Grandparent → ... → Git root
-   - **Stops:** After finding **first match** (all three files, or just one)
-   
-2. **Global Files** (exact paths):
-   - `~/.config/opencode/AGENTS.md` OR
-   - `~/.claude/CLAUDE.md`
-   - **Stops:** After finding **first one**
-
-3. **Config Instructions** (if you add to `opencode.json`):
-   ```json
-   {
-     "instructions": [
-       ".opencode/rules.md",
-       "~/my-custom-rules.md"
-     ]
-   }
-   ```
-   - Supports globs
-   - Loads ALL matches
-
-**🚨 Common Misconceptions:**
-
-❌ "OpenCode loads ALL .md files in .opencode/"  
-✅ **ONLY** loads `AGENTS.md`, `CLAUDE.md`, `CONTEXT.md` (if found)
-
-❌ "OpenCode loads from both local AND global"  
-✅ Loads ONE local file + ONE global file (or until first match)
-
-❌ "OpenCode always loads custom instructions"  
-✅ Only if the specific files exist
-
-**Token cost:**
-- Varies widely: 0 - 5,000+ tokens depending on file content
-- **Typical:** 50-500 tokens per file
-
----
-
-### Step 2: Tool Definitions
-
-**Source:** `packages/opencode/src/session/prompt.ts:514-522`
-
-```typescript
-async function resolveTools(input: {
-  agent: Agent.Info
-  sessionID: string
-  modelID: string
-  providerID: string
-  tools?: Record<string, boolean>
-  processor: Processor
-}) {
-  const tools: Record<string, AITool> = {}
-  const enabledTools = pipe(
-    input.agent.tools,                                  // 1. Agent config
-    mergeDeep(await ToolRegistry.enabled(...)),         // 2. Default tools
-    mergeDeep(input.tools ?? {}),                       // 3. Request override
-  )
-  
-  // Only load enabled tools
-  for (const item of await ToolRegistry.tools(...)) {
-    if (Wildcard.all(item.id, enabledTools) === false) continue
-    // ... load tool definition
-  }
-}
-```
-
-**Verified Tool Sizes (from source code):**
-
-| Tool | Words | Tokens | Description Size |
-|------|-------|--------|-----------------|
-| todowrite | 1,380 | ~1,794 | Largest - complex schema |
-| bash | 1,453 | ~1,889 | Large - detailed examples |
-| task | 625 | ~812 | Medium - agent descriptions |
-| multiedit | 416 | ~541 | Medium |
-| edit | 227 | ~295 | Small-medium |
-| read | 203 | ~264 | Small-medium |
-| todoread | 177 | ~230 | Small-medium |
-| webfetch | 148 | ~192 | Small |
-| grep | 112 | ~146 | Small |
-| write | 108 | ~140 | Small |
-| glob | 94 | ~122 | Small |
-| websearch | 77 | ~100 | Small |
-| ls | 53 | ~69 | Tiny |
-| lsp-hover | 3 | ~4 | Minimal |
-| lsp-diagnostics | 3 | ~4 | Minimal |
-| patch | 3 | ~4 | Minimal |
-
-**Default Tool Set (if not specified):**
-- All 16 tools enabled
-- **Total: ~6,606 tokens** (verified by summing above)
-
-**Tool Enable/Disable Logic:**
-
-```yaml
-# In agent config:
-tools:
-  read: true      # Explicitly enable
-  write: false    # Explicitly disable
-  # If not listed, uses default (usually enabled)
-```
-
-**🔥 Critical:** Tools are **opt-out**, not opt-in! If you don't set `false`, they load by default.
-
----
-
-### Step 3: Message History
-
-Your conversation messages (user + assistant) are added after system prompts and tools.
-
-**Token cost:**
-- Your input: ~1.3 tokens per word
-- Previous messages: Accumulates with conversation history
-
----
-
-## Model-Specific Prompts
-
-### Why Different Models Get Different Prompts
-
-Each model family has different:
-- **Instruction-following style**
-- **Output formatting preferences**
-- **Tool-calling conventions**
-- **Context window sizes**
-
-### Prompt Selection Logic
-
-**Source:** `packages/opencode/src/session/system.ts:25-31`
-
-```typescript
-if (modelID.includes("gpt-5")) return [PROMPT_CODEX]
-if (modelID.includes("gpt-") || modelID.includes("o1") || modelID.includes("o3")) 
-  return [PROMPT_BEAST]
-if (modelID.includes("gemini-")) return [PROMPT_GEMINI]
-if (modelID.includes("claude")) return [PROMPT_ANTHROPIC]
-return [PROMPT_ANTHROPIC_WITHOUT_TODO]  // ← Default
-```
-
-### Detailed Prompt Comparison
-
-#### 1. **Claude (anthropic.txt)** - 1,335 words, ~1,736 tokens
-
-**Optimized for:**
-- Claude 3.5 Sonnet, Claude 3 Opus
-- Anthropic's instruction-following style
-- Tool use patterns
-
-**Key features:**
-- Concise, direct instructions
-- Emphasizes "think step-by-step"
-- Specific tool usage examples
-- Citations format
-
-**Sample excerpt:**
-```
-You are opencode, an AI assistant specialized in software engineering...
-IMPORTANT: Keep responses short and to the point.
-When using tools, plan your approach before executing.
-```
-
----
-
-#### 2. **Qwen/Default (qwen.txt)** - 1,596 words, ~2,075 tokens
-
-**Used by:**
-- Big Pickle
-- Ollama models (llama, qwen, deepseek, etc.)
-- Any model not matching other patterns
-
-**Optimized for:**
-- Open-source models
-- Models with smaller context windows
-- General-purpose instruction following
-
-**Key differences from Claude:**
-- More verbose examples
-- Detailed tool explanations
-- Explicit formatting instructions
-- Less assumption about model capabilities
-
-**Sample excerpt:**
-```
-You are opencode, an interactive CLI tool that helps users with software engineering tasks...
-IMPORTANT: Refuse to write code or explain code that may be used maliciously...
-When the user asks about opencode, use WebFetch tool to gather information...
-```
-
-**🚨 Why this matters for Ollama:**
-- Ollama models often have 4k-32k context
-- 2,075 tokens is 6-50% of total context!
-- No caching support = every token costs
-
----
-
-#### 3. **Beast (beast.txt)** - 1,904 words, ~2,475 tokens
-
-**Used by:**
-- GPT-4, GPT-4 Turbo
-- o1, o1-mini
-- o3
-
-**Optimized for:**
-- OpenAI's reasoning models
-- Structured thinking
-- Chain-of-thought
-
-**Key features:**
-- More detailed reasoning instructions
-- Explicit step-by-step guidance
-- Tool composition patterns
-
----
-
-#### 4. **Codex (codex.txt)** - 3,940 words, ~5,122 tokens
-
-**Used by:**
-- GPT-5 (when available)
-- Future advanced models
-
-**Optimized for:**
-- Multi-step complex tasks
-- Code generation at scale
-- Advanced reasoning
-
-**Why so large:**
-- Comprehensive tool documentation
-- Complex workflow examples
-- Advanced patterns
-
----
-
-#### 5. **Gemini (gemini.txt)** - 2,235 words, ~2,906 tokens
-
-**Used by:**
-- Gemini 1.5 Pro
-- Gemini 2.0
-
-**Optimized for:**
-- Google's instruction format
-- Gemini-specific features
-- Multi-modal capabilities
-
----
-
-### How to Override Model Prompt
-
-#### Method 1: Agent Prompt Override
-
-```yaml
----
-description: "Custom agent"
-mode: primary
-prompt: |
-  You are a helpful assistant. Be concise.
-  You have access to tools for file operations.
----
-```
-
-**Result:** Your prompt **replaces** the base model prompt entirely.
-
-#### Method 2: Command-Line Override
-
-```bash
-opencode --system "You are a helpful assistant."
-```
-
-**Result:** Overrides both agent prompt and model prompt.
-
-#### Method 3: Minimal Prompt (Edit Source)
-
-Edit `packages/opencode/src/session/system.ts`:
-
-```typescript
-export function provider(modelID: string) {
-  // Force minimal for specific models
-  if (modelID.includes("ollama")) return ["You are a coding assistant."]
-  
-  // ... rest of logic
-}
-```
-
----
-
-## How Caching Works
-
-### What is Prompt Caching?
-
-**Concept:** AI providers store frequently-used prompt segments and reuse them across requests, charging a reduced rate for cached content.
-
-### Which Providers Support Caching?
-
-**Source:** `packages/opencode/src/provider/transform.ts:23-74`
-
-```typescript
-function applyCaching(msgs: ModelMessage[], providerID: string): ModelMessage[] {
-  const system = msgs.filter((msg) => msg.role === "system").slice(0, 2)
-  const final = msgs.filter((msg) => msg.role !== "system").slice(-2)
-
-  const providerOptions = {
-    anthropic: {
-      cacheControl: { type: "ephemeral" },
-    },
-    openrouter: {
-      cache_control: { type: "ephemeral" },
-    },
-    bedrock: {
-      cachePoint: { type: "ephemeral" },
-    },
-    openaiCompatible: {
-      cache_control: { type: "ephemeral" },
-    },
-  }
-  // ... applies to last 2 system messages and last 2 conversation messages
-}
-
-export function message(msgs: ModelMessage[], providerID: string, modelID: string) {
-  if (providerID === "anthropic" || modelID.includes("anthropic") || modelID.includes("claude")) {
-    msgs = applyCaching(msgs, providerID)
-  }
-  return msgs
-}
-```
-
-**Verified Providers:**
-
-| Provider | Supports Caching | How it Works |
-|----------|-----------------|--------------|
-| **Anthropic** | ✅ Yes | Auto-applied via `cacheControl: ephemeral` |
-| **OpenRouter** | ✅ Yes (if Anthropic backend) | Auto-applied via `cache_control` |
-| **Bedrock** | ✅ Yes (if Anthropic models) | Auto-applied via `cachePoint` |
-| **OpenAI-compatible** | ✅ Maybe | Depends on backend |
-| **OpenAI** | ⚠️ Partial | Uses `promptCacheKey` (different system) |
-| **Ollama** | ❌ No | Local models don't cache |
-| **LM Studio** | ❌ No | Local server |
-| **OpenCode (Big Pickle)** | ⚠️ Special | Routes through Anthropic API internally |
-
-### What Gets Cached?
-
-**Logic:** First 2 system messages + Last 2 conversation messages
-
-```typescript
-const system = msgs.filter((msg) => msg.role === "system").slice(0, 2)
-const final = msgs.filter((msg) => msg.role !== "system").slice(-2)
-```
-
-**Typical cache structure:**
-
-```
-Message 1 (system) - Header + Base Prompt        [CACHED]
-Message 2 (system) - Environment + Custom + Tools [CACHED]
-...
-Message N-1 (user) - Your previous question      [CACHED]
-Message N (assistant) - Previous response        [CACHED]
-Message N+1 (user) - Current question            [NOT CACHED]
-```
-
-### Cache Expiration
-
-**Anthropic:**
-- **5 minutes** of inactivity
-- Auto-refreshes on each request
-- Free cache writes (no cost)
-- Cache reads: 10% of input token cost
-
-**Example costs (Claude 3.5 Sonnet):**
-- Input tokens: $3.00 per 1M tokens
-- Cached tokens: $0.30 per 1M tokens (10x cheaper!)
-- Output tokens: $15.00 per 1M tokens
-
-### Why You See High Token Counts
-
-**Example session:**
-
-```
-Context: 9,800 tokens
-Breakdown:
-  cache.read: 8,500 tokens  ← From previous request
-  input: 1,200 tokens       ← New content this request
-  output: 100 tokens        ← Response
-```
-
-**Actual cost calculation:**
-```
-Cache read: 8,500 × $0.30 / 1M = $0.00255
-Input: 1,200 × $3.00 / 1M = $0.00360
-Output: 100 × $15.00 / 1M = $0.00150
-─────────────────────────────────────
-Total: $0.00765 (not $0.0294 without cache!)
-```
-
-**🔥 Key Insight:** High token count ≠ High cost when cached!
-
-### Big Pickle Special Case
-
-**Why you see cache for Big Pickle (Ollama model):**
-
-Big Pickle routes through OpenCode's API, which likely uses Anthropic as the backend. So:
-
-```
-You → OpenCode CLI → OpenCode API → Anthropic API → Big Pickle model
-                                    ↑
-                              Caching happens here
-```
-
-**Evidence:**
-- You see `cache.read` tokens
-- Token counts match Anthropic's behavior
-- Costs are charged (not free like local Ollama)
-
-### How to Verify Caching
-
-```bash
-# Check session cache
-cat ~/.local/share/opencode/storage/message/ses_YOUR_SESSION_ID/*.json | \
-  jq '.tokens'
-
-# Example output:
-{
-  "input": 1200,
-  "output": 100,
-  "cache": {
-    "read": 8500,   ← Indicates caching is working
-    "write": 0
-  }
-}
-```
-
----
-
-## Custom Instruction Files
-
-### Verified Loading Behavior
-
-**Source:** `packages/opencode/src/session/system.ts:58-115`
-
-### Local Files (Project-Specific)
-
-**Search path:** Current directory → Parent → ... → Git root
-
-**Files searched (in order):**
-1. `AGENTS.md` ← Most common
-2. `CLAUDE.md` ← Legacy
-3. `CONTEXT.md` ← Deprecated
-
-**Behavior:**
-- Searches UP the directory tree
-- Stops at first directory containing ANY of these files
-- Loads ALL found files from that directory
-- Does NOT search subdirectories
-
-**Example:**
-```
-/Users/you/project/
-  .opencode/
-    AGENTS.md       ← Will be loaded
-    CLAUDE.md       ← Will be loaded
-  subproject/
-    AGENTS.md       ← Will NOT be loaded (parent already matched)
-```
-
-### Global Files
-
-**Exact paths checked (in order):**
-1. `~/.config/opencode/AGENTS.md`
-2. `~/.claude/CLAUDE.md`
-
-**Behavior:**
-- Checks exact paths only
-- Loads first one found
-- Stops after first match
-
-### Custom Instructions via Config
-
-**In `opencode.json`:**
-
-```json
-{
-  "instructions": [
-    ".opencode/rules/*.md",           // Glob pattern
-    "~/global-rules.md",              // Absolute path
-    "docs/coding-standards.md"        // Relative path
-  ]
-}
-```
-
-**Behavior:**
-- Supports globs (`*`, `**`)
-- Searches UP the tree for relative paths
-- Loads ALL matches (no stopping)
-- Loads in addition to AGENTS.md/CLAUDE.md
-
-### Priority Order
-
-When combining instructions:
-
-1. Local hard-coded files (AGENTS.md, CLAUDE.md)
-2. Global hard-coded files
-3. Config-specified files
-
-All are concatenated with:
-```
-Instructions from: /path/to/file.md
-<file content>
-```
-
-### How to Disable Custom Instructions
-
-**Method 1:** Rename files
-```bash
-mv AGENTS.md AGENTS.md.disabled
-mv ~/.claude/CLAUDE.md ~/.claude/CLAUDE.md.disabled
-```
-
-**Method 2:** Move to different location
-```bash
-mkdir .opencode/disabled
-mv .opencode/AGENTS.md .opencode/disabled/
-```
-
-**Method 3:** Remove from config
-```json
-{
-  "instructions": []  // Empty array
-}
-```
-
----
-
-## Tool Loading
-
-### Default Tool Behavior
-
-**Source:** All tools enabled by default unless explicitly disabled
-
-### Tool Token Costs (Verified)
-
-**Total if all enabled: ~6,606 tokens**
-
-**Expensive tools to consider disabling:**
-
-| Tool | Tokens | When to Disable |
-|------|--------|-----------------|
-| todowrite | 1,794 | Don't need task management |
-| bash | 1,889 | Read-only workflows |
-| task | 812 | Don't use subagents |
-| multiedit | 541 | Single-file edits only |
-
-**Cheap tools worth keeping:**
-
-| Tool | Tokens | Why Keep |
-|------|--------|----------|
-| read | 264 | Essential for reading files |
-| write | 140 | Essential for creating files |
-| edit | 295 | Essential for modifying files |
-| grep | 146 | Fast text search |
-| glob | 122 | Find files by pattern |
-
-### How to Configure Tools
-
-#### Global (opencode.json)
-
-```json
-{
-  "tools": {
-    "read": true,
-    "write": true,
-    "edit": true,
-    "bash": true,
-    "grep": true,
-    "glob": false,
-    "ls": false,
-    "patch": false,
-    "webfetch": false,
-    "task": false,
-    "multiedit": false,
-    "lsp-diagnostics": false,
-    "lsp-hover": false,
-    "todoread": false,
-    "todowrite": false
-  }
-}
-```
-
-**Saves:** ~4,856 tokens (keeping only 5 essential tools)
-
-#### Per-Agent
-
-```yaml
----
-description: "Minimal agent"
-tools:
-  read: true
-  write: true
-  edit: true
-  # All others implicitly false
----
-```
-
-**🚨 IMPORTANT:** Must explicitly set `false` or tools remain enabled!
-
----
-
-## Optimization Strategies
-
-### For Anthropic (Claude) - Use Full Context
-
-**Rationale:** Caching makes large contexts cheap
-
-**Recommended:**
-- Keep all tools enabled
-- Include detailed instructions
-- Don't worry about context size
-
-**Typical setup:**
-```
-Base prompt: 1,736 tokens
-Tools: 6,606 tokens
-Environment: 200 tokens
-Custom: 500 tokens
-───────────────────────
-Total: 9,042 tokens
-
-With caching:
-First request: 9,042 tokens (~$0.027)
-Subsequent: 1,200 input + 8,500 cache read (~$0.006)
-Savings: 77% per request!
-```
-
----
-
-### For Ollama (Local Models) - Minimize Everything
-
-**Rationale:** Limited context, no caching, every token matters
-
-#### Strategy 1: Disable Base Prompt (Edit Source)
-
-Edit `packages/opencode/src/session/system.ts`:
-
-```typescript
-export function provider(modelID: string) {
-  // Add before other checks:
-  if (modelID.includes("ollama") || modelID.includes("llama")) {
-    return ["You are a coding assistant. Be concise."]  // 8 tokens!
-  }
-  
-  if (modelID.includes("gpt-5")) return [PROMPT_CODEX]
-  // ... rest
-}
-```
-
-**Saves:** ~2,067 tokens (from 2,075 to 8)
-
-#### Strategy 2: Minimal Tool Set
-
-```json
-{
-  "tools": {
-    "read": true,
-    "write": true,
-    "edit": true,
-    "bash": false,
-    "grep": false
-  }
-}
-```
-
-**Saves:** ~5,906 tokens (from 6,606 to 700)
-
-#### Strategy 3: Remove Custom Instructions
-
-```bash
-mv AGENTS.md AGENTS.md.disabled
-mv ~/.claude/CLAUDE.md ~/.claude/CLAUDE.md.disabled
-```
-
-**Saves:** Varies (typically 200-2,000 tokens)
-
-#### Strategy 4: Minimal Agent
-
-Create `.opencode/agent/ollama.md`:
-
-```yaml
----
-description: "Ollama-optimized"
-mode: primary
-prompt: "Coding assistant. Concise."
-tools:
-  read: true
-  write: true
-  edit: true
----
-```
-
-**Result:**
-```
-Base prompt override: 5 tokens
-Environment: 40 tokens
-Tools: 700 tokens
-───────────────────────
-Total: ~745 tokens
-
-From 8,000+ to 745 = 91% reduction!
-```
-
----
-
-### For OpenAI (GPT-4) - Balanced
-
-**Rationale:** Good context window, some caching support
-
-**Recommended:**
-- Use default prompts (well-optimized)
-- Enable most tools
-- Moderate custom instructions
-
-**Typical setup:**
-```
-Base prompt: 2,475 tokens
-Tools: 4,000 tokens (disable heavy ones)
-Environment: 200 tokens
-Custom: 300 tokens
-───────────────────────
-Total: 6,975 tokens
-```
-
----
-
-### For Big Pickle - Special Case
-
-**Since it routes through Anthropic API:**
-
-**Option 1:** Treat like Claude (use caching)
-- Keep full context
-- Benefit from caching
-- Pay Anthropic rates
-
-**Option 2:** Optimize for cost
-- Disable unnecessary tools
-- Minimal custom instructions
-- Reduce base prompt via agent override
-
----
-
-## Complete Token Breakdown Examples
-
-### Example 1: Default Claude Session
-
-```
-Session: "Fix bug in auth.ts"
-Model: claude-sonnet-4
-Agent: build (default)
-Project: 50 files
-
-TOKEN BREAKDOWN:
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Component                    Tokens    Cached
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Header (anthropic_spoof)         12    Yes
-Base Prompt (anthropic.txt)   1,736    Yes
-Environment Info                 40    Yes
-Project Tree (50 files)         150    Yes
-AGENTS.md                       245    Yes
-~/.claude/CLAUDE.md             356    Yes
-───────────────────────────────────────────
-System Prompt Total          2,539    Yes
-
-Tools (all 16 enabled)       6,606    Yes
-───────────────────────────────────────────
-Context Total                9,145    Yes
-
-Your Message                    15    No
-───────────────────────────────────────────
-TOTAL FIRST REQUEST          9,160
-
-First request cost:  $0.0275
-Subsequent (5min):   $0.0050 (82% savings!)
-```
-
----
-
-### Example 2: Optimized Ollama Session
-
-```
-Session: "Fix bug in auth.ts"
-Model: ollama/qwen2.5:latest
-Agent: ollama-minimal
-Project: 50 files
-
-TOKEN BREAKDOWN:
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Component                    Tokens    Cached
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Header                            0    No
-Agent Prompt Override             8    No
-Environment Info                 40    No
-Project Tree (50 files)         150    No
-No custom instructions            0    No
-───────────────────────────────────────────
-System Prompt Total             198    No
-
-Tools (3 enabled: read,        700    No
-  write, edit)
-───────────────────────────────────────────
-Context Total                   898    No
-
-Your Message                    15    No
-───────────────────────────────────────────
-TOTAL EVERY REQUEST             913
-
-Cost: Free (local)
-Context usage: 11% of 8k window
-```
-
----
-
-### Example 3: Minimal "HI" Test
-
-```
-Session: "Respond with HI"
-Model: big-pickle
-Agent: ultra-minimal
-Project: 1 file
-
-TOKEN BREAKDOWN:
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Component                    Tokens    Cached
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Header                            0    Yes
-Base Prompt (qwen.txt)       2,075    Yes
-Environment Info                 40    Yes
-Project Tree (1 file)             3    Yes
-~/.claude/CLAUDE.md              46    Yes
-───────────────────────────────────────────
-System Prompt Total          2,164    Yes
-
-Tools (ALL disabled)              0    Yes
-───────────────────────────────────────────
-Context Total                2,164    Yes
-
-Your Message                     4    No
-───────────────────────────────────────────
-TOTAL                        2,168
-
-With agent override + no tools:
-Agent Prompt                      3    Yes
-Environment                      40    Yes
-Tree                             3    Yes
-Tools                            0    Yes
-───────────────────────────────────────────
-Context Total                   46    Yes
-Message                          4    No
-───────────────────────────────────────────
-TOTAL                           50    
-
-Savings: 97.7% reduction!
-```
-
----
-
-## Quick Reference
-
-### Files Always Loaded (if exist)
-
-1. `AGENTS.md` (local or global)
-2. `CLAUDE.md` (local or global)
-3. `CONTEXT.md` (deprecated, but still loads)
-4. Files in `config.instructions`
-
-### Files Never Auto-Loaded
-
-- `README.md`
-- `CONTRIBUTING.md`
-- `.opencode/custom.md` (unless in `instructions`)
-- Any other `.md` files
-
-### Minimum Viable Configuration
-
-**For local models (Ollama):**
-
-```yaml
-# .opencode/agent/minimal.md
----
-description: "Minimal"
-mode: primary
-prompt: "Code assistant"
-tools:
-  read: true
-  write: true
-  edit: true
----
-```
-
-```bash
-# Disable global instructions
-mv ~/.claude/CLAUDE.md ~/.claude/CLAUDE.md.disabled
-
-# Result: ~750 tokens total
-```
-
-**For Claude/hosted:**
-
-```yaml
-# Use defaults - caching makes it efficient
-# Just create agents with specific tools per task
----
-description: "Research agent"
-tools:
-  read: true
-  grep: true
-  webfetch: true
----
-```
-
----
-
-## Debugging Context Issues
-
-### Check What's Actually Being Loaded
-
-```bash
-# View session messages
-cat ~/.local/share/opencode/storage/message/ses_YOUR_ID/*.json | jq
-
-# Check custom instruction sources
-grep -r "Instructions from:" ~/.local/share/opencode/storage/message/
-
-# Count tokens per component
-./script/count-agent-tokens.sh your-agent qwen2.5:latest ollama
-```
-
-### Common Issues
-
-**Issue:** "Why 8k tokens for simple query?"  
-**Answer:** Base prompt (2,075) + Tools (6,606) = 8,681 tokens
-
-**Issue:** "Cache not working for Ollama"  
-**Answer:** Ollama doesn't support caching (local models)
-
-**Issue:** "Custom instructions not loading"  
-**Answer:** Check exact filenames (case-sensitive), verify path with `find`
-
-**Issue:** "Tools still loading after disabling"  
-**Answer:** Must set `false` explicitly, not just omit from config
-
----
-
-## Summary: Key Takeaways
-
-1. **Context = Header + Base Prompt + Environment + Custom + Tools**
-2. **Model determines base prompt** (1,335-3,940 words)
-3. **Custom instructions** only from specific files (AGENTS.md, CLAUDE.md, etc.)
-4. **Tools are opt-out**, not opt-in (default = all enabled)
-5. **Caching only works** with Anthropic, OpenRouter (Anthropic backend), Bedrock
-6. **Ollama needs aggressive optimization** (no caching, limited context)
-7. **Claude benefits from full context** (caching makes it cheap)
-8. **Agent prompts override** base prompts (when specified)
-
----
-
-**Last Updated:** Dec 7, 2025  
-**Verified Against:** OpenCode source code `packages/opencode/src/session/`
-

+ 0 - 416
dev/ai-tools/opencode/context/how-context-works.md

@@ -1,416 +0,0 @@
-# OpenCode File Structure & Reference Guide
-
-## Directory Structure
-
-### Global Config (`~/.config/opencode/`)
-
-```
-~/.config/opencode/
-├── opencode.json          # Global config
-├── AGENTS.md              # Auto-loaded instructions
-├── CLAUDE.md              # Auto-loaded instructions
-├── agent/                 # Custom agents
-│   ├── my-agent.md
-│   └── category/
-│       └── nested-agent.md
-├── command/               # Custom commands
-│   └── my-command.md
-└── plugin/                # Custom plugins
-    └── my-plugin.ts
-```
-
-### Local Repo (`.opencode/`)
-
-```
-your-repo/
-├── opencode.json          # Repo config
-├── .opencode/
-│   ├── AGENTS.md          # Auto-loaded instructions
-│   ├── agent/             # Project-specific agents
-│   │   └── my-agent.md
-│   ├── command/           # Project-specific commands
-│   │   └── my-command.md
-│   └── plugin/            # Project-specific plugins
-│       └── my-plugin.ts
-└── src/
-```
-
-## Auto-Loaded Files
-
-**Instruction files** (loaded automatically as system prompts):
-- `AGENTS.md` - Custom instructions (global or local)
-- `CLAUDE.md` - Legacy Claude instructions
-- `CONTEXT.md` - Deprecated, but still works
-
-**Config files** (merged in order):
-1. `~/.config/opencode/opencode.json` (global)
-2. `opencode.json` files from repo root up to current directory
-3. Files from `.opencode/` folders in hierarchy
-
-## Supported Subfolders
-
-| Folder | Files | Purpose |
-|--------|-------|---------|
-| `agent/` | `*.md` | Custom agents with system prompts |
-| `command/` | `*.md` | Custom slash commands |
-| `plugin/` | `*.ts`, `*.js` | Custom tools and extensions |
-
-**⚠️ Use singular names only:** `agent/`, NOT `agents/`
-
-## File References with `@` Symbol
-
-### Immediate vs. Lazy Loading
-
-**With `@` symbol** - **Immediate Loading**:
-- File is fetched and loaded right away
-- Content is immediately available to the agent
-- Use when context is always needed
-
-**Without `@` symbol** - **Lazy Loading**:
-- File is only fetched when the agent determines it's needed
-- Saves tokens if the agent can complete the task without it
-- Agent discovers and loads the file on-demand
-
-### Using the `@` Symbol
-
-**In commands and templates:**
-
-```bash
-# Relative to repo root
-@README.md
-@src/main.ts
-
-# Home directory
-@~/my-file.txt
-
-# Absolute path
-@/absolute/path/file.txt
-
-# If file doesn't exist, looks for agent
-@my-agent
-```
-
-**Resolution order:**
-1. Check if starts with `~/` → resolve to home directory
-2. Check if absolute path → use as-is
-3. Otherwise → resolve relative to repo root (`Instance.worktree`)
-4. If not found → look for agent with that name
-
-### Best Practices for Lazy Loading (Without `@`)
-
-When referencing files without the `@` symbol, help the agent discover them by:
-
-**1. Provide clear file paths**
-```
-"Use the context from .opencode/command/commit.md if needed"
-```
-
-**2. Describe what's there** (so agent knows when to fetch)
-```
-"Check the commit command guidelines in .opencode/command/commit.md 
-when you need to understand our commit message format"
-```
-
-**3. Mention directory conventions**
-```
-"Command templates are in .opencode/command/ - reference them as needed"
-```
-
-**4. Reference by purpose, not just path**
-```
-"Follow our commit guidelines (available in the command directory) 
-when making commits"
-```
-
-### Example: Lazy Loading in Practice
-
-**Without `@` symbol (lazy loading):**
-```
-"Create a git commit. Our commit guidelines are in .opencode/command/commit.md - 
-check them if you need to understand our prefix conventions and message format."
-```
-
-This approach:
-- ✅ Agent knows the file exists and where it is
-- ✅ Agent knows WHEN it would be useful (for commit conventions)
-- ✅ Agent only reads it IF it needs that information
-- ✅ Saves tokens if the agent can complete the task without it
-
-**With `@` symbol (immediate loading):**
-```
-"Create a git commit following these guidelines: @.opencode/command/commit.md"
-```
-
-This approach:
-- ✅ File content is immediately available
-- ✅ Guaranteed the agent has the context
-- ⚠️ Uses tokens even if agent doesn't need it
-
-### When to Use Each Approach
-
-| Use `@` (Immediate) | Omit `@` (Lazy) |
-|---------------------|-----------------|
-| Context always required | Context might be needed |
-| Short, critical files | Large reference files |
-| Agent must follow exact format | Agent can infer or discover |
-| Templates and schemas | Documentation and guides |
-
-**Pro tip:** Modern agents are good at discovering needed files through `codebase_search` or exploring directories, but being explicit about important files helps ensure consistency.
-
----
-
-## Research-Backed Context Architecture
-
-### Three-Layer Progressive Architecture
-
-Based on validated research from Stanford, Anthropic (2025), and recent AI agent engineering studies, effective context loading follows a three-layer progressive architecture:
-
-#### Layer 1: Static Base Context (First 15% of Prompt)
-
-This is your foundational layer, grounded in Stanford's position sensitivity research. **Critical instructions positioned early dramatically improve adherence.**
-
-**What goes here:**
-- Role definition (5-10%)
-- Critical rules (defined once, early positioning)
-- Task definition (clear objective)
-- Constraint summary (high-level "must/must-not")
-
-**Example:**
-```xml
-<role>Expert Prompt Architect</role>
-<critical_rules priority="absolute" enforcement="strict">
-  <rule id="position_sensitivity">Critical rules MUST be in first 15%</rule>
-  <rule id="nesting_limit">Max nesting: 4 levels</rule>
-</critical_rules>
-<execution_priority>
-  <tier level="1">Research patterns (non-negotiable)</tier>
-</execution_priority>
-```
-
-**Why this matters:** Research shows position sensitivity improves adherence across model sizes. Critical rules at the start are more reliably followed than rules buried later in the prompt.
-
-#### Layer 2: Lazy-Loaded Context (Just-in-Time Retrieval)
-
-This layer uses the "just-in-time" approach validated by Anthropic's 2025 research on effective context engineering for AI agents.
-
-> Rather than pre-processing all relevant data up front, agents built with the "just-in-time" approach maintain lightweight identifiers (file paths, stored queries, web links, etc.) and use these references to dynamically load data into context at runtime using tools.
-
-**Implementation:**
-```xml
-<context_sources>
-  <!-- Agent fetches these as needed, not embedded upfront -->
-  <standards>.opencode/context/core/standards/code.md</standards>
-  <practices>.opencode/context/core/practices/review.md</practices>
-  <workflows>.opencode/context/core/workflows/delegation.md</workflows>
-</context_sources>
-```
-
-**Key insight:** This enables **progressive disclosure**. Agents incrementally discover context through exploration:
-- File naming hints at purpose (`.../standards/code.md` vs `.../practices/review.md`)
-- File size signals complexity
-- Timestamps indicate recency
-- Folder structure provides hierarchical context
-
-**Token efficiency gain:**
-- Pre-loading all context: **2,000-5,000+ tokens**
-- Just-in-time loading: **300-1,000 tokens per file** (agents typically need 2-3 files, not 10)
-- **Net savings: 60-80% reduction in token usage**
-
-#### Layer 3: Dynamic Runtime Context (Execution-Time Loading)
-
-This layer handles long-horizon tasks and evolving context through compaction and memory strategies.
-
-**Implementation:**
-```xml
-<session_memory>
-  <!-- Agents write notes persisted outside context window -->
-  <!-- Read back in at later times for coherence -->
-  .opencode/sessions/[task-id].md
-</session_memory>
-
-<dynamic_context>
-  <!-- RAG retrieval results filtered for relevance -->
-  <!-- Tool execution outputs -->
-  <!-- Delegation context from prior agents -->
-</dynamic_context>
-```
-
-**Research backing:** For tasks spanning multiple turns:
-- **Compaction**: Summarize context nearing window limit, reinitiate with summary + critical details
-- **Structured note-taking**: Agent maintains notes in persistent memory (like session files), pulled back in later
-- **Progressive context assembly**: Each interaction yields context informing the next decision
-
-### Progressive Disclosure by Design
-
-Structure your context hierarchy so agents discover relevance layer-by-layer:
-
-```
-.opencode/context/core/
-├── standards/              ← Broad guidelines (agent starts here)
-│   ├── code.md            ← File naming hints: "code" standards
-│   ├── tests.md           ← "tests" = test-specific rules
-│   └── patterns.md        ← "patterns" = architectural patterns
-├── practices/              ← Execution-level practices
-│   ├── analysis.md        ← "analysis" = how to analyze
-│   └── review.md          ← "review" = code review criteria
-├── workflows/              ← Process templates
-│   ├── delegation.md      ← Delegation patterns
-│   ├── task-breakdown.md  ← Task analysis workflows
-│   └── sessions.md        ← Session management
-└── system/
-    └── context-guide.md   ← System internals
-```
-
-Each folder name signals purpose. Each file name within folders signals specific application. This is **progressive disclosure by design** - agents can navigate the hierarchy based on their current needs.
-
-### Long-Horizon Task Strategies
-
-For multi-hour tasks spanning context resets:
-
-**Compaction Strategy:**
-```xml
-<memory_strategy>
-  <!-- Before context reset: Agent summarizes work -->
-  <compaction>
-    Preserve: Architectural decisions, unresolved bugs, key insights
-    Discard: Redundant tool outputs, repeated attempts
-  </compaction>
-  
-  <!-- After reset: Agent reads notes and continues -->
-  <structured_notes path=".opencode/sessions/[id].md">
-    • Decisions made
-    • Current phase
-    • Next steps
-    • Unresolved issues
-  </structured_notes>
-</memory_strategy>
-```
-
-**Example:** Anthropic's Claude Code maintains precise tallies across thousands of steps using persistent notes - the same pattern your session files implement.
-
-### Anti-Patterns to Avoid
-
-Research identifies these common mistakes that reduce effectiveness:
-
-#### ❌ Anti-Pattern 1: Overload Static Context
-
-```xml
-<!-- DON'T DO THIS -->
-<prompt>
-  <all_standards><!-- 5000+ tokens of standards upfront --></all_standards>
-  <task>Fix typo in button</task>
-</prompt>
-```
-
-**Problems:**
-- Attention budget exhaustion (n² transformer relationships)
-- Reduced position sensitivity effectiveness (critical rules get buried)
-- Worse adherence to specific instructions
-
-**Solution:** Use lazy loading for large reference materials.
-
-#### ❌ Anti-Pattern 2: Deep Nesting
-
-```xml
-<!-- DON'T DO THIS -->
-<instructions>
-  <workflow>
-    <delegation>
-      <criteria>
-        <when>
-          <condition>
-            <!-- 6+ levels: breaks clarity -->
-```
-
-**Problem:** Nesting depth >4 levels reduces clarity significantly.
-
-**Solution:** Use attributes and flatter structures with max 4 levels.
-
-#### ❌ Anti-Pattern 3: Repeating Critical Rules
-
-```xml
-<!-- DON'T DO THIS -->
-<rule_1>Always request approval</rule_1>
-... 2000 tokens later ...
-<rule_2>Always get approval before execution</rule_2>
-... 3000 tokens later ...
-<rule_3>Approval must be obtained</rule_3>
-```
-
-**Problem:** Repetition causes ambiguity and wastes tokens.
-
-**Solution:** Define rules once in the first 15%, reference them with `@rule_id` elsewhere.
-
-### Token Efficiency Metrics
-
-Real-world measurements from production agent systems:
-
-| Approach | Token Cost | Files Loaded | Efficiency |
-|----------|-----------|--------------|------------|
-| Pre-load all context | 2,000-5,000+ | 10-15 files | Baseline |
-| Just-in-time loading | 300-1,000 | 2-3 files | **60-80% savings** |
-| With compaction | 500-1,500 | 3-5 files | **50-70% savings** |
-
-**Key insight:** Agents typically need only 2-3 context files per task, not the entire knowledge base.
-
-### Research Validation Summary
-
-| Pattern | Research Basis | Effect |
-|---------|----------------|--------|
-| **Position Sensitivity** | Stanford multi-instruction study | Improves adherence (varies by task/model) |
-| **Just-in-Time Loading** | Anthropic context engineering (2025) | 60-80% token reduction |
-| **Progressive Disclosure** | Anthropic agent research | Agents discover context incrementally |
-| **Nesting Depth ≤4** | Anthropic XML research | Reduces complexity, improves clarity |
-| **Compaction + Memory** | Anthropic long-horizon tasks | Maintains coherence across resets |
-
-### Research Sources
-
-- **Anthropic (2025)**: "Effective Context Engineering for AI Agents"
-- **Stanford**: Multi-instruction position sensitivity study
-- **Anthropic**: "XML Prompting as Grammar-Constrained Interaction" (ArXiv 2509.08182)
-- **ODSC (2025)**: "Building Dynamic In-Context Learning for Self-Optimizing Agents"
-- **ArXiv**: "Optimization of Retrieval-Augmented Generation Context with Outlier Detection" (2407.01403)
-
----
-
-## Custom Instruction Files
-
-**For arbitrary paths, use `instructions` field:**
-
-```json
-{
-  "instructions": [
-    "~/opencode/context/my-context.md",
-    "docs/**/*.md",
-    ".opencode/context/**/*.md"
-  ]
-}
-```
-
-**Paths can be:**
-- Absolute: `/path/to/file.md`
-- Home relative: `~/path/to/file.md`
-- Repo relative: `docs/instructions.md`
-- Glob patterns: `**/*.md`
-
-## Config Merging
-
-**Configs merge with priority** (later overrides earlier):
-1. Global config (`~/.config/opencode/`)
-2. Repo root configs (from root up)
-3. Custom config directories (`.opencode/` folders)
-4. Environment variables (`OPENCODE_CONFIG`)
-
-**Agents, commands, and plugins** from all locations are merged together.
-
-## Quick Reference
-
-| What | Where | How |
-|------|-------|-----|
-| Global agent | `~/.config/opencode/agent/name.md` | Auto-loaded |
-| Local agent | `.opencode/agent/name.md` | Auto-loaded |
-| Global command | `~/.config/opencode/command/name.md` | Auto-loaded |
-| Local command | `.opencode/command/name.md` | Auto-loaded |
-| Global instructions | `~/.config/opencode/AGENTS.md` | Auto-loaded |
-| Local instructions | `.opencode/AGENTS.md` or `AGENTS.md` | Auto-loaded |
-| Custom files | Anywhere | Use `instructions` config or `@` symbol |

+ 0 - 1692
dev/ai-tools/opencode/logging-and-session-storage.md

@@ -1,1692 +0,0 @@
-# OpenCode Logging and Session Storage System
-
-## Overview
-
-OpenCode maintains a comprehensive local logging system that stores all session data, messages, tool calls, and agent interactions. This document provides a complete reference for understanding and working with OpenCode's native logging infrastructure.
-
-**Key Benefits:**
-- ✅ Complete session history and replay capability
-- ✅ Detailed tool call tracking with input/output/timing
-- ✅ Agent identification and switching tracking
-- ✅ Token usage and cost analysis
-- ✅ Error tracking and debugging
-- ✅ Performance metrics and optimization data
-
----
-
-## Architecture Overview
-
-```
-OpenCode Session Storage
-├── Session Info (metadata)
-├── Messages (user/assistant exchanges)
-└── Parts (content, tools, reasoning, patches)
-```
-
-**Storage Location:**
-```
-~/.local/share/opencode/
-├── log/                    # System logs (markdown format)
-└── project/
-    └── {project-name}/
-        └── storage/
-            └── session/
-                ├── info/       # Session metadata
-                ├── message/    # Message metadata
-                └── part/       # Message parts (content, tools, etc.)
-```
-
----
-
-## Directory Structure
-
-### Complete Layout
-
-```
-~/.local/share/opencode/project/{project-name}/storage/
-├── migration                           # Migration version file
-└── session/
-    ├── info/                          # Session-level metadata
-    │   └── {session-id}.json          # One file per session
-    ├── message/                       # Message-level metadata
-    │   └── {session-id}/              # Directory per session
-    │       └── {message-id}.json      # One file per message
-    └── part/                          # Message parts (actual content)
-        └── {session-id}/              # Directory per session
-            └── {message-id}/          # Directory per message
-                └── {part-id}.json     # One file per part
-```
-
-### ID Format
-
-- **Session ID:** `ses_` + 22 characters (e.g., `ses_75545f167ffeWfPEtVLVSaFfjA`)
-- **Message ID:** `msg_` + 22 characters (e.g., `msg_8aaba0e9b0017D9LcZ9dMTd6xA`)
-- **Part ID:** `prt_` + 22 characters (e.g., `prt_8aaba0e9b0027HZzFFZtM4MJnH`)
-- **Call ID:** `toolu_` + 24 characters (e.g., `toolu_01MMtz9DzLzQMow41iLpThHB`)
-
----
-
-## Data Schemas
-
-### 1. Session Info
-
-**Location:** `session/info/{session-id}.json`
-
-**Purpose:** High-level session metadata
-
-**Schema:**
-```typescript
-interface SessionInfo {
-  id: string              // ses_xxxxx
-  version: string         // OpenCode version (e.g., "0.5.1")
-  title: string           // Session title/description
-  time: {
-    created: number       // Unix timestamp (ms)
-    updated: number       // Unix timestamp (ms)
-  }
-}
-```
-
-**Example:**
-```json
-{
-  "id": "ses_75545f167ffeWfPEtVLVSaFfjA",
-  "version": "0.5.1",
-  "title": "Creating RAG agent tasks and workflow",
-  "time": {
-    "created": 1755210976920,
-    "updated": 1755210977929
-  }
-}
-```
-
----
-
-### 2. Message Metadata
-
-**Location:** `session/message/{session-id}/{message-id}.json`
-
-**Purpose:** Message-level metadata including agent info, tokens, cost, timing
-
-**Schema:**
-```typescript
-interface Message {
-  id: string                    // msg_xxxxx
-  role: "user" | "assistant"
-  sessionID: string             // ses_xxxxx
-  
-  // Agent Information (assistant messages only)
-  mode?: string                 // 🎯 Agent name/mode
-  system?: string[]             // System prompt(s)
-  
-  // Model Information
-  modelID?: string              // e.g., "claude-sonnet-4-20250514"
-  providerID?: string           // e.g., "anthropic"
-  
-  // Context
-  path?: {
-    cwd: string                 // Working directory
-    root: string                // Project root
-  }
-  
-  // Metrics
-  cost?: number                 // API cost
-  tokens?: {
-    input: number
-    output: number
-    reasoning: number
-    cache: {
-      write: number             // Cache write tokens
-      read: number              // Cache read tokens
-    }
-  }
-  
-  // Timing
-  time: {
-    created: number             // Unix timestamp (ms)
-    completed?: number          // Unix timestamp (ms) - assistant only
-  }
-  
-  // Error Handling
-  error?: {
-    name: string
-    data: any
-  }
-}
-```
-
-**Example (User Message):**
-```json
-{
-  "id": "msg_8aaba0e9b0017D9LcZ9dMTd6xA",
-  "role": "user",
-  "sessionID": "ses_75545f167ffeWfPEtVLVSaFfjA",
-  "time": {
-    "created": 1755210976926
-  }
-}
-```
-
-**Example (Assistant Message):**
-```json
-{
-  "id": "msg_8aaba0ee3001YGUGe4U2GF5oAZ",
-  "role": "assistant",
-  "sessionID": "ses_75545f167ffeWfPEtVLVSaFfjA",
-  "mode": "code-base-agent",
-  "system": ["You are Claude Code...", "# Agent Instructions..."],
-  "modelID": "claude-sonnet-4-20250514",
-  "providerID": "anthropic",
-  "path": {
-    "cwd": "/Users/user/project",
-    "root": "/Users/user/project"
-  },
-  "cost": 0,
-  "tokens": {
-    "input": 8,
-    "output": 81,
-    "reasoning": 0,
-    "cache": {
-      "write": 376,
-      "read": 9348
-    }
-  },
-  "time": {
-    "created": 1755210976995,
-    "completed": 1755210987509
-  }
-}
-```
-
----
-
-### 3. Message Parts
-
-**Location:** `session/part/{session-id}/{message-id}/{part-id}.json`
-
-**Purpose:** Actual message content, tool calls, reasoning, file changes, etc.
-
-**Part Types:**
-- `text` - Text content (user input, assistant responses)
-- `tool` - Tool calls (read, write, edit, bash, task, etc.)
-- `patch` - File changes/commits
-- `reasoning` - Scratchpad/thinking content
-- `step-start` - Step boundary markers
-- `step-finish` - Step boundary markers
-- `file` - File references
-
----
-
-#### 3.1 Text Part
-
-**Purpose:** Text content from user or assistant
-
-**Schema:**
-```typescript
-interface TextPart {
-  id: string              // prt_xxxxx
-  messageID: string       // msg_xxxxx
-  sessionID: string       // ses_xxxxx
-  type: "text"
-  text: string            // The actual text content
-  synthetic?: boolean     // Whether text is synthetic
-  time: {
-    start: number         // Unix timestamp (ms)
-    end: number           // Unix timestamp (ms)
-  }
-}
-```
-
-**Example:**
-```json
-{
-  "id": "prt_8aaba0e9b0027HZzFFZtM4MJnH",
-  "type": "text",
-  "text": "I want you to make a tasks for making a simple rag agent",
-  "synthetic": false,
-  "time": {
-    "start": 0,
-    "end": 0
-  },
-  "messageID": "msg_8aaba0e9b0017D9LcZ9dMTd6xA",
-  "sessionID": "ses_75545f167ffeWfPEtVLVSaFfjA"
-}
-```
-
----
-
-#### 3.2 Tool Part
-
-**Purpose:** Tool execution tracking with input/output/status
-
-**Schema:**
-```typescript
-interface ToolPart {
-  id: string              // prt_xxxxx
-  messageID: string       // msg_xxxxx
-  sessionID: string       // ses_xxxxx
-  type: "tool"
-  tool: string            // Tool name: read, write, edit, bash, task, list, glob, grep, etc.
-  callID: string          // toolu_xxxxx (Anthropic tool call ID)
-  state: {
-    status: "completed" | "error" | "pending" | "running"
-    input: Record<string, any>    // Tool input arguments
-    output?: string               // Tool output (if completed)
-    error?: string                // Error message (if error)
-    metadata?: Record<string, any> // Additional metadata
-    title?: string                // Tool result title
-    time: {
-      start: number               // Unix timestamp (ms)
-      end: number                 // Unix timestamp (ms)
-    }
-  }
-}
-```
-
-**Example (Completed Tool Call):**
-```json
-{
-  "id": "prt_8aaba2f13001n61qUzBQLt9alA",
-  "messageID": "msg_8aaba0ee3001YGUGe4U2GF5oAZ",
-  "sessionID": "ses_75545f167ffeWfPEtVLVSaFfjA",
-  "type": "tool",
-  "tool": "list",
-  "callID": "toolu_01RGumBKHDY59QqVFf1sf16W",
-  "state": {
-    "status": "completed",
-    "input": {
-      "path": "/Users/user/project"
-    },
-    "output": "/Users/user/project/\n  .opencode/\n    agent/\n...",
-    "metadata": {
-      "count": 9,
-      "truncated": false
-    },
-    "title": "",
-    "time": {
-      "start": 1755210985762,
-      "end": 1755210985770
-    }
-  }
-}
-```
-
-**Example (Error Tool Call):**
-```json
-{
-  "id": "prt_8aaba25b5001qNq116TyFhdZiB",
-  "messageID": "msg_8aaba0ee3001YGUGe4U2GF5oAZ",
-  "sessionID": "ses_75545f167ffeWfPEtVLVSaFfjA",
-  "type": "tool",
-  "tool": "read",
-  "callID": "toolu_01MMtz9DzLzQMow41iLpThHB",
-  "state": {
-    "status": "error",
-    "input": {
-      "filePath": "/path/to/missing/file.md"
-    },
-    "error": "Error: ENOENT: no such file or directory",
-    "time": {
-      "start": 1755210983452,
-      "end": 1755210983456
-    }
-  }
-}
-```
-
-**Tool Call Statuses:**
-- `completed` - Tool executed successfully (95.3% of calls)
-- `error` - Tool execution failed (4.1% of calls)
-- `running` - Tool currently executing (0.5% of calls)
-- `pending` - Tool queued for execution (0.2% of calls)
-
----
-
-#### 3.3 Patch Part
-
-**Purpose:** Track file changes and git commits
-
-**Schema:**
-```typescript
-interface PatchPart {
-  id: string              // prt_xxxxx
-  messageID: string       // msg_xxxxx
-  sessionID: string       // ses_xxxxx
-  type: "patch"
-  hash: string            // Git commit hash
-  files: string[]         // Array of file paths changed
-}
-```
-
-**Example:**
-```json
-{
-  "id": "prt_8e33bae36001OeMs7f18gvEDJN",
-  "messageID": "msg_8e337af2b001raZR3TdjPshyb0",
-  "sessionID": "ses_71cc8d5d1ffeBTr9L0ESbEXfhv",
-  "type": "patch",
-  "hash": "de359d2a9d9edcd5504ad6f25e567e60275b6377",
-  "files": [
-    "/Users/user/project/tasks/subtasks/feature/01-setup.md",
-    "/Users/user/project/tasks/subtasks/feature/02-config.md"
-  ]
-}
-```
-
----
-
-#### 3.4 Reasoning Part
-
-**Purpose:** Capture agent's internal reasoning/scratchpad
-
-**Schema:**
-```typescript
-interface ReasoningPart {
-  id: string              // prt_xxxxx
-  messageID: string       // msg_xxxxx
-  sessionID: string       // ses_xxxxx
-  type: "reasoning"
-  text: string            // Reasoning content
-  time: {
-    start: number         // Unix timestamp (ms)
-    end: number           // Unix timestamp (ms)
-  }
-}
-```
-
----
-
-#### 3.5 Step Boundaries
-
-**Purpose:** Mark step start/finish for workflow tracking
-
-**Schema:**
-```typescript
-interface StepPart {
-  id: string              // prt_xxxxx
-  messageID: string       // msg_xxxxx
-  sessionID: string       // ses_xxxxx
-  type: "step-start" | "step-finish"
-  tool: null
-}
-```
-
----
-
-## Agent Modes
-
-The `mode` field in assistant messages identifies which agent handled the message.
-
-**Agent Modes Found:**
-
-| Mode | Count | Description |
-|------|-------|-------------|
-| `build` | 69 | Build/validation agent |
-| `codebase-agent` | 33 | Codebase analysis agent |
-| `general` | 17 | General purpose agent |
-| `core` | 16 | Core agent |
-| `code-base-agent` | 8 | Code base agent (variant) |
-| `task-manager` | 1 | Task management agent |
-| `plan` | 1 | Planning agent |
-
-**Note:** Agent mode names may vary based on your `.opencode/agent/` configuration.
-
----
-
-## Model and Provider Tracking
-
-The `modelID` and `providerID` fields in assistant messages track which AI model and provider handled each message.
-
-### Models Found in Production Data
-
-| Model | Provider | Usage Count | Percentage | Agents Using It |
-|-------|----------|-------------|------------|-----------------|
-| `claude-sonnet-4-20250514` | anthropic | 117 | 81% | build, code-base-agent, codebase-agent, core, general, plan |
-| `sonic` | opencode | 14 | 10% | build, codebase-agent |
-| `claude-3-5-sonnet-20241022` | anthropic | 8 | 6% | build |
-| `gemini-2.5-flash` | google | 5 | 3% | build, code-base-agent, core, task-manager |
-| `qwen/qwen3-coder` | openrouter | 1 | <1% | core |
-
-### Provider Distribution
-
-```
-Provider Usage:
-├── anthropic:    125 (86.2%)
-├── opencode:      14 (9.7%)
-├── google:         5 (3.4%)
-└── openrouter:     1 (0.7%)
-```
-
-### Key Insights
-
-1. **Multi-Model Support** - System uses 5 different models across 4 providers
-2. **Dominant Model** - Claude Sonnet 4 handles 81% of messages
-3. **Provider Diversity** - Anthropic, Google, OpenRouter, and OpenCode's own models
-4. **Agent-Model Flexibility** - Different agents can use different models
-5. **Fallback Options** - Multiple models available for redundancy
-
-### Model Performance Comparison
-
-Based on real session data, here's how models compare:
-
-**Claude Sonnet 4 (claude-sonnet-4-20250514):**
-- ✅ Most widely used (81% of messages)
-- ✅ Used by all agent types
-- ✅ Highest cache hit rate (avg 9,348 cache read tokens)
-- ✅ Best for complex reasoning and multi-step tasks
-
-**Sonic (opencode):**
-- ✅ Fast response times
-- ✅ Used primarily by build and codebase agents
-- ✅ Good for quick validation tasks
-- ⚠️ Limited to specific agent types
-
-**Gemini 2.5 Flash (google):**
-- ✅ Cost-effective option
-- ✅ Used by multiple agent types
-- ✅ Good for straightforward tasks
-- ⚠️ Lower usage suggests selective deployment
-
-**Claude 3.5 Sonnet (claude-3-5-sonnet-20241022):**
-- ✅ Previous generation model
-- ✅ Used exclusively by build agent
-- ⚠️ Being phased out in favor of Sonnet 4
-
----
-
-## Statistics (From Real Data)
-
-### Part Type Distribution
-
-```
-Total Parts: ~4,787
-├── step-start:   1,334 (27.9%)
-├── step-finish:  1,313 (27.4%)
-├── tool:         1,290 (26.9%)
-├── text:           749 (15.6%)
-├── patch:          726 (15.2%)
-├── reasoning:      369 (7.7%)
-└── file:             6 (0.1%)
-```
-
-### Tool Call Success Rate
-
-```
-Tool Call Statuses:
-├── completed:    1,229 (95.3%)
-├── error:           53 (4.1%)
-├── running:          6 (0.5%)
-└── pending:          2 (0.2%)
-```
-
-**Key Insight:** 95.3% tool success rate indicates high reliability.
-
----
-
-## What Can Be Extracted
-
-### ✅ Available Data
-
-1. **Session Timeline**
-   - Complete conversation flow
-   - Message ordering and timing
-   - Session duration and activity
-
-2. **Agent Tracking**
-   - Which agent handled each message
-   - Agent switching patterns
-   - Agent-specific performance metrics
-
-3. **Tool Usage**
-   - Every tool call with input/output
-   - Tool execution time
-   - Success/failure rates
-   - Error messages and debugging info
-
-4. **Performance Metrics**
-   - Token usage (input/output/cache)
-   - API costs per message
-   - Tool execution times
-   - Message completion times
-
-5. **File Changes**
-   - Git commit hashes
-   - Files modified per session
-   - Change tracking over time
-
-6. **Error Tracking**
-   - Failed tool calls
-   - Error messages
-   - Error frequency by tool/agent
-
-7. **Context & Configuration**
-   - System prompts used
-   - Working directory
-   - Model and provider info
-
-### ❌ Not Available (Limitations)
-
-1. **Approval Gates** - No explicit approval flag (must infer from text)
-2. **Context File Markers** - No explicit flag for context file reads (must check file paths)
-3. **Delegation Reasoning** - No metadata on why delegation occurred
-4. **User Intent** - No structured task classification
-5. **Quality Metrics** - No built-in code quality or test results
-
----
-
-## How to Access the Logs
-
-### Reading Session Data
-
-```typescript
-import fs from 'fs';
-import path from 'path';
-
-// Base path
-const projectName = 'Users-username-Documents-GitHub-project';
-const basePath = path.join(
-  process.env.HOME!,
-  '.local/share/opencode/project',
-  projectName,
-  'storage/session'
-);
-
-// Read session info
-function getSessionInfo(sessionID: string) {
-  const infoPath = path.join(basePath, 'info', `${sessionID}.json`);
-  return JSON.parse(fs.readFileSync(infoPath, 'utf-8'));
-}
-
-// Read all messages for a session
-function getSessionMessages(sessionID: string) {
-  const messagePath = path.join(basePath, 'message', sessionID);
-  const messageFiles = fs.readdirSync(messagePath);
-  
-  return messageFiles.map(file => {
-    const filePath = path.join(messagePath, file);
-    return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
-  }).sort((a, b) => a.time.created - b.time.created);
-}
-
-// Read all parts for a message
-function getMessageParts(sessionID: string, messageID: string) {
-  const partPath = path.join(basePath, 'part', sessionID, messageID);
-  const partFiles = fs.readdirSync(partPath);
-  
-  return partFiles.map(file => {
-    const filePath = path.join(partPath, file);
-    return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
-  }).sort((a, b) => a.time.start - b.time.start);
-}
-```
-
-### Building a Session Timeline
-
-```typescript
-interface TimelineEvent {
-  timestamp: number;
-  type: 'user_message' | 'assistant_message' | 'tool_call' | 'patch';
-  agent?: string;
-  data: any;
-}
-
-function buildSessionTimeline(sessionID: string): TimelineEvent[] {
-  const timeline: TimelineEvent[] = [];
-  const messages = getSessionMessages(sessionID);
-  
-  for (const message of messages) {
-    // Add message event
-    timeline.push({
-      timestamp: message.time.created,
-      type: message.role === 'user' ? 'user_message' : 'assistant_message',
-      agent: message.mode,
-      data: message
-    });
-    
-    // Add parts (tools, patches, etc.)
-    const parts = getMessageParts(sessionID, message.id);
-    for (const part of parts) {
-      if (part.type === 'tool') {
-        timeline.push({
-          timestamp: part.state.time.start,
-          type: 'tool_call',
-          agent: message.mode,
-          data: part
-        });
-      } else if (part.type === 'patch') {
-        timeline.push({
-          timestamp: message.time.created,
-          type: 'patch',
-          agent: message.mode,
-          data: part
-        });
-      }
-    }
-  }
-  
-  return timeline.sort((a, b) => a.timestamp - b.timestamp);
-}
-```
-
-### Extracting Tool Usage
-
-```typescript
-function analyzeToolUsage(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  const toolStats: Record<string, {
-    count: number;
-    success: number;
-    error: number;
-    avgDuration: number;
-  }> = {};
-  
-  for (const message of messages) {
-    const parts = getMessageParts(sessionID, message.id);
-    
-    for (const part of parts) {
-      if (part.type === 'tool') {
-        const tool = part.tool;
-        
-        if (!toolStats[tool]) {
-          toolStats[tool] = { count: 0, success: 0, error: 0, avgDuration: 0 };
-        }
-        
-        toolStats[tool].count++;
-        
-        if (part.state.status === 'completed') {
-          toolStats[tool].success++;
-        } else if (part.state.status === 'error') {
-          toolStats[tool].error++;
-        }
-        
-        const duration = part.state.time.end - part.state.time.start;
-        toolStats[tool].avgDuration += duration;
-      }
-    }
-  }
-  
-  // Calculate averages
-  for (const tool in toolStats) {
-    toolStats[tool].avgDuration /= toolStats[tool].count;
-  }
-  
-  return toolStats;
-}
-```
-
-### Finding Context File Reads
-
-```typescript
-function findContextFileReads(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  const contextReads: Array<{
-    timestamp: number;
-    agent: string;
-    file: string;
-  }> = [];
-  
-  for (const message of messages) {
-    const parts = getMessageParts(sessionID, message.id);
-    
-    for (const part of parts) {
-      if (part.type === 'tool' && part.tool === 'read') {
-        const filePath = part.state.input.filePath || '';
-        
-        // Check if it's a context file
-        if (filePath.includes('.opencode/context/')) {
-          contextReads.push({
-            timestamp: part.state.time.start,
-            agent: message.mode || 'unknown',
-            file: filePath
-          });
-        }
-      }
-    }
-  }
-  
-  return contextReads;
-}
-```
-
----
-
-## Use Cases for Evaluation
-
-### 1. Approval Gate Validation
-
-Check if assistant requested approval before execution tools:
-
-```typescript
-function checkApprovalGate(sessionID: string, messageID: string): boolean {
-  const message = JSON.parse(
-    fs.readFileSync(
-      path.join(basePath, 'message', sessionID, `${messageID}.json`),
-      'utf-8'
-    )
-  );
-  
-  const parts = getMessageParts(sessionID, messageID);
-  
-  // Check if any execution tools were called
-  const executionTools = ['bash', 'write', 'edit', 'task'];
-  const hasExecutionTool = parts.some(
-    p => p.type === 'tool' && executionTools.includes(p.tool)
-  );
-  
-  if (!hasExecutionTool) return true; // No execution, no approval needed
-  
-  // Check if text contains approval language
-  const textParts = parts.filter(p => p.type === 'text');
-  const approvalKeywords = [
-    'approval', 'approve', 'proceed', 'confirm', 
-    'permission', 'before proceeding'
-  ];
-  
-  return textParts.some(part => 
-    approvalKeywords.some(keyword => 
-      part.text.toLowerCase().includes(keyword)
-    )
-  );
-}
-```
-
-### 2. Context Loading Compliance
-
-Verify context files were loaded before execution:
-
-```typescript
-function checkContextLoading(sessionID: string): {
-  compliant: boolean;
-  details: string;
-} {
-  const timeline = buildSessionTimeline(sessionID);
-  const contextReads = timeline.filter(
-    e => e.type === 'tool_call' && 
-    e.data.tool === 'read' &&
-    e.data.state.input.filePath?.includes('.opencode/context/')
-  );
-  
-  const executionTools = timeline.filter(
-    e => e.type === 'tool_call' &&
-    ['write', 'edit', 'bash', 'task'].includes(e.data.tool)
-  );
-  
-  if (executionTools.length === 0) {
-    return { compliant: true, details: 'No execution tools used' };
-  }
-  
-  if (contextReads.length === 0) {
-    return { 
-      compliant: false, 
-      details: 'Execution tools used without loading context' 
-    };
-  }
-  
-  // Check if context was loaded BEFORE execution
-  const firstExecution = executionTools[0].timestamp;
-  const lastContextRead = contextReads[contextReads.length - 1].timestamp;
-  
-  if (lastContextRead < firstExecution) {
-    return { 
-      compliant: true, 
-      details: 'Context loaded before execution' 
-    };
-  }
-  
-  return { 
-    compliant: false, 
-    details: 'Context loaded after execution started' 
-  };
-}
-```
-
-### 3. Agent Performance Analysis
-
-Compare performance across agents:
-
-```typescript
-function analyzeAgentPerformance(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  const agentStats: Record<string, {
-    messageCount: number;
-    totalTokens: number;
-    totalCost: number;
-    avgDuration: number;
-    toolCalls: number;
-  }> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant' || !message.mode) continue;
-    
-    const agent = message.mode;
-    
-    if (!agentStats[agent]) {
-      agentStats[agent] = {
-        messageCount: 0,
-        totalTokens: 0,
-        totalCost: 0,
-        avgDuration: 0,
-        toolCalls: 0
-      };
-    }
-    
-    agentStats[agent].messageCount++;
-    agentStats[agent].totalTokens += 
-      (message.tokens?.input || 0) + (message.tokens?.output || 0);
-    agentStats[agent].totalCost += message.cost || 0;
-    
-    if (message.time.completed) {
-      const duration = message.time.completed - message.time.created;
-      agentStats[agent].avgDuration += duration;
-    }
-    
-    const parts = getMessageParts(sessionID, message.id);
-    agentStats[agent].toolCalls += parts.filter(p => p.type === 'tool').length;
-  }
-  
-  // Calculate averages
-  for (const agent in agentStats) {
-    agentStats[agent].avgDuration /= agentStats[agent].messageCount;
-  }
-  
-  return agentStats;
-}
-```
-
-### 4. Model Performance Comparison
-
-Compare performance metrics across different models:
-
-```typescript
-function compareModelPerformance(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  const modelStats: Record<string, {
-    messageCount: number;
-    totalTokens: number;
-    inputTokens: number;
-    outputTokens: number;
-    cacheReadTokens: number;
-    cacheWriteTokens: number;
-    totalCost: number;
-    avgDuration: number;
-    errorCount: number;
-    successRate: number;
-  }> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant' || !message.modelID) continue;
-    
-    const model = message.modelID;
-    
-    if (!modelStats[model]) {
-      modelStats[model] = {
-        messageCount: 0,
-        totalTokens: 0,
-        inputTokens: 0,
-        outputTokens: 0,
-        cacheReadTokens: 0,
-        cacheWriteTokens: 0,
-        totalCost: 0,
-        avgDuration: 0,
-        errorCount: 0,
-        successRate: 0
-      };
-    }
-    
-    const stats = modelStats[model];
-    stats.messageCount++;
-    
-    if (message.tokens) {
-      stats.inputTokens += message.tokens.input || 0;
-      stats.outputTokens += message.tokens.output || 0;
-      stats.cacheReadTokens += message.tokens.cache?.read || 0;
-      stats.cacheWriteTokens += message.tokens.cache?.write || 0;
-      stats.totalTokens += 
-        (message.tokens.input || 0) + 
-        (message.tokens.output || 0);
-    }
-    
-    stats.totalCost += message.cost || 0;
-    
-    if (message.time.completed) {
-      const duration = message.time.completed - message.time.created;
-      stats.avgDuration += duration;
-    }
-    
-    if (message.error) {
-      stats.errorCount++;
-    }
-  }
-  
-  // Calculate averages and success rates
-  for (const model in modelStats) {
-    const stats = modelStats[model];
-    stats.avgDuration /= stats.messageCount;
-    stats.successRate = 
-      ((stats.messageCount - stats.errorCount) / stats.messageCount) * 100;
-  }
-  
-  return modelStats;
-}
-```
-
-**Example Output:**
-```typescript
-{
-  "claude-sonnet-4-20250514": {
-    messageCount: 117,
-    totalTokens: 1250000,
-    inputTokens: 850000,
-    outputTokens: 400000,
-    cacheReadTokens: 1093716,
-    cacheWriteTokens: 43992,
-    totalCost: 12.50,
-    avgDuration: 7205,
-    errorCount: 2,
-    successRate: 98.3
-  },
-  "gemini-2.5-flash": {
-    messageCount: 5,
-    totalTokens: 45000,
-    inputTokens: 30000,
-    outputTokens: 15000,
-    cacheReadTokens: 0,
-    cacheWriteTokens: 0,
-    totalCost: 0.15,
-    avgDuration: 3200,
-    errorCount: 0,
-    successRate: 100
-  }
-}
-```
-
-### 5. Cost Analysis by Model and Provider
-
-Track spending across models and providers:
-
-```typescript
-function analyzeCostByModel(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  
-  const costByModel: Record<string, number> = {};
-  const costByProvider: Record<string, number> = {};
-  const modelProviderMap: Record<string, string> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant') continue;
-    
-    if (message.modelID && message.cost) {
-      costByModel[message.modelID] = 
-        (costByModel[message.modelID] || 0) + message.cost;
-      
-      if (message.providerID) {
-        costByProvider[message.providerID] = 
-          (costByProvider[message.providerID] || 0) + message.cost;
-        modelProviderMap[message.modelID] = message.providerID;
-      }
-    }
-  }
-  
-  return {
-    byModel: costByModel,
-    byProvider: costByProvider,
-    modelProviderMap,
-    totalCost: Object.values(costByModel).reduce((a, b) => a + b, 0)
-  };
-}
-```
-
-**Example Output:**
-```typescript
-{
-  byModel: {
-    "claude-sonnet-4-20250514": 12.50,
-    "gemini-2.5-flash": 0.15,
-    "sonic": 0.00
-  },
-  byProvider: {
-    "anthropic": 12.50,
-    "google": 0.15,
-    "opencode": 0.00
-  },
-  modelProviderMap: {
-    "claude-sonnet-4-20250514": "anthropic",
-    "gemini-2.5-flash": "google",
-    "sonic": "opencode"
-  },
-  totalCost: 12.65
-}
-```
-
-### 6. Model-Agent Compatibility Analysis
-
-Analyze which models work best with which agents:
-
-```typescript
-function analyzeModelAgentPairs(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  
-  interface PairStats {
-    model: string;
-    agent: string;
-    provider: string;
-    count: number;
-    avgTokens: number;
-    avgCost: number;
-    avgDuration: number;
-    successRate: number;
-  }
-  
-  const pairs: Record<string, PairStats> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant' || !message.modelID || !message.mode) {
-      continue;
-    }
-    
-    const key = `${message.modelID}:${message.mode}`;
-    
-    if (!pairs[key]) {
-      pairs[key] = {
-        model: message.modelID,
-        agent: message.mode,
-        provider: message.providerID || 'unknown',
-        count: 0,
-        avgTokens: 0,
-        avgCost: 0,
-        avgDuration: 0,
-        successRate: 0
-      };
-    }
-    
-    const pair = pairs[key];
-    pair.count++;
-    
-    if (message.tokens) {
-      pair.avgTokens += 
-        (message.tokens.input || 0) + (message.tokens.output || 0);
-    }
-    
-    pair.avgCost += message.cost || 0;
-    
-    if (message.time.completed) {
-      pair.avgDuration += message.time.completed - message.time.created;
-    }
-    
-    if (!message.error) {
-      pair.successRate++;
-    }
-  }
-  
-  // Calculate averages
-  for (const key in pairs) {
-    const pair = pairs[key];
-    pair.avgTokens /= pair.count;
-    pair.avgCost /= pair.count;
-    pair.avgDuration /= pair.count;
-    pair.successRate = (pair.successRate / pair.count) * 100;
-  }
-  
-  return Object.values(pairs).sort((a, b) => b.count - a.count);
-}
-```
-
-**Example Output:**
-```typescript
-[
-  {
-    model: "claude-sonnet-4-20250514",
-    agent: "build",
-    provider: "anthropic",
-    count: 45,
-    avgTokens: 12500,
-    avgCost: 0.125,
-    avgDuration: 6800,
-    successRate: 97.8
-  },
-  {
-    model: "claude-sonnet-4-20250514",
-    agent: "codebase-agent",
-    provider: "anthropic",
-    count: 38,
-    avgTokens: 15200,
-    avgCost: 0.152,
-    avgDuration: 8200,
-    successRate: 100
-  },
-  {
-    model: "sonic",
-    agent: "build",
-    provider: "opencode",
-    count: 12,
-    avgTokens: 3500,
-    avgCost: 0.00,
-    avgDuration: 2100,
-    successRate: 100
-  }
-]
-```
-
-### 7. Provider Reliability Analysis
-
-Compare error rates and reliability across providers:
-
-```typescript
-function analyzeProviderReliability(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  
-  interface ProviderStats {
-    provider: string;
-    totalMessages: number;
-    successfulMessages: number;
-    errorMessages: number;
-    errorRate: number;
-    avgResponseTime: number;
-    modelsUsed: string[];
-  }
-  
-  const providerStats: Record<string, ProviderStats> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant' || !message.providerID) continue;
-    
-    const provider = message.providerID;
-    
-    if (!providerStats[provider]) {
-      providerStats[provider] = {
-        provider,
-        totalMessages: 0,
-        successfulMessages: 0,
-        errorMessages: 0,
-        errorRate: 0,
-        avgResponseTime: 0,
-        modelsUsed: []
-      };
-    }
-    
-    const stats = providerStats[provider];
-    stats.totalMessages++;
-    
-    if (message.error) {
-      stats.errorMessages++;
-    } else {
-      stats.successfulMessages++;
-    }
-    
-    if (message.time.completed) {
-      stats.avgResponseTime += message.time.completed - message.time.created;
-    }
-    
-    if (message.modelID && !stats.modelsUsed.includes(message.modelID)) {
-      stats.modelsUsed.push(message.modelID);
-    }
-  }
-  
-  // Calculate rates and averages
-  for (const provider in providerStats) {
-    const stats = providerStats[provider];
-    stats.errorRate = (stats.errorMessages / stats.totalMessages) * 100;
-    stats.avgResponseTime /= stats.totalMessages;
-  }
-  
-  return Object.values(providerStats).sort((a, b) => 
-    b.totalMessages - a.totalMessages
-  );
-}
-```
-
-**Example Output:**
-```typescript
-[
-  {
-    provider: "anthropic",
-    totalMessages: 125,
-    successfulMessages: 123,
-    errorMessages: 2,
-    errorRate: 1.6,
-    avgResponseTime: 7205,
-    modelsUsed: ["claude-sonnet-4-20250514", "claude-3-5-sonnet-20241022"]
-  },
-  {
-    provider: "opencode",
-    totalMessages: 14,
-    successfulMessages: 14,
-    errorMessages: 0,
-    errorRate: 0,
-    avgResponseTime: 2100,
-    modelsUsed: ["sonic"]
-  },
-  {
-    provider: "google",
-    totalMessages: 5,
-    successfulMessages: 5,
-    errorMessages: 0,
-    errorRate: 0,
-    avgResponseTime: 3200,
-    modelsUsed: ["gemini-2.5-flash"]
-  }
-]
-```
-
-### 8. Cache Efficiency Analysis
-
-Analyze prompt caching effectiveness (Anthropic models):
-
-```typescript
-function analyzeCacheEfficiency(sessionID: string) {
-  const messages = getSessionMessages(sessionID);
-  
-  interface CacheStats {
-    model: string;
-    totalMessages: number;
-    cacheReadTokens: number;
-    cacheWriteTokens: number;
-    inputTokens: number;
-    cacheHitRate: number;
-    costSavings: number;
-  }
-  
-  const cacheStats: Record<string, CacheStats> = {};
-  
-  for (const message of messages) {
-    if (message.role !== 'assistant' || !message.modelID || !message.tokens) {
-      continue;
-    }
-    
-    const model = message.modelID;
-    
-    if (!cacheStats[model]) {
-      cacheStats[model] = {
-        model,
-        totalMessages: 0,
-        cacheReadTokens: 0,
-        cacheWriteTokens: 0,
-        inputTokens: 0,
-        cacheHitRate: 0,
-        costSavings: 0
-      };
-    }
-    
-    const stats = cacheStats[model];
-    stats.totalMessages++;
-    stats.cacheReadTokens += message.tokens.cache?.read || 0;
-    stats.cacheWriteTokens += message.tokens.cache?.write || 0;
-    stats.inputTokens += message.tokens.input || 0;
-  }
-  
-  // Calculate cache hit rate and savings
-  for (const model in cacheStats) {
-    const stats = cacheStats[model];
-    const totalCacheableTokens = stats.inputTokens + stats.cacheReadTokens;
-    
-    if (totalCacheableTokens > 0) {
-      stats.cacheHitRate = 
-        (stats.cacheReadTokens / totalCacheableTokens) * 100;
-    }
-    
-    // Estimate cost savings (cache reads are typically 90% cheaper)
-    // Assuming $3/M input tokens, cache reads are $0.30/M
-    const fullCost = (stats.cacheReadTokens / 1000000) * 3.0;
-    const cacheCost = (stats.cacheReadTokens / 1000000) * 0.3;
-    stats.costSavings = fullCost - cacheCost;
-  }
-  
-  return Object.values(cacheStats).sort((a, b) => 
-    b.cacheReadTokens - a.cacheReadTokens
-  );
-}
-```
-
-**Example Output:**
-```typescript
-[
-  {
-    model: "claude-sonnet-4-20250514",
-    totalMessages: 117,
-    cacheReadTokens: 1093716,
-    cacheWriteTokens: 43992,
-    inputTokens: 936,
-    cacheHitRate: 99.9,
-    costSavings: 2.95  // $2.95 saved via caching
-  }
-]
-```
-
-**Key Insight:** Claude Sonnet 4 shows 99.9% cache hit rate, saving ~$2.95 in API costs through prompt caching.
-
----
-
-## Best Practices
-
-### 1. Session Discovery
-
-Always start by listing available sessions:
-
-```typescript
-function listSessions() {
-  const infoPath = path.join(basePath, 'info');
-  return fs.readdirSync(infoPath)
-    .filter(f => f.endsWith('.json'))
-    .map(f => {
-      const sessionID = f.replace('.json', '');
-      const info = getSessionInfo(sessionID);
-      return {
-        id: sessionID,
-        title: info.title,
-        created: new Date(info.time.created),
-        version: info.version
-      };
-    })
-    .sort((a, b) => b.created.getTime() - a.created.getTime());
-}
-```
-
-### 2. Error Handling
-
-Always handle missing files gracefully:
-
-```typescript
-function safeReadSession(sessionID: string) {
-  try {
-    return getSessionInfo(sessionID);
-  } catch (error) {
-    console.error(`Session ${sessionID} not found`);
-    return null;
-  }
-}
-```
-
-### 3. Memory Management
-
-For large sessions, process parts in streams:
-
-```typescript
-function* streamMessageParts(sessionID: string, messageID: string) {
-  const partPath = path.join(basePath, 'part', sessionID, messageID);
-  const partFiles = fs.readdirSync(partPath);
-  
-  for (const file of partFiles) {
-    const filePath = path.join(partPath, file);
-    yield JSON.parse(fs.readFileSync(filePath, 'utf-8'));
-  }
-}
-```
-
-### 4. Caching
-
-Cache frequently accessed data:
-
-```typescript
-const sessionCache = new Map<string, any>();
-
-function getCachedSession(sessionID: string) {
-  if (!sessionCache.has(sessionID)) {
-    sessionCache.set(sessionID, {
-      info: getSessionInfo(sessionID),
-      messages: getSessionMessages(sessionID)
-    });
-  }
-  return sessionCache.get(sessionID);
-}
-```
-
----
-
-## Integration with Validator Plugin
-
-The Agent Validator Plugin (`.opencode/plugin/agent-validator.ts`) provides real-time tracking that complements the session storage:
-
-**Session Storage (Native):**
-- ✅ Persistent across sessions
-- ✅ Complete historical data
-- ✅ Structured JSON format
-- ❌ No real-time access
-- ❌ Requires file system access
-
-**Validator Plugin (Custom):**
-- ✅ Real-time tracking
-- ✅ Behavior analysis
-- ✅ Compliance checking
-- ❌ Session-scoped only
-- ❌ In-memory (not persistent)
-
-**Best Practice:** Use both together:
-1. Validator plugin for real-time monitoring during development
-2. Session storage for historical analysis and evaluation
-
----
-
-## Future Enhancements
-
-### Potential Additions
-
-1. **Structured Approval Flags** - Explicit approval tracking
-2. **Context File Markers** - Flag context file reads explicitly
-3. **Quality Metrics** - Built-in code quality scores
-4. **Test Results** - Link test execution results to sessions
-5. **Delegation Metadata** - Track why delegation occurred
-6. **User Intent Classification** - Structured task categorization
-
-### OpenTelemetry Integration (Future)
-
-Once local evaluation is stable, consider adding OpenTelemetry:
-- Distributed tracing across agents
-- Real-time metrics dashboards
-- Integration with observability platforms
-- Cross-session analysis
-
----
-
-## Troubleshooting
-
-### Issue: Session files not found
-
-**Cause:** Project name encoding in path
-
-**Solution:**
-```typescript
-// Project names are encoded with dashes replacing slashes
-const projectPath = '/Users/user/Documents/GitHub/project';
-const encodedName = projectPath.replace(/\//g, '-').substring(1);
-// Result: "Users-user-Documents-GitHub-project"
-```
-
-### Issue: Missing parts for a message
-
-**Cause:** Message may have no content (e.g., aborted)
-
-**Solution:**
-```typescript
-function getMessageParts(sessionID: string, messageID: string) {
-  const partPath = path.join(basePath, 'part', sessionID, messageID);
-  
-  if (!fs.existsSync(partPath)) {
-    return []; // No parts directory
-  }
-  
-  const partFiles = fs.readdirSync(partPath);
-  return partFiles.map(file => {
-    const filePath = path.join(partPath, file);
-    return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
-  });
-}
-```
-
-### Issue: Incomplete tool calls
-
-**Cause:** Tool may still be running or was aborted
-
-**Solution:** Check `state.status` field:
-```typescript
-if (part.state.status === 'running' || part.state.status === 'pending') {
-  console.log('Tool call incomplete');
-}
-```
-
----
-
-## Model Selection Recommendations
-
-Based on production data analysis, here are recommendations for model selection:
-
-### By Use Case
-
-**Complex Reasoning & Multi-Step Tasks:**
-- ✅ **Primary:** `claude-sonnet-4-20250514` (anthropic)
-- **Why:** Highest success rate (98.3%), excellent cache efficiency, handles complex workflows
-- **Cost:** Higher per-token cost, but cache savings offset this
-- **Best for:** Code generation, architecture decisions, complex refactoring
-
-**Quick Validation & Build Tasks:**
-- ✅ **Primary:** `sonic` (opencode)
-- **Why:** Fast response times (2.1s avg), zero cost, 100% success rate
-- **Cost:** Free
-- **Best for:** Linting, type checking, quick validations, build verification
-
-**Cost-Sensitive Operations:**
-- ✅ **Primary:** `gemini-2.5-flash` (google)
-- **Why:** Low cost, fast responses (3.2s avg), 100% success rate
-- **Cost:** ~90% cheaper than Claude
-- **Best for:** Simple tasks, documentation generation, straightforward code changes
-
-**Legacy/Fallback:**
-- ⚠️ **Fallback:** `claude-3-5-sonnet-20241022` (anthropic)
-- **Why:** Previous generation, being phased out
-- **Use:** Only when Sonnet 4 unavailable
-
-### By Agent Type
-
-**Build Agent:**
-- Primary: `sonic` (fast, free)
-- Fallback: `claude-sonnet-4-20250514` (complex builds)
-
-**Codebase Agent:**
-- Primary: `claude-sonnet-4-20250514` (complex analysis)
-- Alternative: `sonic` (quick scans)
-
-**Task Manager:**
-- Primary: `gemini-2.5-flash` (cost-effective planning)
-- Alternative: `claude-sonnet-4-20250514` (complex workflows)
-
-**General/Core:**
-- Primary: `claude-sonnet-4-20250514` (versatile)
-- Alternative: `gemini-2.5-flash` (simple tasks)
-
-### Cost Optimization Strategies
-
-1. **Use Prompt Caching** (Anthropic models)
-   - Claude Sonnet 4 shows 99.9% cache hit rate
-   - Saves ~$2.95 per 100 messages
-   - Keep system prompts consistent for maximum caching
-
-2. **Route by Complexity**
-   - Simple tasks → `sonic` or `gemini-2.5-flash`
-   - Complex tasks → `claude-sonnet-4-20250514`
-   - Build validation → `sonic`
-
-3. **Monitor Error Rates**
-   - Track model-specific error rates
-   - Switch models if error rate > 5%
-   - Current data shows all models < 2% error rate
-
-4. **Batch Similar Tasks**
-   - Group similar operations for same model
-   - Maximize cache hit rates
-   - Reduce context switching overhead
-
-### Performance Benchmarks (From Real Data)
-
-| Metric | Claude Sonnet 4 | Sonic | Gemini 2.5 Flash |
-|--------|----------------|-------|------------------|
-| Avg Response Time | 7.2s | 2.1s | 3.2s |
-| Success Rate | 98.3% | 100% | 100% |
-| Avg Tokens/Message | 10,684 | 3,500 | 9,000 |
-| Cache Hit Rate | 99.9% | N/A | N/A |
-| Cost/Message | $0.107 | $0.00 | $0.030 |
-| Best For | Complex tasks | Quick checks | Cost-sensitive |
-
-### Multi-Model Strategy
-
-**Recommended Approach:**
-1. Start with `sonic` for initial validation
-2. Escalate to `gemini-2.5-flash` for simple changes
-3. Use `claude-sonnet-4-20250514` for complex reasoning
-4. Monitor costs and adjust thresholds
-
-**Example Workflow:**
-```typescript
-function selectModel(taskComplexity: 'simple' | 'medium' | 'complex') {
-  switch (taskComplexity) {
-    case 'simple':
-      return 'sonic'; // Free, fast
-    case 'medium':
-      return 'gemini-2.5-flash'; // Low cost, good quality
-    case 'complex':
-      return 'claude-sonnet-4-20250514'; // Best reasoning
-  }
-}
-```
-
-### Monitoring Model Performance
-
-Track these metrics to optimize model selection:
-
-1. **Success Rate** - Target: >95%
-2. **Response Time** - Target: <10s for complex, <3s for simple
-3. **Cost per Task** - Set budget thresholds
-4. **Cache Hit Rate** - Target: >90% for Anthropic models
-5. **Error Patterns** - Identify model-specific failure modes
-
----
-
-## Summary
-
-OpenCode's session storage provides comprehensive logging with:
-
-✅ **Complete session history** - Every message, tool call, and interaction  
-✅ **Agent tracking** - Know which agent handled each message via `mode` field  
-✅ **Model tracking** - Track which AI model and provider handled each message  
-✅ **Performance metrics** - Tokens, cost, timing, cache efficiency for optimization  
-✅ **Error tracking** - Debug failures with full context and model-specific patterns  
-✅ **File change tracking** - Git commits and patches  
-✅ **Structured format** - Easy to parse and analyze  
-✅ **Multi-model support** - Compare performance across 5+ models and 4+ providers  
-
-This foundation enables building robust evaluation frameworks, quality monitoring, cost optimization, and agent/model performance analysis systems.
-
-### Key Capabilities Unlocked
-
-**Agent Evaluation:**
-- Validate approval gates and context loading
-- Track delegation patterns
-- Measure agent-specific performance
-
-**Model Optimization:**
-- Compare model performance and costs
-- Analyze cache efficiency (99.9% hit rate observed)
-- Identify optimal model-agent pairings
-- Track provider reliability
-
-**Cost Management:**
-- Monitor spending by model and provider
-- Identify cost-saving opportunities via caching
-- Optimize model selection for budget constraints
-
-**Quality Assurance:**
-- 95.3% tool success rate baseline
-- Track error patterns by model/agent
-- Identify performance bottlenecks
-
----
-
-## Related Documentation
-
-- [Agent Validator Plugin Guide](/.opencode/plugin/docs/VALIDATOR_GUIDE.md)
-- [Building Plugins](./building-plugins.md)
-- [How Context Works](./how-context-works.md)
-- [Slash Commands and Subagents](./slash-commands-and-subagents.md)
-
----
-
-**Last Updated:** 2025-11-21  
-**OpenCode Version:** 0.5.1+

+ 0 - 1007
dev/ai-tools/opencode/plugins/Plugin-inspiration.md

@@ -1,1007 +0,0 @@
-OpenCode Plugin Architecture & oh-my-opencode Deep Dive
-> A comprehensive guide to understanding OpenCode's plugin system and how oh-my-opencode transforms a single-agent assistant into a multi-model orchestration powerhouse.
----
-Table of Contents
-1. OpenCode Plugin System Overview (#1-opencode-plugin-system-overview)
-2. The @opencode-ai/plugin Package (#2-the-opencode-aiplugin-package)
-3. oh-my-opencode Architecture (#3-oh-my-opencode-architecture)
-4. The Agent Orchestration System (#4-the-agent-orchestration-system)
-5. Background Agent System (#5-background-agent-system)
-6. The Hook Pipeline (#6-the-hook-pipeline)
-7. Custom Tools (#7-custom-tools)
-8. MCP Integrations (#8-mcp-integrations)
-9. Configuration System (#9-configuration-system)
-10. Plugin Loading & Updates (#10-plugin-loading--updates)
-11. Creating Your Own Plugin (#11-creating-your-own-plugin)
-12. Key Files Reference (#12-key-files-reference)
----
-1. OpenCode Plugin System Overview
-What is OpenCode?
-OpenCode is a terminal-based AI coding assistant (similar to Claude Code) created by SST. It's highly extensible through a plugin system.
-Repository: https://github.com/sst/opencode
-How Plugins Work
-Plugins are JavaScript/TypeScript modules that:
-1. Receive a context object with SDK client, project info, and utilities
-2. Return a hooks object to extend OpenCode's behavior
-Plugin locations:
-- .opencode/plugin/ (project-level)
-- ~/.config/opencode/plugin/ (global)
-- npm packages via opencode.json
-The Plugin Interface
-// From @opencode-ai/plugin
-export type PluginInput = {
-  client: ReturnType<typeof createOpencodeClient>  // SDK client for API calls
-  project: Project                                  // Current project info
-  directory: string                                 // Working directory path
-  worktree: string                                  // Git worktree path
-  $: BunShell                                      // Bun's shell API for commands
-}
-export type Plugin = (input: PluginInput) => Promise<Hooks>
----
-2. The @opencode-ai/plugin Package
-Core Types
-Source: packages/plugin/src/index.ts in sst/opencode
-export interface Hooks {
-  // Event subscription - react to 40+ event types
-  event?: (input: { event: Event }) => Promise<void>
-  
-  // Configuration hook - modify agents, MCPs, commands
-  config?: (input: Config) => Promise<void>
-  
-  // Custom tools registration
-  tool?: {
-    [key: string]: ToolDefinition
-  }
-  
-  // Authentication provider
-  auth?: AuthHook
-  
-  // Chat lifecycle hooks
-  "chat.message"?: (input, output: { message: UserMessage; parts: Part[] }) => Promise<void>
-  "chat.params"?: (input, output: { temperature: number; topP: number; topK: number; options: Record<string, any> }) => Promise<void>
-  
-  // Permission hooks
-  "permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void>
-  
-  // Tool execution hooks
-  "tool.execute.before"?: (input: { tool: string; sessionID: string; callID: string }, output: { args: any }) => Promise<void>
-  "tool.execute.after"?: (input: { tool: string; sessionID: string; callID: string }, output: { title: string; output: string; metadata: any }) => Promise<void>
-  
-  // Experimental hooks
-  "experimental.chat.messages.transform"?: (input, output: { messages: { info: Message; parts: Part[] }[] }) => Promise<void>
-  "experimental.chat.system.transform"?: (input, output: { system: string[] }) => Promise<void>
-  "experimental.text.complete"?: (input: { sessionID: string; messageID: string; partID: string }, output: { text: string }) => Promise<void>
-}
-Tool Definition
-export type ToolContext = {
-  sessionID: string
-  messageID: string
-  agent: string
-  abort: AbortSignal
-}
-export function tool<Args extends z.ZodRawShape>(input: {
-  description: string
-  args: Args
-  execute(args: z.infer<z.ZodObject<Args>>, context: ToolContext): Promise<string>
-}) {
-  return input
-}
-tool.schema = z  // Zod schema builder
-Available Events (40+)
-| Category | Events |
-|----------|--------|
-| Command | command.executed |
-| File | file.edited, file.watcher.updated |
-| Installation | installation.updated |
-| LSP | lsp.client.diagnostics, lsp.updated |
-| Message | message.part.removed, message.part.updated, message.removed, message.updated |
-| Permission | permission.replied, permission.updated |
-| Server | server.connected |
-| Session | session.created, session.compacted, session.deleted, session.diff, session.error, session.idle, session.status, session.updated |
-| Todo | todo.updated |
-| Tool | tool.execute.after, tool.execute.before |
-| TUI | tui.prompt.append, tui.command.execute, tui.toast.show |
----
-3. oh-my-opencode Architecture
-What is oh-my-opencode?
-Repository: https://github.com/code-yeongyu/oh-my-opencode
-oh-my-opencode is a comprehensive OpenCode plugin that transforms the single-agent experience into a multi-model, multi-agent orchestration system. It's described as "oh-my-zsh for OpenCode."
-Project Structure
-oh-my-opencode/
-├── src/
-│   ├── agents/           # AI agents (OmO, oracle, librarian, explore, etc.)
-│   │   ├── omo.ts
-│   │   ├── oracle.ts
-│   │   ├── librarian.ts
-│   │   ├── explore.ts
-│   │   ├── frontend-ui-ux-engineer.ts
-│   │   ├── document-writer.ts
-│   │   ├── multimodal-looker.ts
-│   │   ├── index.ts
-│   │   ├── types.ts
-│   │   └── utils.ts
-│   ├── hooks/            # 21 lifecycle hooks
-│   │   ├── anthropic-auto-compact/
-│   │   ├── auto-update-checker/
-│   │   ├── background-notification/
-│   │   ├── claude-code-hooks/
-│   │   ├── comment-checker/
-│   │   ├── directory-readme-injector/
-│   │   ├── interactive-bash-session/
-│   │   ├── keyword-detector/
-│   │   ├── non-interactive-env/
-│   │   ├── rules-injector/
-│   │   ├── session-recovery/
-│   │   ├── think-mode/
-│   │   ├── context-window-monitor.ts
-│   │   ├── empty-task-response-detector.ts
-│   │   ├── grep-output-truncator.ts
-│   │   ├── session-notification.ts
-│   │   ├── todo-continuation-enforcer.ts
-│   │   ├── tool-output-truncator.ts
-│   │   └── index.ts
-│   ├── tools/            # Custom tools (LSP, AST-Grep, background tasks)
-│   │   ├── lsp/
-│   │   ├── ast-grep/
-│   │   ├── background-task/
-│   │   ├── call-omo-agent/
-│   │   ├── look-at/
-│   │   ├── grep/
-│   │   ├── glob/
-│   │   ├── interactive-bash/
-│   │   ├── skill/
-│   │   ├── slashcommand/
-│   │   └── index.ts
-│   ├── mcp/              # MCP server configurations
-│   │   ├── context7.ts
-│   │   ├── grep-app.ts
-│   │   ├── websearch-exa.ts
-│   │   └── index.ts
-│   ├── features/         # Core features
-│   │   ├── background-agent/
-│   │   ├── claude-code-*-loader/
-│   │   ├── hook-message-injector/
-│   │   └── terminal/
-│   ├── auth/             # Google Antigravity OAuth
-│   ├── shared/           # Utilities
-│   ├── config/           # Zod schema, types
-│   └── index.ts          # Main plugin entry
-├── package.json
-└── tsconfig.json
-Main Entry Point (src/index.ts)
-The plugin implements ALL available hooks:
-const OhMyOpenCodePlugin: Plugin = async (ctx) => {
-  // 1. Load configuration
-  const pluginConfig = loadPluginConfig(ctx.directory);
-  
-  // 2. Initialize 20+ hooks with enable/disable support
-  const todoContinuationEnforcer = isHookEnabled("todo-continuation-enforcer")
-    ? createTodoContinuationEnforcer(ctx) : null;
-  const contextWindowMonitor = isHookEnabled("context-window-monitor")
-    ? createContextWindowMonitorHook(ctx) : null;
-  // ... 18 more hooks
-  
-  // 3. Initialize background agent manager
-  const backgroundManager = new BackgroundManager(ctx);
-  
-  // 4. Create tools
-  const backgroundTools = createBackgroundTools(backgroundManager, ctx.client);
-  const callOmoAgent = createCallOmoAgent(ctx, backgroundManager);
-  const lookAt = createLookAt(ctx);
-  
-  return {
-    // Authentication
-    auth: googleAuthHooks?.auth,
-    
-    // Custom tools
-    tool: {
-      ...builtinTools,        // LSP, AST-grep, grep, glob
-      ...backgroundTools,      // background_task, background_output, background_cancel
-      call_omo_agent,
-      look_at,
-      interactive_bash,
-    },
-    
-    // Config modification
-    config: async (config) => {
-      // Inject custom agents
-      config.agent = { OmO: ..., oracle: ..., ... };
-      // Inject MCPs
-      config.mcp = { context7: ..., websearch_exa: ..., grep_app: ... };
-      // Load Claude Code commands, skills, agents
-    },
-    
-    // Event handling
-    event: async (input) => {
-      // Process through all 20+ hooks
-    },
-    
-    // Tool interception
-    "tool.execute.before": async (input, output) => { ... },
-    "tool.execute.after": async (input, output) => { ... },
-    
-    // Chat hooks
-    "chat.message": async (input, output) => { ... },
-    "experimental.chat.messages.transform": async (input, output) => { ... },
-  };
-};
----
-4. The Agent Orchestration System
-The Agent Team
-oh-my-opencode creates a team of specialized agents, each using the optimal model for their task:
-| Agent | Model | Purpose | Mode |
-|-------|-------|---------|------|
-| OmO | anthropic/claude-opus-4-5 | Primary orchestrator, delegates work | primary |
-| oracle | openai/gpt-5.2 | Architecture, debugging, deep reasoning | subagent |
-| librarian | anthropic/claude-sonnet-4-5 | External docs, GitHub examples | subagent |
-| explore | opencode/grok-code | Fast codebase search | subagent |
-| frontend-ui-ux-engineer | google/gemini-3-pro-preview | UI generation | subagent |
-| document-writer | google/gemini-3-pro-preview | Documentation | subagent |
-| multimodal-looker | google/gemini-2.5-flash | PDF/image analysis | subagent |
-OmO Agent System Prompt (Key Excerpts)
-Source: src/agents/omo.ts
-The OmO agent has a 400+ line system prompt that teaches it to:
-const OMO_SYSTEM_PROMPT = `<Role>
-You are OmO, the orchestrator agent for OpenCode.
-**Identity**: Elite software engineer working at SF, Bay Area. You work, delegate, verify, deliver.
-**Operating Mode**: You NEVER work alone when specialists are available. Frontend work → delegate. Deep research → parallel background agents. Complex architecture → consult Oracle.
-</Role>
-<Behavior_Instructions>
-## Phase 0 - Intent Gate (EVERY message)
-### Step 1: Classify Request Type
-| Type | Signal | Action |
-|------|--------|--------|
-| **Trivial** | Single file, known location | Direct tools only, no agents |
-| **Explicit** | Specific file/line, clear command | Execute directly |
-| **Exploratory** | "How does X work?" | Assess scope, then search |
-| **Open-ended** | "Improve", "Refactor" | Assess codebase first |
-## Phase 2A - Exploration & Research
-### Tool Selection:
-| Tool | Cost | When to Use |
-|------|------|-------------|
-| grep, glob, lsp_*, ast_grep | FREE | Always try first |
-| explore agent | CHEAP | Multiple search angles |
-| librarian agent | CHEAP | External docs, GitHub examples |
-| oracle agent | EXPENSIVE | Architecture, review, debugging |
-### Parallel Execution (DEFAULT behavior)
-// CORRECT: Always background, always parallel
-background_task(agent="explore", prompt="Find auth implementations...")
-background_task(agent="librarian", prompt="Find JWT best practices...")
-// Continue working immediately. Collect with background_output when needed.
-## Phase 2B - Implementation
-### GATE: Frontend Files (HARD BLOCK)
-| Extension | Action |
-|-----------|--------|
-| .tsx, .jsx | DELEGATE |
-| .vue, .svelte | DELEGATE |
-| .css, .scss | DELEGATE |
-ALL frontend = DELEGATE to frontend-ui-ux-engineer. Period.
-</Behavior_Instructions>`
-export const omoAgent: AgentConfig = {
-  description: "Powerful AI orchestrator for OpenCode...",
-  mode: "primary",
-  model: "anthropic/claude-opus-4-5",
-  thinking: {
-    type: "enabled",
-    budgetTokens: 32000,  // Extended thinking enabled
-  },
-  maxTokens: 64000,
-  prompt: OMO_SYSTEM_PROMPT,
-  color: "#00CED1",
-}
-Oracle Agent (Strategic Advisor)
-Source: src/agents/oracle.ts
-export const oracleAgent: AgentConfig = {
-  description: "Expert technical advisor with deep reasoning...",
-  mode: "subagent",
-  model: "openai/gpt-5.2",
-  temperature: 0.1,
-  reasoningEffort: "medium",
-  textVerbosity: "high",
-  tools: { write: false, edit: false, task: false, background_task: false },
-  prompt: `You are a strategic technical advisor...
-  
-## Decision Framework
-**Bias toward simplicity**: The right solution is typically the least complex one.
-**Leverage what exists**: Favor modifications to current code over new components.
-**One clear path**: Present a single primary recommendation.
-**Signal the investment**: Tag recommendations with Quick(<1h), Short(1-4h), Medium(1-2d), Large(3d+).
-`,
-}
-How Agents Get Injected
-In the config hook:
-config: async (config) => {
-  const builtinAgents = createBuiltinAgents(...);
-  
-  // OmO becomes primary, original agents become subagents
-  config.agent = {
-    OmO: builtinAgents.OmO,                        // NEW primary
-    "OmO-Plan": omoPlanConfig,                      // NEW plan variant
-    ...builtinAgents,                               // oracle, librarian, etc.
-    ...config.agent,                                // User's original agents
-    build: { ...config.agent?.build, mode: "subagent" },  // DEMOTED
-    plan: { ...config.agent?.plan, mode: "subagent" },    // DEMOTED
-  };
-}
----
-5. Background Agent System
-The BackgroundManager Class
-Source: src/features/background-agent/manager.ts
-This is the key innovation that enables parallel agent execution:
-export class BackgroundManager {
-  private tasks: Map<string, BackgroundTask>
-  private notifications: Map<string, BackgroundTask[]>
-  private client: OpencodeClient
-  private pollingInterval?: Timer
-  async launch(input: LaunchInput): Promise<BackgroundTask> {
-    // 1. Create a NEW child session
-    const createResult = await this.client.session.create({
-      body: {
-        parentID: input.parentSessionID,
-        title: `Background: ${input.description}`
-      }
-    });
-    
-    const sessionID = createResult.data.id;
-    
-    // 2. Track the task
-    const task: BackgroundTask = {
-      id: `bg_${crypto.randomUUID().slice(0, 8)}`,
-      sessionID,
-      parentSessionID: input.parentSessionID,
-      description: input.description,
-      status: "running",
-      startedAt: new Date(),
-    };
-    this.tasks.set(task.id, task);
-    
-    // 3. Fire async prompt (NON-BLOCKING!)
-    this.client.session.promptAsync({
-      path: { id: sessionID },
-      body: {
-        agent: input.agent,
-        tools: { task: false, background_task: false },  // Prevent recursion
-        parts: [{ type: "text", text: input.prompt }]
-      }
-    });
-    
-    // 4. Start polling for completion
-    this.startPolling();
-    
-    return task;
-  }
-  // Event handler for completion detection
-  handleEvent(event: Event): void {
-    if (event.type === "session.idle") {
-      const task = this.findBySession(sessionID);
-      if (task?.status === "running") {
-        task.status = "completed";
-        this.markForNotification(task);
-        this.notifyParentSession(task);  // Send message back!
-      }
-    }
-  }
-  // Notify the main session when background task completes
-  private notifyParentSession(task: BackgroundTask): void {
-    // Show toast notification
-    this.client.tui.showToast({
-      body: {
-        title: "Background Task Completed",
-        message: `Task "${task.description}" finished.`,
-        variant: "success",
-      }
-    });
-    
-    // Send a message to the parent session
-    this.client.session.prompt({
-      path: { id: task.parentSessionID },
-      body: {
-        parts: [{
-          type: "text",
-          text: `[BACKGROUND TASK COMPLETED] Task "${task.description}" finished. Use background_output with task_id="${task.id}" to get results.`
-        }]
-      }
-    });
-  }
-}
-Background Task Tools
-Source: src/tools/background-task/tools.ts
-// background_task - Launch an agent in background
-export function createBackgroundTask(manager: BackgroundManager) {
-  return tool({
-    description: "Launch a background agent task...",
-    args: {
-      description: tool.schema.string(),
-      prompt: tool.schema.string(),
-      agent: tool.schema.string(),
-    },
-    async execute(args, toolContext) {
-      const task = await manager.launch({
-        description: args.description,
-        prompt: args.prompt,
-        agent: args.agent,
-        parentSessionID: toolContext.sessionID,
-        parentMessageID: toolContext.messageID,
-      });
-      
-      return `Background task launched. Task ID: ${task.id}`;
-    },
-  });
-}
-// background_output - Get results from background task
-export function createBackgroundOutput(manager: BackgroundManager, client: OpencodeClient) {
-  return tool({
-    description: "Get output from a background task...",
-    args: {
-      task_id: tool.schema.string(),
-      block: tool.schema.boolean().optional(),  // Wait for completion?
-    },
-    async execute(args) {
-      const task = manager.getTask(args.task_id);
-      if (task.status === "completed") {
-        // Fetch messages from the task's session
-        const messages = await client.session.messages({ path: { id: task.sessionID } });
-        return formatTaskResult(task, messages);
-      }
-      return formatTaskStatus(task);
-    },
-  });
-}
-// background_cancel - Cancel running tasks
-export function createBackgroundCancel(manager: BackgroundManager, client: OpencodeClient) {
-  return tool({
-    description: "Cancel background tasks...",
-    args: {
-      taskId: tool.schema.string().optional(),
-      all: tool.schema.boolean().optional(),  // Cancel all?
-    },
-    async execute(args, toolContext) {
-      if (args.all) {
-        const tasks = manager.getTasksByParentSession(toolContext.sessionID);
-        for (const task of tasks.filter(t => t.status === "running")) {
-          client.session.abort({ path: { id: task.sessionID } });
-          task.status = "cancelled";
-        }
-      }
-      // ...
-    },
-  });
-}
-The Parallel Execution Flow
-You: "Add authentication to my app"
-     │
-     ▼
-┌─────────────────────────────────────────┐
-│           OmO (Claude Opus 4.5)         │
-│  "I'll orchestrate this..."             │
-└─────────────────────────────────────────┘
-     │
-     │ 1. Creates todo list
-     │ 2. Launches background agents:
-     │
-     ├──▶ background_task(agent="librarian", "Find JWT best practices...")
-     │        └── Creates child session, runs async
-     │
-     ├──▶ background_task(agent="explore", "Find existing auth patterns...")
-     │        └── Creates child session, runs async
-     │
-     │ 3. Starts implementing immediately (doesn't wait!)
-     │
-     ▼
-┌─────────────────────────────────────────┐
-│  [MEANWHILE: Background agents working] │
-│  librarian → searching docs             │
-│  explore → scanning codebase            │
-└─────────────────────────────────────────┘
-     │
-     │ 4. BackgroundManager detects completion
-     │ 5. Sends notification to OmO's session
-     │
-     ▼
-┌─────────────────────────────────────────┐
-│ [BACKGROUND TASK COMPLETED]             │
-│ Task "Find JWT best practices" done     │
-│ Use background_output to get results    │
-└─────────────────────────────────────────┘
-     │
-     ▼
-OmO: background_output(task_id="bg_abc123")
-     │
-     ▼
-Integrates findings, continues work...
----
-6. The Hook Pipeline
-Hook Categories
-oh-my-opencode implements 21 hooks across several categories:
-Session Management
-- session-recovery: Auto-recovers from API errors
-- session-notification: OS notifications when session goes idle
-- anthropic-auto-compact: Auto-summarizes when hitting token limits
-Task Management
-- todo-continuation-enforcer: Forces agent to complete all todos
-- empty-task-response-detector: Warns about empty task responses
-Context Management
-- context-window-monitor: Implements "Context Window Anxiety Management"
-- directory-readme-injector: Injects README.md context
-- directory-agents-injector: Injects AGENTS.md context
-- rules-injector: Conditional rules from .claude/rules/
-Output Processing
-- tool-output-truncator: Truncates verbose tool output
-- grep-output-truncator: Specifically handles grep output
-Quality Control
-- comment-checker: Prevents AI-style excessive comments
-- keyword-detector: Detects ultrawork, search, analyze keywords
-- think-mode: Auto-enables extended thinking for complex tasks
-Background System
-- background-notification: Routes events to BackgroundManager
-Compatibility
-- claude-code-hooks: Pre/PostToolUse, UserPromptSubmit, Stop hooks
-- non-interactive-env: Handles non-interactive environments
-- interactive-bash-session: Tmux integration
-Event Handler Pipeline
-event: async (input) => {
-  // Process through ALL hooks in sequence
-  await autoUpdateChecker?.event(input);
-  await claudeCodeHooks.event(input);
-  await backgroundNotificationHook?.event(input);  // Background tracking!
-  await sessionNotification?.(input);
-  await todoContinuationEnforcer?.handler(input);
-  await contextWindowMonitor?.event(input);
-  await directoryAgentsInjector?.event(input);
-  await directoryReadmeInjector?.event(input);
-  await rulesInjector?.event(input);
-  await thinkMode?.event(input);
-  await anthropicAutoCompact?.event(input);
-  await keywordDetector?.event(input);
-  await agentUsageReminder?.event(input);
-  await interactiveBashSession?.event(input);
-  
-  // Handle session lifecycle
-  if (event.type === "session.created") { ... }
-  if (event.type === "session.idle") { ... }
-  if (event.type === "session.error") { ... }
-}
-Tool Execution Hooks
-"tool.execute.before": async (input, output) => {
-  // Claude Code hooks (PreToolUse)
-  await claudeCodeHooks["tool.execute.before"](input, output);
-  // Non-interactive environment handling
-  await nonInteractiveEnv?.["tool.execute.before"](input, output);
-  // Comment checking
-  await commentChecker?.["tool.execute.before"](input, output);
-  
-  // Disable dangerous tools for subagents
-  if (input.tool === "task") {
-    output.args.tools = {
-      ...output.args.tools,
-      background_task: false,  // Prevent nested background tasks
-    };
-  }
-},
-"tool.execute.after": async (input, output) => {
-  // Claude Code hooks (PostToolUse)
-  await claudeCodeHooks["tool.execute.after"](input, output);
-  // Truncate verbose output
-  await toolOutputTruncator?.["tool.execute.after"](input, output);
-  // Track context usage
-  await contextWindowMonitor?.["tool.execute.after"](input, output);
-  // Inject directory context
-  await directoryAgentsInjector?.["tool.execute.after"](input, output);
-  await directoryReadmeInjector?.["tool.execute.after"](input, output);
-  // Inject conditional rules
-  await rulesInjector?.["tool.execute.after"](input, output);
-},
----
-7. Custom Tools
-LSP Tools (11 tools)
-Source: src/tools/lsp/
-export const builtinTools = {
-  // Information
-  lsp_hover,              // Type info, docs at position
-  lsp_goto_definition,    // Jump to definition
-  lsp_find_references,    // Find all usages
-  lsp_document_symbols,   // File symbol outline
-  lsp_workspace_symbols,  // Search symbols by name
-  lsp_diagnostics,        // Get errors/warnings
-  lsp_servers,            // List available LSP servers
-  
-  // Refactoring
-  lsp_prepare_rename,     // Validate rename
-  lsp_rename,             // Rename symbol across workspace
-  lsp_code_actions,       // Get quick fixes/refactorings
-  lsp_code_action_resolve, // Apply code action
-}
-AST-Grep Tools
-Source: src/tools/ast-grep/
-export const astGrepTools = {
-  ast_grep_search,   // AST-aware pattern search (25 languages)
-  ast_grep_replace,  // AST-aware code replacement
-}
-Search Tools (Improved)
-export const searchTools = {
-  grep,  // With timeout protection (original hangs forever)
-  glob,  // With timeout protection
-}
-Special Tools
-// look_at - Multimodal analysis via subagent
-export function createLookAt(ctx: PluginInput) {
-  return tool({
-    description: "Analyze files using multimodal-looker agent",
-    args: { file: tool.schema.string() },
-    async execute(args, toolContext) {
-      // Delegates to multimodal-looker agent internally
-      // Saves context in main session
-    },
-  });
-}
-// call_omo_agent - Specialized agent caller
-export function createCallOmoAgent(ctx: PluginInput, manager: BackgroundManager) {
-  return tool({
-    description: "Call explore or librarian agents",
-    args: {
-      subagent_type: tool.schema.enum(["explore", "librarian"]),
-      prompt: tool.schema.string(),
-      run_in_background: tool.schema.boolean(),
-    },
-    async execute(args, toolContext) {
-      if (args.run_in_background) {
-        return await manager.launch(...);
-      }
-      return await executeSynchronously(...);
-    },
-  });
-}
-// interactive_bash - Tmux integration
-export const interactive_bash = tool({
-  description: "Execute commands in interactive tmux session",
-  // ...
-});
----
-8. MCP Integrations
-Built-in MCPs
-Source: src/mcp/
-// context7.ts - Official documentation lookup
-export const context7 = {
-  type: "remote",
-  url: "https://mcp.context7.io/sse",
-  enabled: true,
-}
-// websearch_exa.ts - Real-time web search
-export const websearch_exa = {
-  type: "remote",
-  url: "https://mcp.exa.ai/sse",
-  enabled: true,
-}
-// grep_app.ts - GitHub code search
-export const grep_app = {
-  type: "remote",
-  url: "https://mcp.grep.app/sse",
-  enabled: true,
-}
-MCP Injection
-config: async (config) => {
-  config.mcp = {
-    ...config.mcp,
-    ...createBuiltinMcps(pluginConfig.disabled_mcps),  // context7, websearch_exa, grep_app
-    ...loadMcpConfigs(),  // Claude Code .mcp.json files
-  };
-}
----
-9. Configuration System
-Config File Locations
-1. ~/.config/opencode/oh-my-opencode.json (user-level)
-2. .opencode/oh-my-opencode.json (project-level, overrides user)
-Config Schema
-Source: src/config/schema.ts
-export const OhMyOpenCodeConfigSchema = z.object({
-  // Enable Google OAuth
-  google_auth: z.boolean().optional(),
-  
-  // Agent overrides
-  agents: z.record(z.object({
-    model: z.string().optional(),
-    temperature: z.number().optional(),
-    prompt: z.string().optional(),
-    tools: z.record(z.boolean()).optional(),
-    disable: z.boolean().optional(),
-    description: z.string().optional(),
-    mode: z.enum(["primary", "subagent"]).optional(),
-    color: z.string().optional(),
-    permission: z.object({
-      edit: z.enum(["ask", "allow", "deny"]).optional(),
-      bash: z.union([
-        z.enum(["ask", "allow", "deny"]),
-        z.record(z.enum(["ask", "allow", "deny"]))
-      ]).optional(),
-    }).optional(),
-  })).optional(),
-  
-  // Disable specific agents
-  disabled_agents: z.array(z.string()).optional(),
-  
-  // Disable specific MCPs
-  disabled_mcps: z.array(z.enum(["context7", "websearch_exa", "grep_app"])).optional(),
-  
-  // Disable specific hooks
-  disabled_hooks: z.array(z.string()).optional(),
-  
-  // Claude Code compatibility toggles
-  claude_code: z.object({
-    mcp: z.boolean().optional(),
-    commands: z.boolean().optional(),
-    skills: z.boolean().optional(),
-    agents: z.boolean().optional(),
-    hooks: z.boolean().optional(),
-  }).optional(),
-  
-  // OmO agent settings
-  omo_agent: z.object({
-    disabled: z.boolean().optional(),
-  }).optional(),
-});
-Example Configuration
-{
-  $schema: https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json,
-  
-  google_auth: true,
-  
-  agents: {
-    OmO: {
-      model: anthropic/claude-sonnet-4
-    },
-    oracle: {
-      temperature: 0.3
-    },
-    frontend-ui-ux-engineer: {
-      disable: true
-    }
-  },
-  
-  disabled_hooks: [comment-checker],
-  disabled_mcps: [grep_app],
-  
-  claude_code: {
-    hooks: true,
-    commands: true,
-    mcp: false
-  }
-}
----
-10. Plugin Loading & Updates
-How OpenCode Loads Plugins
-Source: packages/opencode/src/plugin/index.ts (in sst/opencode)
-for (let plugin of plugins) {
-  if (!plugin.startsWith("file://")) {
-    // Parse version: "oh-my-opencode@2.1.6"
-    const lastAtIndex = plugin.lastIndexOf("@")
-    const pkg = lastAtIndex > 0 ? plugin.substring(0, lastAtIndex) : plugin
-    const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : "latest"
-    
-    // Install via Bun from npm registry
-    plugin = await BunProc.install(pkg, version)
-  }
-  
-  const mod = await import(plugin)
-  for (const [_name, fn] of Object.entries(mod)) {
-    const init = await fn(input)
-    hooks.push(init)
-  }
-}
-Plugin Cache Location
-~/.cache/opencode/
-├── node_modules/
-│   └── oh-my-opencode/           ← THE ACTUAL PLUGIN CODE
-│       ├── dist/
-│       │   └── index.js
-│       └── package.json
-├── package.json
-└── bun.lockb
-Auto-Update Checker
-Source: src/hooks/auto-update-checker/
-export function createAutoUpdateCheckerHook(ctx: PluginInput) {
-  return {
-    event: async ({ event }) => {
-      if (event.type !== "session.created") return;
-      
-      // Check npm registry for latest version
-      const result = await checkForUpdate(ctx.directory);
-      
-      if (result.needsUpdate) {
-        // Show notification
-        await ctx.client.tui.showToast({
-          body: {
-            title: `OhMyOpenCode ${result.latestVersion}`,
-            message: `v${result.latestVersion} available. Restart OpenCode to apply.`,
-          }
-        });
-        
-        // Invalidate cache (delete cached package)
-        invalidatePackage("oh-my-opencode");
-        // Next restart will download new version
-      }
-    },
-  };
-}
-async function getLatestVersion(): Promise<string | null> {
-  const response = await fetch("https://registry.npmjs.org/-/package/oh-my-opencode/dist-tags");
-  const data = await response.json();
-  return data.latest;
-}
-Version Pinning
-// Latest (auto-updates on restart)
-{ plugin: [oh-my-opencode] }
-// Pinned (never auto-updates)
-{ plugin: [oh-my-opencode@2.1.6] }
-// Local development
-{ plugin: [file:///path/to/oh-my-opencode] }
----
-11. Creating Your Own Plugin
-Minimal package.json
-{
-  name: my-opencode-plugin,
-  version: 1.0.0,
-  main: dist/index.js,
-  types: dist/index.d.ts,
-  type: module,
-  files: [dist],
-  exports: {
-    .: {
-      types: ./dist/index.d.ts,
-      import: ./dist/index.js
-    }
-  },
-  scripts: {
-    build: bun build src/index.ts --outdir dist --target bun --format esm && tsc --emitDeclarationOnly,
-    prepublishOnly: bun run build
-  },
-  dependencies: {
-    @opencode-ai/plugin: ^1.0.162
-  },
-  devDependencies: {
-    bun-types: latest,
-    typescript: ^5.7.3
-  },
-  peerDependencies: {
-    bun: >=1.0.0
-  }
-}
-Minimal tsconfig.json
-{
-  compilerOptions: {
-    target: ESNext,
-    module: ESNext,
-    moduleResolution: bundler,
-    declaration: true,
-    declarationDir: dist,
-    outDir: dist,
-    rootDir: src,
-    strict: true,
-    esModuleInterop: true,
-    skipLibCheck: true,
-    lib: [ESNext],
-    types: [bun-types]
-  },
-  include: [src/**/*],
-  exclude: [node_modules, dist]
-}
-Minimal Plugin (src/index.ts)
-import type { Plugin } from "@opencode-ai/plugin"
-import { tool } from "@opencode-ai/plugin"
-const MyPlugin: Plugin = async ({ client, directory }) => {
-  return {
-    // Add custom tools
-    tool: {
-      my_tool: tool({
-        description: "Does something useful",
-        args: {
-          input: tool.schema.string(),
-        },
-        async execute(args) {
-          return `Processed: ${args.input}`;
-        },
-      }),
-    },
-    // Modify config
-    config: async (config) => {
-      config.agent = {
-        ...config.agent,
-        "my-agent": {
-          description: "My custom agent",
-          model: "anthropic/claude-sonnet-4",
-          prompt: "You are helpful...",
-        },
-      };
-    },
-    // React to events
-    event: async ({ event }) => {
-      if (event.type === "session.created") {
-        await client.tui.showToast({
-          body: {
-            title: "Plugin Loaded",
-            message: "My plugin is active!",
-            variant: "success",
-          }
-        }).catch(() => {});
-      }
-    },
-    // Intercept tool calls
-    "tool.execute.before": async (input, output) => {
-      console.log(`Tool ${input.tool} called`);
-    },
-  };
-};
-export default MyPlugin;
-Publish to npm
-npm login
-npm publish
-Users Install
-{
-  plugin: [my-opencode-plugin]
-}
----
-12. Key Files Reference
-Core oh-my-opencode Files
-| File | Purpose |
-|------|---------|
-| src/index.ts | Main plugin entry, orchestrates everything |
-| src/agents/*.ts | Agent definitions (OmO, oracle, etc.) |
-| src/features/background-agent/manager.ts | Background task management |
-| src/tools/background-task/tools.ts | background_task, background_output, background_cancel |
-| src/tools/lsp/*.ts | LSP tool implementations |
-| src/hooks/*.ts | All 21 hooks |
-| src/mcp/*.ts | MCP server configurations |
-| src/config/schema.ts | Zod config schema |
-OpenCode Core Files (sst/opencode)
-| File | Purpose |
-|------|---------|
-| packages/plugin/src/index.ts | Plugin interface types |
-| packages/plugin/src/tool.ts | Tool definition helper |
-| packages/opencode/src/plugin/index.ts | Plugin loading logic |
----
-Summary: Why oh-my-opencode Works So Well
-1. Multi-Model Orchestration: Uses the right model for each task (GPT-5.2 for reasoning, Gemini for UI, Grok for speed)
-2. True Parallel Execution: BackgroundManager creates separate sessions, allowing multiple agents to work simultaneously
-3. Automatic Notifications: Event system detects task completion and injects messages into the main conversation
-4. Defensive Hooks: 21 hooks ensure tasks complete, errors recover, context is managed
-5. Comprehensive System Prompt: OmO's 400+ line prompt teaches proper delegation and orchestration
-6. IDE-Quality Tools: LSP and AST-grep tools give agents the same capabilities as human developers
-7. Context Injection: Automatic README/AGENTS.md injection and conditional rules
-8. Claude Code Compatibility: Existing Claude Code configs just work
-The plugin transforms a single-agent assistant into a dev team where you're the manager and AI models are your specialized engineers.
----
-Session Summary
-What We Covered
-1. Researched the @opencode-ai/plugin API - Examined the Plugin type, Hooks interface, available events, and tool definitions from the sst/opencode repository
-2. Deep-dived into oh-my-opencode architecture - Read and analyzed:
-   - Main entry point (src/index.ts) - 566 lines
-   - Agent definitions (src/agents/) - OmO, oracle, librarian, explore, etc.
-   - BackgroundManager (src/features/background-agent/manager.ts) - 430 lines
-   - Background tools (src/tools/background-task/tools.ts) - 332 lines
-   - Auto-update checker (src/hooks/auto-update-checker/)
-3. Explained key concepts:
-   - How plugins are loaded from npm (not GitHub)
-   - How the config hook injects custom agents
-   - How BackgroundManager enables parallel execution
-   - How notifications work (toast + message injection)
-   - The difference between schema URL (IDE autocomplete) vs actual code (npm)
-4. Created publishing guide - How to create, build, and publish your own OpenCode plugin
-Key Files Examined
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/src/index.ts
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/src/agents/*.ts
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/src/features/background-agent/manager.ts
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/src/tools/background-task/tools.ts
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/src/hooks/auto-update-checker/*.ts
-- /Users/darrenhinde/Documents/GitHub/test-larvel/oh-my-opencode/package.json
-- /tmp/opencode-repo/packages/plugin/src/index.ts (from sst/opencode)
-▣  Compaction · claude-opus-4-5 · 3m 0s
-Thinking: The user is asking me to continue if there are next steps. Let me check what the current state is and if there's anything pending.
-Looking at the comprehensive summary I provided, it seems like we've completed a thorough documentation of the OpenCode plugin system and oh-my-opencode architecture. 
-Let me check if there's a todo list or any pending tasks by reading the todo list.
-⚙ todoread 
-Thinking: The todo list is empty, which means we've completed the documentation work. The user asked "What did we do so far?" and I provided a comprehensive summary. Now they're asking to continue if there are next steps.
-Since there's no active todo list and the documentation seems complete, I should ask what they'd like to do next. Possible directions:
-1. Create a custom plugin based on what we learned
-2. Modify/extend oh-my-opencode
-3. Work on something else in the codebase
-4. Dive deeper into specific components
-Let me ask what direction they want to take.

+ 0 - 538
dev/ai-tools/opencode/slash-commands-and-subagents.md

@@ -1,538 +0,0 @@
-# Clear Guidelines: Main Agent → Slash Command → Subagent
-
-## The Complete Pattern
-
-### Step 1: Create Your Command (Template Only)
-
-```markdown
-# .opencode/command/security/scan.md
----
-description: "Security vulnerability scan"
-# NO agent field - let caller decide
----
-
-Perform security scan on: $ARGUMENTS
-
-@$1
-@AGENTS.md
-@.cursorrules
-
-Check for:
-- SQL injection
-- XSS vulnerabilities
-- Authentication issues
-```
-
-### Step 2: Create Your Subagent
-
-```markdown
-# .opencode/agent/security/scanner.md
----
-mode: "subagent"
-description: "Security vulnerability detection specialist"
-tools:
-  read: true
-  grep: true
----
-
-You are a security expert. Scan code for vulnerabilities.
-```
-
-### Step 3: Document in AGENTS.md (CRITICAL)
-
-```markdown
-# AGENTS.md
-
-## Slash Commands for Subagents
-
-When you need specialized workflows, use the Task tool with slash commands:
-
-### Pattern
-
-```
-Task(
-  subagent_type="[subagent-name]",
-  prompt="/command-name arguments"
-)
-```
-
-### Available Commands
-
-**Security:**
-- `/security/scan [file]`
-  - Use: `Task(subagent_type="security/scanner", prompt="/security/scan auth.ts")`
-  - Performs comprehensive security analysis
-
-**Testing:**
-- `/test/generate [file]`
-  - Use: `Task(subagent_type="testing/generator", prompt="/test/generate service.ts")`
-  - Generates unit tests with project patterns
-
-**Refactoring:**
-- `/refactor/modernize [file] [context]`
-  - Use: `Task(subagent_type="refactor/modernizer", prompt="/refactor/modernize old.js 'use async/await'")`
-  - Updates legacy code to modern standards
-
-### When to Use
-
-- User asks for security audit → Use `/security/scan`
-- After writing code → Use `/test/generate`
-- Legacy code mentioned → Use `/refactor/modernize`
-```
-
-## How It Works
-
-```
-User: "Check auth.ts for security issues"
-    ↓
-Main Agent reads AGENTS.md
-    ↓
-Sees: /security/scan pattern
-    ↓
-Main Agent calls:
-  Task(
-    subagent_type="security/scanner",
-    prompt="/security/scan auth.ts"
-  )
-    ↓
-System processes /security/scan command:
-  - Loads template from command/security/scan.md
-  - Replaces $ARGUMENTS with "auth.ts"
-  - Attaches @auth.ts file
-  - Attaches @AGENTS.md, @.cursorrules
-    ↓
-Subagent "security/scanner" receives:
-  - Full template text
-  - All attached files as context
-    ↓
-Subagent executes → Returns result → Main agent responds to user
-```
-
-## Complete Working Example
-
-### Files Structure
-
-```
-.opencode/
-├── agent/
-│   ├── security/
-│   │   └── scanner.md
-│   ├── testing/
-│   │   └── generator.md
-│   └── refactor/
-│       └── modernizer.md
-├── command/
-│   ├── security/
-│   │   └── scan.md
-│   ├── test/
-│   │   └── generate.md
-│   └── refactor/
-│       └── modernize.md
-└── AGENTS.md  ← Documents the patterns
-```
-
-### 1. Command Template
-
-```markdown
-# .opencode/command/test/generate.md
----
-description: "Generate comprehensive unit tests"
----
-
-Generate unit tests for: $ARGUMENTS
-
-Target file:
-@$1
-
-Existing test patterns:
-!`find $(dirname $1) -name "*.test.*" | head -3`
-
-Requirements:
-- Test all public methods
-- Include edge cases
-- Mock external dependencies
-- Follow project conventions from @AGENTS.md
-```
-
-### 2. Subagent
-
-```markdown
-# .opencode/agent/testing/generator.md
----
-mode: "subagent"
-description: "Use AFTER writing new code to generate comprehensive tests"
-tools:
-  read: true
-  write: true
-  grep: true
----
-
-You generate unit tests by:
-1. Analyzing the implementation
-2. Studying existing test patterns
-3. Creating thorough test coverage
-4. Following project conventions
-```
-
-### 3. AGENTS.md Documentation
-
-```markdown
-# AGENTS.md
-
-## Build/Test Commands
-- Run tests: `npm test`
-- Single test: `npm test -- path/to/test.ts`
-
-## Code Standards
-- TypeScript strict mode
-- camelCase for functions
-- PascalCase for classes
-
-## Slash Commands with Subagents
-
-Use Task tool to invoke specialized workflows:
-
-### Testing Workflow
-
-After writing new code, generate tests:
-
-```
-Task(
-  subagent_type="testing/generator",
-  prompt="/test/generate src/services/payment.ts"
-)
-```
-
-### Security Workflow
-
-Before deploying authentication code:
-
-```
-Task(
-  subagent_type="security/scanner",
-  prompt="/security/scan src/auth/*.ts"
-)
-```
-
-### Refactoring Workflow
-
-When updating legacy code:
-
-```
-Task(
-  subagent_type="refactor/modernizer",
-  prompt="/refactor/modernize src/legacy/util.js 'convert to TypeScript with async/await'"
-)
-```
-
-### Pattern Summary
-
-1. Identify the workflow need
-2. Use Task tool with appropriate subagent_type
-3. Pass slash command as the prompt
-4. Command loads template + context
-5. Subagent executes with full context
-```
-
-## Real Conversation Example
-
-```
-User: "I just wrote a new payment service. Can you add tests?"
-
-Main Agent (reads AGENTS.md, sees testing workflow):
-  "I'll generate comprehensive tests for the payment service."
-  
-  [Calls Task tool:]
-  Task(
-    description="Generate payment service tests",
-    subagent_type="testing/generator",
-    prompt="/test/generate src/services/payment.ts"
-  )
-
-Command System:
-  - Loads .opencode/command/test/generate.md
-  - Replaces $1 with "src/services/payment.ts"
-  - Attaches payment.ts file
-  - Finds existing test files in same directory
-  - Attaches AGENTS.md for conventions
-
-Subagent (testing/generator):
-  - Receives full context
-  - Analyzes payment.ts implementation
-  - Studies existing test patterns
-  - Generates comprehensive tests
-  - Returns result
-
-Main Agent:
-  "✅ Generated comprehensive tests in src/services/payment.test.ts
-  - Tests all public methods
-  - Includes edge cases for failed payments
-  - Mocks payment gateway
-  - Follows project test conventions"
-```
-
-## Template for Your AGENTS.md
-
-```markdown
-# AGENTS.md
-
-## Project Commands
-[Your build/test commands]
-
-## Code Standards
-[Your standards]
-
-## Automated Workflows
-
-I have specialized workflows accessible via slash commands.
-Use the Task tool to invoke them with appropriate subagents.
-
-### Pattern
-
-```
-Task(
-  subagent_type="[subagent-name]",
-  prompt="/[command-name] [arguments]"
-)
-```
-
-### Security Analysis
-
-**When:** Before deploying auth/payment code
-**Command:** `/security/scan [file]`
-**Subagent:** `security/scanner`
-**Example:**
-
-```
-Task(
-  subagent_type="security/scanner",
-  prompt="/security/scan src/auth/jwt.ts"
-)
-```
-
-### Test Generation
-
-**When:** After writing new code
-**Command:** `/test/generate [file]`
-**Subagent:** `testing/generator`
-**Example:**
-
-```
-Task(
-  subagent_type="testing/generator",
-  prompt="/test/generate src/services/payment.ts"
-)
-```
-
-### Code Modernization
-
-**When:** Refactoring legacy code
-**Command:** `/refactor/modernize [file] [instructions]`
-**Subagent:** `refactor/modernizer`
-**Example:**
-
-```
-Task(
-  subagent_type="refactor/modernizer",
-  prompt="/refactor/modernize src/old-api.js 'convert to TypeScript with async/await'"
-)
-```
-
-### Quick Reference
-
-| Task | Command | Subagent |
-|------|---------|----------|
-| Security scan | `/security/scan` | `security/scanner` |
-| Generate tests | `/test/generate` | `testing/generator` |
-| Modernize code | `/refactor/modernize` | `refactor/modernizer` |
-
-## Notes
-
-- Commands are templates that attach context files automatically
-- Subagents receive full context and execute specialized workflows
-- Always specify subagent_type when using Task tool with slash commands
-```
-
-## Key Points
-
-1. **Commands are templates** - They don't execute anything, they just format context
-2. **Subagents do the work** - They receive the processed template + attached files
-3. **AGENTS.md is the bridge** - It tells main agent HOW to connect commands to subagents
-4. **Pattern is always:** `Task(subagent_type="X", prompt="/command args")`
-5. **Main agent decides** which subagent to use based on your documentation
-
-## Checklist
-
-- ✅ Create command templates (no agent field)
-- ✅ Create specialized subagents (mode: "subagent")
-- ✅ Document pattern in AGENTS.md with examples
-- ✅ Include "When to use" triggers
-- ✅ Show exact Task tool syntax
-- ✅ Test with: "Can you [task description]"
-
-That's it! Main agent reads AGENTS.md, sees the patterns, and knows how to invoke slash commands through subagents.
-
----
-
-## Appendix: Path Resolution Test Findings
-
-**Date:** November 19, 2025  
-**Test Objective:** Verify path resolution behavior for portable agent installation strategy
-
-### 🔍 Discovery Phase Results
-
-#### OpenCode Directory Structure
-
-**Global Configuration:**
-- **Location:** `~/.config/opencode/`
-- **Contents:** `opencode.json`, `config.json`, plugins, providers
-- **Note:** No `agent/`, `command/`, or `context/` folders found in default installation
-
-**Authentication & Data:**
-- **Location:** `~/.local/share/opencode/`
-- **Contents:** `auth.json`, bin, log, project, snapshot, storage
-
-**Local Repository:**
-- **Location:** `.opencode/` (in git repository root)
-- **Structure:** `agent/`, `command/`, `context/`, `plugin/`, `tool/`
-
-#### Key Findings
-
-1. ✅ **Global config path confirmed:** `~/.config/opencode/`
-2. ✅ **Local structure confirmed:** `.opencode/` in repo root
-3. ⚠️ **Current agents don't use `@` references** - Context loaded via different mechanism
-4. ✅ **Context files exist** in `.opencode/context/` with subdirectories
-
-### 📊 Path Resolution Analysis
-
-#### From OpenCode Documentation
-
-**`@` Symbol Resolution Order:**
-1. Check if starts with `~/` → resolve to home directory
-2. Check if absolute path → use as-is
-3. Otherwise → resolve relative to repo root (`Instance.worktree`)
-4. If not found → look for agent with that name
-
-#### Implications for Installation
-
-**Local Installation (in repo):**
-```
-Repo structure:
-  .opencode/
-  ├── agent/security/scanner.md
-  └── context/security/patterns.md
-
-Reference: @.opencode/context/security/patterns.md
-Resolution: {repo-root}/.opencode/context/security/patterns.md ✅
-```
-
-**Global Installation:**
-```
-Global structure:
-  ~/.config/opencode/
-  ├── agent/security/scanner.md
-  └── context/security/patterns.md
-
-Reference: @.opencode/context/security/patterns.md
-Resolution: Tries to find .opencode/ relative to... what? ❌
-Problem: No "repo root" for global agents!
-```
-
-### 🎯 Path Pattern Testing
-
-#### Test Setup
-
-Created global test agent with three path patterns:
-
-```markdown
-# Pattern 1: With .opencode prefix
-@.opencode/context/test/global-test-data.md
-
-# Pattern 2: Without .opencode prefix  
-@context/test/global-test-data.md
-
-# Pattern 3: Explicit home path
-@~/.config/opencode/context/test/global-test-data.md
-```
-
-#### Expected Results (Based on Documentation)
-
-| Pattern | Local Install | Global Install | Notes |
-|---------|--------------|----------------|-------|
-| `@.opencode/context/file.md` | ✅ Works | ❌ Fails | No .opencode in global path |
-| `@context/file.md` | ❌ Fails | ❓ Unknown | Might resolve to ~/.config/opencode/context/ |
-| `@~/.config/opencode/context/file.md` | ❌ Fails | ✅ Works | Explicit path, but breaks local |
-
-#### Critical Issue
-
-**No single path pattern works for both local AND global installations!**
-
-This confirms our installation script approach is necessary.
-
-### ✅ Validated Assumptions
-
-1. ✅ **Global path is `~/.config/opencode/`** - Confirmed
-2. ✅ **Local path is `.opencode/`** - Confirmed  
-3. ✅ **Path transformation is required** - Confirmed (no universal pattern)
-4. ✅ **Context folder structure works** - Confirmed (exists in current repo)
-
-### ❌ Invalidated Assumptions
-
-1. ❌ **`@context/file.md` might work universally** - Unconfirmed, likely fails locally
-2. ❌ **Current agents use `@` references** - They don't (different loading mechanism)
-
-### 🔧 Installation Strategy Confirmation
-
-#### Source Code Convention
-
-**All context references MUST use:**
-```markdown
-@.opencode/context/{category}/{file}.md
-```
-
-#### Installation Script Transformation
-
-**Local Installation:**
-- Keep references as-is: `@.opencode/context/...`
-- Copy to: `{repo}/.opencode/`
-
-**Global Installation:**  
-- Transform: `@.opencode/context/` → `@~/.config/opencode/context/`
-- Copy to: `~/.config/opencode/`
-
-#### Transformation Rules
-
-```bash
-# For global installation
-sed 's|@\.opencode/context/|@~/.config/opencode/context/|g'
-
-# Also transform shell commands
-sed 's|\.opencode/context/|~/.config/opencode/context/|g'
-```
-
-### 🚨 Additional Considerations
-
-#### Shell Commands in Templates
-
-**Problem:** Commands like `!`ls .opencode/context/`` also need transformation
-
-**Solution:** Transform both `@` references AND bare paths in shell commands
-
-#### Context Cross-References
-
-**Problem:** Context files may reference other context files
-
-**Solution:** Transform context files too, not just agents/commands
-
-#### Platform Compatibility
-
-**macOS/Linux:** `~/.config/opencode/` ✅  
-**Windows:** Need to verify (likely `%APPDATA%\opencode` or similar)
-
-### 📝 Recommendations
-
-1. **Proceed with Installation Script Approach** - The two-tier distribution with path transformation is necessary and correct
-2. **Strict Convention Enforcement** - Create validation script to ensure all references follow `@.opencode/context/` pattern
-3. **Transform All File Types** - Agent files, command files, AND context files
-4. **Test on Actual OpenCode Installation** - Runtime testing would confirm edge cases
-5. **Platform-Specific Paths** - Verify global paths on Windows before production release

+ 0 - 12
dev/dashboard-project/main.js

@@ -1,12 +0,0 @@
-import { dashboardController } from './ui/index.js';
-
-/**
- * Main entry point for the Dashboard project.
- */
-const main = () => {
-  console.log('Initializing Dashboard...');
-  const output = dashboardController();
-  console.log(output);
-};
-
-main();

+ 0 - 7
dev/dashboard-project/package.json

@@ -1,7 +0,0 @@
-{
-  "name": "dashboard-project",
-  "version": "1.0.0",
-  "type": "module",
-  "description": "A modular dashboard project with Time, Period, and Star Sign APIs.",
-  "main": "main.js"
-}

+ 0 - 23
dev/dashboard-project/period/core.js

@@ -1,23 +0,0 @@
-/**
- * Core logic for the Period component.
- */
-
-export const PERIODS = {
-  DAY: 'day',
-  WEEK: 'week',
-  MONTH: 'month',
-  YEAR: 'year'
-};
-
-/**
- * Returns all available periods.
- * @returns {string[]}
- */
-export const getAvailablePeriods = () => Object.values(PERIODS);
-
-/**
- * Validates if a period is supported.
- * @param {string} period 
- * @returns {boolean}
- */
-export const isValidPeriod = (period) => getAvailablePeriods().includes(period);

+ 0 - 11
dev/dashboard-project/period/index.js

@@ -1,11 +0,0 @@
-import { getAvailablePeriods } from './core.js';
-import { success } from '../shared/utils.js';
-
-/**
- * Period API Handler.
- * @returns {Object}
- */
-export const getPeriodsHandler = () => {
-  const periods = getAvailablePeriods();
-  return success({ periods });
-};

+ 0 - 0
dev/dashboard-project/period/tests/period.test.js


+ 0 - 0
dev/dashboard-project/shared/index.js


+ 0 - 25
dev/dashboard-project/shared/utils.js

@@ -1,25 +0,0 @@
-/**
- * Shared utility functions for the Dashboard project.
- */
-
-/**
- * Wraps a value in a success object.
- * @param {*} data 
- * @returns {Object}
- */
-export const success = (data) => ({ success: true, data });
-
-/**
- * Wraps an error message in a failure object.
- * @param {string} error 
- * @returns {Object}
- */
-export const failure = (error) => ({ success: false, error });
-
-/**
- * Generates a random integer between min and max (inclusive).
- * @param {number} min 
- * @param {number} max 
- * @returns {number}
- */
-export const getRandomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

+ 0 - 19
dev/dashboard-project/star-sign/core.js

@@ -1,19 +0,0 @@
-/**
- * Core logic for the Star Sign component.
- */
-
-export const STAR_SIGNS = [
-  'Aries', 'Taurus', 'Gemini', 'Cancer',
-  'Leo', 'Virgo', 'Libra', 'Scorpio',
-  'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'
-];
-
-/**
- * Returns a random star sign from the list.
- * @param {Function} getRandomInt - Dependency injection for randomness.
- * @returns {string}
- */
-export const getRandomStarSign = (getRandomInt) => {
-  const index = getRandomInt(0, STAR_SIGNS.length - 1);
-  return STAR_SIGNS[index];
-};

+ 0 - 11
dev/dashboard-project/star-sign/index.js

@@ -1,11 +0,0 @@
-import { getRandomStarSign } from './core.js';
-import { success, getRandomInt } from '../shared/utils.js';
-
-/**
- * Star Sign API Handler.
- * @returns {Object}
- */
-export const getStarSignHandler = () => {
-  const starSign = getRandomStarSign(getRandomInt);
-  return success({ starSign });
-};

+ 0 - 0
dev/dashboard-project/star-sign/tests/star-sign.test.js


+ 0 - 18
dev/dashboard-project/time/core.js

@@ -1,18 +0,0 @@
-/**
- * Core logic for the Time component.
- * Pure functions only.
- */
-
-/**
- * Returns the current time in ISO format.
- * @param {Date} [date=new Date()] - Optional date for testing.
- * @returns {string}
- */
-export const getCurrentTimeISO = (date = new Date()) => date.toISOString();
-
-/**
- * Formats a date to a human-readable string.
- * @param {Date} date 
- * @returns {string}
- */
-export const formatHumanReadable = (date) => date.toLocaleString();

+ 0 - 11
dev/dashboard-project/time/index.js

@@ -1,11 +0,0 @@
-import { getCurrentTimeISO } from './core.js';
-import { success } from '../shared/utils.js';
-
-/**
- * Time API Handler.
- * @returns {Object}
- */
-export const getTimeHandler = () => {
-  const time = getCurrentTimeISO();
-  return success({ time });
-};

+ 0 - 0
dev/dashboard-project/time/tests/time.test.js


+ 0 - 26
dev/dashboard-project/ui/core.js

@@ -1,26 +0,0 @@
-/**
- * Core logic for the Dashboard UI.
- * Pure functions for rendering/formatting.
- */
-
-/**
- * Renders the dashboard state into a string (simulating a UI component).
- * @param {Object} state 
- * @returns {string}
- */
-export const renderDashboard = (state) => {
-  const { time, periods, starSign } = state;
-  
-  return `
-=========================================
-          DASHBOARD OVERVIEW
-=========================================
-Current Time: ${time || 'Loading...'}
------------------------------------------
-Available Periods:
-${periods ? periods.map(p => `- ${p}`).join('\n') : 'Loading...'}
------------------------------------------
-Visitor Star Sign: ${starSign || 'Loading...'}
-=========================================
-  `;
-};

+ 0 - 23
dev/dashboard-project/ui/index.js

@@ -1,23 +0,0 @@
-import { renderDashboard } from './core.js';
-import { getTimeHandler } from '../time/index.js';
-import { getPeriodsHandler } from '../period/index.js';
-import { getStarSignHandler } from '../star-sign/index.js';
-
-/**
- * Dashboard UI Controller.
- * Orchestrates data fetching and rendering.
- * @returns {string}
- */
-export const dashboardController = () => {
-  const timeData = getTimeHandler();
-  const periodData = getPeriodsHandler();
-  const starSignData = getStarSignHandler();
-
-  const state = {
-    time: timeData.success ? timeData.data.time : 'Error',
-    periods: periodData.success ? periodData.data.periods : [],
-    starSign: starSignData.success ? starSignData.data.starSign : 'Error'
-  };
-
-  return renderDashboard(state);
-};

+ 0 - 0
dev/dashboard-project/ui/tests/ui.test.js


+ 0 - 364
dev/docs/context-reference-convention.md

@@ -1,364 +0,0 @@
-# Context Reference Convention
-
-## Overview
-
-All context file references in OpenAgents Control **MUST** use the standardized format:
-
-```markdown
-@.opencode/context/path/to/file.md
-```
-
-This convention is **required** for the installation system to work correctly across local and global installations.
-
----
-
-## The Requirement
-
-### ✅ Correct Format
-
-```markdown
-@.opencode/context/core/essential-patterns.md
-@.opencode/context/project/project-context.md
-@.opencode/context/security/auth.md
-```
-
-### ❌ Incorrect Formats
-
-```markdown
-@context/core/patterns.md           ❌ Missing .opencode prefix
-@~/context/file.md                  ❌ Absolute path (breaks local installs)
-@$CONTEXT_DIR/file.md               ❌ Variables (can't be transformed)
-../context/file.md                  ❌ Relative path (unreliable)
-```
-
----
-
-## Why This Convention?
-
-### Problem: Local vs Global Installations
-
-Users can install OpenAgents Control in two ways:
-
-**Local Install:**
-```bash
-.opencode/
-├── agent/
-├── command/
-└── context/
-```
-References work as: `@.opencode/context/file.md` (relative to current directory)
-
-**Global Install:**
-```bash
-~/.config/opencode/
-├── agent/
-├── command/
-└── context/
-```
-References need to be: `@~/.config/opencode/context/file.md` (absolute path)
-
-### Solution: Install-Time Transformation
-
-The installation script automatically transforms references based on installation type:
-
-```bash
-# Local install (.opencode/)
-@.opencode/context/test.md  →  @.opencode/context/test.md  (no change)
-
-# Global install (~/.config/opencode/)
-@.opencode/context/test.md  →  @~/.config/opencode/context/test.md  (transformed)
-
-# Custom install (/usr/local/opencode/)
-@.opencode/context/test.md  →  @/usr/local/opencode/context/test.md  (transformed)
-```
-
----
-
-## How It Works
-
-### Repository Files (Source)
-
-All files in the repository use the standard format:
-
-```markdown
-# Example Agent
-
-Load patterns from @.opencode/context/core/essential-patterns.md
-```
-
-### Installation Process
-
-When a user installs globally, the installer:
-
-1. Downloads the file
-2. Detects global installation (INSTALL_DIR != ".opencode")
-3. Transforms all references:
-   ```bash
-   sed -e "s|@\.opencode/context/|@${INSTALL_DIR}/context/|g" \
-       -e "s|\.opencode/context|${INSTALL_DIR}/context|g" file.md
-   ```
-4. Saves the transformed file
-
-### Result
-
-**After global install to ~/.config/opencode:**
-```markdown
-# Example Agent
-
-Load patterns from @/Users/username/.config/opencode/context/core/essential-patterns.md
-```
-
----
-
-## What Gets Transformed
-
-### All File Types
-
-The transformation applies to **EVERY** file during installation:
-
-- ✅ Agent files (`.opencode/agent/*.md`)
-- ✅ Subagent files (`.opencode/agent/subagents/*.md`)
-- ✅ Command files (`.opencode/command/*.md`)
-- ✅ Context files (`.opencode/context/**/*.md`)
-- ✅ Any other markdown files
-
-### All Reference Types
-
-Both patterns are transformed:
-
-**Pattern 1: @ References (OpenCode syntax)**
-```markdown
-@.opencode/context/file.md  →  @/install/path/context/file.md
-```
-
-**Pattern 2: Shell Commands**
-```markdown
-.opencode/context/file.md  →  /install/path/context/file.md
-```
-
----
-
-## Testing & Validation
-
-### Why We Enforce This
-
-During development and testing, we discovered:
-
-1. **Inconsistent references broke installations** - Some files used `@context/`, others used `@.opencode/context/`
-2. **Variable-based paths couldn't be transformed** - `@$CONTEXT_DIR/file.md` can't be reliably replaced
-3. **Relative paths were unreliable** - `../context/file.md` broke when files moved
-4. **Absolute paths broke local installs** - `@~/.config/opencode/context/` doesn't work for `.opencode/`
-
-### Test Results
-
-With the standardized convention:
-- ✅ 31/31 tests passed (100% success rate)
-- ✅ Works for local installations
-- ✅ Works for global installations
-- ✅ Works for custom installation paths
-- ✅ Transforms all file types correctly
-- ✅ Handles multiple references per file
-
----
-
-## Implementation Details
-
-### Detection Logic
-
-The installer determines if transformation is needed:
-
-```bash
-if [[ "$INSTALL_DIR" != ".opencode" ]] && [[ "$INSTALL_DIR" != *"/.opencode" ]]; then
-    # Global install detected → Transform paths
-else
-    # Local install detected → Keep original paths
-fi
-```
-
-### Transformation Command
-
-```bash
-sed -i.bak -e "s|@\.opencode/context/|@${expanded_path}/context/|g" \
-           -e "s|\.opencode/context|${expanded_path}/context|g" "$dest"
-rm -f "${dest}.bak"
-```
-
-**Explanation:**
-- `-i.bak` - Edit in-place, create backup
-- First pattern - Transform @ references
-- Second pattern - Transform shell command paths
-- `g` flag - Replace ALL occurrences
-- Remove backup file after transformation
-
----
-
-## Developer Guidelines
-
-### When Creating New Files
-
-**Always use the standard format:**
-
-```markdown
-# Good Examples ✅
-@.opencode/context/core/essential-patterns.md
-@.opencode/context/project/project-context.md
-@.opencode/context/security/auth.md
-
-# Bad Examples ❌
-@context/file.md
-@~/context/file.md
-@$CONTEXT_DIR/file.md
-../context/file.md
-```
-
-### When Referencing Context
-
-**In agents:**
-```markdown
-Load context from @.opencode/context/core/essential-patterns.md
-```
-
-**In commands:**
-```markdown
-Reference: @.opencode/context/project/project-context.md
-```
-
-**In context files:**
-```markdown
-See also: @.opencode/context/security/auth.md
-```
-
-**In shell commands:**
-```markdown
-!`ls .opencode/context/`
-!`find .opencode/context -name "*.md"`
-```
-
----
-
-## Validation
-
-### Pre-Commit Validation
-
-The repository includes a validation script:
-
-```bash
-./scripts/validation/validate-context-refs.sh
-```
-
-This checks all markdown files for:
-- ✅ Correct `@.opencode/context/` format
-- ❌ Forbidden dynamic variables (`@$VAR/`)
-- ❌ Non-standard references
-
-### Manual Validation
-
-Check a file manually:
-
-```bash
-# Should only find @.opencode/context/ references
-grep -E '@[^~$]' file.md | grep -v '@.opencode/context/'
-
-# Should return nothing (empty result = good)
-```
-
----
-
-## Examples
-
-### Example 1: Agent File
-
-**File:** `.opencode/agent/core/openagent.md`
-
-```markdown
-# OpenAgent
-
-<context>
-Load essential patterns from @.opencode/context/core/essential-patterns.md
-Load project context from @.opencode/context/project/project-context.md
-</context>
-
-## Workflow
-1. Analyze request
-2. Check patterns in @.opencode/context/core/essential-patterns.md
-3. Execute task
-```
-
-**After global install to ~/.config/opencode:**
-```markdown
-# OpenAgent
-
-<context>
-Load essential patterns from @/Users/username/.config/opencode/context/core/essential-patterns.md
-Load project context from @/Users/username/.config/opencode/context/project/project-context.md
-</context>
-
-## Workflow
-1. Analyze request
-2. Check patterns in @/Users/username/.config/opencode/context/core/essential-patterns.md
-3. Execute task
-```
-
----
-
-### Example 2: Command File
-
-**File:** `.opencode/command/commit.md`
-
-```markdown
-# Commit Command
-
-Reference patterns from @.opencode/context/core/essential-patterns.md
-
-Check .opencode/context/project/project-context.md for commit conventions.
-```
-
-**After global install to /usr/local/opencode:**
-```markdown
-# Commit Command
-
-Reference patterns from @/usr/local/opencode/context/core/essential-patterns.md
-
-Check /usr/local/opencode/context/project/project-context.md for commit conventions.
-```
-
----
-
-## Summary
-
-### The Rule
-
-**All context references MUST use:**
-```markdown
-@.opencode/context/path/to/file.md
-```
-
-### Why
-
-- ✅ Works for local installations
-- ✅ Works for global installations
-- ✅ Works for custom installation paths
-- ✅ Automatically transformed during installation
-- ✅ Tested and validated
-- ✅ Consistent across all files
-
-### Enforcement
-
-- Pre-commit validation script
-- Installation system validation
-- Code review guidelines
-- This documentation
-
----
-
-## Related Documentation
-
-- [Installation Flow Analysis](../../INSTALLATION_FLOW_ANALYSIS.md)
-- [Test Report](../../TEST_REPORT.md)
-- [Final Review](../../FINAL_REVIEW.md)
-
----
-
-**Last Updated:** 2024-11-19  
-**Status:** Required Convention  
-**Validation:** Automated via `scripts/validation/validate-context-refs.sh`

+ 1 - 1
docs/architecture/canonical-refactor/00-INDEX.md

@@ -261,7 +261,7 @@ against the corpus, and the authored order only makes sense under last-match), b
 **primary verification against OpenCode's actual resolver is still REQUIRED before Stage 1.**
 
 **In-repo sources (self-authored — corroborating, not probative):**
-- `docs/planning/12-MASTER-SYNTHESIS.md:432` — *"The `permission:` field uses **last-match-wins**
+- `docs/archive/planning/12-MASTER-SYNTHESIS.md:432` — *"The `permission:` field uses **last-match-wins**
   evaluation (same as OpenCode's native system)"*
 - `.opencode/context/openagents-repo/standards/permission-patterns.md:11` — *"OpenCode v1.1.1+
   uses `permission:` … Rules follow **last-matching-wins** evaluation order."*

+ 2 - 2
docs/architecture/canonical-refactor/03-adapter-specs.md

@@ -125,7 +125,7 @@ report task status. That is precisely the breakage the index cites as Option A's
 
 Under **last-match-wins**, both files behave exactly as authored and intended.
 
-The repo's own planning doc agrees — `docs/planning/12-MASTER-SYNTHESIS.md:442`:
+The repo's own planning doc agrees — `docs/archive/planning/12-MASTER-SYNTHESIS.md:442`:
 
 > "The `permission:` field uses **last-match-wins** evaluation (same as OpenCode's native
 > system) … Rules are evaluated in order; the LAST matching rule wins. This matches OpenCode's
@@ -834,7 +834,7 @@ the current file**.
 ## Open Questions
 
 1. **Q1 — first-match-wins vs last-match-wins (BLOCKING; §0.5).** The locked shape says
-   first-match-wins; all 34 authored agents and `docs/planning/12-MASTER-SYNTHESIS.md:442`
+   first-match-wins; all 34 authored agents and `docs/archive/planning/12-MASTER-SYNTHESIS.md:442`
    say last-match-wins, and first-match-wins would silently break `coder-agent`'s `router.sh`
    allowlist and neuter `openagent`'s `sudo *: deny`. The index's own `coder-agent` example is
    broken as printed under first-match-wins. **Recommend adopting last-match-wins.** This

+ 2 - 2
docs/architecture/canonical-refactor/06-REVIEW.md

@@ -117,7 +117,7 @@ the claim of independence does not hold.**
 
 | Cited source | Verified? | What it actually is |
 |---|---|---|
-| `docs/planning/12-MASTER-SYNTHESIS.md:432` | ✅ text at :432 | **This project's own planning doc**, describing a *different, rejected* format |
+| `docs/archive/planning/12-MASTER-SYNTHESIS.md:432` | ✅ text at :432 | **This project's own planning doc**, describing a *different, rejected* format |
 | `.opencode/context/openagents-repo/standards/permission-patterns.md:11` | ✅ verbatim | **This project's own context file** |
 | `.opencode/context/openagents-repo/standards/agent-frontmatter.md:45` | ✅ verbatim | **This project's own context file** |
 
@@ -453,7 +453,7 @@ target at all.
 
 ### C10 🟡 `03`'s citation drift
 
-`03:129` cites `docs/planning/12-MASTER-SYNTHESIS.md:442`; the index cites `:432`; `:432` is
+`03:129` cites `docs/archive/planning/12-MASTER-SYNTHESIS.md:442`; the index cites `:432`; `:432` is
 correct (verified). Minor on its own, but it is the same quote used to close the most important
 question in the set (F3), and two of the docs citing it disagree on where it is.
 

+ 6 - 1
docs/planning/00-INDEX.md → docs/archive/planning/00-INDEX.md

@@ -1,7 +1,12 @@
 # OAC Package Refactor - Planning Index
 
+> **ARCHIVED (2026-07-15):** These planning documents are historical proposals from the
+> February 2026 package-refactor planning phase. They are superseded by the canonical
+> refactor spec set in `docs/architecture/canonical-refactor/` and are kept for reference
+> only. Do not treat anything here as current direction.
+
 **Date**: 2026-02-14  
-**Status**: Comprehensive Planning Phase  
+**Status**: Archived — superseded by `docs/architecture/canonical-refactor/`  
 **Branch**: `feature/oac-package-refactor`  
 **Issue**: #206
 

+ 0 - 0
docs/planning/01-main-plan.md → docs/archive/planning/01-main-plan.md


+ 0 - 0
docs/planning/02-quickstart-guide.md → docs/archive/planning/02-quickstart-guide.md


+ 0 - 0
docs/planning/03-critical-feedback.md → docs/archive/planning/03-critical-feedback.md


+ 0 - 0
docs/planning/04-solo-developer-scenarios.md → docs/archive/planning/04-solo-developer-scenarios.md


+ 0 - 0
docs/planning/05-team-lead-scenarios.md → docs/archive/planning/05-team-lead-scenarios.md


+ 0 - 0
docs/planning/07-content-creator-scenarios.md → docs/archive/planning/07-content-creator-scenarios.md


+ 0 - 0
docs/planning/08-open-source-maintainer-scenarios.md → docs/archive/planning/08-open-source-maintainer-scenarios.md


+ 0 - 0
docs/planning/09-SYNTHESIS.md → docs/archive/planning/09-SYNTHESIS.md


+ 0 - 0
docs/planning/10-FINAL-REVIEW.md → docs/archive/planning/10-FINAL-REVIEW.md


+ 0 - 0
docs/planning/11-json-config-system-SUMMARY.md → docs/archive/planning/11-json-config-system-SUMMARY.md


+ 0 - 0
docs/planning/11-json-config-system.md → docs/archive/planning/11-json-config-system.md


+ 0 - 0
docs/planning/12-MASTER-SYNTHESIS.md → docs/archive/planning/12-MASTER-SYNTHESIS.md


+ 0 - 0
docs/planning/13-PROJECT-BREAKDOWN.md → docs/archive/planning/13-PROJECT-BREAKDOWN.md


+ 0 - 0
docs/planning/14-PROVIDER-PATTERN-FINAL.md → docs/archive/planning/14-PROVIDER-PATTERN-FINAL.md


+ 0 - 0
docs/planning/mvp/00-MVP-PLAN.md → docs/archive/planning/mvp/00-MVP-PLAN.md


+ 1 - 1
docs/maintenance/REPOSITORY_MANAGEMENT_PLAN.md

@@ -230,4 +230,4 @@ Until formal ADRs are adopted, use:
 3. Package-level READMEs for implemented package behavior.
 4. Current repository standards and context.
 5. Contributor guides and historical audits.
-6. `docs/planning/` as proposals only.
+6. `docs/archive/planning/` as archived historical proposals only.

+ 1 - 1
plugins/claude-code/README.md

@@ -486,7 +486,7 @@ Create `hooks/hooks.json`:
 
 - [Main Documentation](../.opencode/docs/)
 - [Context System](../docs/context-system/)
-- [Planning Documents](../docs/planning/)
+- [Planning Documents (archived)](../docs/archive/planning/)
 
 ## 🤝 Contributing