Commit Graph

499 Commits

Author SHA1 Message Date
Dhanji R. Prasanna
a09967eb27 refactor(streaming): Extract deduplication and auto-continue logic into helpers
Improve readability of stream_completion_with_tools (~1000 line function):

- Add deduplicate_tool_calls() helper with closure for previous-message check
- Add should_auto_continue() with AutoContinueReason enum for clearer control flow
- Replace inline deduplication loop with helper call (-19 lines)
- Replace complex auto-continue conditional with match on reason enum (-13 lines)
- Add section comments for major phases (State Init, Pre-loop, Main Loop, Auto-Continue, Post-Loop)
- Add comprehensive tests for new helpers

Net reduction: 82 deletions, behavior unchanged (172+ tests pass)

Agent: carmack
2026-01-13 11:44:06 +05:30
Dhanji R. Prasanna
dc45987e8d Add characterization tests for UTF-8 truncation and parser sanitization
Agent: hopper

Adds 32 new integration tests covering recent commits:

## UTF-8 Safe Truncation Tests (14 tests)
Covers commit f30f145 (Fix UTF-8 panics):
- Topic extraction with emoji, CJK, and multi-byte characters
- Truncation at character boundaries (not byte boundaries)
- Edge cases: exactly 50 chars, 51 chars, 2-byte/3-byte/4-byte UTF-8
- Stub generation with multi-byte topics
- Combining characters and diacritics

## Parser Sanitization Tests (18 tests)
Covers commit 4c36cc0 (Prevent parser poisoning):
- Code block contexts (inline code, after fences, prose)
- Line boundary edge cases (empty lines, whitespace, indentation)
- Unicode handling (emoji, bullets, CJK before patterns)
- Multiple patterns on same line
- Negative cases (similar but different patterns, partial patterns)
- Real-world scenarios from the original bug report

All tests are blackbox/characterization style - they test observable
outputs through stable public interfaces without encoding internal
implementation details.
2026-01-13 11:22:46 +05:30
Dhanji R. Prasanna
8dcb7a3dba feat: add compact styled output for TODO tools
TODO tools (todo_read, todo_write) now display with a cleaner, more
compact format:

- Styled header: " ● todo_read" or " ● todo_write"
- Tree-style prefixes for content lines (│ and └)
- Checkbox conversion: "- [ ]" → □, "- [x]" → ■
- Dimmed content for visual distinction
- No timing footer (cleaner output)

Changes:
- Add print_todo_compact() method to UiWriter trait
- Implement print_todo_compact() in ConsoleUiWriter
- Update todo.rs to call print_todo_compact() instead of line-by-line output
- Skip tool header, output header, and timing for TODO tools in agent streaming
2026-01-13 10:58:55 +05:30
Dhanji R. Prasanna
4c36cc058c fix: prevent parser poisoning from inline tool-call JSON patterns
When the streaming parser encountered fragments of JSON that looked like
partial tool calls (e.g., {"tool":) embedded in inline text (like code
examples or prose), it would incorrectly enter JSON parsing mode and
poison the parser state, causing control to be returned to the user
mid-task.

This fix:
- Adds sanitize_inline_tool_patterns() to detect tool-call patterns that
  are NOT on their own line and replace the opening brace with a Unicode
  homoglyph (fullwidth left curly bracket U+FF5B)
- Integrates sanitization into process_chunk() before text is buffered
- Updates system prompts to instruct LLMs to use homoglyphs when showing
  example tool call JSON in prose
- Adds comprehensive tests for the sanitization logic

Real tool calls from LLMs always appear on their own line, so those are
left untouched. Only inline patterns (with non-whitespace before them)
are sanitized.
2026-01-13 10:58:41 +05:30
Dhanji R. Prasanna
a0b9126555 Revert "refactor(g3-core): extract streaming logic to agent_streaming.rs"
This reverts commit a2e51cf075.
2026-01-13 07:59:18 +05:30
Dhanji R. Prasanna
6907fa36c0 UI: Add newline before auto-memory skip message 2026-01-13 07:03:42 +05:30
Dhanji R. Prasanna
08e6a1dca0 Merge sessions/fowler/f8c3f2e5 2026-01-13 06:58:01 +05:30
Dhanji R. Prasanna
98eea09dc8 UI: Show consecutive read_file calls as continuation lines
When the LLM reads the same file multiple times in sequence (scrolling
through a large file), instead of showing each as a separate line:

  ● read_file | path [0..2000] | 50 lines | 100 ◉ 5ms
  ● read_file | path [2000..4000] | 50 lines | 100 ◉ 5ms
  ● read_file | path [4000..6000] | 50 lines | 100 ◉ 5ms

Now shows a cleaner continuation format:

  ● read_file | path [0..2000] | 50 lines | 100 ◉ 5ms
     └─ reading further [2000..4000] | 50 lines | 100 ◉ 5ms
     └─ reading further [4000..6000] | 50 lines | 100 ◉ 5ms

This makes it visually clear that the agent is scrolling through
a single file rather than reading multiple different files.

Implementation:
- Added last_read_file_path field to ConsoleUiWriter
- Detect when consecutive read_file calls target the same file
- Print continuation format for subsequent reads
- Reset tracking when:
  - A different tool is executed (shell, write_file, etc.)
  - A different file is read
  - Text is output between tool calls
2026-01-13 06:25:28 +05:30
Dhanji R. Prasanna
a2e51cf075 refactor(g3-core): extract streaming logic to agent_streaming.rs
Reduce lib.rs complexity by extracting the streaming completion logic:

- Extract stream_completion_with_tools (~1080 lines) to agent_streaming.rs
- Extract stream_with_retry helper method
- Extract parse_diff_stats helper function
- Add handle_pre_stream_compaction helper for cleaner pre-stream logic
- Add format_tool_output helper for tool output formatting
- Remove 3 unused constructor variants:
  - new_with_readme
  - new_autonomous_with_readme
  - new_with_quiet

Results:
- lib.rs reduced from 2974 to 1791 lines (40% reduction)
- Streaming logic cleanly separated into dedicated module
- All tests pass, no behavior changes

Agent: fowler
2026-01-13 06:14:56 +05:30
Dhanji R. Prasanna
5c9404e292 Refactor: improve readability in CLI modules
- project_files.rs: Fix UTF-8 safety in truncate_for_display (use char
  boundaries instead of byte slicing), add test for multi-byte chars
- task_execution.rs: Extract recoverable_error_name() helper, use shared
  calculate_retry_delay() from error_handling.rs to eliminate duplication
- ui_writer_impl.rs: Extract duration_color() helper for timing display,
  add clear_tool_state() to consolidate repeated mutex clearing patterns

Agent: carmack
2026-01-13 05:58:54 +05:30
Dhanji R. Prasanna
f30f145c85 Fix UTF-8 panics and inconsistent retry logic
- Fix 7 UTF-8 byte slicing panics that crash on multi-byte characters:
  - acd.rs: extract_topic_from_text() [..50] slice
  - streaming.rs: log_stream_error() [..500] slice
  - tools/acd.rs: rehydrate message truncation [..2000] slice
  - history.rs: git commit message truncation [..69] slice
  - planner.rs: commit summary/description truncation [..69] slices
  - llm.rs: requirements summary line truncation [..117] slice

- All now use chars().count() and chars().take(N).collect() for
  UTF-8 safe truncation

- Fix inconsistent retry logic in task_execution.rs:
  - Previously only retried on Timeout errors
  - Now retries on ALL recoverable errors (rate limits, network,
    server errors, model busy, token limits, context length)
  - Added error-specific base delays (rate limit: 5s, server: 2s, etc.)
  - Added exponential backoff with ±20% jitter
  - Consistent with autonomous mode retry behavior
2026-01-13 05:49:45 +05:30
Dhanji R. Prasanna
6f50d01ab6 Add comprehensive end-of-turn behavior tests for g3-core
Agent: hopper

Adds 56 new integration tests covering the observable end-of-turn
behaviors in the streaming module:

- Timing footer formatting (5 tests): verifies user-facing timing display
  with various durations, token counts, and context percentages

- Tool call duplicate detection (6 tests): ensures identical sequential
  tool calls are detected while different tools/args are not

- Empty response detection (9 tests): validates detection of empty,
  whitespace-only, and timing-only responses that trigger auto-continue

- Connection error classification (5 tests): verifies EOF, connection,
  chunk, and body errors are correctly identified for graceful recovery

- Tool output summary formatting (17 tests): covers read_file, write_file,
  str_replace, remember, screenshot, coverage, and rehydrate summaries

- Duration formatting (4 tests): milliseconds, seconds, minutes, zero

- Text truncation (4 tests): short/long strings, multiline, flag behavior

- LLM token cleaning (3 tests): removal of stop tokens like <|im_end|>

- Edge cases (4 tests): empty inputs, unicode handling, large numbers

All tests are blackbox/characterization style - they test observable
outputs through stable public interfaces without encoding internal
implementation details. Tests remain stable under refactoring that
preserves behavior.
2026-01-12 21:17:32 +05:30
Dhanji R. Prasanna
d164c97ad2 Fix multi-line error messages in compact tool output
The truncate_for_display() function now takes only the first line
of input before truncating. This prevents multi-line error messages
(like str_replace failures) from breaking the compact single-line
format.

Added tests for multi-line input handling.
2026-01-12 20:55:05 +05:30
Dhanji R. Prasanna
81ea149369 Fix confusing documentation references
1. architecture.md: Fixed diagram to show 'studio' instead of 'g3-console'
   (the crate was renamed during development)

2. analysis/memory.md: Removed reference to non-existent machine_ui_writer.rs

3. theme.rs: Clarified that 'retro' is a theme option (the default theme),
   not a separate TUI mode. No --retro CLI flag exists.
2026-01-12 20:49:37 +05:30
Dhanji R. Prasanna
1b051aad94 Fix write_file compact summary to show actual line/char counts
The write_file compact display was showing 1 line because it was
counting lines in the success message, not the actual written content.

Now parses the tool result (e.g. ' wrote 150 lines | 4.2k chars')
to extract and display the correct counts.

Added format_write_file_result() to parse the tool output.
2026-01-12 20:32:54 +05:30
Dhanji R. Prasanna
fe67e72ddd Merge sessions/fowler/e5c0ed6b 2026-01-12 20:23:00 +05:30
Dhanji R. Prasanna
de83b7fa4c Add visual spacing between text and tool calls in compact output
Adds blank line separation between text and tool calls for better readability:
- Text → Tool: blank line before tool call
- Tool → Text: blank line before text
- Tool → Tool: no gap (stays tight)

Implemented via two state tracking flags in ConsoleUiWriter:
- last_output_was_text
- last_output_was_tool

Updated print_tool_output_header(), print_tool_compact(), and
print_agent_response() to check and set these flags appropriately.
2026-01-12 20:20:41 +05:30
Dhanji R. Prasanna
32bfad69d1 refactor(g3-cli): extract functions from lib.rs to appropriate modules
- Move run_flock_mode() to autonomous.rs (parallel execution mode belongs with autonomous code)
- Move initialize_logging() to utils.rs (utility function with simple bool parameter)
- lib.rs reduced from 274 to 216 lines

No behavior changes. All 28 unit tests pass.

Agent: fowler
2026-01-12 20:10:52 +05:30
Dhanji R. Prasanna
6f3530544d Fix compact tool failure display to use single-line format
When compact tools (read_file, write_file, str_replace, etc.) failed,
they would fall through to the non-compact output path, causing:
- Missing or incorrect headers
- Stray footers with wrong formatting
- State leakage (is_shell_compact) between tool calls

Now failed compact tools display in the same single-line format as
successful ones, just with a truncated error message instead of the
success summary:

  ● read_file | path/to/file.txt |  Failed to read file... | 123 ◉ 0ms

This keeps the UI consistent and avoids the "stray footer" bug.
2026-01-12 20:02:08 +05:30
Dhanji R. Prasanna
e65bd61683 Inject working directory into context to prevent path hallucinations
The LLM often hallucinates incorrect paths like /Users/jnbrymn/GitHub/g3
when the actual working directory is different. This causes wasted tokens
and failed commands as the LLM tries cd commands that fail.

Fix: Add the current working directory to the combined project content
that gets injected into the context at startup. This appears as:

  📂 Working Directory: /actual/path/to/workspace

This is prepended before AGENTS.md, README.md, and project memory,
so the LLM knows the correct path from the start.
2026-01-12 18:27:29 +05:30
Dhanji R. Prasanna
78516722df Remove accidentally committed legacy logs/ directories 2026-01-12 18:20:20 +05:30
Dhanji R. Prasanna
c2aa80647a Remove legacy logs/ directory, consolidate all data under .g3/
This change removes the legacy logs/ directory and consolidates all
session data, error logs, and discovery files under the .g3/ directory.

New directory structure:
- .g3/sessions/<session_id>/session.json - session logs
- .g3/errors/ - error logs (was logs/errors/)
- .g3/background_processes/ - background process logs
- .g3/discovery/ - planner discovery files (was workspace/logs/)

Changes:
- paths.rs: Remove get_logs_dir()/logs_dir(), add get_errors_dir(),
  get_background_processes_dir(), get_discovery_dir()
- session.rs: Anonymous sessions now use .g3/sessions/anonymous_<ts>/
- error_handling.rs: Errors now saved to .g3/errors/
- project.rs: Remove logs_dir() and ensure_logs_dir() methods
- feedback_extraction.rs: Remove logs_dir field and fallback logic
- planner: Use .g3/ for workspace data and .g3/discovery/ for reports
- flock.rs: Look for session metrics in .g3/sessions/
- coach_feedback.rs: Remove fallback to logs/ path
- Update all tests to use new paths
- Update README.md and .gitignore
2026-01-12 18:20:08 +05:30
Dhanji R. Prasanna
43a5d27149 Add compact format for remember, take_screenshot, code_coverage, rehydrate
Extend compact single-line output to additional tools:
- remember: shows '📝 memory updated (size)'
- take_screenshot: shows '📸 path'
- code_coverage: shows '📊 report generated'
- rehydrate: shows '🔄 restored fragment_id'

Tools without file_path argument use simplified format:
  ● tool_name | summary | tokens ◉ time
2026-01-12 14:45:50 +05:30
Dhanji R. Prasanna
2c411c058a Compact single-line tool output for file operations and shell
Implement compact display format for read_file, write_file, str_replace, and shell:

- read_file/write_file/str_replace: Single line with dimmed summary and timing
  Format: ● tool_name | path [range] | summary | tokens ◉ time

- shell: Two-line format with command header and dimmed output
  Format: ● shell | command
          └─ output (N lines) | tokens ◉ time

Changes:
- Add print_tool_compact() method to UiWriter trait
- Add is_shell_compact state tracking in ConsoleUiWriter
- Add format_write_file_summary() and format_str_replace_summary() helpers
- Fix duplicate response output by checking if response is empty before printing
- Add finish_streaming_markdown() call before return to flush markdown buffer
2026-01-12 14:37:47 +05:30
Dhanji R. Prasanna
8d5dd9f84a Merge sessions/hopper/1156b5c9 2026-01-12 11:53:14 +05:30
Dhanji R. Prasanna
5dfabaf19a Add 72 integration tests for compaction, retry, tool execution, and error classification
Agent: hopper

Added 4 new test files with blackbox/characterization-style integration tests:

- compaction_behavior_test.rs (14 tests): Token cap calculation, thinking mode
  disable logic, summary message building, CompactionResult behavior

- retry_behavior_test.rs (17 tests): RetryConfig presets and customization,
  RetryResult state handling, retry_operation behavior with simulated errors

- tool_execution_roundtrip_test.rs (16 tests): End-to-end tool execution through
  Agent interface for read_file, write_file, shell, str_replace, and TODO tools

- error_classification_test.rs (25 tests): Recoverable vs non-recoverable error
  classification, retry delay calculation, edge cases and priority handling

All tests follow integration-first philosophy:
- Test through stable public interfaces
- Assert observable behavior, not implementation details
- Use characterization style to document current behavior
- Enable refactoring by not encoding internal structure
2026-01-12 11:40:19 +05:30
Dhanji R. Prasanna
9e26d6bbf9 Fix black box artifact in context thinning status line
Add ANSI clear-to-end-of-line escape sequence (\x1b[K]) after the
reset code in the context thinning animation. This prevents leftover
background color artifacts when the carriage return overwrites the
line during the flash animation.
2026-01-12 11:39:20 +05:30
Dhanji R. Prasanna
d508ddd508 Move project memory from .g3/ to analysis/ for version control
Project memory is now stored at analysis/memory.md instead of .g3/memory.md.
This change enables:
- Shared memory across git worktrees (studio agent sessions)
- Version-controlled memory that persists across clones
- Memory changes tracked in git history and reviewable in PRs

Changes:
- crates/g3-core/src/tools/memory.rs: Update get_memory_path() to use analysis/
- crates/g3-cli/src/project_files.rs: Update read_project_memory() path
- crates/g3-core/src/prompts.rs: Update documentation references (2 occurrences)
- analysis/memory.md: Add memory file (copied from .g3/memory.md)
2026-01-12 10:20:33 +05:30
Dhanji R. Prasanna
21ecbb3fb8 Merge sessions/fowler/9b17499a 2026-01-12 10:15:19 +05:30
Dhanji R. Prasanna
6c2563cd07 Merge sessions/fowler/36f031d6 2026-01-12 10:14:09 +05:30
Dhanji R. Prasanna
30bb63715e Fix studio status to show full markdown-formatted summary
Changes:
- Fix JSON path for session logs: now reads from context_window.conversation_history
  (with fallback to messages for backwards compatibility)
- Remove 500-character truncation to show full summary
- Add termimad dependency for terminal markdown rendering
- Display summary with proper markdown formatting (headers, bold, code, lists)

The extract_session_summary() function was looking for messages at the wrong
JSON path. Session logs store conversation history at context_window.conversation_history,
not at the top-level messages key.
2026-01-12 10:13:58 +05:30
Dhanji R. Prasanna
8df044ac13 refactor(g3-core): reduce lib.rs complexity by extracting utilities
- Extract truncate_to_word_boundary() to utils.rs with tests
- Consolidate duplicate detection: use streaming::are_tool_calls_duplicate()
  instead of inline closures (eliminates code-path aliasing)
- Remove unused regex import
- Remove wrapper methods format_duration/format_timing_footer that just
  delegated to streaming module - call streaming::* directly

Reduces lib.rs from 2945 to 2897 lines (-48 lines, -1.6%)
All 159+ g3-core tests pass.

Agent: fowler
2026-01-12 09:47:47 +05:30
Dhanji R. Prasanna
3a0b656161 refactor(g3-cli): eliminate code-path aliasing in config and project content loading
Consolidate duplicated logic into canonical shared functions:

- Extract load_config_with_cli_overrides() to utils.rs
  - Was duplicated in lib.rs and accumulative.rs with subtle differences
  - lib.rs version had Chrome diagnostics + provider validation
  - accumulative.rs version was missing both
  - Now all callers use the complete canonical implementation

- Extract combine_project_content() to project_files.rs
  - Was duplicated inline in lib.rs and agent_mode.rs
  - Simplified implementation using iterator flatten
  - Added unit tests for all cases

This eliminates drift risk where the duplicated implementations
could diverge over time (accumulative.rs was already missing
Chrome diagnostics and provider validation).

Agent: fowler
2026-01-12 08:57:49 +05:30
Dhanji R. Prasanna
6c17f269d7 Add studio tool for multi-agent workspace management
Studio enables running multiple g3 agents concurrently without conflicts
by using git worktrees for isolation.

Features:
- studio run --agent <name> [args...]: Create worktree, spawn g3, tail output
- studio list: Show all active sessions
- studio status <id>: Show session details and summary
- studio accept <id>: Merge session branch to main and cleanup
- studio discard <id>: Delete session without merging

Each session gets:
- Isolated worktree at .worktrees/sessions/<agent>/<session-id>
- Dedicated branch: sessions/<agent>/<session-id>
- Short UUID (8 chars) for easy reference
- Automatic --workspace and --agent flags passed to g3
2026-01-12 07:26:17 +05:30
Dhanji R. Prasanna
02799a8e69 refactor(g3-core): extract streaming helpers and simplify cache control logic
Readability improvements to g3-core/src/lib.rs:

- Extract format_tool_arg_value() to streaming.rs for tool argument display
- Extract format_read_file_summary() to streaming.rs for file read summaries
- Add format_tool_output_summary() helper for consistent output formatting
- Add get_provider_cache_control() helper to eliminate duplicated cache lookup
- Simplify cache control logic in execute_single_task and stream_completion_with_tools
- Add unit tests for all new streaming helpers

Results:
- lib.rs: 2979 → 2945 lines (34 lines saved)
- streaming.rs: 305 → 379 lines (74 lines added as reusable, tested helpers)
- All 155+ tests pass

Agent: carmack
2026-01-12 07:21:40 +05:30
Dhanji R. Prasanna
f10374c925 Remove machine mode entirely from g3
- Delete machine_ui_writer.rs
- Remove --machine CLI flag from cli_args.rs
- Remove run_machine_mode(), run_interactive_machine(), run_autonomous_machine() functions
- Remove handle_machine_command() function
- Simplify OutputMode enum to just use SimpleOutput directly
- Simplify SimpleOutput struct (remove machine_mode field)
- Remove machine_mode parameter from setup_workspace_directory()
- Remove test_machine_option_accepted test
- Disable ACD by default in agent_mode (requires --acd flag)
- Change 'memory checkpoint' message formatting
- Remove dehydration status message
2026-01-12 06:01:31 +05:30
Dhanji R. Prasanna
b9cdb99557 refactor(g3-cli): break lib.rs into focused modules
Extract 7 modules from the 2966-line lib.rs:
- cli_args.rs (133 lines): CLI argument parsing with clap
- autonomous.rs (785 lines): coach-player feedback loop
- agent_mode.rs (284 lines): specialized agent execution
- accumulative.rs (343 lines): iterative requirements mode
- interactive.rs (851 lines): REPL with command handling
- task_execution.rs (212 lines): unified retry logic
- utils.rs (91 lines): display and workspace helpers

Key improvements:
- lib.rs reduced from 2966 to 415 lines (86% reduction)
- Eliminated duplicate retry logic between execute_task and execute_task_machine
- Each module has a single responsibility
- Easier to reason about and maintain

Agent: fowler
2026-01-12 05:35:08 +05:30
Dhanji R. Prasanna
14cc28d9ba Include full task in ACD dehydration stub for forensics
Added first_user_message field to Fragment struct that captures the
full first user message (task) from the dehydrated conversation.
This is now displayed at the top of the stub with a 📋 Task: prefix.

Removed the Topics section from the stub since the full task provides
better context for forensics and debugging.

Agent: g3
2026-01-12 05:17:45 +05:30
Dhanji R. Prasanna
f415dbb84b Fix ACD turn summary loss and add /dump command
ACD (Aggressive Context Dehydration) fixes:
- Fixed dehydrate_context() to extract turn summary from context window
  instead of using the passed-in final_response (which contained only
  the timing footer, not the actual LLM response)
- Removed final_response parameter from dehydrate_context() since it
  now self-extracts the last assistant message as the summary
- This ensures the actual turn summary is preserved after dehydration,
  not just the timing footer

New /dump command:
- Added /dump command to dump entire context window to tmp/ for debugging
- Shows message index, role, kind, content length, and full content
- Available in both console and machine modes

UTF-8 safety:
- Fixed truncate_to_word_boundary() to use character indices instead of
  byte indices, preventing panics on multi-byte UTF-8 characters
- Added UTF-8 string slicing guidance to AGENTS.md

Agent: g3
2026-01-12 05:13:02 +05:30
Dhanji R. Prasanna
ac17b95b24 fix(read_file): clamp end position instead of erroring when it exceeds file length
When read_file is called with an end position beyond the file length,
instead of returning an error that forces a retry, now clamps to the
actual file length and returns the content with an informative message.

This eliminates wasteful retry cycles where the LLM had to make a
second request with the corrected end position.
2026-01-12 05:11:09 +05:30
Dhanji R. Prasanna
da63e79a13 Move read_file metadata to end of output
Change read_file output format so the "🔍 N lines read" appears as
the last line after the file content, not before it. This keeps the
output cleaner with just one metadata line at the end.
2026-01-11 19:56:23 +05:30
Dhanji R. Prasanna
ed1c31dd70 Improve tool output formatting
1. str_replace: Show insertion/deletion counts with colors
   " +N insertions | -M deletions" (green/red)

2. write_file: Compact format with human-readable sizes
   " wrote N lines | Xk chars"

3. read_file: Cleaner format
   "🔍 N lines read" instead of "📄 File content (N lines)"

4. webdriver_quit: Show correct driver name (safaridriver vs chromedriver)

5. read_file: When start position exceeds file length, read last 100 chars
   with explanation instead of failing

6. shell: Remove redundant "Command failed:" prefix from error messages
2026-01-11 19:52:00 +05:30
Dhanji R. Prasanna
7c960875ef Add hint to re-read memory from disk in system prompt
Added note that agents can use read_file .g3/memory.md to refresh
project memory if needed (e.g., after another agent updates it).
2026-01-11 19:40:02 +05:30
Dhanji R. Prasanna
9754c4ee66 Fix code fence closing without trailing newline
When a code block ended without a trailing newline after the closing
\`\`\`, two bugs occurred in flush_incomplete():

1. The closing \`\`\` was included as part of the code block content
   (displayed with syntax highlighting)
2. The same \`\`\` was then emitted again as literal text because
   current_line was not cleared after being pushed to block_buffer

The fix:
- Check if current_line is the closing fence before adding to block_buffer
- Always clear current_line after processing in the CodeBlock case

Added two tests:
- test_code_fence_after_blank_line: code fence with trailing newline
- test_code_fence_no_trailing_newline: code fence without trailing newline
2026-01-11 19:34:46 +05:30
Dhanji R. Prasanna
bb25c7881a Change agent mode header text
From: 🤖 Running as agent: fowler
To: >> agent mode | fowler
2026-01-11 17:24:26 +05:30
Dhanji R. Prasanna
4962f439f3 Simplify agent mode working directory display
Change from: 📁 Working directory: "/Users/dhanji/src/g3"
To: -> ~/src/g3

Replaces home directory with ~ for cleaner output.
2026-01-11 17:20:26 +05:30
Dhanji R. Prasanna
f83ae7fd39 Add status line showing loaded context in agent mode
Shows checkmarks for README, AGENTS.md, and Memory if loaded,
or dots if not found. Displayed below the working directory line.
2026-01-11 17:13:32 +05:30
Dhanji R. Prasanna
2b87a89617 Revert "Add fancy ASCII art header for agent mode"
This reverts commit 08747595a1.
2026-01-11 17:12:32 +05:30
Dhanji R. Prasanna
08747595a1 Add fancy ASCII art header for agent mode
The agent mode header now shows:
- Agent name in uppercase with box art
- Working directory (truncated if too long)
- Status indicators for README, AGENTS.md, and Memory loading
- Task preview if provided

Also exports truncate_for_display and adds truncate_path_for_display
helper functions in project_files module.
2026-01-11 17:11:14 +05:30
Dhanji R. Prasanna
2fbdac7aa9 Fix extra newlines before tool calls in JSON filter
The JSON tool call filter was outputting newlines immediately as they
were encountered. When the LLM output contained multiple newlines before
a tool call, each newline was output before the tool call JSON was
detected and suppressed, leaving orphaned blank lines in the output.

Changes:
- Add pending_newlines field to FilterState to buffer newlines at line start
- First newline after content is output immediately, subsequent ones buffered
- When tool call confirmed, pending_newlines cleared (suppressing extra blanks)
- When not a tool call, pending_newlines output with the buffer
- Add flush_json_tool_filter() to flush pending content at end of streaming
- Update tests to reflect new behavior
- Add tests for newline suppression behavior
2026-01-11 17:04:27 +05:30