DEVELOPER DOCS · PLUGINS

Extend VibeLink

Connect an agent lifecycle to VibeLink or build a safe companion for the Chrome you already use. This guide covers the complete path in one place.

DESKTOP 0.7.xMANIFEST V3GPL-3.0

01 / START HERE

Choose the extension point

VibeLink has three extension points. Pick the smallest one that matches the job.

A

Agent hook

Connect start, tool, permission, and completion events to pane state and Review.

hook 만들기 →
B

Browser Control

A Manifest V3 companion controls existing Chrome tabs over a local WebSocket. Data does not go to the website.

확장 만들기 →
권장 순서Skill로 지침을 정리하고 → hook으로 상태/결과를 연결하고 → 브라우저 제어가 필요할 때만 MV3 확장을 추가하세요.

02 / MENTAL MODEL

The data flow

Agents and Chrome do not talk to each other directly. Adapters translate into a narrow VibeLink CLI contract, and the daemon validates the pane instance.

Agent CLInative events / payload
Hook adapterstate + completion
VibeLink daemonworkspace · pane · instance
Pane / Reviewworking · waiting · idle
Chrome service workerchrome.debugger
loopback WebSocketOrigin: chrome-extension://…
VibeLink daemonpaired extension id

03 / AGENT HOOKS

Build an agent hook

Desktop supports JSON hooks, drop-in TypeScript plugins, the Hermes Python plugin, and Kimi TOML. Merge into existing configuration; never overwrite a user’s hooks.

1

이벤트를 고릅니다

Working: prompt/tool events · Waiting: permission/question · Idle: completed turn · Bind: session start.

2

VibeLink 환경을 확인합니다

VIBELINK_SESSION_ID, VIBELINK_PANE_ID, VIBELINK_PANE_INSTANCE_ID, VIBELINK_CLI_EXE가 없으면 조용히 stdin을 소비하고 종료합니다.

3

상태와 완료를 분리합니다

상태는 terminal state, 최종 답변은 terminal complete --hook-stdin으로 보냅니다. 완료 payload는 가능한 경우 원문을 보존합니다.

// OpenCode drop-in example
import { spawn } from 'node:child_process'

const cli = process.env.VIBELINK_CLI_EXE
const ids = ['--workspace', process.env.VIBELINK_SESSION_ID, '--pane', process.env.VIBELINK_PANE_ID, '--agent-id', 'my-agent', '--pane-instance-id', process.env.VIBELINK_PANE_INSTANCE_ID]
const reportState = (state) => cli && spawn(cli, ['terminal', 'state', ...ids, '--state', state], { detached: true, windowsHide: true }).unref()
const reportCompletion = (text) => {
  if (!cli || !text?.trim()) return
  const child = spawn(cli, ['terminal', 'complete', ...ids, '--hook-stdin'], { windowsHide: true })
  child.stdin.end(JSON.stringify({ vibelinkFinalResponse: text.trim() }))
}

export const VibeLinkCompletion = async ({ client }) => ({
  'chat.message': async () => reportState('working'),
  event: async ({ event }) => {
    if (event.type === 'permission.asked') return reportState('waiting')
    if (event.type !== 'session.idle') return
    const text = await lastAssistantText(client, event.properties.sessionID)
    reportState('idle')
    reportCompletion(text)
  },
})

지원 어댑터와 기본 위치

Agent기본 파일방식주요 이벤트
Claude Code~/.claude/settings.jsonJSON hookSessionStart · Stop · PreToolUse · PermissionRequest · PostToolUse
Codex$CODEX_HOME/hooks.jsonJSON hookSessionStart · UserPromptSubmit · PreToolUse · PermissionRequest · Stop
Gemini CLI~/.gemini/settings.jsonJSON hookBeforeAgent · AfterAgent
Cursor Agent~/.cursor/hooks.jsonJSON hookbeforeSubmitPrompt · stop
OpenCode~/.config/opencode/plugins/vibelink-complete.jsdrop-in pluginchat.message · event · session.idle
Pi / Oh My Pi~/.pi or ~/.omp/agent/extensions/TypeScript extensionagent_start · message_end · agent_settled
Hermes%LOCALAPPDATA%/hermes/config.yamlPython pluginpre_llm_call · post_llm_call · on_session_end
Kimi Code$KIMI_CODE_HOME/config.tomlTOML hookUserPromptSubmit · PreToolUse · Stop

04 / CHROME MV3

Build a Chrome extension

Browser Control uses a Manifest V3 service worker and chrome.debugger, with one loopback WebSocket to the VibeLink daemon. It does not load page scripts or remote code.

{
  "manifest_version": 3,
  "name": "My VibeLink Control",
  "version": "0.1.0",
  "background": { "service_worker": "service-worker.js", "type": "module" },
  "permissions": ["debugger", "storage", "tabs"]
}

권한을 최소화하세요

debugger는 Chrome이 사용자에게 디버깅 알림을 표시합니다. 이 알림을 숨기거나 우회하지 말고, 필요한 권한만 manifest에 선언합니다.

브리지를 인증하세요

Chrome이 보내는 Origin: chrome-extension://<id>를 daemon에서 확인하고, 첫 연결 ID를 data 디렉터리에 저장해 다른 확장 ID를 거부합니다.

보안 경계웹사이트 서버·외부 API·native messaging host를 경로에 넣지 않습니다. VibeLink Browser Control의 기본 통신은 로컬 loopback뿐입니다.

05 / LOCAL DEVELOPMENT

Install and develop locally

STORE

Chrome Web Store

  1. VibeLink Download에서 Browser Control zip을 받습니다.
  2. Chrome Web Store에서 확장을 설치하고 사용 설정합니다.
  3. Desktop을 재시작한 뒤 `vibelink browser chrome`의 connected/version을 확인합니다.
UNPACKED

unpacked 개발

  1. Desktop Settings → Browser → Install Chrome extension을 실행합니다.
  2. chrome://extensions에서 Developer mode를 켜고 Load unpacked를 선택합니다.
  3. 코드만 바뀌었으면 Reload를 누릅니다. ID·경로·bridge 계약이 바뀌었으면 기존 복사본을 제거하고 다시 Load 합니다.
# 연결 상태 확인
vibelink --json status
vibelink --json browser chrome

# 확장 ID를 바꾼 뒤 pairing 초기화
vibelink browser chrome --unpair

06 / CONTRACT

State and completion contract

Keep state values small. Completion payloads differ by agent, so read direct text first, then a transcript path, then a session id as a conservative fallback.

bindpane와 agent 연결
workingprompt / tool 실행
waiting권한·질문 대기
idleturn 종료·Review 생성
{
  "vibelinkFinalResponse": "에이전트가 실제로 반환한 최종 답변",
  "agent": "opencode",
  "transcript_path": "C:/…/session.jsonl"
}

직접 답변 필드 예: vibelinkFinalResponse, last_assistant_message, prompt_response, assistant_response. 경로 필드 예: transcript_path, session_id.

07 / SHIP IT

Verification checklist

릴리스 호환성OpenCode 2 plugin API는 2026년 9월 기준 beta입니다. 지원할 최소 버전과 최신 버전에서 모두 테스트하고, exact npm version 또는 Git commit으로 재현 가능한 빌드를 고정하세요.

08 / REFERENCES

Official references

Basis: VibeLink Desktop agent_hooks and browser-extension sources, plus official platform docs checked in September 2026.