Safely inspect and modify local Avibe configuration, routing, runtime settings, watches, scheduled tasks, Avibe Cloud remote access, and operational state.
version
0.6.1
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 vibe CLI. Avibe's internal storage is opaque — do not read, query, or hand-edit it.
POST /config persists 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 through POST /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 60 so 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 /health or GET /status.
Decide whether the request belongs in:
POST /config for global defaults, platform credentials, runtime config, agent defaults, UI config, remote-access provider settings, update policy, or global display toggles
POST /settings for channel-level routing, working directory, visibility, enablement, and mention policy
/api/users and /api/bind-codes for 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 /doctor only 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.
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.
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 through POST /config, not by editing the file
~/.avibe/logs/vibe_remote.log — main application log; read via POST /logs
~/.avibe/screenshots/ — default output directory for vibe 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
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"}
source can be service or another source listed in the response; use all for aggregated logs
GET /version
returns current version and update metadata
GET /api/csrf-token
issues the vibe_csrf_token cookie and returns the matching token value for X-Vibe-CSRF-Token
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 /config to see which platforms are enabled and whether credentials are configured.
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 a vibe restart --delay-seconds 60 after any credential, proxy_url, or transport-level change.
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_url from the shared BaseIMConfig. Set it when the host machine cannot reach the upstream API directly. Accepts standard HTTP/HTTPS proxy URLs and any socks*:// URL (socks4, socks4a, socks5, socks5h). SOCKS variants route through aiohttp_socks.
slack.disable_link_unfurl suppresses link previews when posting messages.
discord.thread_auto_archive_minutes must be one of 60, 1440, 4320, or 10080.
discord.guild_allowlist / guild_denylist are legacy input lists; current runtime server access lives in /settings under guilds.
telegram.forum_auto_topic enables automatic topic creation in forum chats; use_webhook plus webhook_url / webhook_secret_token switches Telegram delivery to the webhook transport.
telegram.allowed_chat_ids / allowed_user_ids restrict which chats and users Telegram will respond to.
wechat.cdn_base_url controls the CDN host used for fetching WeChat media; the default novac2c.cdn.weixin.qq.com is the official c2c CDN.
update.auto_update, check_interval_minutes, and idle_minutes control unattended upgrades; notify_admins posts the upgrade announcement to bound admins.
ui.setup_host, setup_port, and open_browser configure the local Web UI server; changing host or port requires POST /ui/reload.
Secret-bearing config fields that you should not print:
slack.bot_token
slack.app_token
slack.signing_secret
discord.bot_token
telegram.bot_token
telegram.webhook_secret_token
lark.app_id (treat as a sensitive identifier)
lark.app_secret
wechat.bot_token
gateway.workspace_token
gateway.client_secret
remote_access.vibe_cloud.tunnel_token
remote_access.vibe_cloud.instance_secret
remote_access.vibe_cloud.session_secret
remote_access.vibe_cloud.client_id
any proxy_url value that embeds credentials such as user:pass@host
Channel settings
GET /settings?platform=<platform>
returns channel settings, user settings, and bind codes for one platform
enabled: whether this channel is allowed to use Avibe
show_message_types: visible intermediate messages; allowed values are system, assistant, toolcall
custom_cwd: scope-level working directory override; empty string or null means use global default
require_mention: null inherits the platform default, true requires mention, false disables mention gating for that channel
require_bind: null/false lets any channel member use the bot (current default); true gates 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, so require_bind means "is this sender a bound user", not a per-channel allowlist.
routing.agent_name: Vibe Agent name for this scope, or null to inherit the default Agent
routing.model: canonical scope-level model override for the selected Agent backend
routing.reasoning_effort: canonical scope-level reasoning override for the selected Agent backend
routing.<backend>_model / routing.<backend>_reasoning_effort: legacy aliases accepted on input and derived on read-back; do not treat them as independent state
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"}
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.
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.
payload: {"base_url": "https://ilinkai.weixin.qq.com"} or {}
POST /wechat/qr_login/poll
payload: {"session_key": "..."}
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 /api/remote-access/status
returns enabled, paired, public_url, running (tunnel up), pid, pid_state, plus binary_found / binary_path / binary_version for the resolved cloudflared executable. Use running: true to assert the tunnel is up.
POST /api/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_cloud block; on success Avibe launches the cloudflared tunnel
POST /api/remote-access/start
payload: {}
starts the cloudflared tunnel using the persisted pairing config
POST /api/remote-access/stop
payload: {}
stops the cloudflared tunnel; configuration is preserved so start can resume later
POST /api/remote-access/optimize-route
payload: {}
starts one guarded make-before-break route evaluation; it does not override a pinned protocol
GET /api/remote-access/network-interfaces
returns currently assigned, up, non-loopback local source addresses that may be selected for cloudflared
applies policy-only changes immediately; Connector-affecting changes start and verify a replacement before draining the previous Connector, and keep the previous persisted settings when the replacement cannot become ready
POST /api/remote-access/diagnostics
payload: {}
returns bounded DNS, TCP/HTTP2, and observed-active-QUIC reachability without exposing probe targets or local interface addresses
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 200 with an auth-state payload, never 401. 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. Check authenticated to gate behavior; do not poll for HTTP status codes.
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>/install
name must be opencode, claude, or codex
POST /opencode/options
payload: {"cwd": "/path/to/repo"}
returns OpenCode model, agent, and reasoning option data for that cwd
POST /opencode/setup-permission
intentionally writes OpenCode native config to set permission to allow
GET /claude/agents?cwd=/path/to/repo
GET /codex/agents?cwd=/path/to/repo
GET /claude/models
GET /codex/models
POST /browse
payload: {"path": "~", "show_hidden": false}
Control endpoints
POST /control
payload: {"action": "start"}, {"action": "stop"}, or {"action": "restart"}
POST /ui/reload
payload: {"host": "127.0.0.1", "port": 5123}
POST /upgrade
payload: {}
triggers an in-place upgrade to the latest released version using the same code path as vibe upgrade
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_name from /settings or /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_cwd on the target channel or user scope
runtime.default_cwd from /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.
routing.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 requested
routing.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:
proxy_url accepts http://, https://, and any socks*:// scheme (socks4, socks4a, socks5, socks5h). The SOCKS variants route through aiohttp_socks (bundled).
Set the field to null (or omit it on a fresh save) to disable the proxy.
POST /config only persists the new value; running platform adapters keep their old transport until the service restarts. After saving, run vibe restart --delay-seconds 60 (or POST /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 (format vrp_...).
Call POST /remote-access/vibe-cloud/pair with {"pairing_key": "vrp_..."} from the local Web UI origin.
Verify with GET /remote-access/status — enabled: true, paired: true, public_url populated, running: true.
Have the user open public_url and 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. Runs are async by default; pass --sync only when the current CLI must wait for the result.
vibe task: save a time trigger that creates Agent Runs later
vibe watch: save a condition trigger that waits for a process, file, log, CI, review, or other signal, then creates a follow-up Agent Run
vibe 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:
delegate to another Agent in a private/background Session from an Avibe Agent shell: vibe agent run --agent '<agent-name>' --message '...'
delegate to a visible sibling Session in the same scope from an Avibe Agent shell: vibe agent run --agent '<agent-name>' --same-scope --message '...'
wait for an Agent result in the terminal: vibe agent run --sync --agent '<agent-name>' --message '...'
continue a specific existing Session: vibe agent run --session-id '<session-id>' --message '...'
explicitly steer a new message as P1 into the active Turn: vibe agent run --session-id '<session-id>' --send-now --message '...'
steer an already-queued exact head without adding a message: vibe session send-now '<session-id>'
inspect another Session's durable FIFO queue: vibe session queue list '<session-id>'
remove one exact queued message after inspecting its stable ID: vibe session queue remove '<session-id>' '<message-id>'
fork this Session for an alternate path: vibe agent run --fork-self --message '...'
fork another explicit Session for an alternate path: vibe agent run --fork-session '<source-session-id>' --message '...'
recurring task for this conversation: vibe task add --cron '<expr>' --message '...'
one-off task for this conversation: vibe task add --at '<ISO-8601>' --message '...'
task that creates a visible sibling Session: vibe task add --create-session --same-scope --cron '<expr>' --message '...'
scheduled command with no Agent turn: vibe task add --cron '<expr>' --shell '<command>'
command task with AI failure triage: vibe task add --cron '<expr>' --shell '<command>' --on-failure agent --message '<what to do>'
immediate rerun: vibe task run <id>
managed background watch for this conversation: vibe watch add --message '...' -- <cmd> (or --shell '<cmd>' to pass a single shell string)
watch that creates a visible sibling Session: vibe watch add --create-session --same-scope --message '...' -- <cmd>
In an Avibe-injected Agent shell, commands that operate on this conversation default to the current Agent Session. Omit the target when the work should continue here.
Use --session-id <id> only when the command should operate on a different existing Agent Session.
When vibe agent run --session-id <id> targets an existing Session, it sends a new message into that Session. It does not change that Session's cwd, scope, Agent, model, or reasoning settings.
When coordinating another Workbench Session, decide whether its current turn should finish or be preempted from the work dependency, urgency, and cost of discarding in-flight work. An explicit user request is one signal, not a prerequisite.
Add --send-now to explicitly select the normal content-bearing P1 behavior for an existing Session. It steers that new message into an active Turn, starts it when idle, and falls back to P3 only after a definitive refusal; it never promotes an older queued message.
Use vibe session send-now <session-id> when a Session already has queued work and no new message should be added. This promotes the existing FIFO head.
Both commands use the shared steering path for Workbench and IM Sessions. A refused or stale steer leaves the affected input durably queued and never falls back to Stop.
Use vibe session queue list <session-id> before changing another Workbench Session's queue. If an instruction is obsolete, contradictory, or duplicated, remove that exact stable row with vibe session queue remove <session-id> <message-id>. Never guess a message ID or delete another row to simulate reordering.
When vibe agent run creates a new Session, the default placement is private/background. Add --same-scope for a visible sibling Session in the same Workbench project or IM scope, or --scope-id <scopes.id> for a specific existing scope.
When a task, watch, or new Agent run creates a Session and --cwd is omitted, Avibe uses the command's current working directory. Forks keep the source Session cwd by default.
Async Agent runs return the final result to this conversation by default. Pass --no-callback only when you will inspect the run later with vibe runs. Pass --callback-session-id <id> only when the final result should return to a different Session.
--message and --message-file are the user-message flags for task, watch, and agent-run commands.
vibe task add stores a message template — or, with --shell / a trailing -- <argv>, a command — and creates Runs when the time trigger fires. A command task runs with no Agent turn: silent on success, a failure notice on failure, --on-failure agent to escalate failures to an Agent.
vibe watch add uses --message as the instruction template for the Agent Run created after the waiter reaches a reportable state.
--fork-self forks this Session's native backend context. --fork-session <id> forks another explicit Session. Forks keep the source Session backend, scope, and cwd by default.
Fork overrides are intentionally narrow: --agent, --model, and --reasoning-effort can override the forked Session only if the backend stays the same. Do not combine fork flags with existing-session or session-creation flags.
Operational guidance:
use vibe task list before editing or deleting an existing task; use vibe watch list before touching a managed watch
if this is the first time using vibe task add, vibe agent run, vibe runs, or vibe watch add, read the matching --help output first — watches and command tasks both accept --shell and --timeout (per-cycle for watches, per-run for tasks), while --lifetime-timeout (overall), --forever, --retry-exit-code, and --retry-delay stay watch-only
for Watch waiters, exit 0 means one new reportable event; an allowed retry exit code keeps either mode waiting, while 64 plus avibe-watch: no-event ends a once Watch or re-arms a forever Watch without an Agent Run; a once waiter that is still waiting must use a retry exit code
a forever waiter must keep a durable cursor, state transition, or domain cooldown; Avibe serializes its event follow-ups and automatically pauses plus sends a repair Run after six successful events within 60 seconds
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
Agent-facing collection commands return 20 compact rows per page, cap --limit at 100, and have no unpaginated --all mode; follow pagination.next_command when more rows exist
read task/watch records from definition for detail commands and definitions for list commands; command-specific duplicate aliases are not emitted
use --include-finished for paginated task/watch one-shot history
both list commands hide successful one-shot definitions by default while failures stay visible; use --include-finished and follow pagination.next_command for bounded history
use vibe task show <id>, vibe watch show <id>, or vibe runs show <run-id> to inspect stored fields and runtime state
use vibe task pause / vibe task resume and vibe watch pause / vibe watch resume to disable a task or watch without deleting it
treat warnings from 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_agent or through prefix routing such as reviewer: ....
Claude subagents are selected through routing.claude_agent or prefix routing.
Codex subagents are selected through routing.codex_agent or prefix routing.
Claude reasoning is selected through routing.claude_reasoning_effort; common values are low, medium, and high, and some models also allow max.
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
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:
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 service
vibe status — print service status, PID metadata, and last action
vibe stop — stop main service, Web UI, and any background helpers
vibe restart — stop and re-start the service. Pass --delay-seconds N when 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 result
vibe version — print the installed version
Updates:
vibe check-update — query the release feed and print whether an upgrade is available
vibe upgrade — reinstall Avibe to the latest release. The CLI does not restart the service for you; it prints "Please restart vibe..." and exits. Run vibe restart (or vibe restart --delay-seconds 60 from inside an active conversation) yourself after the upgrade reports success. The Web UI's POST /upgrade endpoint is the path that performs an automatic restart.
Remote access:
vibe remote — guided Avibe Cloud pairing
vibe remote pair <key> — pair using an existing one-time key
vibe remote status [--json] — show tunnel + OIDC state
vibe 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
For any subcommand, prefer <command> --help before composing a new invocation. Harness commands default to this Agent Session inside an Avibe-injected Agent shell. Use --session-id only to target a different existing Session, --same-scope or --scope-id when creating a Session in a visible scope, and --no-callback only when an async Agent run will be inspected later through vibe runs. 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 --sync; 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). vibe task add also accepts --shell or a command after --, plus --on-failure {none,agent} and a per-run --timeout; a pure command task takes no session, scope, or agent flags. Do not copy flags between task, watch, and agent-run commands without checking help.
Troubleshooting
Start with evidence:
GET /status
POST /doctor
POST /logs with a small line count and focused source
read back /config, /settings, or /api/users for 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/detect finds it
channel does not respond: verify /settings?platform=<platform> contains the channel and enabled is true
wrong repository/cwd: inspect custom_cwd and runtime.default_cwd
DM access denied: inspect /api/users?platform=<platform> and bind-code state
platform cannot reach API: inspect proxy_url on that platform's config block; check logs for proxy/TLS errors; for SOCKS proxies confirm aiohttp_socks is installed
remote URL is unreachable: GET /remote-access/status should show running: true and binary_found: true; if not, run POST /doctor and check the configured cloudflared_path
remote session expired: instruct the user to re-sign in at the public URL (24h TTL with sliding renewal); use POST /auth/logout to clear a stale session on the current device
upgrade did not apply: inspect the response from POST /upgrade (auto-restart on success) or vibe upgrade (does not auto-restart — run vibe restart manually), then verify with vibe status that 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 vibe CLI
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