@freebuild/opencode

中文文档
0.0.36发布于 2026/11/09SEE LICENSE IN LICENSEES Module近 30 天下载 3269

Paid sponsored plan plugin for Freebuild on OpenCode: license activation, broker provider, and sponsor panel.

原始使用文档
文档目录14 节
  1. Panel labels
  2. Paid plan
  3. Founding beta (invite only)
  4. Install
  5. Connect a license
  6. Model metadata
  7. Behavior
  8. Wrapper mode
  9. Entitlement
  10. Sponsor feed
  11. Environment
  12. Development
  13. Test
  14. License

Freebuild OpenCode sponsor panel

A V2 TUI plugin for the paid Freebuild Lite and Freebuild Standard plans. It adds a host-managed sponsor panel while the agent works, automatically connects the freebuild model provider, and shows plan and token usage.

Freebuild is not built by the OpenCode team and is not affiliated with OpenCode.

Docs: https://freebuild.dev/docs/

┌────────────────────────────────┬────────────────────────────────┐
│                                │  FREEBUILD · Acme              │
│  normal OpenCode session       │                                │
│  reflowed to half width        │  SHIP FASTER                   │
│                                │  Acme CI runs your tests...    │
│                                │                                │
│                                │                                │
└────────────────────────────────┴────────────────────────────────┘

Panel labels

  • SPONSORED for paid campaigns
  • AFFILIATE for affiliate campaigns
  • FREEBUILD for house inventory
  • ADVERTISE for advertising inventory

Paid campaigns outrank affiliates, and affiliates outrank house inventory.

Paid plan

There is no free or ad-free tier. The plugin is inactive until a sponsored license is connected:

  • No license: no panel, no ads, no broker tokens.
  • Active Lite or Standard license: broker tokens plus the mandatory sponsor panel.
  • Canceled or unpaid subscription: the broker rejects requests and the panel stays closed.

Founding beta (invite only)

Founding beta uses the same checkout as the paid plans. Run /freebuild-founding and paste the private code. The plan is free for 90 days, grants 10,000,000 weighted tokens per billing month, and includes the sponsor panel. The Stripe subscription cancels automatically at day 90, before any payment. The license connects automatically, the same way as Lite and Standard.

Install

Install the published package with OpenCode V2:

opencode plugin add @freebuild/opencode@latest

The old unscoped freebuild-sponsor package is legacy. New installs should use @freebuild/opencode.

Restart OpenCode so it loads the plugin. To update later:

opencode plugin update

For local development from this repository, install the directory directly:

powershell -ExecutionPolicy Bypass -File .\opencode-plugin\install.ps1
bash ./opencode-plugin/install.sh

To build the npm tarball before publishing:

cd opencode-plugin
npm pack

The package contains src/tui.tsx, package.json, and this README. Test the tarball with a clean OpenCode config before publishing.

Connect a license

You can start in OpenCode or buy first in the browser. Both paths require the plugin installed above. Browser buyers run /freebuild-key and paste the key from the Stripe success page; the plugin validates it, writes the provider, and selects the model. The screenshot guide is at https://freebuild.dev/docs/install/.

Inside OpenCode, with no key connected:

/freebuild-license

The plugin asks the app for a one-time activation code, opens /terminal/activate.html in the browser, and polls until Stripe Checkout finishes. The browser asks for the email first and sends a 6-digit code. Verify it before checkout. The same verified email gets a one-time license link, so a typo cannot attach the license to an address you do not control. When the webhook issues the license, the plugin:

  1. stores the key in ~/.config/freebuild/credentials.json,
  2. writes a freebuild provider to ~/.config/opencode/opencode.json(c),
  3. refreshes entitlement and enables the sponsor panel,
  4. shows the license key and the remaining setup steps.

The plugin writes the provider config, connects the credential, and selects Freebuild → DeepSeek V4.1 Flash 1017 for the current session. In /models it appears under Freebuild the first time. After you use it, OpenCode moves it to Recent. If it is still missing, run /freebuild-setup and restart OpenCode once.

