New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@beremaran/opencode-beanie-plugin

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@beremaran/opencode-beanie-plugin

Combined OpenCode plugin: agent orchestration, subagent throttling, persistent goals, OpenAI-compatible provider auto-configuration, MCP tool aggregation, and skill discovery.

latest
Source
npmnpm
Version
0.2.1
Version published
Maintainers
1
Created
Source

opencode-beanie-plugin

A batteries-included plugin for OpenCode that merges eight productivity features into a single package: agent orchestration, subagent throttling, persistent goals, OpenAI-compatible provider auto-configuration, MCP tool aggregation, skill discovery, tool-usage directives, and self-configuration. It also includes an optional TUI companion.

This plugin consolidates six previously separate projects — mcp-skillbox, agent-toolbox, opencode-subagent-throttle, opencode-agent-tree, opencode-openai-compatible-auto-configure, and opencode-goal — into one composable, configurable plugin.

Features

FeatureWhat it does
OrchestratorTurns the main agent into an orchestrator that decomposes requests into small, verifiable subtasks and delegates them via the task tool to routed subagents (explore/general), with per-level models and an optional multi-level delegation chain.
ThrottleLimits how many task invocations run in parallel (default 2), queues the rest, and releases them as sessions go idle.
GoalPersistent, independently evaluated goals. Set an objective with /goal; after every turn an evaluator model decides whether it's complete, and the plugin auto-continues, budget-limits, or reports completion.
ProvidersAuto-configures OpenAI-compatible providers (baseURL, apiKey, headers, model fetching) into OpenCode via /add-provider and /providers, with sources defined inline in the plugin config.
ToolboxAggregates tools from configured MCP servers (stdio and HTTP) behind three tools: list_tools, get_tool_schema, invoke_tool.
SkillboxDiscovers agent skills from the skills.sh API or public GitHub repositories and exposes list_skills, search_skills, and load_skill.
DirectivesInjects system-prompt guidance about the plugin's own tools and mechanisms, and appends "when to use" notes to their descriptions.
ConfiguratorSelf-configuration: /beanie status|validate|apply|init plus the configure_plugin tool inspect, validate, and write the plugin's options directly into opencode.json.
TUI companionAdds a Beanie dashboard route, command-palette actions (/beanie-dashboard and /beanie-dashboard-refresh), a <leader>d shortcut, a session status strip, goal controls with confirmation before clearing, and attention notifications for unhealthy MCP/LSP services, session errors, and completed child sessions.

Requirements

  • Node.js 18+ (NodeNext ESM)
  • OpenCode with plugin support

Installation

Build and register the plugin in your project's opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["@beremaran/opencode-beanie-plugin"]
}

The server plugin and TUI companion are registered separately. The current OpenCode TUI configuration uses a separate tui.json (or tui.jsonc) file with the same top-level plugin key; do not add a tui.plugin key to opencode.json:

{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["@beremaran/opencode-beanie-plugin/tui"]
}

When developing locally, register both built exports separately:

opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["file:/path/to/opencode-beanie-plugin/dist/index.js"]
}

tui.json:

{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["file:/path/to/opencode-beanie-plugin/dist/tui.js"]
}

The only option that is strictly required is the orchestrator's subagent model. If orchestrator.subagentModel is missing, the plugin refuses to start. After installing, run /beanie init in OpenCode for a guided, interactive setup.

Quick start

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    [
      "@beremaran/opencode-beanie-plugin",
      {
        "orchestrator": { "subagentModel": "anthropic/claude-sonnet-4-6" },
        "throttle": { "maxParallel": 3 },
        "goal": { "defaultTokenBudget": 100000, "defaultMaxTurns": 20 }
      }
    ]
  ]
}

Configuration is read from the plugin tuple's options object. Feature names are camelCase (matching the schema); the JSON schema itself uses kebab-case for property names like per_page.

Restart OpenCode after changing plugin options for changes to take effect.

Restart OpenCode after changing either plugin registration or options. TUI plugin changes are loaded when the TUI starts; close and reopen the TUI to reload them. The companion reads server state through the public TUI APIs, so the current goal is not shown live in the dashboard or status strip when OpenCode does not expose a public goal-state bridge; use /goal status for the authoritative goal state.

