CodeDocs Vault

Entry Points and Execution Flow

This document details the application entry points and how execution flows through the system.

Primary Entry Point

File: vibe/cli/entrypoint.py Function: main() at line 137

Execution Sequence

main() [entrypoint.py:137]
    │
    ├─1─► parse_arguments() [entrypoint.py:20]
    │     Parse CLI arguments using argparse
    │
    ├─2─► Handle --workdir [entrypoint.py:140-147]
    │     Change to specified directory if provided
    │
    ├─3─► Trusted folder check (interactive only) [entrypoint.py:151]
    │     check_and_resolve_trusted_folder()
    │     ├── Detect trustable content (.vibe/, AGENTS.md, VIBE.md)
    │     ├── Show trust dialog if unknown
    │     └── Record trust decision
    │
    ├─4─► unlock_config_paths() [entrypoint.py:152]
    │     Allow ConfigPath instances to resolve
    │
    └─5─► run_cli(args) [entrypoint.py:156]
          Delegates to vibe/cli/cli.py
          │
          ├── Load API keys from ~/.vibe/.env
          ├── Load config via VibeConfig.load()
          ├── Handle session resume (--continue / --resume)
          │   ├── SessionLoader.find_latest_session()
          │   └── SessionLoader.load_session()
          │
          ├── If --prompt: run_programmatic()
          └── Else: run_textual_ui()

CLI Arguments

Defined in parse_arguments() at entrypoint.py:20-100:

Argument Description
initial_prompt Positional argument for initial prompt
-p, --prompt Run in programmatic mode
--max-turns Maximum assistant turns (programmatic only)
--max-price Maximum cost in dollars
--enabled-tools Enable specific tools (exact names, globs, or regex)
--output Output format (text/json/streaming)
--agent Agent to use (builtin: default, plan, accept-edits, auto-approve, or custom)
--workdir Change to this directory before running
--setup Setup API key and exit
-c, --continue Continue from most recent session
--resume Resume a specific session by ID (supports partial matching)

Interactive Mode Flow

Entry: run_textual_ui() at vibe/cli/textual_ui/app.py:1079

def run_textual_ui(
    config: VibeConfig,
    auto_approve: bool = False,
    enable_streaming: bool = False,
    initial_prompt: str | None = None,
    loaded_messages: list[LLMMessage] | None = None,
    session_info: ResumeSessionInfo | None = None,
) -> None:

VibeApp Initialization

Class: VibeApp at app.py:65

VibeApp.__init__() [app.py:77-129]
    │
    ├── Store config, auto_approve, enable_streaming
    ├── Initialize agent as None (lazy initialization)
    ├── Create EventHandler (None until mount)
    ├── Create CommandRegistry
    └── Store initial_prompt, loaded_messages, session_info

App Mounting

Method: on_mount() at app.py:156

on_mount() [app.py:156-185]
    │
    ├─1─► Create EventHandler [app.py:157-163]
    │     Callbacks for mount, scroll, todo area
    │
    ├─2─► Query UI widgets [app.py:165-167]
    │     ChatInputContainer, AgentIndicator, ContextProgress
    │
    ├─3─► Set token state if auto_compact enabled [app.py:169-172]
    │
    ├─4─► Focus chat input [app.py:174-175]
    │
    ├─5─► Show dangerous directory warning [app.py:176]
    │
    ├─6─► Schedule update notification [app.py:177]
    │
    ├─7─► Show session info if resuming [app.py:179-180]
    │
    └─8─► Process initial prompt OR init agent [app.py:182-185]
          │
          ├── If initial_prompt: call_after_refresh(_process_initial_prompt)
          └── Else: _ensure_agent_init_task()

Agent Initialization

Method: _initialize_agent() at app.py:406

_initialize_agent() [app.py:406-443]
    │
    ├─1─► Guard: Return if agent exists or initializing [app.py:407-409]
    │
    ├─2─► Set _agent_initializing = True [app.py:410]
    │
    ├─3─► Create AgentLoop instance
    │     AgentLoop(config, agent_name, enable_streaming)
    │
    ├─4─► Set approval callback if not auto_approve
    │
    ├─5─► Load previous messages if resuming
    │     Filter out system messages, extend agent.messages
    │
    └─6─► Store agent, handle errors

Programmatic Mode Flow

Entry: run_programmatic() at vibe/core/programmatic.py