The model has the same thinking levels as DeepSeek's own API: none, low, high, and max. Use /thinking to switch levels without changing models. The provider points at the Freebuild broker; the license key is the broker API key.

Model metadata

GET https://freebuild.dev/broker/v1/models is OpenAI-compatible and returns the model id, context and output limits, capabilities, compatibility fields, token weights, and plan prices. Clients and routers can use it to configure the provider without hardcoding limits.

When a key is already connected, /freebuild-license checks it first and offers reconnect, paste a replacement, open the account page, or buy another license. It never starts a second checkout on its own, and a rejected key (rotated, revoked, or cancelled) only offers a replacement or the account page.

To move this terminal to a key recovered at /account:

/freebuild-key

The plugin prompts for the key, checks GET /api/me/entitlement before saving anything, then writes the provider config, connects the credential, and selects the model. An inactive key is reported and the current license is left untouched. A network failure also leaves the current key in place.

If the automatic connect fails, run /freebuild-setup to write the provider config and select the model again.

Useful commands:

  • /freebuild-license — connect, reconnect, replace, or buy a license.
  • /freebuild-key — paste and validate a replacement key.
  • /models — select the Freebuild provider model. It appears under Freebuild until first use, then moves to Recent.
  • /thinking — choose none, low, high, or max thinking for DeepSeek V4.1 Flash 1017.
  • /freebuild-plan - show weighted used/limit, raw tokens, cache hit rate, and reservations.
  • /freebuild-billing — open the Stripe customer portal.
  • /freebuild-setup — repair the provider configuration.
  • /freebuild-sponsor, ctrl+o, ctrl+shift+o, or alt+o — open the sponsor link currently on screen. Clicking anywhere on the sponsor panel does the same. If no campaign is cached yet, Ctrl+O resolves one with a non-counting preview request so it still opens a link instead of a menu or document. Ctrl+O keeps its normal OpenCode meaning when no sponsored license is active; use /open for the picker while a sponsored license is active.
  • /freebuild-adtest - preview the next run's sponsor panel for 4 seconds without counting an impression.

Behavior

  • Opens on the first agent step and closes when the run ends. Each run fetches one authenticated sponsor for a fresh run ID and keeps it for the whole run; the server counts one impression when that run's panel opens. Repeated panel fetches and duplicate events are idempotent, so a long run stays one impression. There is no mid-run carousel.
  • /freebuild-adtest uses the preview endpoint, stores the selected campaign as the next run's campaign for that license and install, and never counts an impression or emits trackable open, close, or click events. The next run uses the previewed campaign when it is still eligible.
  • The panel measures its own box and fits the campaign wordmark and copy to it. Larger logo tiers are only used when both width and height leave room, and body and hint rows drop out as the panel gets smaller. A fixed wordmarkFont falls back to Auto when it does not fit; showWordmark: false hides the big text entirely.
  • OpenCode uses a split layout at 108+ columns; narrower terminals render the panel fullscreen and show a resize hint.
  • The panel content comes from the sponsor feed. Image ads render a static image above the copy; text-only ads render the wordmark and formatted copy. Image-only ads render the image across the whole creative area with no kicker, headline, body, or wordmark. GIFs are flattened to their first frame. If the feed or image is unavailable, a bundled house ad or text fallback is used.
  • Clicking the panel resolves the sponsor destination through the authenticated click endpoint. The TUI sends the license, install, session, and run IDs, then opens the returned URL. Direct anonymous click URLs return 401.
  • The panel cannot be hidden with a keybinding. Ads are part of the sponsored plan.
  • In the experimental Freebuild Terminal wrapper, the TUI panel stays closed and the plugin writes busy and entitlement state for the wrapper's side pane. The wrapper is not part of the first launch.

Wrapper mode

Set FREEBUILD_WRAPPER=1 and FREEBUILD_WRAPPER_STATE to a writable file path. The plugin then writes:

{
  "busy": true,
  "panel": true,
  "sessionId": "c13792d2135744c5bb309fa7",
  "updatedAt": 1793480000000
}

busy drives the wrapper's status line. panel is the entitlement decision: true for an active sponsored license. The wrapper keeps the sponsor pane visible for the whole app session whenever panel is true.

updatedAt is Unix milliseconds. It is refreshed every 10 seconds while a run is active. A run that finishes in under 3 seconds keeps busy: true for the remainder of a 3-second minimum window so a short run is not missed. The wrapper clears the file before starting OpenCode and ignores a stale busy flag older than 90 seconds.

Without FREEBUILD_WRAPPER_STATE, FREEBUILD_WRAPPER=1 is ignored and the normal TUI panel remains available.

Entitlement

The plugin reads a license key from:

  1. FREEBUILD_LICENSE_KEY or FREEBUILD_API_KEY,
  2. ~/.config/freebuild/credentials.json, or
  3. the legacy freebuild provider entry in OpenCode's auth.json.

On OpenCode V2, provider calls use the credential connected through the integration API. The plugin keeps credentials.json so it can refresh entitlement and the sponsor panel across launches.

Credentials file:

{
  "installId": "a stable installation id",
  "licenseKey": "fb_...",
  "apiUrl": "https://freebuild.dev",
  "brokerUrl": "https://freebuild.dev/broker",
  "sponsorUrl": "https://freebuild.dev/api/sponsor/panel"
}

It calls:

GET {brokerUrl}/api/me/entitlement
Authorization: Bearer <licenseKey>
X-Freebuild-Install: <installId>
  • sponsored: true → the panel may open during runs.
  • sponsored: false → the panel never opens.
  • No license key → inactive; run /freebuild-license.
  • 401 for a connected key → rotated, revoked, or cancelled; run /freebuild-key with the replacement from /account or /freebuild-license for the recovery menu. The plugin does not start a new checkout automatically.
  • Broker unreachable with a license key → the panel stays closed and the license is not discarded.
  • /freebuild-adtest forces a preview without changing entitlement.

The generated provider also sends X-Freebuild-Install and X-Freebuild-Client. The install ID lets broker usage line up with a license, and the client ID records which surface made the request.

Sponsor feed

The plugin fetches:

GET {sponsorUrl}
Authorization: Bearer <licenseKey>
X-Freebuild-Install: <installId>
X-Freebuild-Client: opencode/<pluginVersion>

Expected response:

{
  "campaign": {
    "id": "acme-2026-11",
    "brand": "Acme",
    "kicker": "SHIP FASTER",
    "title": "Acme CI runs your tests in 30 seconds.",
    "body": "Use code FREEBUILD for 3 months free.",
    "url": "https://acme.example/freebuild",
    "clickUrl": "https://freebuild.dev/api/sponsor/click?id=acme-2026-11",
    "eventUrl": "https://freebuild.dev/api/sponsor/event",
    "accent": "#39d98a",
    "wordmark": "ACME",
    "wordmarkFont": "block",
    "showWordmark": true,
    "imageOnly": false,
    "titleStyle": { "bold": true, "italic": false, "underline": false },
    "bodyStyle": { "bold": false, "italic": true, "underline": false },
    "align": "center",
    "imageUrl": "https://freebuild.dev/ads/acme.webp"
  },
  "serverTime": 1793480000
}

imageUrl is optional. When present, the panel and wrapper render it as a static image above the copy; when absent, the panel shows the wordmark and the formatted text. imageOnly: true requires an imageUrl and renders the image across the full creative area without a kicker, headline, body, or wordmark. wordmark defaults to FREEBUILD; wordmarkFont accepts auto, huge, block, slick, shade, tiny, grid, or pallet; showWordmark: false hides it. Uploads from /admin/ads.html are normalized to static PNG; GIFs use their first frame. titleStyle and bodyStyle accept bold, italic, and underline; align accepts center or left. videoUrl is legacy and ignored.

Panel events are posted as:

{
  "campaignId": "acme-2026-11",
  "sessionId": "c13792d2135744c5bb309fa7",
  "installId": "fa0515ea6e0c419db3f00901ea697316",
  "runId": "run-0001",
  "client": "opencode/0.0.27",
  "event": "open",
  "durationMs": 0,
  "tokens": 75
}