Configuration reference

All options are optional per feature; only orchestrator.subagentModel is required. The complete schema is exposed by configure_plugin with action schema, or via /beanie validate.

Orchestrator

OptionTypeDefaultDescription
subagentModelstringrequiredModel id used for every routed subagent, e.g. "anthropic/claude-sonnet-4-6".
orchestratorModelstringModel used for the orchestrator agent(s). Falls back to OpenCode's default model.
orchestratorAgentstring"Manager"Name of the top-level orchestrator agent.
orchestratorDepthinteger1Number of orchestrator levels; level 1 is the primary agent, deeper levels are subagents (<agent>-2, ...).
orchestratorModelsstring[]Per-level orchestrator models; length must not exceed orchestratorDepth.
agentsstring[]built-ins + existingExplicit list of subagents the orchestrator is allowed to delegate to.
agentModelsobjectPer-agent model overrides, e.g. { "general": "anthropic/claude-sonnet-4-6" }.
instructionsstringExtra instructions appended to the orchestrator's prompt.
blockedToolsstring[]["edit", "bash"]Hands-on tools denied to orchestrator agents so they only plan and delegate.
restrictTaskbooleanfalseRestrict the final orchestrator's task tool to the routed subagents only.

Throttle

OptionTypeDefaultDescription
maxParallelinteger2Maximum number of task calls running at once.
mode"session" | "global""session"Scope of the parallel limit: per session or across all sessions.
maxWaitMsnumber3600000Max time a queued task waits before being dropped.
notifyQueuebooleanfalsePost progress messages to the session when tasks are queued/started.

Goal

OptionTypeDefaultDescription
evaluatorModelstringModel used for independent completion evaluation. Defaults to the session's model.
evaluatorAgentstringAgent used for the evaluator session.
stateDirectorystringXDG state dirDirectory where goal state JSON files are stored.
maxTranscriptCharsinteger48000Max transcript characters sent to the evaluator per turn.
defaultTokenBudgetintegerDefault token budget applied to new goals.
defaultMaxTurnsintegerDefault turn budget applied to new goals.
continuationDelayMsinteger0Delay before the plugin auto-continues an active goal.
deleteEvaluatorSessionsbooleantrueDelete the temporary evaluator session after each evaluation.

Providers

OptionTypeDefaultDescription
providersarrayStatic provider sources defined inline (see below).
modelstringSet config.model (default model) to this id.
smallModelstringSet config.small_model to this id.
timeoutinteger10000Model-fetch timeout in milliseconds.
npmstring@ai-sdk/openai-compatiblenpm package used for the provider.
envbooleantrueAllow ${VAR} interpolation of apiKey/headers/baseURL from environment variables.

Per-provider source options (providers array entries):

OptionTypeDefaultDescription
idstringProvider id (also used as the config key).
namestringDisplay name.
baseURLstringOpenAI-compatible base URL, e.g. http://localhost:11434/v1.
apiKeystringBearer token (supports ${VAR} interpolation).
headersobjectExtra headers sent with model fetch requests.
npmstring@ai-sdk/openai-compatiblenpm package used for this provider.
kind"auto" | "openai" | "ollama" | "unsloth" | "lmstudio""auto"Server protocol used to discover model limits (see below).
modelsURLstring<baseURL>/modelsOverride the model list URL (OpenAI-compatible shape).
fetchModelsbooleantrueFetch the model list at startup.
staticModelsobjectExplicit model entries (name/limit/capabilities) merged with discovered ones.
overridesobjectPer-model overrides, highest precedence.
include / excludestring[]Glob filters over discovered model ids.
defaultLimitobjectContext/output fallback for models the server/inference doesn't cover.
envbooleantrueAllow ${VAR} interpolation for this source.
timeoutinteger10000Fetch timeout in milliseconds.
{
  "id": "my-ollama",
  "name": "Local Ollama",
  "baseURL": "http://localhost:11434/v1",
  "kind": "ollama",
  "apiKey": "${OLLAMA_KEY}",
  "headers": { "X-Custom": "value" },
  "fetchModels": true,
  "defaultLimit": { "context": 64000, "output": 8192 },
  "include": ["my-model-*"],
  "exclude": ["test-*"],
  "env": true
}