run_programmatic(config, prompt, max_turns, max_price, output_format, previous_messages)
    │
    ├─1─► Create Agent with auto_approve=True
    │     Agent(config, auto_approve=True, max_turns, max_price)
    │
    ├─2─► Load previous messages if provided
    │
    ├─3─► Create OutputFormatter based on output_format
    │     TextOutputFormatter | JsonOutputFormatter | StreamingJsonOutputFormatter
    │
    ├─4─► Run agent.act(prompt) loop
    │     async for event in agent.act(prompt):
    │         formatter.handle_event(event)
    │
    └─5─► Return formatted output

User Message Processing

When a user submits a message in interactive mode:

Handler: on_chat_input_container_submitted() at app.py:193

on_chat_input_container_submitted() [app.py:193-213]
    │
    ├─1─► Get and strip input value [app.py:196-198]
    │
    ├─2─► Clear input widget [app.py:200-201]
    │
    ├─3─► Interrupt agent if running [app.py:203-204]
    │
    ├─4─► Check for special prefixes:
    │     │
    │     ├── "!" prefix: _handle_bash_command() [app.py:206-208]
    │     │   Direct shell execution, not through agent
    │     │
    │     └── "/" prefix: _handle_command() [app.py:210-211]
    │         Slash commands like /help, /status, /config
    │
    └─5─► Normal message: _handle_user_message() [app.py:213]

User Message Flow

Method: _handle_user_message() at app.py:353

_handle_user_message(message) [app.py:353-368]
    │
    ├─1─► Ensure agent init task [app.py:354]
    │     _ensure_agent_init_task()
    │
    ├─2─► Create UserMessage widget [app.py:356]
    │     Mark as pending if init in progress
    │
    ├─3─► Mount message to UI [app.py:358]
    │
    └─4─► Run worker for processing [app.py:360-368]
          _process_user_message_after_mount()

Agent Turn Processing

Method: _handle_agent_turn() at app.py:470

_handle_agent_turn(prompt) [app.py:470-522]
    │
    ├─1─► Set _agent_running = True [app.py:474]
    │
    ├─2─► Show loading widget [app.py:476-480]
    │
    ├─3─► Render path prompt [app.py:483-484]
    │     render_path_prompt(prompt, base_dir)
    │     Expands @file references to file contents
    │
    ├─4─► Process agent events [app.py:486-499]
    │     async for event in self.agent.act(rendered_prompt):
    │         │
    │         ├── Update context progress [app.py:487-492]
    │         │
    │         └── Delegate to EventHandler [app.py:494-499]
    │             event_handler.handle_event(event, ...)
    │
    └─5─► Cleanup [app.py:515-522]
          _agent_running = False
          Remove loading widget
          Finalize streaming message

Key State Transitions

┌─────────────────┐
│   App Started   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Agent = None   │◄────────────────────────────────┐
│  Not Running    │                                 │
└────────┬────────┘                                 │
         │ User sends message                       │
         ▼                                          │
┌─────────────────┐                                 │
│ Agent Initializing │                              │
│ _agent_init_task   │                              │
└────────┬────────┘                                 │
         │ Init complete                            │
         ▼                                          │
┌─────────────────┐                                 │
│ Agent Ready     │                                 │
│ _agent_running=F│─────────────────────────────────┤
└────────┬────────┘ /clear clears history           │
         │ Message submitted                        │
         ▼                                          │
┌─────────────────┐                                 │
│ Agent Running   │                                 │
│ _agent_running=T│                                 │
│ _agent_task     │                                 │
└────────┬────────┘                                 │
         │                                          │
         ├── Normal completion ──► Agent Ready ─────┤
         │                                          │
         └── Interrupt (Escape) ─► Agent Ready ─────┘
             _interrupt_agent() [app.py:524]

Source File References

File Key Lines Description
entrypoint.py:20-100 parse_arguments() CLI argument parsing
entrypoint.py:103-135 check_and_resolve_trusted_folder() Trust check flow
entrypoint.py:137-160 main() Main entry point
cli.py run_cli() Config loading and mode dispatch
app.py:65-129 VibeApp.__init__() TUI app initialization
app.py:156-185 on_mount() App mounting and setup
app.py:193-213 on_chat_input_container_submitted() Input handling
app.py:353-368 _handle_user_message() User message processing
app.py:406-443 _initialize_agent() Agent creation
app.py:470-522 _handle_agent_turn() Agent turn execution
app.py:524-562 _interrupt_agent() Interrupt handling
app.py:1079-1099 run_textual_ui() TUI entry point