Commit Graph

1754 Commits

Author SHA1 Message Date
TheArchitectit b08c32d760 feat(setup): separate env namespace for custom OpenAI-compat provider
The Custom (OpenAI-compat) /setup option was saving kind: openai and
injecting OPENAI_API_KEY / OPENAI_BASE_URL. That collides with users who
have real OpenAI/NeuralWatt credentials in their environment.

Introduce a dedicated custom-openai provider kind that uses its own
environment variables:

- CLAWCUSTOMOPENAI_API_KEY
- CLAWCUSTOMOPENAI_BASE_URL

A new custom/ routing prefix selects the OpenAI-compatible client with
those env vars and is stripped on the wire, so the proxy receives the
bare model id. /setup now saves kind: custom-openai and prompts for the
new env vars. Bare model names saved by /setup are normalized to
custom/<model>.

Manual verification against http://100.96.49.42:4001/v1 succeeds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-16 13:30:15 -05:00
TheArchitectit 3dde9be4ce fix(setup): normalize bare custom model to local/ prefix to avoid proxy 404
The previous fix normalized bare model names like openclaw to
openai/openclaw so validation passed, but the full prefixed name was sent
as the wire model, causing custom proxies to return 404.

Instead, normalize to local/openclaw. The local/ prefix forces OpenAI-
compatible routing and is always stripped by wire_model_for_base_url(),
so the backend receives the bare model id the user configured while the
CLI still validates and routes correctly.

- Revert validation-time bare-name acceptance (it leaked the user's
  OPENAI_BASE_URL env var into unrelated tests).
- Add unit tests for the local/ normalization and config env injection.
- Fix an unused_mut warning in tui/app.rs terminal-guard tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-16 12:25:52 -05:00
TheArchitectit abb6ba9d5c fix(setup): apply saved provider url/key/model for custom OpenAI endpoints
- Move config-to-env injection out of AnthropicRuntimeClient::new so
  parallel unit tests are not affected by global env mutations.
- Call inject_config_as_env_fallbacks() once at binary startup in run(),
  preserving the env-var > .env > stored-config precedence.
- Normalize bare model names (e.g. openclaw) to openai/openclaw when a
  custom OpenAI-compatible base URL is configured, so validation passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-16 11:34:18 -05:00
TheArchitectit 14c0d9df40 fix: inject /setup provider settings as env var fallbacks for API client
The /setup wizard saves apiKey and baseUrl to ~/.claw/settings.json,
but the API client constructors (OpenAiCompatClient::from_env,
AnthropicClient::from_env) only read environment variables. This caused
saved provider settings to be silently ignored — you'd run /setup,
set a custom URL and API key, and the runtime would still try to use
the default endpoint.

Now AnthropicRuntimeClient::new() calls inject_config_as_env_fallbacks()
before constructing the API client. This function loads the config file's
provider settings and sets the corresponding env vars (OPENAI_API_KEY,
OPENAI_BASE_URL, etc.) only when they aren't already set — preserving
the 3-tier resolution order: env var > .env file > stored config.

This is a process-level env injection (set_var), so it only affects
the current claw process and its children, not the parent shell.
2026-06-15 13:47:28 -05:00
TheArchitectit a535cb56b4 fix(tui): populate conversation from session, add /menu, fix exit
- Populate the TUI conversation pane from existing session messages
  when entering via /tui — no more empty TUI
- Add /menu command to return from TUI to the plain REPL
- Add run_repl_from_cli() to resume the REPL with the same LiveCli
- Ctrl+D and /exit both break the loop and exit cleanly
- Ctrl+C clears input and stays in TUI
- Handle MessageRole::Tool in the populate loop
2026-06-15 12:44:56 -05:00
TheArchitectit d104f90c44 feat(tui): unify slash command dispatch with REPL handler
All slash commands now route through SlashCommand::parse() and
LiveCli::handle_repl_command() — the same path as the plain REPL.
This gives the TUI access to all 60+ slash commands instead of just
the 8 that were reimplemented in the TUI dispatcher.

