Agent hook
Connect start, tool, permission, and completion events to pane state and Review.
hook 만들기 →DEVELOPER DOCS · PLUGINS
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.
01 / START HERE
VibeLink has three extension points. Pick the smallest one that matches the job.
Connect start, tool, permission, and completion events to pane state and Review.
hook 만들기 →A Manifest V3 companion controls existing Chrome tabs over a local WebSocket. Data does not go to the website.
확장 만들기 →A SKILL.md package adds instructions and workflow knowledge without executable hooks.
스킬 설정 보기 →02 / MENTAL MODEL
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.
03 / AGENT HOOKS
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.
Working: prompt/tool events · Waiting: permission/question · Idle: completed turn · Bind: session start.
VIBELINK_SESSION_ID, VIBELINK_PANE_ID, VIBELINK_PANE_INSTANCE_ID, VIBELINK_CLI_EXE가 없으면 조용히 stdin을 소비하고 종료합니다.
상태는 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.json | JSON hook | SessionStart · Stop · PreToolUse · PermissionRequest · PostToolUse |
| Codex | $CODEX_HOME/hooks.json | JSON hook | SessionStart · UserPromptSubmit · PreToolUse · PermissionRequest · Stop |
| Gemini CLI | ~/.gemini/settings.json | JSON hook | BeforeAgent · AfterAgent |
| Cursor Agent | ~/.cursor/hooks.json | JSON hook | beforeSubmitPrompt · stop |
| OpenCode | ~/.config/opencode/plugins/vibelink-complete.js | drop-in plugin | chat.message · event · session.idle |
| Pi / Oh My Pi | ~/.pi or ~/.omp/agent/extensions/ | TypeScript extension | agent_start · message_end · agent_settled |
| Hermes | %LOCALAPPDATA%/hermes/config.yaml | Python plugin | pre_llm_call · post_llm_call · on_session_end |
| Kimi Code | $KIMI_CODE_HOME/config.toml | TOML hook | UserPromptSubmit · PreToolUse · Stop |
04 / CHROME MV3
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를 거부합니다.
05 / LOCAL DEVELOPMENT
chrome://extensions에서 Developer mode를 켜고 Load unpacked를 선택합니다.# 연결 상태 확인
vibelink --json status
vibelink --json browser chrome
# 확장 ID를 바꾼 뒤 pairing 초기화
vibelink browser chrome --unpair06 / 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.
{
"vibelinkFinalResponse": "에이전트가 실제로 반환한 최종 답변",
"agent": "opencode",
"transcript_path": "C:/…/session.jsonl"
}직접 답변 필드 예: vibelinkFinalResponse, last_assistant_message, prompt_response, assistant_response. 경로 필드 예: transcript_path, session_id.
07 / SHIP IT
08 / REFERENCES
Basis: VibeLink Desktop agent_hooks and browser-extension sources, plus official platform docs checked in September 2026.