Avibe Configuration Manager
Configure and manage local Avibe installations, routing, models, and integrations.
Installation
- Make sure Claude is on your device and in your terminal.
Skills load from
~/.claude/skills/when Claude Code starts up — so you need it on your machine first. If you don't have it yet, install it once with the command below, then runclaudein any terminal to verify.One-time setupnpm i -g @anthropic-ai/claude-codeAlready have it? Skip ahead.
- Paste into Claude Code or into your terminal.
This copies the whole skill folder into
~/.claude/skills/use-avibe-avibe-bot/— the SKILL.md plus any scripts, reference docs, or templates the skill ships with. Safe default: works for every skill.Faster alternative (instruction-only skills)
Skips the clone and grabs only the SKILL.md file. Don't use this if the skill ships Python scripts, reference markdowns, or asset templates — they won't be downloaded and the skill will fail when it tries to load them.
Quick install (SKILL.md only)Sign up to copy - Restart Claude Code.
Quit and reopen Claude Code (or any other agent that loads from
~/.claude/skills/). New skills are picked up on startup. - Just ask Claude.
Skills auto-activate when your request matches the skill's description — no slash command needed. Trigger phrases live in the skill's own frontmatter; you can read them in the “What this skill does” section above.
Prefer to read the source first? Open on GitHub.
When Claude uses it
Safely inspect and modify local Avibe configuration, routing, runtime settings, watches, scheduled tasks, Avibe Cloud remote access, and operational state.
What this skill does
Use Avibe
Use this skill when the user asks you to configure, repair, explain, or operate a local Avibe installation.
Typical requests include:
- enable a Slack, Discord, Telegram, Lark/Feishu, or WeChat scope
- route one channel or DM user to OpenCode, Claude, or Codex
- set a working directory for a channel or DM user
- choose a backend model, subagent, or reasoning level
- show or hide intermediate message types
- configure an outbound proxy (
proxy_url) for an IM platform that cannot reach its API directly - pair, start, stop, or inspect Avibe Cloud remote Web UI access
- create, update, inspect, pause, resume, or remove a managed background watch with
vibe watch - create, inspect, run, pause, resume, or remove a scheduled task with
vibe task - run a one-shot Agent job with
vibe agent run, including async background runs - inspect or cancel concrete Agent Run records with
vibe runs - check or apply Avibe updates (
vibe check-update,vibe upgrade) - inspect logs, run doctor, check service status, or explain where Avibe stores state
- decide whether a requested change belongs in Avibe config or in the host backend's own config
Follow this skill as an operations playbook for agents, not as end-user marketing copy.
Core Rules
- Prefer the Web UI API for Avibe configuration changes. Do not hand-edit config files for routine work.
- Read current API state before mutating. Merge the user's requested change into the current payload.
- Preserve unrelated scopes, platforms, users, and secrets.
- Treat secrets as opaque. Do not print, invent, rotate, or overwrite tokens unless the user explicitly provides replacements.
- Use the smallest viable API call and verify by reading back the API response.
- For
POST /settings, preserve every existing channel for that platform; the endpoint replaces the platform's channel map. - For
POST /api/users, merge each edited user with its current user payload first; missing user fields are not a patch. - Make every persistent-state change through the Web UI API or the
vibeCLI. Avibe's internal storage is opaque — do not read, query, or hand-edit it. POST /configpersists the new payload but does not restart running platform adapters by itself. When the change is platform credentials,proxy_url, or other transport-level settings, plan an explicit restart afterwards; prefer the delayed CLI form (vibe restart --delay-seconds 60) when triggering it from inside an active conversation. The only credential save that restarts on its own is the WeChat QR-login completion throughPOST /wechat/qr_login/poll.- Do not restart the service by default. Use
POST /doctor,GET /status, and read-back checks first. - Only start, stop, restart, or reload Avibe when the user explicitly asks or when a change cannot take effect otherwise; explain why before doing it.
- If an agent must restart Avibe from an active conversation, use
vibe restart --delay-seconds 60so the current session can receive the reply before the restart lands. - Tell the user whether the change is global or scope-specific.
API First Workflow
Use this order when changing Avibe configuration:
- Determine the Web UI base URL.
- Default is
http://127.0.0.1:5123. - If the user has a custom UI host or port (from
ui.setup_host/ui.setup_port), use that exact origin. - When Avibe Cloud remote access is active, the public origin (e.g.
https://<slug>.avibe.bot) also speaks the same API and requires OIDC session cookies — prefer the local origin from the host running Avibe. - Check liveness with
GET /healthorGET /status.
- Default is
- Decide whether the request belongs in:
POST /configfor global defaults, platform credentials, runtime config, agent defaults, UI config, remote-access provider settings, update policy, or global display togglesPOST /settingsfor channel-level routing, working directory, visibility, enablement, and mention policy/api/usersand/api/bind-codesfor DM user binding and user-scope settings/remote-access/*for Avibe Cloud pairing and tunnel control- host backend config instead of Avibe when the request is OpenCode, Claude Code, or Codex native behavior
- Fetch the current state from the matching GET endpoint.
- Merge the requested change in memory.
- Send the mutating request through the Web UI API with CSRF protection.
- Read back the changed resource and verify the effective payload.
- Run
POST /doctoronly when the change affects runtime health, platform credentials, or backend availability. - Report the changed scope or global keys and whether a restart was avoided or still required.
Calling the Web UI API
Mutating API calls require:
- same-origin
OriginorRefererheader - CSRF cookie named
vibe_csrf_token - matching
X-Vibe-CSRF-Tokenheader
Use this local curl pattern:
BASE="http://127.0.0.1:5123"
COOKIE_JAR="$(mktemp)"
CSRF="$(
curl -fsS -c "$COOKIE_JAR" "$BASE/api/csrf-token" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["csrf_token"])'
)"
curl -fsS -b "$COOKIE_JAR" -c "$COOKIE_JAR" \
-H "Origin: $BASE" \
-H "X-Vibe-CSRF-Token: $CSRF" \
-H "Content-Type: application/json" \
-X POST "$BASE/doctor" \
--data '{}'
For DELETE, use the same cookie jar, Origin, and CSRF header.
When the Web UI is served through Avibe Cloud, the same calls require an authenticated OIDC session cookie issued by /auth/callback. Prefer hitting 127.0.0.1:5123 directly from the local machine for maintenance work.
Do not log full request bodies when they contain tokens or secrets.
Reusable local API helper
For multi-step maintenance, use the bundled helper at scripts/vibe_api.py instead of hand-writing curl commands. The helper handles CSRF, same-origin headers, cookies, JSON encoding, and readable error output.
Resolve paths relative to this skill directory. If the skill is installed at skills/use-avibe, run:
Usage examples:
export VIBE_UI_BASE="http://127.0.0.1:5123"
python3 skills/use-avibe/scripts/vibe_api.py GET /health
python3 skills/use-avibe/scripts/vibe_api.py GET '/settings?platform=slack'
python3 skills/use-avibe/scripts/vibe_api.py POST /doctor '{}'
python3 skills/use-avibe/scripts/vibe_api.py POST /config '{"show_duration":true}'
python3 skills/use-avibe/scripts/vibe_api.py DELETE '/api/users/U123?platform=slack'
Payload can be passed as inline JSON, as @payload.json, or as - to read JSON from stdin.
For scope updates, still fetch and merge first:
API_HELPER="skills/use-avibe/scripts/vibe_api.py"
python3 "$API_HELPER" GET '/settings?platform=slack' > /tmp/slack_settings.json
python3 - <<'PY'
import json
from pathlib import Path
settings = json.loads(Path("/tmp/slack_settings.json").read_text())
channels = settings.get("channels") or {}
channels["C123"] = {
**channels.get("C123", {}),
"enabled": True,
"show_message_types": channels.get("C123", {}).get("show_message_types") or ["assistant"],
"custom_cwd": channels.get("C123", {}).get("custom_cwd"),
"require_mention": channels.get("C123", {}).get("require_mention"),
"routing": {
**(channels.get("C123", {}).get("routing") or {}),
"agent_name": "codex",
"model": "gpt-5.4",
"reasoning_effort": "high",
"codex_model": "gpt-5.4",
"codex_reasoning_effort": "high",
},
}
Path("/tmp/slack_payload.json").write_text(json.dumps({"platform": "slack", "channels": channels}))
PY
python3 "$API_HELPER" POST /settings @/tmp/slack_payload.json
python3 "$API_HELPER" GET '/settings?platform=slack'
Runtime Layout
Avibe stores runtime data under ~/.avibe/ by default, or under AVIBE_HOME when that env var is set. Existing default ~/.vibe_remote/ homes may be migrated to ~/.avibe/ with ~/.vibe_remote kept as a back-symlink. The only paths an agent normally needs:
~/.avibe/config/config.json— global config; mutate throughPOST /config, not by editing the file~/.avibe/logs/vibe_remote.log— main application log; read viaPOST /logs~/.avibe/screenshots/— default output directory forvibe screenshot~/.avibe/state/user_preferences.md— shared long-term preference file (safe to read and update)
Agent harness state is managed through vibe agent run, vibe task, vibe watch, and vibe runs (or their API endpoints), not by editing persistence files. Everything else under state/ and runtime/ is internal — treat it as opaque.
API Endpoint Reference
Health and inspection
GET /health- returns
{"status":"ok"}when the Web UI server is reachable
- returns
GET /status- returns runtime status, running state, PID metadata, and last action
GET /doctor- reads the latest persisted doctor result
POST /doctor- runs doctor immediately and returns the result
POST /logs- payload:
{"lines": 500, "source": "service"} sourcecan beserviceor another source listed in the response; useallfor aggregated logs
- payload:
GET /version- returns current version and update metadata
GET /api/csrf-token- issues the
vibe_csrf_tokencookie and returns the matching token value forX-Vibe-CSRF-Token
- issues the
GET /platforms- returns the static catalog of supported IM platforms only (id, config_key, title/description i18n keys, credential field names, capabilities). It does not include enablement or credential-presence state — fetch
/configto see which platforms are enabled and whether credentials are configured.
- returns the static catalog of supported IM platforms only (id, config_key, title/description i18n keys, credential field names, capabilities). It does not include enablement or credential-presence state — fetch
Global config
GET /config- returns the current V2 config payload
POST /config- accepts a partial object, deep-merges it with current config, validates it through
V2Config.from_payload, then persists it - use for platform credentials, enabled platforms, primary platform, runtime defaults, agent defaults, UI config, remote-access provider settings, update policy, and global toggles
- the handler only persists and (for
remote_access) reconciles the cloudflared tunnel; running platform adapters keep using their previous credentials and transport until a restart. Plan avibe restart --delay-seconds 60after any credential,proxy_url, or transport-level change.
- accepts a partial object, deep-merges it with current config, validates it through
Important config payload shape:
{
"platform": "slack",
"platforms": {
"enabled": ["slack", "discord", "telegram", "lark", "wechat"],
"primary": "slack"
},
"mode": "self_host",
"version": "v2",
"slack": {
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"signing_secret": "...",
"team_id": "T...",
"team_name": "...",
"app_id": "A...",
"require_mention": false,
"disable_link_unfurl": false,
"proxy_url": null
},
"discord": {
"bot_token": "...",
"application_id": "...",
"require_mention": false,
"thread_auto_archive_minutes": 10080,
"guild_allowlist": null,
"guild_denylist": null,
"proxy_url": null
},
"telegram": {
"bot_token": "123:abc",
"require_mention": true,
"forum_auto_topic": true,
"use_webhook": false,
"webhook_url": null,
"webhook_secret_token": null,
"allowed_chat_ids": null,
"allowed_user_ids": null,
"proxy_url": null
},
"lark": {
"app_id": "...",
"app_secret": "...",
"require_mention": false,
"domain": "feishu",
"proxy_url": null
},
"wechat": {
"bot_token": "...",
"base_url": "https://ilinkai.weixin.qq.com",
"cdn_base_url": "https://novac2c.cdn.weixin.qq.com/c2c",
"require_mention": false,
"proxy_url": null
},
"runtime": {
"default_cwd": "/path/to/workdir",
"log_level": "INFO"
},
"agents": {
"opencode": {
"enabled": true,
"cli_path": "opencode",
"default_agent": null,
"default_model": null,
"default_reasoning_effort": null,
"error_retry_limit": 1
},
"claude": {
"enabled": true,
"cli_path": "claude",
"default_model": null,
"idle_timeout_seconds": 600
},
"codex": {
"enabled": true,
"cli_path": "codex",
"default_model": null,
"idle_timeout_seconds": 600
}
},
"ui": {
"setup_host": "127.0.0.1",
"setup_port": 5123,
"open_browser": true
},
"remote_access": {
"provider": "vibe_cloud",
"vibe_cloud": {
"enabled": false,
"backend_url": "https://avibe.bot",
"public_url": "",
"instance_id": "",
"client_id": "",
"issuer": "",
"authorization_endpoint": "",
"token_endpoint": "",
"jwks_uri": "",
"redirect_uri": "",
"tunnel_token": "",
"instance_secret": "",
"session_secret": "",
"cloudflared_path": "",
"dev_login_hint": ""
}
},
"update": {
"auto_update": true,
"check_interval_minutes": 60,
"idle_minutes": 30,
"notify_admins": true
},
"ack_mode": "typing",
"language": "en",
"show_duration": false,
"include_time_info": true,
"include_user_info": true,
"reply_enhancements": true
}
Discord server access belongs to /settings, not /config. Store enabled
servers under guilds, next to channel settings:
{
"platform": "discord",
"guilds": {
"900740769198006293": { "enabled": true }
},
"channels": {
"1067738479234138202": { "enabled": true }
}
}
When switching the active platform, update platforms.primary and make sure platforms.enabled contains the new primary. Keep the legacy platform field aligned for readability, but platforms.primary is the real multi-platform source of truth.
Per-platform fields worth knowing about:
- every platform inherits
proxy_urlfrom the sharedBaseIMConfig. Set it when the host machine cannot reach the upstream API directly. Accepts standard HTTP/HTTPS proxy URLs and anysocks*://URL (socks4,socks4a,socks5,socks5h). SOCKS variants route throughaiohttp_socks. slack.disable_link_unfurlsuppresses link previews when posting messages.discord.thread_auto_archive_minutesmust be one of60,1440,4320, or10080.discord.guild_allowlist/guild_denylistare legacy input lists; current runtime server access lives in/settingsunderguilds.telegram.forum_auto_topicenables automatic topic creation in forum chats;use_webhookpluswebhook_url/webhook_secret_tokenswitches Telegram delivery to the webhook transport.telegram.allowed_chat_ids/allowed_user_idsrestrict which chats and users Telegram will respond to.wechat.cdn_base_urlcontrols the CDN host used for fetching WeChat media; the defaultnovac2c.cdn.weixin.qq.comis the official c2c CDN.update.auto_update,check_interval_minutes, andidle_minutescontrol unattended upgrades;notify_adminsposts the upgrade announcement to bound admins.ui.setup_host,setup_port, andopen_browserconfigure the local Web UI server; changing host or port requiresPOST /ui/reload.
Secret-bearing config fields that you should not print:
slack.bot_tokenslack.app_tokenslack.signing_secretdiscord.bot_tokentelegram.bot_tokentelegram.webhook_secret_tokenlark.app_id(treat as a sensitive identifier)lark.app_secretwechat.bot_tokengateway.workspace_tokengateway.client_secretremote_access.vibe_cloud.tunnel_tokenremote_access.vibe_cloud.instance_secretremote_access.vibe_cloud.session_secretremote_access.vibe_cloud.client_id- any
proxy_urlvalue that embeds credentials such asuser:pass@host
Channel settings
GET /settings?platform=<platform>- returns channel settings, user settings, and bind codes for one platform
POST /settings- payload:
{"platform": "<platform>", "channels": {...}} - validates message visibility and routing, normalizes Claude reasoning, persists the full channel map for that platform
- payload:
Important: POST /settings replaces the entire channels map for the selected platform. To change one channel:
GET /settings?platform=<platform>- copy
response.channels - merge or add one channel entry
POST /settingswith the full mergedchannelsobjectGET /settings?platform=<platform>again and verify
Channel entry shape:
{
"enabled": true,
"show_message_types": ["assistant"],
"custom_cwd": "/path/to/repo",
"require_mention": null,
"require_bind": null,
"routing": {
"agent_name": "codex",
"model": "gpt-5.4",
"reasoning_effort": "high",
"opencode_agent": null,
"opencode_model": null,
"opencode_reasoning_effort": null,
"claude_agent": null,
"claude_model": null,
"claude_reasoning_effort": null,
"codex_agent": "reviewer",
"codex_model": "gpt-5.4",
"codex_reasoning_effort": "high"
}
}
Field meanings:
enabled: whether this channel is allowed to use Avibeshow_message_types: visible intermediate messages; allowed values aresystem,assistant,toolcallcustom_cwd: scope-level working directory override; empty string ornullmeans use global defaultrequire_mention:nullinherits the platform default,truerequires mention,falsedisables mention gating for that channelrequire_bind:null/falselets any channel member use the bot (current default);truegates the channel to bound users only — messages from unbound senders are silently ignored (no denial reply), while the bot's own replies stay visible to everyone. Enforced in the shared auth pipeline, so it applies on every platform. Bind is platform-wide, sorequire_bindmeans "is this sender a bound user", not a per-channel allowlist.routing.agent_name: Vibe Agent name for this scope, ornullto inherit the default Agentrouting.model: canonical scope-level model override for the selected Agent backendrouting.reasoning_effort: canonical scope-level reasoning override for the selected Agent backendrouting.<backend>_agent: backend-specific subagentrouting.<backend>_model/routing.<backend>_reasoning_effort: legacy aliases accepted on input and derived on read-back; do not treat them as independent state
DM users and bind codes
GET /api/users?platform=<platform>- returns bound DM users for one platform
POST /api/users- payload:
{"platform": "<platform>", "users": {...}} - merges included users into existing users and preserves each existing user's
dm_chat_id
- payload:
POST /api/users/<user_id>/admin- payload:
{"platform": "<platform>", "is_admin": true}
- payload:
DELETE /api/users/<user_id>?platform=<platform>- removes a bound user; this is the reliable way to revoke DM access
GET /api/bind-codes- returns all bind codes
POST /api/bind-codes- payload:
{"type": "one_time"}or{"type": "expiring", "expires_at": "2026-04-18"}
- payload:
DELETE /api/bind-codes/<code>- deactivates a bind code
GET /api/setup/first-bind-code- returns an existing valid setup bind code or creates a new one-time code
Important: user updates are not field patches. Before changing a user's routing, cwd, visibility, or enabled flag, read the current user object and send the merged full user entry.
User entry shape:
{
"display_name": "Alice",
"is_admin": false,
"bound_at": "2026-03-20T12:34:56+00:00",
"enabled": true,
"show_message_types": ["assistant"],
"custom_cwd": "/path/to/repo",
"routing": {
"agent_name": "claude",
"model": "claude-sonnet-4-6",
"reasoning_effort": "high",
"opencode_agent": null,
"opencode_model": null,
"opencode_reasoning_effort": null,
"claude_agent": "reviewer",
"claude_model": "claude-sonnet-4-6",
"claude_reasoning_effort": "high",
"codex_agent": null,
"codex_model": null,
"codex_reasoning_effort": null
}
}
DM caveat: current DM authorization checks whether the user is bound, not whether enabled is true. If the user wants to revoke DM access, use DELETE /api/users/<user_id>?platform=<platform> instead of only setting enabled to false.
Platform discovery and validation
GET /slack/manifest- returns Slack app manifest JSON for setup
POST /slack/auth_test- payload:
{"bot_token": "xoxb-..."}
- payload:
POST /slack/channels- payload:
{"bot_token": "xoxb-...", "browse_all": false}
- payload:
POST /discord/auth_test- payload:
{"bot_token": "..."}
- payload:
POST /discord/guilds- payload:
{"bot_token": "..."}
- payload:
POST /discord/channels- payload:
{"bot_token": "...", "guild_id": "..."}
- payload:
POST /telegram/auth_test- payload:
{"bot_token": "123:abc"}
- payload:
POST /telegram/chats- payload:
{"include_private": false}
- payload:
POST /lark/auth_test- payload:
{"app_id": "...", "app_secret": "...", "domain": "feishu"}
- payload:
POST /lark/chats- payload:
{"app_id": "...", "app_secret": "...", "domain": "feishu"}
- payload:
POST /lark/temp_ws/start- payload:
{"app_id": "...", "app_secret": "...", "domain": "feishu"}
- payload:
POST /lark/temp_ws/stop- payload:
{}
- payload:
POST /wechat/qr_login/start- payload:
{"base_url": "https://ilinkai.weixin.qq.com"}or{}
- payload:
POST /wechat/qr_login/poll- payload:
{"session_key": "..."}
- payload:
WeChat QR login is special: when login is confirmed and a token is returned, the API auto-binds the WeChat user and schedules an internal service restart so the new token can take effect. Do not add an extra restart unless the user asks.
Remote access (Avibe Cloud)
These endpoints drive the managed avibe.bot tunnel that exposes the local Web UI to other devices. They are paired with the remote_access.vibe_cloud block under /config.
GET /remote-access/status- returns
enabled,paired,public_url,running(tunnel up),pid,pid_state, plusbinary_found/binary_path/binary_versionfor the resolvedcloudflaredexecutable. Userunning: trueto assert the tunnel is up.
- returns
POST /remote-access/vibe-cloud/pair- payload:
{"pairing_key": "vrp_..."} - exchanges the one-time key for an OIDC client, tunnel token, and persists the full
remote_access.vibe_cloudblock; on success Avibe launches the cloudflared tunnel
- payload:
POST /remote-access/start- payload:
{} - starts the cloudflared tunnel using the persisted pairing config
- payload:
POST /remote-access/stop- payload:
{} - stops the cloudflared tunnel; configuration is preserved so
startcan resume later
- payload:
GET /auth/callback- OIDC redirect target used by avibe.bot during sign-in. Browser-driven; do not call directly from automation.
GET /api/session- always returns
200with an auth-state payload, never401. Three shapes:{"remote": false}when remote access is not configured for this request,{"remote": true, "authenticated": false}when remote access is on but the caller has no valid session cookie, and{"remote": true, "authenticated": true, "email": "..."}when signed in. Checkauthenticatedto gate behavior; do not poll for HTTP status codes.
- always returns
POST /auth/logout- clears the avibe.bot session cookie on this device. Does not stop the tunnel.
The session cookie is bound to the tunnel session and expires after roughly 24 hours; the server slides the TTL when activity reaches the half-life. Do not invent custom auth headers — rely on the existing cookie issued by /auth/callback.
Treat tunnel_token, instance_secret, session_secret, and client_id from remote_access.vibe_cloud as opaque secrets.
Backend and local helper endpoints
GET /cli/detect?binary=<name-or-path>- detects a CLI binary path
POST /agent/<name>/installnamemust beopencode,claude, orcodex
POST /opencode/options- payload:
{"cwd": "/path/to/repo"} - returns OpenCode model, agent, and reasoning option data for that cwd
- payload:
POST /opencode/setup-permission- intentionally writes OpenCode native config to set
permissiontoallow
- intentionally writes OpenCode native config to set
GET /claude/agents?cwd=/path/to/repoGET /codex/agents?cwd=/path/to/repoGET /claude/modelsGET /codex/modelsPOST /browse- payload:
{"path": "~", "show_hidden": false}
- payload:
Control endpoints
POST /control- payload:
{"action": "start"},{"action": "stop"}, or{"action": "restart"}
- payload:
POST /ui/reload- payload:
{"host": "127.0.0.1", "port": 5123}
- payload:
POST /upgrade- payload:
{} - triggers an in-place upgrade to the latest released version using the same code path as
vibe upgrade
- payload:
Avoid these for routine configuration. POST /control starts, stops, or restarts the service. POST /ui/reload restarts only the Web UI server to apply host or port changes. POST /upgrade reinstalls Avibe and then restarts the service. Use them only with explicit user intent or a concrete need.
When the restart is initiated by an agent from an active conversation, use the CLI delayed form vibe restart --delay-seconds 60 so the transport does not cut off the current reply.
Scope and Precedence Rules
Agent selection
Agent resolution priority is:
- existing Agent Session backend snapshot, when the message belongs to an existing session/thread
- scope-level
routing.agent_namefrom/settingsor/api/users, for new sessions - global default Vibe Agent from the Agent catalog
- registered backend compatibility fallback, only when no enabled default Agent is available
If the user names a specific channel or DM and wants a specific Agent, use the scope API, not global /config. New routing is Agent-based.
Working directory
Working directory resolution is:
custom_cwdon the target channel or user scoperuntime.default_cwdfrom/config
Message visibility
show_message_types is scope-local. Preserve existing values unless the user wants an explicit replacement.
If a user asks for "vault messages", "internal messages", or "tool execution messages", map that request to show_message_types. Current Avibe does not expose a separate vault field.
Mention policy
require_mention works like this:
null: inherit platform default from/configtrue: require mention in that channelfalse: do not require mention in that channel
Recipes
Route one Slack channel to Codex
Goal:
- enable Slack channel
C123 - route it to Codex
- use Codex subagent
reviewer - use model
gpt-5.4 - set reasoning
high
API flow:
GET /settings?platform=slack- merge
channels.C123 POST /settingswith all Slack channels- read back
GET /settings?platform=slack
Merged channel entry:
{
"enabled": true,
"show_message_types": ["assistant"],
"custom_cwd": null,
"require_mention": null,
"routing": {
"agent_name": "codex",
"model": "gpt-5.4",
"reasoning_effort": "high",
"opencode_agent": null,
"opencode_model": null,
"opencode_reasoning_effort": null,
"claude_agent": null,
"claude_model": null,
"claude_reasoning_effort": null,
"codex_agent": "reviewer",
"codex_model": "gpt-5.4",
"codex_reasoning_effort": "high"
}
}
Route one channel to OpenCode with a subagent
Use /settings and set:
routing.agent_name = "opencode"routing.opencode_agent = "<agent>"routing.model = "<model>"if requestedrouting.reasoning_effort = "<effort>"if requested
If the user wants OpenCode-native defaults, providers, MCP servers, skills, plugins, or API credentials, use OpenCode config instead of Avibe scope routing.
Route one scope to Claude with model and reasoning
Use /settings for a channel or /api/users for a DM user and set:
routing.agent_name = "claude"routing.claude_agent = "<agent>"if requestedrouting.model = "<model>"routing.reasoning_effort = "<effort>"
The API normalizes Claude reasoning for incompatible model combinations; verify by reading back the saved payload.
Change the global default working directory
Use POST /config:
{
"runtime": {
"default_cwd": "/path/to/workdir"
}
}
Do not overwrite scope-level custom_cwd entries.
Show tool execution messages in one channel
Use /settings and add toolcall to the target channel's show_message_types.
Preserve existing system and assistant values unless the user asked for a full replacement.
Switch primary platform
Use POST /config and keep platforms.enabled complete:
{
"platform": "discord",
"platforms": {
"enabled": ["slack", "discord"],
"primary": "discord"
}
}
Make sure the target platform config section exists and validates. Do not delete old platform config unless the user explicitly asks.
Configure an outbound proxy for an IM platform
When the host cannot reach a platform API directly, set proxy_url on that platform's config block.
Use POST /config with only the proxy field for the affected platform:
{
"telegram": {
"proxy_url": "http://proxy.internal:3128"
}
}
Notes:
proxy_urlacceptshttp://,https://, and anysocks*://scheme (socks4,socks4a,socks5,socks5h). The SOCKS variants route throughaiohttp_socks(bundled).- Set the field to
null(or omit it on a fresh save) to disable the proxy. POST /configonly persists the new value; running platform adapters keep their old transport until the service restarts. After saving, runvibe restart --delay-seconds 60(orPOST /control {"action":"restart"}with the user's confirmation) so the proxy applies to live connections.- Do not paste credentialed proxy URLs (
user:pass@host) into logs or chat replies; mask the credentials portion when reporting back.
Pair Avibe Cloud remote access
Goal: connect the local Web UI to avibe.bot so it is reachable from another device.
- The user signs in at
https://avibe.bot, creates a remote-access bot, and copies the one-time pairing key (formatvrp_...). - Call
POST /remote-access/vibe-cloud/pairwith{"pairing_key": "vrp_..."}from the local Web UI origin. - Verify with
GET /remote-access/status—enabled: true,paired: true,public_urlpopulated,running: true. - Have the user open
public_urland sign in with the same avibe.bot account.
Alternatively, drive the same flow from the CLI:
vibe remote # guided flow
vibe remote pair vrp_abc123 # paste key directly
vibe remote status --json # inspect tunnel state
vibe remote stop # stop tunnel; keep config
vibe remote start # bring tunnel back up
Treat the pairing key, tunnel token, instance secret, and session secret as opaque. Never echo them in chat replies.
Generate a DM bind code
Use POST /api/bind-codes:
{
"type": "one_time"
}
For an expiring code:
{
"type": "expiring",
"expires_at": "2026-04-18"
}
Do not expose bind codes unless the user explicitly asks for them.
Agent Harness: Runs, Tasks, and Watches
Use the harness commands when the user wants an agent to leave the current turn and continue later, repeatedly, or in the background. The mental model is:
vibe agent run: run one concrete Agent job now; add--asyncwhen it should continue in the backgroundvibe task: save a time trigger that creates Agent Runs latervibe watch: save a condition trigger that waits for a process, file, log, CI, review, or other signal, then creates a follow-up Agent Runvibe runs: inspect and cancel concrete run records
Agents should prefer these managed harness commands over ad-hoc detached shells when the work should be inspectable, resumable, or report back to the conversation.
Preferred CLI shape:
- one-shot direct run:
vibe agent run --agent '<agent-name>' --message '...' - one-shot async run:
vibe agent run --async --session-id '<session-id>' --message '...' - fork a Session for an alternate path:
vibe agent run --fork-session '<source-session-id>' --message '...' - delegated async run that reports back:
vibe agent run --async --session-id '<target-session-id>' --callback-session-id '<caller-session-id>' --message '...' - recurring task:
vibe task add --session-id '<session-id>' --cron '<expr>' --message '...' - one-off task:
vibe task add --session-id '<session-id>' --at '<ISO-8601>' --message '...' - immediate rerun:
vibe task run <id> - managed background watch:
vibe watch add --session-id '<session-id>' --message '...' -- <cmd>(or--shell '<cmd>'to pass a single shell string) - update a watch:
vibe watch update <id> --name '...' --timeout 1200 - inspect a run:
vibe runs show <run-id> - cancel a run:
vibe runs cancel <run-id>
Delivery controls (apply to vibe agent run --create-session, vibe task add, and vibe watch add):
--session-idcontrols which Agent Session Avibe continues using- when you want to keep the current session, use the current Agent Session ID
- if no usable Agent Session ID is available, confirm the target session first instead of guessing
- use
--post-to channelwhen the task or watch should keep the same Agent Session but publish to the parent channel - use
--deliver-key '<key>'only when delivery must go to a different explicit target than the continued session - do not combine
--post-toand--deliver-keyin the same command --messageand--message-fileare the current user-message flags for task, watch, and agent-run commandsvibe task addstores the message template and creates Agent Runs when the time trigger firesvibe agent run --asyncqueues one Agent Run immediately without storing a task definition--fork-sessioncreates a new Agent Session by forking the source Session's native backend context. Use it when work should branch from an existing context without mutating that source Session.- fork overrides are intentionally narrow:
--agent,--model, and--reasoning-effortcan override the forked Session only if the backend stays the same; cross-backend forks are rejected. - do not combine
--fork-sessionwith--session-id,--create-session,--deliver-key, or--post-to. --callback-session-idon an async Agent Run sends the final result text back into the caller Session as a follow-up Agent message; it is independent from--post-toand--deliver-keyvibe watch adduses--messageas the instruction template for the Agent Run created after the waiter reaches a reportable state
Legacy compatibility:
--session-keyis still accepted for old scripts; do not use it in new examples or instructions unless the user explicitly asks for legacy targeting--prompt/--prompt-fileare deprecated compatibility inputs. Do not use them in new invocations; use--message/--message-file.vibe hook sendis deprecated. Do not use it for new one-shot async work; usevibe agent run --async.
Operational guidance:
- use
vibe task listbefore editing or deleting an existing task; usevibe watch listbefore touching a managed watch - if this is the first time using
vibe task add,vibe agent run,vibe runs, orvibe watch add, read the matching--helpoutput first — watches accept additional flags like--shell,--timeout(per-cycle),--lifetime-timeout(overall),--forever,--retry-exit-code, and--retry-delay - use
vibe task update <id>to keep the same task ID while changing name, schedule, message, agent, or target - use
vibe watch update <id> ...when you must rename, retarget, or change the waiter/options - use
vibe task list --briefandvibe watch list --brieffor scheduling-focused summaries vibe task listhides completed one-shot tasks by default; usevibe task list --allwhen you need full history- use
vibe task show <id>,vibe watch show <id>, orvibe runs show <run-id>to inspect stored fields and runtime state - use
vibe task pause/vibe task resumeandvibe watch pause/vibe watch resumeto disable a task or watch without deleting it - treat
warningsfrom task, watch, agent-run, or runs commands as delivery-risk hints to fix proactively
Agent Backend Capability Matrix
Current Avibe Agent capabilities are:
| Backend | Select through Vibe Agent | Subagent | Model | Reasoning |
|---|---|---|---|---|
| OpenCode | yes | yes | yes | yes |
| Claude | yes | yes | yes | yes |
| Codex | yes | yes | yes | yes |
Behavior notes:
- OpenCode subagents are selected through
routing.opencode_agentor through prefix routing such asreviewer: .... - Claude subagents are selected through
routing.claude_agentor prefix routing. - Codex subagents are selected through
routing.codex_agentor prefix routing. - Claude reasoning is selected through
routing.claude_reasoning_effort; common values arelow,medium, andhigh, and some models also allowmax. - If a Claude reasoning value is invalid for the chosen model, the API normalizes or drops that override and falls back to the backend default.
Subagent and Prefix Routing
If the user asks for subagents, remember:
- OpenCode, Claude, and Codex support prefix-triggered subagent selection like
planner: draft a migration plan - when a subagent definition provides its own default model or reasoning setting, that subagent-level value overrides the channel default
- Claude subagents are discovered from markdown files under:
~/.claude/agents/- project
.claude/agents/
- Codex custom agents are discovered from TOML files under:
~/.codex/agents/- project
.codex/agents/
- OpenCode subagent and model defaults come from the OpenCode runtime/config rather than only from Avibe's own config
Host Backend Guidance
When the request belongs to the host backend, do not force it into Avibe config.
OpenCode
Use OpenCode-native config when the user wants to change:
- personal default model
- global reasoning behavior
- provider and API keys
- MCP servers
- skills, plugins, tools, or project-local OpenCode behavior
Important locations:
~/.config/opencode/opencode.json: global OpenCode config- project
opencode.json: project-level OpenCode config file .opencode/: project-local OpenCode config directory~/.config/opencode/agents/: global OpenCode agents.opencode/agents/: project-local OpenCode agents~/.config/opencode/skills/: global OpenCode skills.opencode/skills/: project-local OpenCode skills
Relevant docs:
- config:
https://opencode.ai/docs/config/ - skills:
https://opencode.ai/docs/skills - plugins:
https://opencode.ai/docs/plugins/ - MCP servers:
https://opencode.ai/docs/mcp-servers/
Inside Avibe, a scope can select an OpenCode-backed Vibe Agent and then set subagent, model, and reasoning effort overrides. Use POST /opencode/setup-permission only for the specific permission helper.
Claude Code
Use Claude-native config when the user wants to change:
- Claude subagent definitions
- Claude skills
- CLAUDE instructions and project rules
Important locations:
~/.claude/agents/: global Claude subagents.claude/agents/: project subagents~/.claude/skills/: global Claude skills.claude/skills/: project skills
Relevant docs:
- subagents:
https://docs.anthropic.com/en/docs/claude-code/sub-agents
Inside Avibe, a scope can select a Claude-backed Vibe Agent and then set model, subagent, and reasoning effort overrides.
Codex
Use Codex-native config when the user wants to change:
- personal default model
- global reasoning defaults
- MCP servers, approvals, or sandbox policy
- Codex CLI profiles and behavior outside Avibe
Important locations:
~/.codex/config.toml: global Codex config.codex/config.toml: project-local Codex config~/.codex/agents/: global Codex custom agents.codex/agents/: project-local Codex custom agents
Relevant docs:
- config basics:
https://developers.openai.com/codex/config-basic/ - config reference:
https://developers.openai.com/codex/config-reference/ - CLI overview:
https://developers.openai.com/codex/cli - subagents:
https://developers.openai.com/codex/subagents
Inside Avibe, a scope can select a Codex-backed Vibe Agent and then set subagent, model, and reasoning effort overrides.
CLI Reference
Use the CLI only when the Web UI API cannot cover the request, when the user explicitly asks for the command, or when restarting/upgrading from an active conversation.
Service lifecycle:
vibe— start Avibe if needed and open the local Web UI; it does not stop an already-running servicevibe status— print service status, PID metadata, and last actionvibe stop— stop main service, Web UI, and any background helpersvibe restart— stop and re-start the service. Pass--delay-seconds Nwhen triggering from inside an active conversation so the current reply has time to deliver before the restart lands.vibe doctor— run diagnostics and print the latest resultvibe version— print the installed version
Updates:
vibe check-update— query the release feed and print whether an upgrade is availablevibe upgrade— reinstall Avibe to the latest release. The CLI does not restart the service for you; it prints "Please restart vibe..." and exits. Runvibe restart(orvibe restart --delay-seconds 60from inside an active conversation) yourself after the upgrade reports success. The Web UI'sPOST /upgradeendpoint is the path that performs an automatic restart.
Remote access:
vibe remote— guided Avibe Cloud pairingvibe remote pair <key>— pair using an existing one-time keyvibe remote status [--json]— show tunnel + OIDC statevibe remote start/vibe remote stop— manage the cloudflared tunnel after pairing
Screenshots:
vibe screenshot— capture the local desktop to~/.avibe/screenshots/vibe screenshot --output <path>/--json— pick an explicit output path or get machine-readable output
Scheduled tasks:
vibe task add,vibe task update,vibe task list [--all|--brief],vibe task show <id>,vibe task run <id>,vibe task pause <id>,vibe task resume <id>,vibe task remove <id>
Agent runs:
vibe agent run— run one Agent job now; add--asyncfor one-shot background workvibe runs list,vibe runs show <id>,vibe runs cancel <id>— inspect and manage concrete Agent Run records
Watches:
vibe watch add,vibe watch update <id>,vibe watch list [--brief],vibe watch show <id>,vibe watch pause <id>,vibe watch resume <id>,vibe watch remove <id>
For any subcommand, prefer <command> --help before composing a new invocation. The delivery flags shared by harness commands are --session-id, --post-to, and --deliver-key, with command-specific mutual exclusion rules. Use --message / --message-file for user messages. vibe task add and vibe watch add take --name; only vibe task add takes --cron / --at / --timezone; vibe agent run takes --async; and vibe watch add takes its own waiter options (--shell or a positional command after --, --cwd, --timeout, --forever, --lifetime-timeout, --retry-exit-code, --retry-delay). Do not copy flags between task, watch, and agent-run commands without checking help.
Troubleshooting
Start with evidence:
GET /statusPOST /doctorPOST /logswith a small line count and focused source- read back
/config,/settings, or/api/usersfor the affected scope
Common cases:
- config does not apply: verify the API read-back first; only restart if the changed field is startup-only
- backend missing: confirm backend is enabled, CLI path is executable, and
/cli/detectfinds it - channel does not respond: verify
/settings?platform=<platform>contains the channel andenabledis true - wrong repository/cwd: inspect
custom_cwdandruntime.default_cwd - DM access denied: inspect
/api/users?platform=<platform>and bind-code state - platform cannot reach API: inspect
proxy_urlon that platform's config block; check logs for proxy/TLS errors; for SOCKS proxies confirmaiohttp_socksis installed - remote URL is unreachable:
GET /remote-access/statusshould showrunning: trueandbinary_found: true; if not, runPOST /doctorand check the configuredcloudflared_path - remote session expired: instruct the user to re-sign in at the public URL (24h TTL with sliding renewal); use
POST /auth/logoutto clear a stale session on the current device - upgrade did not apply: inspect the response from
POST /upgrade(auto-restart on success) orvibe upgrade(does not auto-restart — runvibe restartmanually), then verify withvibe statusthat the new PID is running - startup failure: use
GET /status,POST /doctor, then inspect logs
Do not use vibe restart, POST /control {"action":"restart"}, or POST /ui/reload as a first response to config problems.
If a restart is still required and you are replying through an active Avibe conversation, use vibe restart --delay-seconds 60 so the current reply can be delivered before the restart lands.
Safety Boundaries
Always follow these constraints:
- never delete unrelated platform scopes
- never blank out tokens or secrets as part of an unrelated config task
- never claim a backend feature exists if current Avibe behavior does not support it
- never read, query, or hand-edit Avibe's internal state storage — go through the Web UI API or
vibeCLI - never expose bind codes, pairing keys, tunnel tokens, instance secrets, or session secrets unless the user explicitly asks
- never paste a credentialed
proxy_url(user:pass@host) back into chat — mask the credentials portion when echoing the value - always say when a requested change actually belongs in OpenCode, Claude Code, or Codex config instead of Avibe
Escalation
If the user still cannot solve a problem after API read-back checks, doctor, and log inspection, point them to the Avibe repository:
- repo:
https://github.com/avibe-bot/avibe
Use that link when:
- the behavior looks like a real bug rather than a local misconfiguration
- the user is asking for a feature Avibe does not support yet
- backend integration behavior appears inconsistent with the documented configuration surface
If the user wants to contribute back, suggest opening an issue or a pull request in that repository.
Response Pattern
When you complete an Avibe maintenance task, report back with:
- which API endpoint changed the state
- whether the change is global or scope-specific
- which keys changed
- the read-back or doctor evidence
- whether a restart was avoided, deferred, or still required and why
Related skills
n8n Architect
EtienneLescot
Create, edit, and validate n8n workflows and automation configurations.
Deploy to Vercel
vercel-labs
Deploy your app to Vercel with preview or production environments.
Vercel CLI with Tokens
vercel-labs
Deploy and manage Vercel projects using token-based authentication instead of interactive login.
Understand Diff
Egonex-AI
Analyze git diffs and pull requests to understand changes, affected components, and risks.