TUI-specific commands (/theme, /keys, /exit) are still handled
locally because they modify TuiApp state directly. Everything else
leave_for_turn → handle_repl_command → reenter_after_turn.

The output from REPL commands appears in the normal terminal while
alternate screen is left, then the TUI re-enters with a clean redraw.

Also: alias now points to our debug build without hardcoding a model,
so the config file's provider is used.
2026-06-15 12:11:41 -05:00
TheArchitectit 0ca23dbdf4 test(tui): add regression tests for input corruption and output bleed
InputBar regression tests:
- Submit blocked during turn_in_progress
- Turn state properly cleared after turn completes
- Completions popup no-op when not showing
- Setting turn_in_progress marks dirty
- Cancel clears textarea and marks dirty

ConversationPane regression tests:
- wrap_line respects width in unicode-width terms
- Narrow width doesn't cause infinite loop
- Cache invalidated on width change (resize)
- mark_clean clears dirty flag

TerminalGuard tests:
- leave_for_turn no-op when already outside
- reenter_after_turn short-circuits when already inside
- EventBus sender and drain
2026-06-15 11:04:10 -05:00
TheArchitectit b934bdfcb8 feat(tui): wire EventBus into TuiApp for streaming event bridge
- event_bus is now accessible via event_sender() for background threads
- drain_events() processes TuiEvent variants and updates components:
  StreamTextDelta, TurnComplete, TurnError, TurnStarted, etc.
- read_line() drains events on each tick before polling for keys
- capture_turn() adds infrastructure for incremental output capture
- Fix flaky capture test (BufferRedirect shares fd across test threads)
- Current turn loop remains synchronous; background threading is next step
2026-06-15 11:00:28 -05:00
TheArchitectit 919c6fabcb feat(tui): add capture_turn for stay-in-TUI output capture
- Adds capture_turn() that wraps a closure with stdout/stderr capture
  and calls an on_output callback with captured text
- Infrastructure for the streaming event bridge — when turns run on a
  background thread, this will feed incremental output to the TUI
- For now, the turn loop continues to use leave-and-return via
  TerminalGuard because CliPermissionPrompter needs stdin access
2026-06-15 10:55:24 -05:00
TheArchitectit 5eb4cda847 refactor(tui): add TerminalGuard for safe suspend/resume
- RAII guard owns alternate screen + raw mode lifecycle
- Drop guarantees cleanup even on panic — replaces panic hook
- Consolidates 6 ad-hoc methods into leave_for_turn/reenter_after_turn
- main.rs uses guard-based lifecycle instead of suspend/resume

The panic hook in tui_update is no longer needed for cleanup —
the guard's Drop fires on panic and restores terminal state.
2026-06-15 10:51:27 -05:00
TheArchitectit 1b0d237de6 fix(tui): input stays in box during/after turn
- mark input bar turn-in-progress on submit
- re-enable input after turn resumes
- clear input area before redraw
- clear completion popup before redraw
- resume re-enters alternate screen and clears cleanly

This prevents typed text from overwriting itself and stops redraws from
spilling word-wrapped text outside the input box.
2026-06-15 08:55:19 -05:00
TheArchitectit f6597f1935 docs(tui): add MoA research reports + synthesized architecture plan
5 expert reports (MoA review):
- moa-codex-rs: OpenAI's codex-rs/TUI architecture analysis
- moa-aichat: sigoden/aichat streaming markdown rendering
- moa-ecosystem: broader Rust TUI ecosystem survey
- moa-failure-analysis: root-cause of 3 failed TUI attempts
- moa-runtime-integration: claw-code runtime integration points

