Entry Points and Execution Flow
mistral-vibe
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 |