vibekit

command module
v0.2.49 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: GPL-2.0, GPL-3.0 Imports: 20 Imported by: 0

README

vibekit

Image Size Platforms Test coverage Mutation OpenSSF Best Practices OpenSSF Scorecard SBOM

A browser-based front-end for the Kiro CLI: chat with an AI coding agent from any device, with a live terminal, a file editor, checkpoints, and git/forge workflows in the same tab.

Vibekit runs kiro-cli as an Agent Client Protocol (ACP) subprocess and wraps it in a full workspace UI. The server is the single source of truth: every action is persisted and echoed to all connected clients over Server-Sent Events, so a conversation open on your phone and your desktop stays in sync with no drift. One kiro-cli bridge backs each chat and is shared by every tab and device viewing it.

Published as a multi-arch (amd64 + arm64) container image on GHCR (ghcr.io/cplieger/vibekit) and Docker Hub (cplieger/vibekit).

⚠️ It drives an AI agent with shell and file access

Vibekit controls an agent that can run shell commands and read and write your files under /workspace, and it exposes kiro-cli's stored credentials. It has no built-in authentication — anyone who can reach the port can use it. Before exposing it beyond your own machine, do one (ideally both) of:

  • put it behind an authenticating reverse proxy (Caddy forward-auth, oauth2-proxy, Authentik, …), and/or
  • keep the published port on loopback or a private network.