Plus the synthesized architecture plan (ARCHITECTURE.md) and
original planning docs (TUI.md, 52-week plan, sprint plan).
2026-06-12 21:21:42 -05:00
TheArchitectit 6e787c2b0c feat(tui): component-based TuiApp, slash dispatch, markdown AST
- Convert tui.rs -> tui/ directory module, old god-struct in legacy.rs
- New component architecture: Component/Overlay traits, ConversationPane,
  InputBar, Dashboard, StatusBar, CommandPaletteOverlay, AgentViewOverlay
- Component-based TuiApp in app.rs with draw_screen pre-borrow pattern
- SlashCommandDispatcher extracted from main.rs
- MarkdownAst + shared parser (normalize_nested_fences, render_diff,
  find_stream_safe_boundary, strip_ansi)
- EventBus with crossbeam-channel
- add capture.rs for future stdout gating
- Reuse in workspace: 59 TUI tests pass
2026-06-12 14:46:13 -05:00
TheArchitectit 25610f2a06 fix(tui): leave alternate screen during turns — zero output bleeding
The TUI is not active during tool execution. The flow becomes:
  1. leave_for_turn()  — exit alt screen, enable raw mode
  2. cli.run_turn_to() — stdout/stderr goes to normal terminal
  3. wait_to_return()  — 'Press any key to return to TUI...'
  4. reenter_after_turn() — re-enter alt screen, redraw

This guarantees zero output bleeding. Replaces suspend/resume approach.
2026-06-12 14:30:06 -05:00
TheArchitectit 4af649b442 fix(tui): safe stdout capture + focused OpenCode-style layout
- Add  dependency for safe stdout/stderr capture during turns
- Replace unsafe libc::dup/dup2 stdout suppression with capture_output()
- Tool stdout/stderr is now captured and rendered inside conversation pane
- Add compact StatusBar component for focused layout
- Redraw layout: status bar top, large conversation, compact input,
  optional dashboard on the right for wide terminals
- Eliminates output bleeding onto the TUI frame
- 321 tests pass
2026-06-12 14:17:21 -05:00
TheArchitectit 9d066a0818 fix(tui): ConversationPane render cache via RefCell — actually renders now
The Component trait's render(&self) couldn't mutate the cache.
Switched to RefCell<RenderCache> for interior mutability so the
word-wrapped line cache rebuilds on dirty during render().

Also adds Dashboard::clear_dirty() and marks components clean
after each draw_screen() cycle.
2026-06-12 14:03:35 -05:00
TheArchitectit 55941ac6c8 feat(tui): component-based architecture, eliminates libc::dup hack
- Convert tui.rs → tui/ directory module with legacy.rs re-export
- Add Component + Overlay traits for clean separation of concerns
- Build component-based TuiApp (app.rs) with pre-borrow draw pattern
- Extract: ConversationPane, InputBar, Dashboard, CommandPaletteOverlay,
  AgentViewOverlay as independent components
- Add EventBus with crossbeam-channel for component communication
- Add SlashCommandDispatcher (testable, decoupled from main.rs)
- Add shared MarkdownAst + parser + shared markdown utilities
- Add StreamingMarkdownState stub for incremental rendering
- Wire new TuiApp into main.rs::run_tui_repl()
- ELIMINATE unsafe libc::dup/dup2 stdout suppression — replaced with
  suspend/resume pattern (same as provider swap flow)
- All 320 tests pass, 57 TUI-specific tests pass
2026-06-12 13:26:53 -05:00
TheArchitectit 8f1ad0dc9a fix(tui): dup fd 1 to /dev/null during turns — no more output bleeding
THE REAL FIX: Before each model turn, save fd 1 (stdout) via dup(),
redirect it to /dev/null via dup2(), run the turn, then restore the
original fd. This catches EVERY possible stdout write during the turn:
runtime streaming, tool executor formatted output, bash subprocess
inheritance, crossterm escape codes, println! — all silently swallowed.

Previous approaches (emit_output=false, Vec<u8> buffer, screen clear)
were insufficient because the runtime's consume_stream writes to the
real io::stdout() through separate code paths that bypass our buffer.