The OpenAI-compatible /v1/models spec has no context-window field, so the plugin discovers limits per kind:

kindModel sourceContext detection
openai / auto<modelsURL> or <baseURL>/modelsFields embedded in the listing (context_length, max_context_length, n_ctx, context_window, input_token_limit, …); output via max_output_tokens, max_tokens, output_token_limit, …
ollama<baseURL>/api/tagsOllama's context_length field per model
unsloth<baseURL>/models + per-model /api/models/gguf-variants?repo_id=…The GGUF's real context_length
lmstudio<baseURL>/api/v0/modelsLM Studio's native max_context_length (embedding models are filtered out)

When neither the server nor defaultLimit provides a context window, the plugin falls back to a curated model-family table (Qwen 3.5/3.6 → 256k, Qwen 3 → 128k, DeepSeek → 128k, Llama 3.1+ → 128k, etc.). OpenCode requires both context and output per model and disables auto-compaction when the context is unknown, so the plugin always writes a complete limit: a missing output defaults to half the context (capped at 32000), a missing context to 128000. Precedence: detected API value > defaultLimit > name-based inference.

Vision-capable models are marked automatically so OpenCode accepts image attachments: attachment: true plus modalities: { "input": ["text", "image"] } (this is what actually enables sending images). Sources: Unsloth's has_vision, LM Studio's type: "vlm", Ollama's capabilities, or embedded has_vision/modalities/input_modalities fields. Set attachment: false in overrides to force a text-only model, or modalities to fine-tune input support.

Skillbox

OptionTypeDefaultDescription
registry"auto" | "skills-sh" | "github""auto"Registry backend. auto uses skills.sh when a token is present, otherwise GitHub.
skillsShTokenstringenv SKILLS_SH_TOKENToken for the skills.sh API.
githubSourcesstring[]7 curated reposGitHub owner/repo skill sources.
githubTokenstringenv GITHUB_TOKENToken for private/high-rate GitHub access.
maxBytesintegerByte budget for load_skill payloads; overflow is truncated with a marker.
debugbooleanenv SKILL_DEBUGEmit debug logs to OpenCode.

Defaults for githubSources: vercel-labs/skills, anthropics/skills, obra/superpowers, mattpocock/skills, microsoft/azure-skills, supabase/agent-skills, prisma/skills.

Toolbox

OptionTypeDefaultDescription
configobjectInline config object with mcpServers (and optional tuning keys, see below). External JSON config files are not supported.
serversobjectInline MCP server map (merged with config).

An MCP server can be stdio or HTTP:

{
  "servers": {
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest"],
      "env": { "HOME": "/home/user" },
      "cwd": "/path/to/project",
      "timeout": 30,
      "toolFilter": ["browser_*"],
      "tags": ["web"],
      "disabled": false
    },
    "remote": {
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer ${TOKEN}" },
      "transportType": "streamable-http"
    }
  }
}

Inline config options also accept searchTopK (default 20), cacheToolMetadata (default true), processPoolSize (default 8), timeoutSeconds (default 30), and idleTimeoutMs (default 300000).

list_tools connects servers whose metadata is not loaded yet on the default path (rows marked [stale] otherwise), so it reflects reality on a cold session. Pass refresh: true to force a reconnect and reload of tool metadata, or refresh: false to use only already-loaded metadata.

Directives

OptionTypeDefaultDescription
defaultsbooleantrueInject the default plugin-capabilities system directive.
systemstring[][]Extra system prompt lines appended verbatim.
toolsobject{}Extra "when to use" guidance appended to specific tool descriptions.
mechanismsstring[]allWhich mechanism notes to include in the system directive: goal, orchestrator, throttle, skillbox, toolbox, providers, configurator.

Slash commands

CommandDescription
/beanieShow current effective configuration and validation.
/beanie statusSame as above.
/beanie helpShow usage help.
/beanie validate [json]Validate the current config, or a JSON object of options.
/beanie apply <json>Validate and write options to opencode.json.
/beanie initGuided setup: the agent walks through each feature and writes the config.
/goal <condition>Set a persistent goal, e.g. /goal --tokens 100k --max-turns 20 Fix the failing checkout tests.
/goal statusShow the current goal's status, budgets, and latest evaluation.
/goal pause / /goal resume / /goal clearPause, resume, or clear the session goal.
/add-provider <id> <baseURL> [apiKey] [--name "..." --kind auto|openai|ollama|unsloth|lmstudio --context N --output N --no-fetch]Add or update an OpenAI-compatible provider by writing it into the plugin's providers option in opencode.json.
/providersList configured providers with live model counts.

/goal supports --tokens (plain integers or k/m suffixes) and --max-turns before the objective.

Tools

ToolFeatureDescription
get_goalGoalRead the active goal's status, budgets, usage, and last evaluator reason.
update_goalGoalClaim the goal complete (for independent verification) or blocked (after ≥3 recurring turns of the same blocker).
list_skillsSkillboxBrowse skills from the registry with pagination and views (all-time, trending, hot).
search_skillsSkillboxKeyword search across the registry.
load_skillSkillboxLoad a skill's full SKILL.md and optional supporting files, byte-budgeted.
list_toolsToolboxList or search aggregated MCP tools; auto-connects idle servers on the default path (refresh: true forces a reload, refresh: false uses the cache only).
get_tool_schemaToolboxFetch the full JSON Schema for one upstream tool.
invoke_toolToolboxInvoke one upstream tool and serialize the result faithfully.
configure_pluginConfiguratorstatus/schema/validate/apply the plugin's options in opencode.json.

How goals work

  • /goal <objective> persists a goal keyed to the session (state stored under the XDG state directory, scoped by project and directory).
  • While a goal is active, every session turn triggers an independent evaluator call that judges completion against evidence in the transcript.
  • If incomplete and under budget, the plugin auto-continues with a continuation prompt. completionClaims made via update_goal are verified by the evaluator.
  • Goals stop at completion, pause (interruption/error), blocked (after ≥3 turns of the same blocker), or budget/turn limits — the last case produces a concise handoff.

To avoid surprises, set goal.evaluatorModel and budgets (defaultTokenBudget, defaultMaxTurns) so evaluation cost and runtime stay bounded.

Development

npm install
npm run check   # tsc --noEmit — the verification gate
npm run lint    # biome check src
npm run build   # tsc emitting to dist/ (required before loading the plugin)
  • dist/ is gitignored build output; it is never edited by hand.
  • Relative imports must use explicit .js extensions (NodeNext).
  • There is no @types/node; each feature ships a hand-written node-shims.d.ts for the Node APIs it uses. Extend the local shim if more APIs are needed — do not add @types/node.
  • To add a feature, create src/features/<name>/index.ts exporting a Plugin, and register it in the features record in src/index.ts (feature options are read from options.<featureName>).
  • @opencode-ai/plugin is pinned to 1.18.16; reconcile features when hooks/types change upstream.

Contributing

Bug reports, feature ideas, and pull requests are welcome. Please open an issue first for non-trivial changes so the direction is agreed before the work begins. Ensure npm run check and npm run lint pass on your changes.

Releasing

Releases are published to npm automatically by the Publish to npm GitHub Actions workflow:

  • Bump the version in package.json (keep SemVer and add a matching entry to CHANGELOG.md).
  • Commit the change and push it to main.
  • Tag the release with the same version, e.g. git tag v0.2.0 && git push origin v0.2.0.

The workflow type-checks, builds, verifies the tag matches the package.json version, then runs npm publish --provenance --access public using npm's trusted publishing (OIDC), so no token secret is needed. Set it up once in your npm account:

  • Go to npmjs.comAccount SettingsAccess TokensAdd Publisher (or under the package's Access tab).
  • Enter the GitHub repo (beremaran/opencode-beanie-plugin) and the environment name npm-publish (this must match the environment in the workflow).
  • Create the npm-publish environment in GitHub: SettingsEnvironments, optionally with a protection rule so publishing is gated.

The workflow must be run from a matching release tag; manually dispatching it from a branch fails tag verification.

License

MIT

Keywords

opencode

FAQs

Package last updated on 13 Aug 2026

Related posts