close events include the visible duration. The client field is client-reported, not verified. Use it to split events by surface, not as proof that the panel was visible.

Environment

FREEBUILD_LICENSE_KEY    broker license key
FREEBUILD_API_KEY        fallback license key
FREEBUILD_BROKER_URL     broker base URL (default https://freebuild.dev/broker)
FREEBUILD_API_URL        app base URL for activation (default https://freebuild.dev)
FREEBUILD_SPONSOR_URL    sponsor panel feed
FREEBUILD_CREDENTIALS    alternate credentials JSON path
FREEBUILD_AD_DEMO=1      preview the panel on startup
FREEBUILD_AD_DEMO_MS     preview duration in milliseconds
FREEBUILD_WRAPPER=1      suppress the TUI panel and emit wrapper busy state
FREEBUILD_WRAPPER_STATE  busy-state file for the desktop wrapper
FREEBUILD_WRAPPER_DEBUG  optional log file for plugin/wrapper diagnostics

Development

OpenCode 2.2.0 requires removing the resize listener with renderer.off(...); calling the return value of renderer.on(...) crashes the plugin during cleanup.

The TUI loads plugins live, so a setup or cleanup exception can take down the host terminal. Test changed plugins in a separate OpenCode process before replacing the copy used for daily work, and keep FREEBUILD_WRAPPER unset unless the desktop wrapper is actually launching OpenCode.

Validation used in this repository:

wrapper\node_modules\.bin\esbuild.cmd opencode-plugin\src\tui.tsx --bundle `
  --loader:.tsx=tsx --external:* --outfile=$env:TEMP\plugin-check.js

Test

  • With no license key, no panel opens during a run.
  • /freebuild-license completes Stripe Checkout and writes the provider config.
  • After checkout, the plugin stores the credential and /freebuild-setup selects the model.
  • With an existing key, /freebuild-license asks before buying and never opens a second checkout.
  • /freebuild-key rejects an inactive key and keeps the current license; an active key is saved, connects the provider, and selects the Freebuild model.
  • /account reveals, rotates, and opens billing for licenses owned by the signed-in email.
  • With a sponsored license, the panel opens and shows the fetched campaign.
  • /freebuild-plan shows weighted used, reserved, limit, raw tokens, and cache hit rate.
  • A canceled subscription makes /api/me/entitlement return 401 and the panel stops opening.

License

Proprietary. Copyright (c) 2026 Freebuild. All rights reserved.

This package is licensed under the Freebuild Proprietary License. See LICENSE.

版本与发布记录

@freebuild/opencode 共发布 17 个版本,首次发布于 2026/11/07;过去 12 个月发布了 17 个版本。

版本发布日期距今
0.0.36latest2026/11/096 天前
0.0.352026/11/096 天前
0.0.342026/11/096 天前
0.0.332026/11/097 天前
0.0.322026/11/097 天前
0.0.312026/11/087 天前

关于 @freebuild/opencode 的常见问题

@freebuild/opencode 是什么?

Paid sponsored plan plugin for Freebuild on OpenCode: license activation, broker provider, and sponsor panel.

如何安装 @freebuild/opencode?

在项目目录运行 npm install @freebuild/opencode,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:solid-js(>=1.9.0)、@opentui/core(>=0.6.6)、@opentui/solid(>=0.6.6)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@freebuild/opencode 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/freebuild__opencode 是否存在。

@freebuild/opencode 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@freebuild/opencode 可以商用吗?

@freebuild/opencode 使用 SEE LICENSE IN LICENSE 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@freebuild/opencode 的下载量有多少?

根据 npm 官方下载统计,@freebuild/opencode 在 2026/10/16 – 2026/11/14 这 30 天内被下载 3,269 次,日均约 109 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@freebuild/opencode 还在维护吗?

最新版本 0.0.36 发布于 2026/11/09(6 天前);至今共发布 17 个版本,其中过去 12 个月发布了 17 个;首次发布于 2026/11/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。