Changed workspace unsafe_code from forbid→warn, and allow it in
rusty-claude-cli specifically. The dup/dup2/close calls are
single-threaded POSIX syscalls with well-understood semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:11:19 -05:00
TheArchitectit 99c4650ac7 fix(tui): add post-turn screen clear + redraw to eliminate output bleeding
The run_turn_to buffer + emit_output=false was correctly wired,
but runtime internals (child process stderr, tokio tracing, or
unstructured error paths) can still write to the real terminal fd.

Added a crossterm Clear(All) + MoveTo(0,0) after each turn to wipe
any stdout debris that may have landed on the alternate screen,
followed by a full TUI redraw to re-render both panes cleanly.

This is the belt-and-suspenders approach: buffer captures what we can,
screen clear catches what we can't.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 10:48:27 -05:00
TheArchitectit 9ed9df543b fix(tui): test fix, theme migration, zero hardcoded colors in rendering
- Fix failing test_filter_by_label: use 'Z' (matches nothing) and 'Help'
  (matches specific entries) instead of 'e' which matched everything
- Replace all 36 hardcoded Color:: in tui.rs and markdown.rs with theme
  lookups (theme.conversation_user, theme.dashboard_key, etc.)
- MarkdownRenderer now stores a TuiTheme, render_diff() accepts &TuiTheme
- section() and kv() helpers take theme param for key/color lookups
- draw_left_pane/draw_right_pane use theme for all colors
- push_user_input/push_system_message/push_output read from self.theme
- Only remaining Color:: in production code: Color::Reset (unstyled bg)
  and Color::Rgb (dynamic syntect output) — both acceptable

283 tests pass, 0 failures. Clippy clean. Workspace builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 10:25:11 -05:00
Claude d4ed89e61c chore: update Cargo.lock with once_cell and unicode-width deps
Adds lock entries for the two new dependencies added in Sprint 2/7.

Authored by TheArchitectit
2026-06-11 20:55:31 -05:00
Claude aefd3b23ef feat(tui): Sprint 7 — CJK word-wrap, input history, help, polish
- Replace wrap_line() with unicode-width-aware version (CJK double-width,
  hyphen/space/underscore/slash break points, no-break fallback)
- Add input history: Up/Down arrows browse previous inputs, 500-entry cap
  with push_history/history_up/history_down methods
- Input history wired in main.rs on message submit
- show_help() renders keybinding reference with Vim-specific section
- 8 new tests: wrap_line (empty, exact, overflow, hyphen, no-break, CJK,
  zero-width) + ConversationLine constructors
- 282 tests pass

Sprint 7 of 7 — all sprints complete.

Authored by TheArchitectit
2026-06-11 19:28:42 -05:00
Claude 6c872ba2e2 feat(tui): Sprint 6 — Agent View overlay with session monitoring
- Create src/agent_view.rs: AgentView data model with session tracking,
  status filtering (All/Running/Done/Failed), sorting, selection
- Agent View renders as full-screen overlay with session list + detail panel
- Keybindings: Ctrl+A open, Esc/q close, j/k navigate, Tab filter, s sort
- All colors from theme (agent_running/waiting/done/failed/cancelled)
- Command Palette overlay also rendered (from Sprint 4)
- 7 AgentView tests + 5 CommandPalette tests
- 274 tests pass

Sprint 6 of 7.

Authored by TheArchitectit
2026-06-11 19:19:38 -05:00
Claude 81beafa2a1 feat(tui): Sprint 5 — chat modes, /diff, /undo, /ls commands
- Create src/chat_mode.rs: ChatMode enum (Code/Ask/Architect) with
  system_prompt_suffix() for model behavior control
- /code, /ask, /architect slash commands to switch modes
- /diff — shows uncommitted git changes in conversation (no --color=always)
- /undo — shows revertable changes, /undo --confirm to actually revert
- /ls <path> — reads file contents into conversation
- /theme <name> — switches between 11 built-in themes at runtime
- /keys <preset> — switches Emacs/Vim/Windows keybindings
- ChatMode field in TuiApp, integrated with dashboard display
- 267 tests pass