Signing in from the UI authenticates kiro-cli to AWS (the agent's identity); it is not a gate on vibekit itself.

Run

# compose.yaml
services:
  vibekit:
    image: ghcr.io/cplieger/vibekit:latest
    user: "1000:1000" # match your host user
    ports:
      - "9847:9847"
    volumes:
      - ./config:/config # chats, kiro-cli auth/state, tools
      - ./workspace:/workspace # your repos
    restart: unless-stopped

Before the first start, create and own the bind-mount directories, since the container runs as user: "1000:1000". The entrypoint does not chown them, so a root-owned host directory makes first boot fail with failed to create config directories:

mkdir -p /opt/appdata/vibekit/config /opt/appdata/vibekit/workspace
chown -R 1000:1000 /opt/appdata/vibekit

To skip managing host ownership, run as root instead with user: "0:0" (less secure).

Open http://localhost:9847. kiro-cli is downloaded and pinned on first boot (it is not redistributed in the image, per the AWS Customer Agreement). On first launch, sign in to kiro-cli and start chatting.

Capabilities

Vibekit is a full workspace in the browser, not just a chat box. Everything below is reachable from any device viewing the same server.

Chat, from any device and always in sync:

  • Multi-device conversations kept in sync live over SSE; full history, one file per chat.
  • Streaming markdown responses with collapsible reasoning ("thinking") blocks.
  • Prompt queue: keep typing while the agent works; queued prompts drain in order as turns finish.
  • Inline shell: prefix a message with ! to run a command locally.
  • Slash commands (/compact, …) with type-ahead completion.
  • File attachments by drag-drop or paperclip; PDF/CSV/Office documents are sent to the agent as documents.
  • Find-in-chat (Ctrl-F) and per-chat export to Markdown or JSON.
  • On-demand and automatic context compaction; configurable chat retention with an archive/History view.

Agent control over models, modes, and turns:

  • Switch modes/roles — bundled workflow modes (Default, Spec, Quick Spec, Bug Fix, Plan, Autonomous) and your own workspace agents from .kiro/agents/.
  • Switch models on the fly, with per-model credit multipliers.
  • Set reasoning effort (low through max).
  • Approve or deny tool-call permission prompts; answer MCP input (elicitation) forms.
  • Plan handoff: edit a proposed plan in the editor, or run it directly.
  • Rewind: branch a new conversation from any past turn, then merge it back or discard it.
  • Subagents and agent-spawned terminals render as nested, collapsible cards.

Editing and files in the browser:

  • File browser: navigate, rename, delete, download, and upload (dialog or drag-drop).
  • Syntax-highlighted editor with edit/save and deep links to a line (#L<n>).
  • Diff view against the last save or against git HEAD.
  • Merge-conflict resolver — accept ours/theirs/both per hunk, with an AI "suggest" merge.
  • Gutter markers on the lines the agent changed.

A real terminal in the browser:

  • A PTY shell (via web-terminal-engine) that survives sleep and network drops, with a mobile key toolbar.

Version control and forges for GitHub, GitLab, Codeberg, and Gitea/Forgejo:

  • Git panel: stage, commit (with an AI-written message), diff, and switch branches.
  • Pull requests: list, create (with an AI-written description), merge, and close.
  • Connect forge accounts via OAuth device flow or a token (driven by the gh / glab / tea CLIs).

Safety nets around the agent's file edits:

  • Checkpoints: content-addressed per-file snapshots, independent of git — restore a turn's file edits or undo a single file, with cross-chat conflict detection and click-to-diff.
  • Supervised mode: stage every agent file write for per-hunk accept/reject/merge before it touches disk; grant trust for the rest of a turn when you're confident.
  • Permissions: a Cedar policy editor (allow/deny/ask per capability, with path scoping) and a "test a decision" explainer — one policy governs every tool call, shell commands included.
  • Scope: checkpoints and supervised staging cover the agent's file-write channel. Changes made through shell commands or terminals (the agent's or yours) are approved via permissions but not snapshotted or staged — use git for those.

MCP server management:

  • Add, edit, and remove MCP servers (local, or remote over HTTP/SSE) from the UI.
  • OAuth (device flow, client id/secret), per-server auto-approve, live reconnect, and prompt/resource browsing.

Workspace tools and agent configuration:

  • Manage installed tools — search a catalog of ~700 runtimes, language servers, and CLIs (compiled from the mise and aqua registries by tool-catalog as they release), install them in the background with streamed progress, pin versions, or bring your own install command. The catalog refreshes itself at boot and every VIBEKIT_TOOL_CATALOG_REFRESH (default 24h; off disables the schedule) with the last good copy kept on any failure, and Settings → Tools shows its freshness plus a Refresh catalog button; VIBEKIT_TOOL_CATALOG_URL points refreshes at a fork or mirror. Every tool has an enable/disable switch: disabling uninstalls it but keeps the entry as a template, and fresh installs start with language-server templates (Go, TypeScript, Python, Rust) ready to switch on. Enabling one also activates kiro-cli's code intelligence for the workspace automatically — the agent gains LSP-backed navigation, rename, and diagnostics on top of the always-on tree-sitter analysis, live chats included, no restart. The detected-language set is frozen into /workspace/.kiro/settings/lsp.json at first activation; after adding a new language to the workspace, delete that file and vibekit re-initializes it on the next boot or language-server install.
  • Knowledge bases: index workspace directories, with live progress.
  • Spec board (/specs): a live requirements → design → tasks tree.
  • Hooks: list, enable/disable, and run agent hooks; create one from chat context.
  • Edit global custom instructions and browse steering docs, skills, and agents.

Notifications and PWA install:

  • Installable as a PWA, with a home-screen icon and a share target.
  • Web-push notifications when a turn finishes or the agent needs permission — even with the tab closed.

Settings and per-device preferences:

  • Per-device layout (tabs, open files, shell) with light and dark themes.
  • Account/subscription usage, a per-session context/credit meter, build versions, and a copyable diagnostics report.

Configuration

The image ships working defaults; most setups only choose the volumes and how to expose the port.

  • Port: 9847 (HTTP + SSE + the shell WebSocket).
  • Volumes: /config persists chats, kiro-cli auth/state, installed tools, and settings; /workspace is your repositories.
  • User: the compose above runs as 1000:1000 (see the first-boot ownership note). Run as root (user: "0:0") to skip managing host ownership.
  • Health: GET /api/health reports healthy once the server is up. If the first-boot kiro-cli download failed, the web UI still starts (files, git, settings, and the shell all work) but health reports 503 kiro-cli unavailable, the UI shows a banner, and chats can't run — restart the container to retry the install.
Behind a reverse proxy (TRUSTED_PROXIES)

The access log and the login/logout audit logs record a client_ip. How that address is resolved depends on how you expose vibekit:

  • Directly exposed (no reverse proxy in front): leave TRUSTED_PROXIES unset. client_ip is the address of the connecting socket, which cannot be forged at this layer. Any X-Forwarded-For header a client sends is ignored.

  • Behind a reverse proxy: set TRUSTED_PROXIES to your proxy's address range so client_ip shows the real client instead of the proxy's own address. It is a comma-separated list of CIDRs (bare IPs are accepted as single hosts), for example:

    environment:
      TRUSTED_PROXIES: "10.0.0.0/8,192.168.0.0/16"
    

X-Forwarded-For is honored only when the connecting peer falls inside TRUSTED_PROXIES; otherwise the header is ignored and the socket peer is logged. List every proxy hop between the client and vibekit. This is spoof-safe by default: an empty, unset, or misconfigured value falls back to the unspoofable socket peer rather than trusting a client-supplied header.

Host allowlist (ALLOWED_HOSTS)

Set ALLOWED_HOSTS to the exact hostnames/IPs you browse vibekit at (comma-separated, e.g. ALLOWED_HOSTS: "localhost,192.168.1.5,vibekit.example.com"); a request with any other Host header is rejected with 403.

This blocks DNS rebinding: an attacker's page makes its own hostname resolve to your vibekit address, and because Origin and Host then agree, same-origin checks pass — through your own browser, even against a loopback- or LAN-bound deployment. An exact-Host allowlist breaks that chain. Requests made from the container itself (loopback socket peer with a loopback Host) are always admitted, so the image's healthcheck keeps working under any allowlist. Unset accepts every Host (and logs a startup warning); set it for any long-running deployment.

Extra browse roots (VIBEKIT_BROWSE_ROOTS)

The file browser sees exactly the granted roots — /workspace and /config by default — and nothing else in the container. Anything outside the grants (system directories, the image's own install tree, paths that don't exist yet) is denied by default rather than hidden by an enumerated block-list. To browse additional mounts, grant them explicitly with a colon-separated list of absolute paths:

environment:
  VIBEKIT_BROWSE_ROOTS: "/tmp:/data"

Each grant must exist in the container (mount it via volumes: first); a malformed or missing entry is logged and skipped, never fatal. Credential and internal state files under /config (SSH keys, cloud tokens, chat store, MCP config) stay blocked regardless of grants.

Environment variable reference

Every knob, including the ones detailed above. A malformed duration value logs a warning and falls back to its default.

Variable Default Purpose
TRUSTED_PROXIES (unset) Reverse-proxy CIDRs whose X-Forwarded-For resolves client_ip. See Behind a reverse proxy.
ALLOWED_HOSTS (unset) Exact hostnames/IPs vibekit answers for; anything else is rejected (anti-DNS-rebinding). See Host allowlist.
VIBEKIT_BROWSE_ROOTS (unset) Extra file-browser grants, colon-separated absolute paths. See Extra browse roots.
KIRO_WORK_DIR /workspace Directory chats and the shell start in. Must exist and be a directory; startup fails otherwise.
KIRO_CONFIG_DIR /config Persistent state root (chats, kiro-cli home, installed tools, settings). Must exist and be writable; startup fails otherwise.
KIRO_CLI_PATH kiro-cli Path to the kiro-cli binary (resolved via PATH when bare). When missing the server still starts degraded: the UI works, health reports 503 kiro-cli unavailable, chats can't run.
KIRO_HOME $HOME/.kiro Where vibekit resolves kiro-cli's per-user state tree (steering, settings, session files).
VIBEKIT_TOOLS_DIR <KIRO_CONFIG_DIR>/tools Tools engine install tree (bin/, opt/, npm/, python/) on the persistent volume.
VIBEKIT_TOOL_CATALOG /opt/vibekit/tool-catalog.json Image-baked tool catalog used at first boot and when offline, until a successfully fetched catalog replaces it.
VIBEKIT_TOOL_CATALOG_URL the tool-catalog latest-release artifact Where catalog refreshes fetch from. Point it at a fork or mirror to decouple from the default publisher.
VIBEKIT_TOOL_CATALOG_REFRESH 24h Catalog refresh cadence (Go duration, clamped to 1h-30d); off or 0 disables the schedule while the manual Refresh button and API stay available.
VIBEKIT_TOOL_CATALOG_OVERLAY /opt/vibekit/catalog-overlays.json Image-internal: display-patch overlay re-applied to every loaded catalog. An explicitly set path that does not resolve logs a warning and overlays are skipped.
VAPID_SUBJECT mailto:vibekit@noreply.invalid Contact URI embedded in the Web Push (VAPID) keys used for chat notifications.
VIBEKIT_AUTH_LOGIN_URL_TIMEOUT 10s How long to wait for kiro-cli login to print the sign-in URL.
VIBEKIT_AUTH_LOGIN_PROCESS_CAP 16m Hard cap on a whole login attempt, device-flow confirmation included.
VIBEKIT_AUTH_LOGOUT_TIMEOUT 10s Timeout for kiro-cli logout.
VIBEKIT_AUTH_WHOAMI_TIMEOUT 5s Timeout for the kiro-cli whoami sign-in status probe.

How it fits together

Browser (any device)          vibekit server (Go)            kiro-cli (ACP)
--------------------          -------------------            --------------
POST /api/command        →    persist + dispatch        →    one bridge per chat
GET  /api/events (SSE)   ←    broadcast to all clients  ←    stream updates

The server owns all state and writes one JSON file per chat; clients render only what the server has confirmed. That is what keeps every device — phone, tablet, laptop — showing the same conversation with no optimistic local state and no multi-device drift.

Security

  • No built-in authentication — put vibekit behind an authenticating reverse proxy and/or a private network (see the warning above).
  • Web push uses an SSRF-hardened transport.
  • Debian base: a shell and the kiro-cli subprocess are required, so this is intentionally not distroless.
  • Images are published with cosign signatures and SBOM attestations.

kiro-cli

kiro-cli is downloaded and pinned on first boot rather than baked into the image (the AWS Customer Agreement governs redistribution, so you accept it by booting the container). Upgrades arrive by pulling a newer image tag; there is no in-place self-update.

  • web-terminal-kiro: the sister app — a raw browser terminal that drives kiro-cli's own TUI, instead of this chat-first UI.
  • web-terminal-engine: the terminal engine (Go PTY/VT + TypeScript renderer) behind vibekit's shell.
  • actions: the client-side action framework vibekit's UI is built on.

Contributing

Architecture, the invariants you must not break, and local build/test instructions are in CONTRIBUTING.md.

Disclaimer

This project is built with care and follows security best practices, but it is intended for personal / self-hosted use. No guarantees of fitness for production environments. Use at your own risk.

This project was built with AI-assisted tooling using Claude, GPT, and Kiro. The human maintainer defines architecture, supervises implementation, and makes all final decisions.

License

GPL-3.0. See LICENSE.

Documentation

Overview

Vibekit for Kiro: ACP-based web interface for kiro-cli.

One kiro-cli subprocess per active chat; multiple browsers on the same chat share the same bridge and context. Server is the source of truth; the browser projects server state via SSE + GET /api/chats.

Directories

Path Synopsis
cmd
bundle command
Command bundle builds vibekit's browser client: it bundles the TypeScript entrypoints with esbuild (a Go library — no Node, no npm, per the fleet's no-Node-in-the-builder doctrine), assembles the CSS bundle from the manifest files, and writes precompressed .gz siblings for every emitted text asset.
Command bundle builds vibekit's browser client: it bundles the TypeScript entrypoints with esbuild (a Go library — no Node, no npm, per the fleet's no-Node-in-the-builder doctrine), assembles the CSS bundle from the manifest files, and writes precompressed .gz siblings for every emitted text asset.
wire-codegen command
Command wire-codegen generates TypeScript interfaces, validating decoders, and an SSE event→decoder registry from Go wire types using the wiregen library (AST-based; github.com/cplieger/wiregen/v2).
Command wire-codegen generates TypeScript interfaces, validating decoders, and an SSE event→decoder registry from Go wire types using the wiregen library (AST-based; github.com/cplieger/wiregen/v2).
internal
api
Package api defines the internal contracts between vibekit components.
Package api defines the internal contracts between vibekit components.
auth
Package auth wires the /api/whoami, /api/login, /api/logout endpoints that shell out to the bundled kiro-cli binary for identity operations.
Package auth wires the /api/whoami, /api/login, /api/logout endpoints that shell out to the bundled kiro-cli binary for identity operations.
bridge
Package bridge manages a single kiro-cli ACP subprocess.
Package bridge manages a single kiro-cli ACP subprocess.
buffer
Package buffer provides the per-chat assistant turn buffering subsystem.
Package buffer provides the per-chat assistant turn buffering subsystem.
chat
Package chat implements per-chat persistence: one JSON file per chat under <dir>/<chat_id>.json.
Package chat implements per-chat persistence: one JSON file per chat under <dir>/<chat_id>.json.
chat/archive
Package archive implements the chat archive lifecycle: move to archive, list, restore, update summary, delete, and age-based purge.
Package archive implements the chat archive lifecycle: move to archive, list, restore, update summary, delete, and age-based purge.
checkpoint/gc
Package gc implements the blob garbage collector for the checkpoint subsystem.
Package gc implements the blob garbage collector for the checkpoint subsystem.
checkpoint/types
Package types defines checkpoint domain types shared between the checkpoint implementation and its consumers (api, hub).
Package types defines checkpoint domain types shared between the checkpoint implementation and its consumers (api, hub).
command
Package command implements the POST /api/command dispatch table.
Package command implements the POST /api/command dispatch table.
composition
Package composition wires all vibekit services together and manages application lifecycle.
Package composition wires all vibekit services together and manages application lifecycle.
dedup
Package dedup provides a bounded, TTL-based idempotency cache for deduplicating repeated requests by request ID.
Package dedup provides a bounded, TTL-based idempotency cache for deduplicating repeated requests by request ID.
filehandler
Package filehandler provides HTTP endpoints for browsing, reading, editing, uploading, and downloading files.
Package filehandler provides HTTP endpoints for browsing, reading, editing, uploading, and downloading files.
fileutil
Package fileutil provides small filesystem helper utilities used across vibekit packages.
Package fileutil provides small filesystem helper utilities used across vibekit packages.
forges
Package forges integrates remote git forges (GitHub, GitLab, Gitea/Codeberg) by orchestrating their first-party CLI tools (gh, glab, tea).
Package forges integrates remote git forges (GitHub, GitLab, Gitea/Codeberg) by orchestrating their first-party CLI tools (gh, glab, tea).
forges/cliexec
Package cliexec provides CLI subprocess execution with structured output capture, size-capped buffers, and typed errors.
Package cliexec provides CLI subprocess execution with structured output capture, size-capped buffers, and typed errors.
forges/gitea
Package gitea provides the Gitea/Codeberg ForgeOps implementation.
Package gitea provides the Gitea/Codeberg ForgeOps implementation.
forges/github
Package github provides the GitHub ForgeOps implementation.
Package github provides the GitHub ForgeOps implementation.
forges/gitlab
Package gitlab provides the GitLab ForgeOps implementation.
Package gitlab provides the GitLab ForgeOps implementation.
forges/oauth
Package oauth implements the GitHub OAuth device flow protocol.
Package oauth implements the GitHub OAuth device flow protocol.
git
Package git provides HTTP handlers and utilities for git operations and AI-assisted workflows.
Package git provides HTTP handlers and utilities for git operations and AI-assisted workflows.
gitexec
Package gitexec provides hardened git subprocess execution and credential scrubbing shared by the git and forges packages.
Package gitexec provides hardened git subprocess execution and credential scrubbing shared by the git and forges packages.
hub
Package hub coordinates the server's per-chat runtime: SSE fan-out, ACP bridge lifecycle, and POST /api/command dispatch — plus the service surfaces that ride the shared utility bridge (knowledge, specs, hooks, governance, account usage, policy), checkpoint HTTP, agent terminals, the browser PTY shell shim, and the MCP runtime registry.
Package hub coordinates the server's per-chat runtime: SSE fan-out, ACP bridge lifecycle, and POST /api/command dispatch — plus the service surfaces that ride the shared utility bridge (knowledge, specs, hooks, governance, account usage, policy), checkpoint HTTP, agent terminals, the browser PTY shell shim, and the MCP runtime registry.
ids
Package ids provides random identifier generation for stored records.
Package ids provides random identifier generation for stored records.
ignore
Package ignore is a gitignore-style agent read filter.
Package ignore is a gitignore-style agent read filter.
kiroauth
Package kiroauth reads (and refreshes) the ambient kiro-cli SSO access token so vibekit can answer the v3 (KAS) host-mediated auth callback (_kiro/auth/getAccessToken) over the ACP bridge.
Package kiroauth reads (and refreshes) the ambient kiro-cli SSO access token so vibekit can answer the v3 (KAS) host-mediated auth callback (_kiro/auth/getAccessToken) over the ACP bridge.
kirosession
Package kirosession reaps kiro-cli / KAS on-disk session state that vibekit no longer needs.
Package kirosession reaps kiro-cli / KAS on-disk session state that vibekit no longer needs.
logctl
Package logctl owns the process-wide slog handler so settings toggles can flip the log level at runtime without restarting the container.
Package logctl owns the process-wide slog handler so settings toggles can flip the log level at runtime without restarting the container.
mcp
Package mcp persists and serves the user's configured MCP (Model Context Protocol) servers.
Package mcp persists and serves the user's configured MCP (Model Context Protocol) servers.
mcp/prewarm
Package prewarm handles npx package pre-warming for MCP servers.
Package prewarm handles npx package pre-warming for MCP servers.
pending
Package pending implements the staging store for Supervised mode.
Package pending implements the staging store for Supervised mode.
permissions
Package permissions holds vibekit's one remaining permission control: the Supervised-mode default for newly-auto-created chats (SupervisedDefault, permissions_read.go).
Package permissions holds vibekit's one remaining permission control: the Supervised-mode default for newly-auto-created chats (SupervisedDefault, permissions_read.go).
policyfile
Package policyfile reads and writes kiro-cli's native Cedar permission policy files (permissions.yaml) for the user and workspace scopes.
Package policyfile reads and writes kiro-cli's native Cedar permission policy files (permissions.yaml) for the user and workspace scopes.
push
Package push manages Web Push subscriptions and delivers VAPID-signed notifications.
Package push manages Web Push subscriptions and delivers VAPID-signed notifications.
push/crypto
Package crypto provides RFC 8291 encryption helpers and VAPID JWT construction for Web Push.
Package crypto provides RFC 8291 encryption helpers and VAPID JWT construction for Web Push.
server
Package server — REST Idempotency-Key dedup middleware.
Package server — REST Idempotency-Key dedup middleware.
settings
Package settings provides a single-source-of-truth reader for <configDir>/config.json.
Package settings provides a single-source-of-truth reader for <configDir>/config.json.
steering
Package steering generates the environment.md steering file kiro-cli reads on every session.
Package steering generates the environment.md steering file kiro-cli reads on every session.
testsupport
Package testsupport provides shared test fakes for interfaces defined in the api package.
Package testsupport provides shared test fakes for interfaces defined in the api package.
translate
Package translate handles ACP → domain event translation.
Package translate handles ACP → domain event translation.
version
Package version holds the single-source-of-truth build version string for vibekit.
Package version holds the single-source-of-truth build version string for vibekit.
workspace
Package workspace provides path helpers for kiro-cli's per-user state directory.
Package workspace provides path helpers for kiro-cli's per-user state directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL