# j-cli Quick Reference Guide
## π― Quick Answer Guide
### Q1: How is `auto_compact` triggered?
- **When:** When token count exceeds 204,800 tokens (256 * 800)
- **Where called:** 4 places in `agent.rs` (lines 53, 319, 402, 452)
- **What it does:**
1. Saves transcript to `.transcripts/`
2. Calls LLM to summarize
3. Replaces all messages with summary
### Q2: How does the toast system work?
- **Storage:** `app.ui.toast = Some((msg, is_error, timestamp))`
- **Show:** `app.show_toast("msg", false/true)` in `app.rs:2633`
- **Clear:** `tick_toast()` clears after 4 seconds `app.rs:2715`
- **Render:** `draw_toast()` in top-right corner `ui/chat.rs:882`
### Q3: How does title bar show loading status?
- **Checks:** `app.state.is_loading` flag
- **Priority 1:** Show executing tool: "π§ ζ§θ‘ {tool_name}..."
- **Priority 2:** Show pending tool: "π§ θ°η¨ {tool_name}..."
- **Fallback:** "β³ ζθδΈ..." generic indicator
### Q4: How are tool calls displayed?
- **Request messages:** `render_tool_call_request_msg()` in `render_cache.rs:1038`
- Expanded: Full details with JSON
- Collapsed: Name + 60-char preview
- **Result messages:** `render_tool_result_msg()` in `render_cache.rs:1165`
- Shows "π§ {name} {status} {summary}"
- Errors shown with red styling
- Full content optional (expand mode)
### Q5: Where are ToolExecStatus and active_tool_calls?
- **Enum:** `app.rs:44-57` (5 states: PendingConfirm, Executing, Done, Rejected, Failed)
- **Struct:** `app.rs:60-66` (ToolCallStatus with tool_name, arguments, status)
- **Active list:** `app.rs:276` in ToolExecutor (Vec<ToolCallStatus>)
---
## ποΈ File Structure
```
src/command/chat/
βββ app.rs
β βββ ToolExecStatus enum (line 44)
β βββ ToolCallStatus struct (line 60)
β βββ UIState toast field (line 138)
β βββ ChatState is_loading (line 259)
β βββ ToolExecutor active_tool_calls (line 276)
β βββ show_toast() (line 2633)
β βββ tick_toast() (line 2715)
βββ agent.rs
β βββ auto_compact call 1 - tokens check (line 53)
β βββ auto_compact call 2 - after tool (line 319)
β βββ auto_compact call 3 - after tool (line 402)
β βββ auto_compact call 4 - after tool (line 452)
β βββ process_tool_calls() flow (line 587)
βββ compact.rs
β βββ CompactConfig struct (line 18)
β βββ micro_compact() (line 65)
β βββ save_transcript() (line 130)
β βββ auto_compact() (line 174)
βββ ui/chat.rs
β βββ draw_title_bar() (line 83)
β βββ Tool status logic (line 87)
β βββ draw_toast() (line 882)
βββ render_cache.rs
β βββ build_message_lines_incremental() (line 50)
β βββ Tool call rendering (line 135)
β βββ Tool result rendering (line 177)
β βββ render_tool_call_request_msg() (line 1038)
β βββ render_tool_result_msg() (line 1165)
βββ handler/tui_loop.rs
β βββ Toast polling (line 259)
βββ constants.rs
βββ TOAST_DURATION_SECS = 4 (line 57)
```
---
## π Data Flow
### Message Lifecycle with Tool Calls
```
1. User sends message
βββ app.state.is_loading = true
2. Background agent loop starts
βββ Calls LLM
3. LLM returns tool_calls
βββ agent.rs:639 sends StreamMsg::ToolCallRequest(tool_items)
βββ UI receives and enters ToolConfirm mode
4. User confirms tool execution
βββ ToolExecutor marks tool as Executing
βββ Tool status = ToolExecStatus::Executing
5. Tool execution completes
βββ ToolExecDoneMsg received
βββ poll_results() updates ToolCallStatus.status
βββ Tool results added to messages as role="tool"
6. UI renders
βββ draw_title_bar checks active_tool_calls status
βββ draw_messages calls render_tool_call_request_msg()
βββ Then calls render_tool_result_msg() for results
```
---
## π State Machine: ToolExecStatus
```
βββββββββββββββββββ
β PendingConfirm β
ββββββββββ¬βββββββββ
β
βββββββββββΌββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββ ββββββββ ββββββββββ
β Rejectedβ βCancel β βExecutingβ
βββββββββββ ββββββββ ββββββ¬ββββ
β
βββββββββββββΌββββββββββββ
βΌ βΌ βΌ
ββββββββββββ ββββββββββββββ
βDone(str) β βFailed(str) β
ββββββββββββ ββββββββββββββ
```
---
## π¨ UI Rendering Stack
```
draw_chat_ui() [ui/chat.rs:22]
ββ draw_title_bar() [line 40]
β ββ Shows: "π§ {tool_name}..." if app.state.is_loading
β ββ Checks: active_tool_calls[*].status
ββ draw_messages() [line 49]
β ββ build_message_lines_incremental() [render_cache.rs:50]
β ββ For each message:
β β ββ role="assistant" with tool_calls
β β β ββ render_tool_call_request_msg() [line 1038]
β β ββ role="tool"
β β β ββ render_tool_result_msg() [line 1165]
β β ββ role="user" / other content
β ββ render_tool_confirm_area() if in ToolConfirm mode [line 577]
ββ draw_input() [line 53]
ββ draw_hint_bar() [line 56]
ββ draw_toast() [line 59]
ββ Shows: βοΈ green or βοΈ red box (top-right)
ββ Auto-clears: after 4 seconds [tick_toast()]
```
---
## πΎ Data Structures
### Toast Notification
```rust
app.ui.toast: Option<(
msg: String, // Notification text
is_error: bool, // Success (false) or Error (true)
created: Instant, // Timestamp
)>
// Set: app.show_toast("message", is_error)
// Clear: After 4 seconds or manually set to None
```
### Tool Call Execution Status
```rust
app.tool_executor.active_tool_calls: Vec<ToolCallStatus>
ββ tool_call_id: String ββ tool_name: String ββ arguments: String ββ confirm_message: String ββ status: ToolExecStatus ββ PendingConfirm ββ Executing ββ Done(summary) ββ Rejected ββ Failed(summary) ```
### Message with Tool Calls
```rust
ChatMessage {
role: "assistant",
content: "Here's what I'll do...", // Can be empty
tool_calls: Some(vec![
ToolCallItem {
id: "call_abc123",
name: "bash",
arguments: r#"{"command":"ls"}"#,
},
// ...
]),
tool_call_id: None,
images: None,
}
// Followed by tool result:
ChatMessage {
role: "tool",
content: "file1.txt\nfile2.txt",
tool_calls: None,
tool_call_id: Some("call_abc123"),
images: None,
}
```
---
## βοΈ Configuration
### Compaction Settings
```rust
CompactConfig {
enabled: true, // default
token_threshold: 256 * 800, // ~204K tokens
keep_recent: 10, // tool results to preserve
}
micro_compact triggers when:
- Tool result > 800 bytes (MICRO_COMPACT_BYTES_COUNT_THRESHOLD)
- Keep most recent 10, compress older ones
- Exempt tools: LoadSkill, Task, TodoWrite, TodoRead, Ask
auto_compact triggers when:
- Total tokens > threshold
- Saves transcript to disk
- Calls LLM for summary
- Graceful degradation on error
```
### Toast Settings
```rust
TOAST_DURATION_SECS = 4 // Auto-dismiss after 4 seconds
toast_position = top-right corner
toast_padding = 1 char from edge
toast_icons:
- Success (false): "βοΈ"
- Error (true): "βοΈ"
```
---
## π Debug Tips
### Find auto_compact calls:
```bash
grep -n "auto_compact" src/command/chat/agent.rs
# Lines: 53, 319, 402, 452
```
### Find toast usage:
```bash
grep -n "show_toast\|\.toast\s*=" src/command/chat/app.rs
# Lines: 2634 (set), 2719 (clear)
```
### Find tool rendering:
```bash
grep -n "render_tool" src/command/chat/render_cache.rs
# Lines: 135-136 (request), 177-184 (result)
```
### Check loading status:
```bash
grep -n "is_loading" src/command/chat/ui/chat.rs
# Lines: 87, 202, 223, 249, 273, 546, 699, 710, 747
```
---
## π Common Patterns
### Show notification to user:
```rust
self.show_toast("Operation successful", false); // Green
self.show_toast("Error occurred", true); // Red
```
### Check if loading:
```rust
if app.state.is_loading {
// Show loading indicator
}
```
### Access active tools:
```rust
for tool_call in &app.tool_executor.active_tool_calls {
if matches!(tool_call.status, ToolExecStatus::Executing) {
// Tool is running
}
}
```
### Render tool info:
```rust
let expand = app.ui.expand_tools; // Toggle with Ctrl+O
render_tool_call_request_msg(tool_calls, bubble_width, lines, theme, expand);
```