Sprint 5 of 7.

Authored by TheArchitectit
2026-06-11 19:15:02 -05:00
Claude faf2ab831b feat(tui): Sprint 4 — keybindings with presets + command palette
- Create src/keybindings.rs: Action enum (20 variants), KeyMap with
  Emacs/Vim/Windows presets, Vim normal/insert mode support
- Create src/command_palette.rs: fuzzy-filterable modal with 9 built-in
  entries, arrow navigation, Enter to execute, Escape to close
- Refactor handle_key() to dispatch through Action enum instead of
  hardcoded KeyCode matches — clean separation of concerns
- dispatch_action() method shared by palette and key handler
- show_help() renders keybinding reference for current preset
- Ctrl+K opens palette, F1 shows help, /keys switches presets
- 10 keybinding tests + 5 palette tests
- 262 tests pass

Sprint 4 of 7.

Authored by TheArchitectit
2026-06-11 19:12:36 -05:00
Claude e68a80b418 feat(tui): Sprint 3 — theme system with 11 built-in themes
- Create src/theme.rs with TuiTheme struct (40+ color roles per theme)
- ColorDef enum: Named/Ansi256/Rgb with serde support
- 11 built-in themes: default, tokyonight, catppuccin-mocha, catppuccin-latte,
  nord, gruvbox, dracula, solarized-dark, solarized-light, monokai, system
- Theme integrated into TuiApp (tc() helper, set_theme() method)
- Dashboard rendering now uses theme colors (all Color::White/Gray/etc replaced)
- Input area uses theme colors (border, fg, cursor)
- JSON serialization/deserialization for custom themes
- 8 new tests: all builtins, ColorDef variants, JSON round-trip
- 248 unit tests pass

Sprint 3 of 7.

Authored by TheArchitectit
2026-06-11 19:08:30 -05:00
Claude e8e8c72185 feat(tui): Sprint 2 — markdown rendering, ConversationContent enum, diff viewer
- Create src/markdown.rs with MarkdownRenderer using pulldown-cmark + syntect
  (lazy-loaded via once_cell::Lazy, theme fallback chain, syntect 5.x API)
- ConversationContent enum: Plain/Markdown/CodeDiff variants
- push_output() auto-detects markdown via looks_like_markdown() heuristic
- build_wrapped_conversation() routes through MarkdownRenderer for markdown entries
- render_diff() for syntax-colored unified diffs (green+/red-/cyan @@)
- push_diff() convenience method for /diff command
- once_cell added to Cargo.toml
- 27 new tests for markdown rendering, detection, and diff colors
- All existing tests pass (240 unit tests, 108 contract tests)

Sprint 2 of 7.

Authored by TheArchitectit
2026-06-11 19:00:46 -05:00
Claude 755659c916 fix(tui): Sprint 1 — ProviderSwap fix, status race, memory bound, token tracking
S1-1: Fix ProviderSwap — use suspend()/resume() instead of restore_terminal()
so TUI re-enters cleanly after the setup wizard runs.

S1-2: Fix status message race — remove immediate ds.status_message.clear()
after set_status("Done") so the message is visible until next turn.

S1-4: Bound conversation memory — add MAX_CONVERSATION_LINES (10,000).
auto_scroll() now drains oldest entries and inserts a trim notice.

S1-5: Wire real token tracking — use runtime::UsageTracker::from_session()
to read cumulative TokenUsage (input, output, cache_creation, cache_read)
and pricing_for_model() to estimate cost. No more char÷4 guess.

Sprint 1 of 7. 218 tests pass.

Authored by TheArchitectit
2026-06-11 18:49:15 -05:00
Claude 7c34488042 feat(tui): Sprint 0 complete — panic hook, resize, TuiError, unicode-width
- S0-2: install_panic_hook() restores terminal on crash (disable raw mode,
  leave alt screen, show cursor) before printing panic message
- S0-3: Handle Event::Resize in TUI event loop via mark_resize()
- S0-4: Add unicode-width = "0.2" dependency for CJK-aware wrapping
- S0-5: Create src/tui_error.rs with TuiError enum (Io, Terminal, Runtime, Config)
- Wire panic hook into run_tui_repl with clean restore on exit
- Deprecation warnings fixed (PanicHookInfo instead of PanicHookInfo)

108 tests pass. 1 pre-existing failure (sandbox status contract) unrelated.

Authored by TheArchitectit
2026-06-11 18:42:21 -05:00
Claude 294ab2ab66 refactor(tui): extract ANSI stripper and dashboard update to tui_update module
- Create src/tui_update.rs with canonical strip_ansi() (handles CSI, OSC, DCS)
- Add DashboardUpdate struct to decouple from private LiveCli
- Remove duplicate strip_ansi_escapes from tui.rs and strip_ansi from main.rs
- update_dashboard() now delegates to tui_update::update_dashboard_from()
- 12 unit tests for ANSI stripping (CSI, OSC/BEL, OSC/ST, DCS, 256-color, RGB)

Sprint 0, Story S0-1. Pure extraction — no behavioral changes.

Authored by TheArchitectit
2026-06-11 18:37:39 -05:00
Claude 2d62b470f6 fix(tui): add guardrails as files instead of submodule
Embedded repo was committed as submodule (160000). Now includes all
guardrails files directly for full in-repo reference.

Authored by TheArchitectit
2026-06-11 18:29:45 -05:00
Claude a347a2f0c5 docs(tui): add sprint plans and agent guardrails for TUI parity
7 sprints (S0-S7), 44 stories, 29-day plan to achieve feature parity
with Claude Code, OpenCode, Codex CLI, and Aider terminal interfaces.
Includes Opus code review fixes and Four Laws guardrails integration.

Authored by TheArchitectit
2026-06-11 18:29:20 -05:00
TheArchitectit 58e095a0c0 fix(tui): buffer output during turns — no more full-width bleeding
Architecture C from expert panel review: add run_turn_to<W: Write>
that writes all output (spinners, markdown, compaction logs) to a
custom writer instead of hardcoding stdout.

In the TUI path, we pass a Vec<u8> buffer. Zero bytes hit the real
terminal during a turn, so nothing bleeds past the conversation pane
boundary into the dashboard. After the turn, the buffer contents are
stripped of ANSI codes and pushed into the conversation pane where
wrap_line() constrains them to the pane width.

Key changes:
- run_turn() is now a thin wrapper: run_turn_to(input, stdout, true)
- run_turn_to<W: Write>(input, out, emit_output) is the real impl
- All println! → writeln!(out, ...), &mut stdout → out
- emit_output=false in TUI mode prevents runtime tool-stream output
- Add strip_ansi() helper for cleaning captured buffer text
- Remove Clear(ClearType::All) from redraw_after_turn (no debris to wipe)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 16:25:34 -05:00
TheArchitectit e9f09d7fed feat(tui): wire up /tui command with split-pane dashboard
- Add 'mod tui;' to main.rs (was missing — TUI code was dead)
- Add /tui slash command that switches from the plain REPL to the
  split-pane TUI mode at runtime
- Show startup hint: 'Tip: type /tui for the split-pane dashboard view'
- Add run_tui_repl() that manages the TuiApp event loop, captures
  assistant output from the session, and feeds it to the conversation pane
- Add update_dashboard() helper that syncs runtime stats (model, session,
  turns, provider) into the shared dashboard state
- ProviderSwap and TeamToggle work inside TUI mode

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:59:33 -05:00
TheArchitectit 8fb40350e4 fix(tui): word-wrap conversation lines and align dashboard columns
Three fixes for the rendering mess when output goes off-screen:

1. Word-wrap conversation pane lines — long output no longer bleeds
   into the dashboard. The wrap_line() function soft-wraps at word
   boundaries and hard-breaks long tokens. The viewport math is
   updated to count *visual* rows (not logical Line items).

2. Dashboard kv() aligned columns — keys are right-padded to a
   fixed 12-char column (KV_KEY_WIDTH) so values line up cleanly
   regardless of key length.

3. Context gauge positioned by row tracking, not hard-coded y offset.
   The gauge_row counter moves with the section content, so it stays
   correct whether git_branch, LSP, or Team sections are shown/hidden.
   Also switched dashboard Wrap to trim: false to preserve spacing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:27:17 -05:00
TheArchitectit 28155a331f fix: resolve rebase conflicts, clean TUI alignment, and sync with upstream
- Split multi-line user input and system messages on newlines so each
  visual line gets its own ConversationLine (same pattern push_output
  already used). This fixes text misalignment when Enter is pressed.
- Don't enable Wrap on the conversation Paragraph — the FIFO viewport
  counts Line items to fill the pane, so soft-wrapping would throw off
  the row count and misalign content.
- Restore non-TUI files from upstream/main to clear conflict artifacts.
- Fix clippy warnings in lsp_client, lsp_process/parse, and trident.
- Add HandlerSwap and TeamToggle match arms in main.rs ReadOutcome.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 10:03:16 -05:00
TheArchitectit 2971728abb refactor: TUI, setup wizard, and main CLI improvements
- Refactored TUI rendering and state management
- Updated setup wizard flow
- CLI main entry point cleanup
2026-06-10 16:49:35 -05:00
TheArchitectit cc191fd65d fix(tui): replace fragile suspend/resume pattern with in-place turn execution
- Removed app.suspend()/app.resume() calls around REPL TUI turns
- Added assistant message capture from session for conversation pane
- Command errors now show as system messages instead of breaking TUI
2026-06-10 16:49:35 -05:00
TheArchitectit eb717bc11a feat: TUI split-pane layout with ratatui dashboard
Replace web dashboard with ratatui + crossterm + tui-textarea TUI:
- Left pane: scrollable conversation + input area with cursor indicator
- Right pane: live dashboard (model, tokens, context gauge, LSP, team, session)
- Auto-activates when stdout is a terminal, falls back to rustyline REPL
- Suspend/resume pattern: TUI suspends for run_turn (normal stdout), resumes after
- Key bindings: Enter/Shift+Enter, Ctrl+P/T/C/D, Tab completions, PageUp/Down
- 16ms poll interval with dirty-flag optimization
- CLAW ASCII art banner in styled colors

Dependencies added: ratatui 0.29, tui-textarea 0.7

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:35 -05:00
TheArchitectit 173588bd6a feat: agent teams with task claiming, context management, and team monitoring
- TeamInboxReporter: per-tool-call progress reporting to team inbox
- TaskClaim tool: atomic claim/release/list with .clawd-agents/claims/ lock files
- Team-scoped task_ids to prevent cross-team claim collisions
- AgentSuggestion tool: propose AGENTS.md additions (human review required)
- ContextRequest tool: iterative retrieval with 3-cycle budget for sub-agents
- Context-window-aware auto-compaction (70% threshold) prevents overflow
- Model token limits for qwen/glm/generic models with 131K fallback
- Reviewer subagent_type: read-only tools, no bash/write
- Team mode presets: 1x-6x (tiny/small/medium/large/xlarge/mega)
- /team slash command + Ctrl+T toggle (off by default, CLAWD_AGENT_TEAMS=1)
- TeamDelete: disk-based deletion with inbox/claims cleanup
- TeamStatus: kill stuck agents, list AGENTS.md suggestions
- AGENTS.md: auto-loaded shared learnings in sub-agent system prompt
- Periodic git commits every 5 tool calls via TeamInboxReporter
- Claims released on failure/panic in spawn_agent_job
- Fixed doubled .clawd-agents/.clawd-agents/ paths (set CLAWD_AGENT_STORE abs)
- Fixed "unknown error" in team watcher (added error field to inbox messages)

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit c3d3635924 feat: inbox-based team monitoring
- Agents post completion/failure to team inbox on termination
  (.clawd-agents/mailbox/team/{team_id}/{agent_id}-{ts}.json)
