跳到主要内容
    ↑↓ 选择↵ 打开esc 关闭
    Bandonker

    Code Review

    @bandonker/opencode-code-review·v1.2.1·模型接入

    Review source files and diffs for security vulnerabilities, code smells, and type safety issues. Stores review history in a local SQLite FTS5 database with full-text search.

    GitHub 星标

    0

    月装机量

    0

    综合评分

    20.0

    生态多维模型

    最近提交

    7 天前

    2026-10-13

    快速安装与配置

    opencode.json

    写入当前项目的 opencode.json,只对这个仓库生效。

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["@bandonker/opencode-code-review@1.2.1"]
    }

    OpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。

    open-toolbox — 19 local plugins for opencode Desktop v2

    19 local plugins that turn opencode Desktop v2 into a serious daily driver.

    ci npm — 19 packages license: MIT opencode plugin v2 PRs welcome

    One npm install gives your sessions a memory, a plan, a flight recorder, and a seatbelt: durable decisions, errors and long-term memory; agent orchestration with real file locks; a plan mode that executes itself; context pruning that keeps prompts lean; secret redaction for everything outbound; and a local dashboard of what it all cost. Everything runs in-process, stores to local SQLite, and calls no external service.


    Contents


    Highlights

    Four workflows that show what the pack does best:

    1. Multi-agent orchestration

    Spawn child sessions, hand off work, and keep agents from colliding:

    You: "Refactor the auth module — spawn a reviewer when done"
    → Agent spawns a child session via spawn_session
    → Child completes, parent receives result
    → /handoff migrates the working point to a fresh session
    

    Key tools: spawn_session, session_wait, session_send, session_handoff, session_permission, session_cancel

    Or let the pack run the orchestrations for you: /plan walks a task through a real planning phase — research, clarifying questions, a phased plan with risks and success criteria — then executes it by spawning one child session per step (free models first). /deep-research fans a topic across parallel research child sessions, iterates on the gaps they report, and consolidates the findings into one report.

    2. Durable knowledge

    Build a searchable memory of decisions, errors, snippets, and code:

    /decide     → Record an architectural decision with context
    /journal    → Log a bug with full context for later search
    /recall     → Search decisions, errors, snippets, and indexed code
    /memory     → Store long-term project knowledge in local SQLite
    

    All stored locally in SQLite FTS5 — no cloud, no embedding API.

    3. Context optimization

    Keep prompts lean without losing information:

    • context-pruner trims stale tool output from requests (transcript untouched)
    • strip-skills-catalog removes the skills catalog from the system prompt
    • compress tool summarizes old tool output on demand

    4. Security and reliability

    • secret-shield scrubs secrets from outbound HTTP, prompts, and tool args
    • finish-guard fixes SSE streams that send content after finish_reason
    • tool-audit records every tool call with redaction for debugging
    • code-review reviews files, diffs, and whole projects — then optionally spawns fixer agents for what it finds

    Getting started

    Requires opencode v2.

    Quick start

    Install the pack from npm — no clone, no build:

    CFG="$HOME/.config/opencode"
    mkdir -p "$CFG/toolbox" && cd "$CFG/toolbox"
    npm init -y >/dev/null 2>&1
    npm install \
      @bandonker/opencode-code-review \
      @bandonker/opencode-codebase-index \
      @bandonker/opencode-command-pack \
      @bandonker/opencode-context-pruner \
      @bandonker/opencode-decision-log \
      @bandonker/opencode-deep-research \
      @bandonker/opencode-error-journal \
      @bandonker/opencode-finish-guard \
      @bandonker/opencode-goal \
      @bandonker/opencode-loop-guard \
      @bandonker/opencode-memory \
      @bandonker/opencode-plan \
      @bandonker/opencode-secret-shield \
      @bandonker/opencode-session-export \
      @bandonker/opencode-sessions \
      @bandonker/opencode-snippet-library \
      @bandonker/opencode-strip-skills-catalog \
      @bandonker/opencode-tool-audit \
      @bandonker/opencode-usage-stats
    

    Register the packages in the global config. This merges into an existing opencode.jsonc rather than overwriting it:

    node -e '
    const fs=require("fs"),os=require("os"),path=require("path");
    const cfgDir=path.join(os.homedir(),".config/opencode");
    const scope=path.join(cfgDir,"toolbox","node_modules","@bandonker"), file=path.join(cfgDir,"opencode.jsonc");
    const raw=fs.existsSync(file)?fs.readFileSync(file,"utf8"):"{}";
    const cfg=JSON.parse(raw.replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,""));
    const mine=fs.readdirSync(scope).filter(n=>fs.existsSync(path.join(scope,n,"package.json"))).sort().map(n=>path.join(scope,n));
    cfg.plugins=[...(cfg.plugins??[]).filter(p=>typeof p!=="string"||!p.includes("@bandonker/opencode-")),...mine];
    fs.writeFileSync(file,JSON.stringify(cfg,null,2)+"\n");
    console.log("registered "+mine.length+" plugins -> "+file);
    '
    

    Then reload opencode (opencode reload, or restart the app).

    Install just one plugin
    CFG="$HOME/.config/opencode"
    mkdir -p "$CFG/toolbox" && cd "$CFG/toolbox"
    npm init -y >/dev/null 2>&1
    npm install @bandonker/opencode-memory
    

    Add "$CFG/toolbox/node_modules/@bandonker/opencode-memory" to the plugins array in opencode.jsonc and reload.

    Build from source
    git clone https://github.com/bandonker/open-toolbox.git
    cd open-toolbox
    npm install                  # build, link, install runtime deps, write opencode.jsonc
    

    That is the whole install. npm install runs prepare, which builds the packages, links them into $HOME/.config/opencode/toolbox/, installs the @opencode/plugin runtime there, applies the exports patch the v2 loader needs on Linux, and registers every plugin in opencode.jsonc. Nothing is hardcoded: the repo location comes from the clone, the toolbox from $HOME.

    It is safe to run repeatedly — a second npm install on an already-set-up machine changes nothing. If it ever needs re-doing by hand:

    npm run setup                # the same, without reinstalling dependencies
    npm run deploy:check         # report toolbox drift, change nothing
    

    Register with the same node -e snippet above, then reload.

    Windows / PowerShell

    Run the install snippet in PowerShell (with $CFG = "$HOME\.config\opencode"), or in WSL/Git Bash unchanged. The registration snippet uses os.homedir() and path.join() so it is platform-neutral. Backslashed paths in JSON must be escaped (C:\\path\\to); the snippet emits forward slashes, which opencode accepts on Windows.

    Project-local install

    Same packages, but under <repo>/.opencode/toolbox/ instead of $HOME/.config/opencode/toolbox/, registered in the project opencode.jsonc:

    mkdir -p .opencode/toolbox && cd .opencode/toolbox
    npm init -y >/dev/null 2>&1
    npm install @bandonker/opencode-sessions @bandonker/opencode-memory
    

    Verify

    From the repo root — no opencode server needed:

    npm install --no-audit --no-fund
    npm test          # helper unit tests + mock-context checks
    npm run typecheck # tsc --noEmit over plugins/ and lib/
    

    The same two commands run on every push in CI.

    Layout

    After npm run setup (which npm install runs automatically):

    ~/.config/opencode/        # or <repo>/.opencode/
     ├── opencode.jsonc         # "plugins" array pointing at toolbox/*/
     └── toolbox/               # one directory per plugin
         ├── package.json       # shared dependency manifest
         ├── node_modules/      # one install, shared by all 19
         ├── opencode-sessions/ # index.js + helpers.js
         │   └── node_modules -> ../node_modules
         ├── memory/
         │   ├── package.json
         │   ├── index.js
         │   ├── lib/sqlite.js
         │   └── node_modules -> ../node_modules
         ├── context-pruner/
         ├── secret-shield/
         └── … 19 in total
    
    Why a directory per plugin, not loose files?
    1. Resolution. opencode v2 auto-discovers loose .ts files under plugins/, but does not resolve bare npm specifiers from the config directory. A plugin that does import { Plugin } from "@opencode/plugin" fails with Cannot find package '@opencode/plugin'.
    2. The loader treats every export as a plugin factory. A stray helper export in plugins/ fails with prompt.split is not a function and cascades into config/provider errors.
    Why does every package need its own node_modules symlink?

    Resolution is anchored at the package directory, not hoisted to the config root. A single npm install in toolbox/ populates the shared copy; the per-package symlink makes it reachable from each plugin. Same layout pnpm uses.


    Plugins

    19 plugins grouped by category. Click any name to jump to its expandable documentation.

    Orchestration

    Plugin Tools Description
    opencode-sessions 9 Spawn child sessions, wait for results, send follow-ups, answer permission prompts, cancel — and hand off the current working point into a fresh session. Adds targeted project presence and file-collision warnings.
    goal 3 Set an objective and keep working until it is reached. Auto-continues turns, re-injects the goal into every request, and stops on completion, block, interrupt, stall, or budget exhaustion.
    plan 37 /plan runs a full planning phase — research, questions, a phased plan with risks, criteria and estimates — then executes it with one child session per step. Tracks progress, checkpoints and rollbacks per project.
    deep-research 6 /deep-research fans a topic across parallel research child sessions, iterates on the gaps the agents report, and consolidates deduplicated, conflict-flagged findings into one report.
    command-pack — Registers 7 slash commands so the pack is one keystroke away (see Commands).

    Data / Storage

    Plugin Tools Description
    decision-log 5 Record and search architectural decisions in a local SQLite FTS5 database.
    error-journal 5 Log errors with context, search past ones, and record resolutions.
    snippet-library 5 Save reusable code snippets and search by language, tag, or full text.
    codebase-index 4 Index a codebase directory and run BM25-ranked full-text search.
    tool-audit 3 Flight recorder for every tool call — args, status, duration, error — with secret redaction.
    session-export 2 Dump a session transcript to markdown / json / jsonl / text with filters and redaction.
    memory 5 Local-first long-term memory in SQLite FTS5. Auto-injects relevant memories into each request.
    usage-stats 5 Lifetime token / dollar / tool accounting in local SQLite with an HTML dashboard.

    Context

    Plugin Tools Description
    context-pruner 1 Token-accurate context compiler: trims stale tool output from requests only, plans once per epoch for cache stability, dedupes, and can proactively summarise.
    strip-skills-catalog — Strips the <available_skills> catalog from the system prompt to save tokens. The skill tool still works on demand.

    Quality

    Plugin Tools Description
    secret-shield 4 v2-native secret detector and redactor for outbound HTTP, prompts, tool args/results, and child-process env.
    finish-guard — Normalises OpenAI-compatible SSE streams so content after finish_reason cannot abort the turn.
    loop-guard — Always-on doom-loop breaker: nudges the model after a run of identical tool calls or replies, then cancels the turn.
    code-review 11 Reviews files, diffs and whole projects for security issues, smells and type problems — with an LLM fallback pass, fixer subagents, and trend tracking in local SQLite FTS5.

    All SQLite-backed plugins use bun:sqlite when available and fall back to node:sqlite. Databases land in ~/.opencode-plugins/.


    Plugin details

    Zero config is required: everything loads with defaults. Each knob is read from the plugin options object (npm installs) or its env var (always works), when the plugin loads — restart opencode after changing values:

    {
      "plugins": [
        "@bandonker/opencode-context-pruner",
        { "package": "@bandonker/opencode-tool-audit", "options": { "retentionDays": 90 } },
        { "package": "-some-plugin" }
      ]
    }
    

    Local .ts plugins take no options. The loader rejects a bare file path with configured plugin path must be a directory, and files in plugins/ load with defaults — that is why every knob below has an env var.


    Orchestration

    opencode-sessions — session orchestration and handoff

    Spawn child sessions, wait for their results, send follow-ups, answer permission prompts, cancel them, and hand off the current working point into a fresh session. Created sessions are real opencode sessions and appear in the Desktop session switcher.

    Project presence: any session working in a repo can see the other sessions in that repo — including ones this plugin did not spawn — and can message them. Peers are discovered from the server-wide event stream and announced by each session on its first turn.

    The brief injected into each request is targeted, not a roster: a session is told about a peer only when that peer could affect its work — it holds a file this session is writing, it is in this session's lineage, it is mid-turn, or it declared overlapping work. When nothing is relevant, nothing is injected.

    With fileLocks: "enforce" two agents about to write the same file don't just get told to take turns — the write actually waits for the holder, and fails loudly naming who has it if the wait runs out. A peer that has gone quiet is verified with session.get rather than assumed dead.

    Tools: 9. See the opencode-sessions package documentation for the complete tool list and configuration knobs.

    goal — persistent autonomous goal loops

    Start an objective with /goal <objective> and optional success criteria. The goal is re-injected into requests and the model is automatically continued when a turn ends, until goal_complete, goal_blocked, an interrupt, a stall, repeated failures, or the iteration/time budget stops it.

    Goal state is persisted per session, so it survives plugin reloads and long turns. Tools: goal_complete, goal_blocked, goal_progress.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_GOAL_ENABLED true Turn the goal loop off without uninstalling
    maxIterations OPENCODE_GOAL_MAX_ITERATIONS 30 Max continuation turns per goal
    maxMinutes OPENCODE_GOAL_MAX_MINUTES 180 Wall-clock budget per goal (minutes)
    stallLimit OPENCODE_GOAL_STALL_LIMIT 3 Turns with no tool use and an unchanged reply before stopping as stalled
    maxFailures OPENCODE_GOAL_MAX_FAILURES 3 Consecutive execution errors before stopping
    requireEvidence OPENCODE_GOAL_REQUIRE_EVIDENCE true Require evidence in goal_complete
    maxInjectChars OPENCODE_GOAL_MAX_INJECT_CHARS 1600 Character cap on the injected goal reminder
    notify OPENCODE_GOAL_NOTIFY true Post loop start/stop notes into the session
    log OPENCODE_GOAL_LOG false Log loop activity to stderr

    The loop. /goal Ship the login fix stores the objective and starts a normal turn. Follow it with dash-prefixed lines to list success criteria. The objective is re-injected into every request, so it survives long turns and compaction; when a turn ends the plugin queues a continuation prompt carrying the objective and the remaining budget. It stops when the model calls goal_complete (which requires concrete evidence unless requireEvidence is off) or goal_blocked, when you interrupt a turn (the goal pauses rather than fighting you), when stallLimit turns run no tools and the reply is unchanged, after maxFailures consecutive execution errors, or when the iteration/time budget is exhausted. A paused or budget-stopped goal can be resumed with /goal resume.

    plan — a planning phase that executes as child sessions

    /plan <task> walks a task through a real planning phase: the agent researches the task, asks clarifying questions, and writes a phased plan annotated with risks, success criteria, time and cost estimates, and research notes. Execution then spawns one child session per step — free models first, paid as fallback — with parallel children capped and progress tracked per project; /plan status shows the live board.

    Plan state is tracked in-plugin per project and session and exposed to the model as 37 tools (plan plus 36 plan_* helpers), including plan_add_step, plan_add_risk, plan_add_criterion, plan_add_research, plan_progress, plan_checkpoint, plan_approve_phase, plan_rollback, plan_spawn_child, plan_metrics, plan_cost_optimize, plan_test_strategy, plan_time_estimate, plan_generate_docs — and plan_link_decision, plan_link_error, plan_link_snippet to tie the plan into the decision log, error journal, and snippet library.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_PLAN_ENABLED true Register the plugin, its tools and /plan
    maxParallelChildren OPENCODE_PLAN_MAX_PARALLEL_CHILDREN 3 Child sessions allowed to run at once (1–10)
    notify OPENCODE_PLAN_NOTIFY true Post plan notifications into the session
    log OPENCODE_PLAN_LOG false Log plan activity to stderr

    deep-research — autonomous multi-agent research

    /deep-research <topic> fans the topic out across a taxonomy of research angles as parallel child sessions (bounded by maxConcurrent), then iterates: it reads what the agents report, finds the gaps, and dispatches follow-up questions with deep_research_deliberate, recording the agents' answers with deep_research_answer. deep_research_consolidate merges the findings and the deliberation Q&A into one deduplicated, conflict-flagged report.md inside the topic folder; deep_research_runs lists past runs and their report paths. History lives in local SQLite.

    Tools: deep_research, deep_research_deliberate, deep_research_answer, deep_research_consolidate, deep_research_write_report, deep_research_runs.

    Options
    Option Env var Default Meaning
    — OPENCODE_DEEP_RESEARCH_ENABLED true Turn deep research off without uninstalling (0 disables)
    dir OPENCODE_DEEP_RESEARCH_DIR ~/.opencode-plugins/deep-research Where the SQLite history and reports are written
    maxConcurrent OPENCODE_DEEP_RESEARCH_CONCURRENCY 4 Research agents running at once (1–8)
    model OPENCODE_DEEP_RESEARCH_MODEL — Pin research agents to providerID/modelID

    command-pack — slash commands for the toolbox

    Registers slash commands for the most common toolbox actions: /handoff, /decide, /journal, /recall, /index, /trace, /toolbox, and /stats.

    See Commands for the full list. Commands inject short instructions into the current session and use the corresponding toolbox tools.


    Data / Storage

    decision-log — durable architecture decisions

    Record architectural decisions with context and consequences, then search and update them from a local SQLite FTS5 database.

    Tools: decision_log, decision_search, decision_list, decision_get, decision_update.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_DECISION_LOG_ENABLED true Turn the plugin off without uninstalling
    dir OPENCODE_DECISION_LOG_DIR ~/.opencode-plugins/decision-log Where the SQLite DB lives
    log OPENCODE_DECISION_LOG_LOG false Log activity to stderr

    error-journal — searchable debugging history

    Log errors with context, search previous failures, and record resolutions so recurring problems do not have to be debugged from scratch.

    Tools: error_log, error_search, error_list, error_resolve, error_delete.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_ERROR_JOURNAL_ENABLED true Turn the plugin off without uninstalling
    dir OPENCODE_ERROR_JOURNAL_DIR ~/.opencode-plugins/error-journal Where the SQLite DB lives
    log OPENCODE_ERROR_JOURNAL_LOG false Log activity to stderr

    snippet-library — reusable code snippets

    Save reusable code snippets locally and search them by language, tags, or full text. Everything is stored locally in SQLite with full-text search.

    Tools: snippet_save, snippet_get, snippet_list, snippet_search, snippet_delete.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_SNIPPET_LIBRARY_ENABLED true Turn the plugin off without uninstalling
    dir OPENCODE_SNIPPET_LIBRARY_DIR ~/.opencode-plugins/snippet-library Where the SQLite DB lives
    log OPENCODE_SNIPPET_LIBRARY_LOG false Log activity to stderr

    codebase-index — local codebase search

    Index a codebase directory and run BM25-ranked full-text search over it. The index is local and can be refreshed incrementally as the project changes.

    Tools: codebase_index, codebase_search, codebase_index_status, codebase_delete_index.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_CODEBASE_INDEX_ENABLED true Turn the plugin off without uninstalling
    dir OPENCODE_CODEBASE_INDEX_DIR ~/.opencode-plugins/codebase-index Where the SQLite index lives
    log OPENCODE_CODEBASE_INDEX_LOG false Log activity to stderr

    tool-audit — local tool-call flight recorder

    Record every tool call with its tool name, arguments, status, duration, and error. Secrets in arguments are redacted before they touch disk.

    Tools: trace_query, trace_stats, trace_export.

    Options
    Option Env var Default Meaning
    dir OPENCODE_TOOL_AUDIT_DIR ~/.opencode-plugins/tool-audit Where the SQLite DB lives
    enabled OPENCODE_TOOL_AUDIT_ENABLED true Turn recording off without uninstalling
    redact OPENCODE_TOOL_AUDIT_REDACT true Scrub secrets from arguments before writing
    maxInputChars OPENCODE_TOOL_AUDIT_MAX_INPUT_CHARS 2000 Per-call argument cap
    retentionDays OPENCODE_TOOL_AUDIT_RETENTION_DAYS 30 Prune rows older than this (0 = keep forever)
    ignoreTools OPENCODE_TOOL_AUDIT_IGNORE todowrite + its own tools Comma-separated tools to skip

    session-export — transcript exports

    Export session transcripts to Markdown, JSON, JSONL, or text with a model and usage header. Exports support role and tool filters, optional reasoning, per-part truncation, secret redaction, and safe non-overwriting filenames.

    session_export writes a file or returns the export inline; session_export_info reports the current configuration and last export.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_SESSION_EXPORT_ENABLED true Disable exporting without uninstalling
    dir OPENCODE_SESSION_EXPORT_DIR <cwd>/.opencode-exports Default output directory
    format OPENCODE_SESSION_EXPORT_FORMAT markdown markdown | json | jsonl | text
    includeReasoning OPENCODE_SESSION_EXPORT_INCLUDE_REASONING false Include assistant reasoning parts
    includeToolResults OPENCODE_SESSION_EXPORT_INCLUDE_TOOL_RESULTS true Include tool results/errors
    maxCharsPerPart OPENCODE_SESSION_EXPORT_MAX_PART_CHARS 4000 Truncate each part to this many chars
    redact OPENCODE_SESSION_EXPORT_REDACT true Scrub secrets; rewrite home paths to ~

    memory — local-first long-term memory

    Store and recall durable local memories without an embedding API, cloud service, or network request. Relevant memories are injected into each request within a character budget and deduplicated per session.

    Tools: memory_remember, memory_recall, memory_forget, memory_list, memory_stats. The database lives at ~/.opencode-plugins/memory/memory.db.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_MEMORY_ENABLED true Turn the plugin off without uninstalling
    autoRecall OPENCODE_MEMORY_AUTO_RECALL true Inject relevant memories into each request
    budgetChars OPENCODE_MEMORY_BUDGET_CHARS 1200 Hard character budget per injection
    topK OPENCODE_MEMORY_TOP_K 5 Max memories per recall/injection
    minScore OPENCODE_MEMORY_MIN_SCORE 0 Minimum BM25 score (0 = any FTS hit)
    scope OPENCODE_MEMORY_SCOPE project Default scope: global | project | session
    maxEntries OPENCODE_MEMORY_MAX_ENTRIES 0 Prune least-important rows beyond this (0 = unlimited)
    log OPENCODE_MEMORY_LOG false Log activity to stderr

    usage-stats — lifetime usage dashboard

    Track lifetime tokens, cost, tool calls, model usage, and background title or compaction spend in local SQLite. Use stats_summary, stats_tools, stats_tokens, stats_heatmap, or /stats for the data, and stats_dashboard to write a self-contained HTML dashboard.

    The dashboard includes an activity heatmap, a 30-day token chart, tool and model tables, exact hover breakdowns, searchable multi-select model filtering, responsive layout, and automatic refresh without spending model tokens.

    Options
    Option Env var Default Meaning
    dir OPENCODE_USAGE_STATS_DIR ~/.opencode-plugins/usage-stats Where the SQLite DB and dashboard live
    enabled OPENCODE_USAGE_STATS_ENABLED true Turn recording off without uninstalling
    retentionDays OPENCODE_USAGE_STATS_RETENTION_DAYS 0 Prune daily rollups older than this (0 = keep forever)
    heatmapMetric OPENCODE_USAGE_STATS_HEATMAP_METRIC tokens Heatmap metric (tokens | cost | calls)
    heatmapWeeks OPENCODE_USAGE_STATS_HEATMAP_WEEKS 26 Heatmap width in weeks
    includeBackground OPENCODE_USAGE_STATS_INCLUDE_BACKGROUND true Include title/compaction spend in charts
    autoRefreshSec OPENCODE_USAGE_STATS_AUTO_REFRESH 20 Regenerate the dashboard this often (s) when data changed; 0 disables
    pricingRefreshMin OPENCODE_USAGE_STATS_PRICING_REFRESH_MIN 10 Re-fetch model price lists this often (min); 0 disables
    prices OPENCODE_USAGE_STATS_PRICES (none) JSON rate overrides keyed providerID/modelID
    openOnStart OPENCODE_USAGE_STATS_OPEN false Open the dashboard in your browser when opencode starts
    log OPENCODE_USAGE_STATS_LOG false Log plugin activity to stderr
    Dashboard screenshots

    Usage-stats dashboard overview

    Usage-stats dashboard with a populated activity chart

    Usage-stats dashboard details

    Cost is computed from the provider's real price list. The plugin reads each model's published per-million-token rates via ctx.model.list() and shows both reported (what opencode billed) and list price (API-equivalent) — so free models show $0.00, unpriced ones show — (never a fake zero), and flat-rate subscriptions still show what the usage was worth. Local models have no published price; give them one with prices, e.g. OPENCODE_USAGE_STATS_PRICES={"lmstudio/qwen3-coder":{"input":0,"output":0,"cache":{"read":0,"write":0}}}.

    The plugin API has no way to add a Settings tab, so /stats opens the dashboard for you directly from the server process — it never calls the model. Set OPENCODE_USAGE_STATS_OPEN=true to open it automatically at startup, or OPENCODE_USAGE_STATS_NO_OPEN=1 to suppress browser launches (headless).

    Note: https://opencode.ai/config.json describes the TUI's settings, not the server config. The server validates a plugins (plural) array — that is the key the runtime reads, confirmed in the server log when the config is reloaded.


    Context

    context-pruner — token-accurate context compiler

    Trims stale tool output from the outgoing request only. The session transcript on disk is unchanged, and pruned tool output can be recalled or re-run. The planner preserves a stable prompt-cache prefix, removes superseded output, and can proactively summarise stale context before the model window fills.

    Use context_pruner_stats to inspect savings, context_report to inspect the active budget and epoch, and context_pruner_recall to retrieve pruned output without re-running the original tool.

    How it works

    context-pruner is a context compiler: it trims stale tool output from the outgoing request only. The session transcript on disk is unchanged, and a pruned tool can simply be re-run.

    It measures tokens (calibrated against provider usage), plans prune changes once per epoch, and reuses those decisions verbatim so the prompt-cache prefix stays stable between replans. By default it also keeps the outgoing request near a steady ceiling well below the model window (steadyTargetRatio, default 0.06), so stale closed topics are summarised before the window ever fills; set proactiveSummarize: false or steadyTargetRatio: 0 for window-only behaviour. Without a resolvable window it falls back to the positional rules below.

    On top of that it removes output that is provably superseded (a newer read or write of the same file), and over the target it summarises the largest stale units — tool output and, since prose is on by default, assistant/user text — with the session model automatically, so savings land even when the model ignores nudges. It reads optional config from .opencode/context-pruner.jsonc (project) then ~/.config/opencode/context-pruner.jsonc (global), and can also read a DCP dcp.jsonc for migration.

    Session-scoped state and the digests a session produced are reclaimed when the host reports session.deleted, with a startup sweep covering sessions deleted while opencode was closed. The non-session digest/calibration caches are capped by count (storageGc).

    Options

    Full reference: See the options table below — 50+ options organised by category.

    Option Env var Default Meaning
    enabled OPENCODE_CONTEXT_PRUNER_ENABLED true Turn pruning off without uninstalling
    keepRecent OPENCODE_CONTEXT_PRUNER_KEEP_RECENT 6 Most-recent tool results to leave untouched
    minChars OPENCODE_CONTEXT_PRUNER_MIN_CHARS 2000 Only prune results longer than this
    keepHeadChars OPENCODE_CONTEXT_PRUNER_KEEP_HEAD 200 Characters of the result kept as a preview
    keepErrors OPENCODE_CONTEXT_PRUNER_KEEP_ERRORS true Never prune error results
    ignoreTools OPENCODE_CONTEXT_PRUNER_IGNORE context_pruner_stats Comma-separated tools to never prune
    log OPENCODE_CONTEXT_PRUNER_LOG false Log each prune to stderr
    budgetRatio OPENCODE_CONTEXT_PRUNER_BUDGET_RATIO 0.9 Fraction of the model window treated as input budget
    targetRatio OPENCODE_CONTEXT_PRUNER_TARGET_RATIO 0.85 Fraction of the budget to prune down to
    maxOutputReserve OPENCODE_CONTEXT_PRUNER_MAX_OUTPUT_RESERVE 8192 Tokens reserved for the model's output
    keepRecentTurns OPENCODE_CONTEXT_PRUNER_KEEP_RECENT_TURNS 2 Recent turns left untouched
    minReplanTokens OPENCODE_CONTEXT_PRUNER_MIN_REPLAN_TOKENS 2000 New tokens saved needed to justify a replan
    dedupe OPENCODE_CONTEXT_PRUNER_DEDUPE true Stub duplicate tool output
    purgeErrors OPENCODE_CONTEXT_PRUNER_PURGE_ERRORS true Stub stale errors (only when keepErrors is false)
    charsPerToken OPENCODE_CONTEXT_PRUNER_CHARS_PER_TOKEN 3.6 Seed estimator before calibration
    protectedTools OPENCODE_CONTEXT_PRUNER_PROTECTED_TOOLS task,skill,compress,context_report Tools never pruned
    protectedPatterns OPENCODE_CONTEXT_PRUNER_PROTECTED_PATTERNS (none) Regexes of tools never pruned
    notify OPENCODE_CONTEXT_PRUNER_NOTIFY true Receipt verbosity: off | minimal | detailed
    notifyType OPENCODE_CONTEXT_PRUNER_NOTIFY_TYPE toast chat posts the receipt inline; toast logs to stderr
    notifyMinTokens OPENCODE_CONTEXT_PRUNER_NOTIFY_MIN_TOKENS 500 Turn savings needed to trigger a receipt (0 = every prune)
    notifyOnTopic OPENCODE_CONTEXT_PRUNER_NOTIFY_ON_TOPIC true Also send a receipt when a summary is applied
    collapseRanges OPENCODE_CONTEXT_PRUNER_COLLAPSE true Collapse fully-pruned message spans
    collapseStubs OPENCODE_CONTEXT_PRUNER_COLLAPSE_STUBS true Also collapse spans that are only stubbed
    superseded OPENCODE_CONTEXT_PRUNER_SUPERSEDED true Prune output superseded by a newer read/write of the same file
    autoSummarize OPENCODE_CONTEXT_PRUNER_AUTO_COMPRESS true Summarise automatically when the token target is exceeded
    autoSummarizeMaxCalls OPENCODE_CONTEXT_PRUNER_AUTO_COMPRESS_MAX 0 Max automatic summariser calls per session (0 = unlimited)
    autoSummarizeMinTokens OPENCODE_CONTEXT_PRUNER_AUTO_COMPRESS_MIN 4000 Minimum tokens a range must hold to be auto-summarised
    maxAutoSummaries OPENCODE_CONTEXT_PRUNER_MAX_AUTO_SUMMARIES 12 Max stale units covered per proactive summary
    proactiveSummarize OPENCODE_CONTEXT_PRUNER_PROACTIVE true Keep the request near the steady ceiling even when the window is wide
    steadyTargetRatio OPENCODE_CONTEXT_PRUNER_STEADY_RATIO 0.06 Steady ceiling as a fraction of the window (0 disables)
    steadyTargetMinTokens OPENCODE_CONTEXT_PRUNER_STEADY_MIN 1500 Floor for the steady ceiling
    compressText OPENCODE_CONTEXT_PRUNER_COMPRESS_TEXT true Let the summariser cover assistant/user prose
    compactionCheckpoint OPENCODE_CONTEXT_PRUNER_COMPACTION true Replace native compaction with a deterministic checkpoint
    retryOnOverflow OPENCODE_CONTEXT_PRUNER_RETRY true Recover from context-limit errors by trimming harder and retrying
    titleShortCircuit OPENCODE_CONTEXT_PRUNER_TITLE false Skip model title generation using the first user line
    cacheAware OPENCODE_CONTEXT_PRUNER_CACHE_AWARE true Defer voluntary replans until the cache rewrite premium amortises
    cacheAmortize OPENCODE_CONTEXT_PRUNER_CACHE_AMORTIZE 4 Requests over which a cache rewrite must pay back
    recall OPENCODE_CONTEXT_PRUNER_RECALL true Keep pruned output locally so it can be recalled
    recallKeep OPENCODE_CONTEXT_PRUNER_RECALL_KEEP 50 Most pruned outputs kept per session
    recallMaxChars OPENCODE_CONTEXT_PRUNER_RECALL_MAX_CHARS 200000 Max characters returned by a single recall
    storageGc OPENCODE_CONTEXT_PRUNER_STORAGE_GC true Bound the non-session KV caches
    summaryCacheMax OPENCODE_CONTEXT_PRUNER_SUMMARY_CACHE_MAX 500 Max persisted digest-cache entries (0 = unlimited)
    calibrationMax OPENCODE_CONTEXT_PRUNER_CALIBRATION_MAX 256 Max persisted calibration entries (0 = unlimited)
    compressEnabled OPENCODE_CONTEXT_PRUNER_COMPRESS true Enable the model-callable compress tool
    compressMaxSourceChars OPENCODE_CONTEXT_PRUNER_COMPRESS_MAX_CHARS 24000 Max characters sent to the summariser per call
    protectTags OPENCODE_CONTEXT_PRUNER_PROTECT_TAGS true Preserve <protect> blocks during summarisation
    protectUserMessages OPENCODE_CONTEXT_PRUNER_PROTECT_USER false Never summarise user messages
    summaryBuffer OPENCODE_CONTEXT_PRUNER_SUMMARY_BUFFER true Let summary tokens extend the effective budget
    minContextLimit OPENCODE_CONTEXT_PRUNER_MIN_CONTEXT_LIMIT (none) Token count or percent at which nudges start
    maxContextLimit OPENCODE_CONTEXT_PRUNER_MAX_CONTEXT_LIMIT (none) Token count or percent treated as the hard window
    nudgeEnabled OPENCODE_CONTEXT_PRUNER_NUDGE true Tell the model to compress when context grows
    nudgeFrequency OPENCODE_CONTEXT_PRUNER_NUDGE_FREQUENCY 5 Requests between nudges
    nudgeForce OPENCODE_CONTEXT_PRUNER_NUDGE_FORCE soft soft or strong nudge wording
    iterationNudgeThreshold OPENCODE_CONTEXT_PRUNER_ITERATION_NUDGE 15 Tool results after which a nudge is sent
    protectedFilePatterns OPENCODE_CONTEXT_PRUNER_PROTECTED_FILES (none) Globs of file paths never pruned
    debug OPENCODE_CONTEXT_PRUNER_DEBUG false Write a debug log under ~/.config/opencode/logs/context-pruner

    strip-skills-catalog — smaller system prompts

    Strips the <available_skills> catalog from the system prompt to save tokens. The skill tool remains available on demand, so agents can still load a skill when they need it.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_STRIP_SKILLS_ENABLED true Turn stripping off without uninstalling

    Quality

    secret-shield — secret detection and redaction

    Detect and redact secrets across outbound HTTP bodies, prompts, tool arguments and results, and child-process environments. Choose observe, redact, or block mode, with high-precision rules, entropy fallback detection, allowlists, and a hashed JSONL audit that never stores the secret value.

    Tools: secret_shield_scan, secret_shield_stats, secret_shield_shape, secret_shield_keys.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_SECRET_SHIELD_ENABLED true Turn the shield off without uninstalling
    mode OPENCODE_SECRET_SHIELD_MODE observe observe (audit only) | redact | block
    entropy OPENCODE_SECRET_SHIELD_ENTROPY true Shannon-entropy fallback for unlabelled tokens
    allow OPENCODE_SECRET_SHIELD_ALLOW (none) Comma-separated literals, /regex/, globs or rule ids
    blockEnvReads OPENCODE_SECRET_SHIELD_BLOCK_ENV_READS true In block mode, deny protected secret-file reads
    log OPENCODE_SECRET_SHIELD_LOG false Emit diagnostics to stderr

    finish-guard — resilient SSE stream handling

    Normalise OpenAI-compatible SSE streams when a content, reasoning, or tool delta arrives after the provider's finish_reason chunk. This prevents AI.Error.InvalidProviderOutput: OpenAI Chat received content after the finish reason and the follow-on Failed to drain Session cascade for reasoning models behind strict gateways.

    A stream the gateway cuts mid-generation (content in hand, no finish reason) is deliberately left unterminated rather than closed with an invented finish_reason. A fabricated "stop" would mark the turn as a clean completion, hiding the cut and suppressing opencode's own recovery — an incomplete stream is a retryable error, so the turn is re-attempted and continued instead of silently keeping truncated text. Cuts are counted in finish_guard_stats (truncated) and the payloads immediately before the cut are dumped to the capture file.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_FINISH_GUARD_ENABLED true Turn stream normalisation off without uninstalling
    log OPENCODE_FINISH_GUARD_LOG false Log each normalised stream to stderr
    retry OPENCODE_FINISH_GUARD_RETRY true Ask opencode to retry the turn when a stream is malformed
    retryMax OPENCODE_FINISH_GUARD_RETRY_MAX 3 Maximum retry attempts before the turn is allowed to fail
    retryDelayBase OPENCODE_FINISH_GUARD_RETRY_DELAY_BASE 300 Initial retry delay in milliseconds
    retryDelayMax OPENCODE_FINISH_GUARD_RETRY_DELAY_MAX 2000 Maximum retry delay in milliseconds
    - OPENCODE_FINISH_GUARD_CAPTURE /tmp/opencode/finish-guard-toolcalls.jsonl Where truncated or undecodable provider streams are dumped for diagnosis

    Tools: finish_guard_test (run the SSE transform on a sample payload), finish_guard_stats (observed stream metrics — normalised, truncated, retries).

    loop-guard — always-on repetition breaker

    Weak or free models sometimes degenerate into repetition — the same tool call, or the same assistant reply, over and over — until the user aborts. The goal plugin has a stall detector, but it only runs while a /goal is active; an ordinary build/explore/general session has no guard.

    loop-guard watches every tool call and every outgoing request. It counts consecutive identical tool calls (tool name plus a stable stringification of the input, so key order does not matter) and consecutive identical assistant replies (text and reasoning plus any tool calls). Any different call or reply resets the run, so legitimate re-reads spread across a long session never trip it. At repeatLimit it injects a system nudge telling the model to change approach or conclude; if the run continues to cancelLimit it calls session.interrupt to cancel the turn.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_LOOP_GUARD_ENABLED true Turn the guard off without uninstalling
    repeatLimit OPENCODE_LOOP_GUARD_REPEAT_LIMIT 4 Consecutive identical calls/replies before nudging the model
    cancelLimit OPENCODE_LOOP_GUARD_CANCEL_LIMIT 8 Consecutive identical calls/replies before cancelling the turn
    notify OPENCODE_LOOP_GUARD_NOTIFY true Post a note into the session when the guard acts
    log OPENCODE_LOOP_GUARD_LOG false Log guard activity to stderr

    code-review — security and quality review, with fixer agents

    Reviews files, diffs, and whole projects for security vulnerabilities, code smells, and type-safety issues. A static pass runs first; when it finds fewer than llmFallbackThreshold findings, a free-LLM pass fills in the gaps. Reviews and custom rules live in a local SQLite FTS5 database, so history, search, per-category stats, and trend analysis accumulate over time.

    With enableAgentFixes on, findings are handed to fixer subagents (at most maxFixAgents at once); code_review_fix returns the suggested patch for one finding.

    Commands: /code-review file <path>, /code-review diff, /code-review project [path], /code-review fix-all [reviewId], /code-review deep [path], /deep-code-review [path].

    Tools (11): code_review_file, code_review_diff, code_review_project, code_review_history, code_review_get, code_review_search, code_review_stats, code_review_trends, code_review_fix, code_review_custom_rules, code_review_config.

    Options
    Option Env var Default Meaning
    enabled OPENCODE_CODE_REVIEW_ENABLED true Register the plugin and its tools
    enableLlmFallback OPENCODE_CODE_REVIEW_LLM_FALLBACK true Run a free-LLM pass when the static scan is sparse
    llmFallbackThreshold OPENCODE_CODE_REVIEW_LLM_FALLBACK_THRESHOLD 5 Findings below this trigger the LLM fallback
    enableAgentFixes OPENCODE_CODE_REVIEW_AGENT_FIXES true Hand findings to fixer subagents after a review
    enableAutoFix OPENCODE_CODE_REVIEW_ENABLE_AUTOFIX true Attach a suggested fix to each finding
    maxFixAgents OPENCODE_CODE_REVIEW_MAX_FIX_AGENTS 6 Fixer children allowed to run at once
    spawnMode OPENCODE_CODE_REVIEW_SPAWN_MODE agent agent = the reviewer spawns fixers; direct = the plugin does
    directReviewTimeoutSec OPENCODE_CODE_REVIEW_DIRECT_REVIEW_TIMEOUT_SEC 300 Seconds direct mode waits for its reviewer
    reviewModel / fixModel OPENCODE_CODE_REVIEW_REVIEW_MODEL / OPENCODE_CODE_REVIEW_FIX_MODEL — Pin the reviewer / fixer model as providerID/modelID
    deepReview OPENCODE_CODE_REVIEW_DEEP true Expose /deep-code-review and /code-review deep

    More knobs: per-category rule toggles (rules.security, rules.bugs, rules.style, rules.performance), focusAreas, severity and severityOverrides, includePatterns / excludePatterns, file and finding caps (maxFiles 50, maxFindingsPerFile 20), and the enableTrendAnalysis / enableConfidenceScoring toggles.


    Commands

    command-pack adds these to your command palette (usage-stats adds /stats, goal adds /goal, plan adds /plan, deep-research adds /deep-research, and code-review adds /code-review and /deep-code-review):

    Command Does
    /handoff Hand the current working point off to a fresh session
    /decide Record a decision in the decision log
    /journal Log a bug or recurring failure in the error journal
    /recall Search past decisions, errors, snippets and indexed code
    /index Index this project for full-text code search
    /trace Inspect the tool-call audit log
    /toolbox Show which pack tools are installed in this session
    /stats Refresh and open the usage dashboard — runs server-side, so it costs zero model tokens
    /goal Set an objective the agent keeps working toward until it is reached (/goal status, pause, resume, done, clear manage it)
    /plan Run a full planning phase — research, clarifying questions, a phased plan — then execute it with one child session per step
    /deep-research <topic> Fan a topic out across parallel research child sessions and consolidate the findings into one report
    /code-review file <path> | diff | project [path] Review a file, a diff, or a whole project — fix-all spawns fixer agents, deep escalates
    /deep-code-review [path] Deep review of a path (same as /code-review deep)

    Each command injects a short instruction into the current session, so the agent does the work with its normal tools. If a command's tool isn't installed, the instruction says so instead of failing silently.


    Troubleshooting

    failed to load plugin / Cannot find package '@opencode/plugin'

    The loose-file layout is the cause. If you copied plugins/*.ts into ~/.config/opencode/plugins/, opencode v2 will discover those files but cannot resolve their npm imports from the config directory, so every plugin fails identically.

    Fix: install the built packages and register them instead. See Quick start. Remove the old loose files afterwards:

    rm -rf ~/.config/opencode/plugins
    
    prompt.split is not a function

    A helper file ended up inside plugins/. opencode treats every export of a file under plugins/ as a plugin factory, so a stray helper export breaks the load.

    Fix: the package layout avoids this by construction. If you are on the flat layout, move lib/ and opencode-sessions/ out of plugins/ and restart.

    Tools don't appear after installing

    Check each of these in order:

    1. npm run setup completed (packages/<name>/package.json exists).
    2. toolbox/node_modules exists.
    3. Every toolbox/<name>/ resolves (a symlink in link mode).
    4. The absolute paths in the plugins array of opencode.jsonc are the package directories, not the .ts files.
    5. You reloaded (opencode reload) or restarted — a reload is required, and for a fresh install a full restart is safer.

    If any of those are wrong, npm run setup repairs all of them.

    Confirm what opencode actually registered:

    opencode plugin list
    

    opencode plugin list reports the configured plugin paths, including ones that failed to load. To verify a plugin truly loaded, check the log:

    grep -E 'loading plugin|failed to load plugin' ~/.local/share/opencode/log/opencode.log | tail
    
    A third-party npm plugin fails to load

    Third-party packages are often still v1-only. A v1 plugin depends on @opencode-ai/plugin and/or exports Plugin differently, and will fail under v2.

    Fix: check its package.json for a dependency on @opencode/plugin (v2) versus @opencode-ai/plugin (v1), and confirm the release you are installing predates the v2 migration, before adding it to the plugins array.

    Context-pruner is not saving tokens
    1. Check context_pruner_stats — if it shows no prunes, the plugin may not be loaded.
    2. Verify enabled is true and OPENCODE_CONTEXT_PRUNER_ENABLED is not set to false.
    3. Check that minChars (default 2000) is not higher than most of your tool outputs.
    4. Set log: true to see prune decisions on stderr.
    Secret-shield is blocking legitimate requests
    1. Switch to observe mode to audit without blocking: OPENCODE_SECRET_SHIELD_MODE=observe.
    2. Use the allow option to whitelist specific patterns: OPENCODE_SECRET_SHIELD_ALLOW="/my-safe-token/".
    3. Check secret_shield_stats for what is being detected.
    Permission denied on SQLite database

    The SQLite databases are stored in ~/.local/share/opencode/. Ensure your user has write access to this directory:

    chmod -R u+w ~/.local/share/opencode/
    
    Plugin crashes on startup

    Check the OpenCode Desktop logs for error messages. Common causes:

    • Missing environment variables
    • Incompatible Node.js/Bun version
    • Corrupted plugin state (try deleting the plugin's state directory)
    Goal loop not continuing

    Check that:

    • The goal is not paused (/goal resume to resume)
    • The iteration/time budget has not been exhausted
    • The model is calling goal_complete or goal_blocked

    Getting help

    If you're still stuck, please open an issue with:

    • Your OpenCode Desktop version
    • Your operating system
    • The plugin(s) you're having trouble with
    • Relevant log output

    Development

    Repo layout

    opencode-sessions/ is the source of truth for the sessions plugin. It is no longer mirrored into plugins/ — copy the two files where your opencode install expects them:

    cp opencode-sessions/opencode-sessions.ts <plugins-dir>/opencode-sessions.ts
    cp opencode-sessions/helpers.ts          <plugins-dir>/../opencode-sessions/helpers.ts
    

    Building

    npm run build:packages   # transpile + write packages/<dir>/ and smoke-load each entry
    npm run pack:check       # the above, plus `npm pack --dry-run` per package
    

    Publishing

    Each plugin ships as its own scoped npm package (the v2 loader allows exactly one plugin per package). The build inlines each plugin's helpers and rewrites the relative imports, so the published package is self-contained.

    Then publish (one package at a time):

    npm login                                  # once per machine
    cd packages/decision-log
    npm publish --access public                # scoped packages need --access public
    

    packages/ is generated and gitignored. Publish order does not matter — the packages have no runtime dependency on each other.

    Release rule: one version for all 19. Bump version in the root package.json; the build stamps that value onto every package, and they are always published in lockstep. Never publish packages at mixed versions — a user installing the pack over time would otherwise end up with an untested combination. Publish only from a green main (npm test, typecheck, pack:check).

    Releases go through the publish workflow, not npm publish by hand. Pushing a tag vX.Y.Z runs the full gate (tests, typecheck, pack check), refuses to publish when the tag disagrees with the root version, then publishes everything not already on npm at that version with provenance via OIDC trusted publishing — no npm token involved. Versions already on npm are skipped, so tagging a release that was published by hand (or tagging twice) is a clean no-op that just syncs GitHub with npm:

    npm version minor   # or major/patch; bumps root package.json
    git push origin main
    git tag v1.2.0 && git push origin v1.2.0
    

    One-time setup, per package: npmjs.com → package → Settings → Trusted publisher → GitHub Actions, this repo, workflow publish.yml. Until that is done for a package, its publish step fails and the workflow stops — add all 19 before the first tagged release.


    FAQ

    Does the pack work with opencode v1?

    No. This pack requires opencode v2. The plugin loader, hook APIs, and package resolution model are all v2-specific.

    Can I use only some of the plugins?

    Yes. Each plugin is an independent npm package. Install only what you need and register just those directories in opencode.jsonc.

    Where is data stored?

    All SQLite databases live under ~/.opencode-plugins/ (or the directory specified by each plugin's dir option). No data leaves your machine.

    How do I disable a plugin without uninstalling?

    Every plugin has an enabled option (default true). Set it to false in the plugin's options object or via its env var, then reload opencode.

    Why does context-pruner have so many options?

    Context management is inherently complex — token estimation, cache awareness, summarisation strategy, and recovery behaviour all need tuning. The defaults work well for most users; the options are there for edge cases. See the Context Pruner section above for the full reference.

    How do I back up my data?

    All plugin data is stored locally under ~/.opencode-plugins/. To back up your data:

    cp -r ~/.opencode-plugins/ ~/backup-opencode-plugins/
    

    To restore:

    cp -r ~/backup-opencode-plugins/ ~/.opencode-plugins/
    
    What happens when I uninstall?

    Uninstalling a plugin removes its code but does not delete its data. Your SQLite databases and configuration remain in ~/.opencode-plugins/. To fully remove a plugin and its data:

    npm uninstall @bandonker/opencode-<plugin-name>
    rm -rf ~/.opencode-plugins/<plugin-name>/
    
    Is there a performance impact?

    Most plugins have negligible overhead. The context pruner runs only when token usage exceeds the threshold, and the usage stats plugin samples periodically. The goal loop adds minimal overhead — it only re-injects the objective into requests and checks for continuation conditions.

    Can I use this with other AI tools?

    No. These plugins are designed specifically for OpenCode Desktop and rely on its plugin API, hook system, and package resolution model. They are not compatible with other AI coding tools.


    Contributing

    Issues and PRs are welcome. Here are some guidelines:

    Getting started

    1. Fork and clone the repository
    2. Run npm install to install dependencies
    3. Run npm run build to build all plugins
    4. Run npm test to verify everything works

    Making changes

    • Keep changes scoped — one feature or fix per PR
    • Run npm test and npm run typecheck before opening a PR
    • Describe the tool behavior you changed and why
    • Update the README if you add or change plugin options
    • Add tests for new functionality

    Adding a new plugin

    1. Create a new directory under plugins/
    2. Add a package.json with the plugin metadata
    3. Implement the plugin following the existing patterns
    4. Add the plugin to the install command in this README
    5. Add a section in this README under the appropriate category
    6. Run npm run build and npm test

    Code style

    • TypeScript strict mode
    • Use bun:sqlite when available, fall back to node:sqlite
    • Follow the existing naming conventions
    • Keep plugins self-contained — no cross-plugin dependencies

    Changelog

    1.2.1 — 2026-10-13

    All 19 packages published to npm as 1.2.1.

    • finish-guard: a stream the gateway cuts mid-generation (content in hand, no finish reason) is left unterminated instead of being closed with an invented finish_reason. A fabricated "stop" marked the turn as a clean completion — hiding the cut, skipping opencode's retry-and-continue recovery, and leaving finish_guard_stats at retries: 0 while turns kept dying. The cut is still counted (truncated) and captured with the payloads immediately before it.
    • finish-guard: a socket that dies mid-stream now arrives as a clean end instead of a rejected body, unlabelled SSE bodies are normalised rather than skipped, and finish_guard_stats reports normalised (streams the transform actually rewrote — "loaded but never fires" is directly answerable) and counts retries opencode scheduled on its own.
    • Tooling: one npm install builds, links and configures the whole toolbox; a new test asserts every installed plugin registers its tools.

    2026-09-28

    • Initial release with 15 plugins
    • All plugins published to npm under @bandonker/opencode-*
    • CI/CD pipeline with GitHub Actions
    • Comprehensive test suite

    License

    MIT © Bandonker


    If open-toolbox earns a place in your setup, a star on the repo helps other opencode users find it.

    同类生态推荐