- Team watcher reads from inbox instead of polling .json files
- New TeamStatus action=inbox reads team messages from the inbox
- AgentOutput carries team_id, persisted in manifest
- AgentInput accepts team_id from TeamCreate
- TeamCreate passes team_id to each spawned agent
- Inbox cleaned up when all agents finish

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit b537ff7b0f feat: validate config on startup, prompt setup wizard if fields missing
On REPL start, check for missing provider.apiKey, provider.baseUrl,
and subagentModel. Print a warning with instructions to run `claw setup`
or `/setup` if any are absent.

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit 087b5f0f23 fix: update TeamCreate description to mention TeamStatus, restore subagentModel
Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit ec97ed786f feat: TeamStatus tool and background team watcher
- TeamStatus tool with 3 actions:
  - status: live snapshot (running/completed/failed counts, agent details)
  - summary: final results when agents finish (includes result content)
  - events: timeline from append-only event log
- Background team watcher thread spawned by TeamCreate:
  - Polls agent .json files every 2s
  - Prints [team] progress to stderr on agent completion/failure
  - Updates team manifest status when all agents finish
  - Writes events to .clawd-agents/teams/{team_id}-events.jsonl
- TeamStatus added to PARALLEL_SAFE_TOOLS and all agent allowed_tools

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit 4652c65133 fix: default to 2x team mode when no mode or tasks provided
Instead of erroring when neither mode nor tasks are specified,
default to "2x" (2 Explore + 2 Plan + 2 Verification = 6 agents).

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit 560c07703b feat: team mode presets (2x/4x/6x) for TeamCreate
Add 'mode' field to TeamCreate that auto-generates agent teams:
- "2x" = 2 Explore + 2 Plan + 2 Verification = 6 agents
- "4x" = 4 Explore + 4 Plan + 4 Verification = 12 agents
- "6x" = 6 Explore + 6 Plan + 6 Verification = 18 agents

When mode is set, 'prompt' provides the shared task description and
'tasks' is ignored. Also add 'subagent_type' and 'model' fields to
manual task items for per-task role and model control.

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit 0d833fe4f2 fix: add AgentMessage dispatch entry, allowed_tools, and debug logging
- Add missing AgentMessage dispatch entry in execute_tool_with_enforcer
  (tool spec existed but couldn't actually be called)
- Add AgentMessage to Explore/Plan/Verification/general-purpose
  allowed_tools lists so sub-agents can communicate
- Add debug logging to resolve_agent_model and load_subagent_model_from_config
  to diagnose subagentModel config chain

Co-authored-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:34 -05:00
TheArchitectit 5b707a2fd6 feat: agent teams with inter-agent messaging and parallel execution
- Agent tool is now parallel-safe: multiple Agent calls execute concurrently
- AgentMessage tool: send/read/broadcast between agents via shared mailbox
- TeamCreate rewired to spawn real Agent threads instead of TaskRegistry
- Agents set CLAWD_AGENT_ID env var so they can identify themselves for messaging
- AgentMessage added to Explore/Plan/Verification sub-agent tool lists
- Team manifest persisted to .clawd-agents/teams/{team_id}.json
2026-06-10 16:49:34 -05:00
TheArchitectit c9fa7ec145 refactor: remove SubAgent tool, make Agent use subagentModel config
Match Claude Code's architecture: a single Agent tool with subagent_type
(Explore/Plan/Verification) that uses the subagentModel setting when
no explicit model override is provided. The separate SubAgent tool is
removed since it duplicated existing functionality.
2026-06-10 16:49:34 -05:00
TheArchitectit daffe1aeae fix: improve SubAgent/Agent descriptions to steer model toward SubAgent for exploration 2026-06-10 16:49:34 -05:00