Commit Graph

1735 Commits

Author SHA1 Message Date
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
TheArchitectit aec1c02281 feat: SubAgent tool for fast sub-agent delegation
Add a SubAgent tool that lets the main model delegate multi-step read
and search tasks to a fast, inexpensive sub-agent. The sub-agent runs
autonomously with its own ConversationRuntime, making multiple tool
calls without round-tripping through the main model.

- SubAgent tool with prompt, task_type (Explore/Plan/Verify), and
  optional model override
- Explore: read_file, glob_search, grep_search, WebFetch, WebSearch
- Plan: Explore + TodoWrite
- Verify: Plan + bash
- subagentModel config field in settings.json (falls back to main model)
- Uses ProviderRuntimeClient + SubagentToolExecutor (same as Agent tool)

This dramatically reduces token usage for information-gathering tasks.
Example: "find all Rust files that import X and summarize their usage"
→ one SubAgent call instead of 10 sequential main-model round trips.
2026-06-10 16:49:33 -05:00
TheArchitectit 0ff3882ca3 feat: parallel tool execution for read-only tools
When the model returns multiple tool_use blocks in a single response,
read-only tools (read_file, glob_search, grep_search, WebFetch,
WebSearch, LSP, Git*) now execute concurrently via std:🧵:scope
instead of sequentially.

Architecture:
- Add ToolCall/ToolResult types to ToolExecutor trait
- Add execute_batch() with default sequential fallback
- CliToolExecutor overrides execute_batch to classify tools as
  parallel-safe or sequential, then runs parallel-safe tools
  concurrently via thread scopes
- run_turn refactored into 3 phases:
  1. Pre-hooks + permission checks (sequential, hooks may mutate state)
  2. Tool execution (batch, parallel for read-only tools)
  3. Post-hooks + session updates (sequential, preserves ordering)

Safety guarantees:
- Pre/post hooks always run sequentially
- Permission checks complete before any tool executes
- Tool results pushed to session in original model order
- Fallback to sequential for single-tool batches
2026-06-10 16:49:33 -05:00
TheArchitectit 5bb811aa5e feat: project rules with .claw/rules/ and multi-framework auto-import
Adds a project rules system for loading instruction files into the
system prompt, plus auto-import from other AI coding frameworks.

- `.claw/rules/*.md` / `.claw/rules/*.txt` / `.claw/rules/*.mdc`
- `.claw/rules.local/*.md` — personal/local rules (gitignored)
- Existing: `CLAUDE.md`, `CLAUDE.local.md`, `.claw/CLAUDE.md`,
  `.claw/instructions.md`

When users switch to claw-code from another tool, their existing
rules are automatically detected and loaded:
- Cursor: `.cursorrules`, `.cursor/rules/`
- GitHub Copilot: `.github/copilot-instructions.md`
- Windsurf: `.windsurfrules`, `.windsurfrules/`
- Aider: `.aider.conf.yml` instructions block
- Pi (Plandex): `.plandex/instructions.md`, `.plandex/plan.md`
- OpenCode: `opencode.json` instructions field
- Crush: `.crush/CLAUDE.md`, `.crush/rules/`

`rulesImport` in settings.json controls framework auto-import:
- `"auto"` (default) — import from all detected frameworks
- `"none"` — only load .claw/rules/ and CLAUDE.md files
- `["cursor", "copilot"]` — import only from listed frameworks

```json
{
  "rulesImport": "auto"
}
```

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:33 -05:00
TheArchitectit 72f50b840e feat(lsp): show "Loading LSP servers..." with start/stop hints
- Startup now shows "Loading LSP servers..." then ✓/✗ per server
- When auto-start is on: shows disable hint (toggle or settings.json)
- When auto-start is off: shows available servers with how to start

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:33 -05:00
TheArchitectit b00628f5ff fix(lsp): suppress Node.js deprecation warnings from JS-based LSP servers
Set NODE_NO_WARNINGS=1 when spawning LSP server processes to suppress
noisy punycode deprecation warnings from bash-language-server,
yaml-language-server, vscode-* servers, etc.

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:33 -05:00
TheArchitectit 2b5f46080e feat(lsp): add TCP transport for GDScript/Godot LSP (port 6008)
Godot LSP runs as a TCP server on localhost:6008 when the editor is
open — it doesn't speak LSP over stdio like other servers. Added
connect_tcp() to LspTransport which uses socat (or nc fallback) as
a stdio↔TCP bridge, reusing the existing Content-Length framing.
lsp_process detects tcp:// URIs and routes to TCP transport.

LSP startup now gracefully handles servers that fail to start
(gdscript without a running Godot editor) without blocking other
servers from initializing.

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:33 -05:00
TheArchitectit 7cdccc3ca5 feat(lsp): install prompts, new servers, and advanced LSP features
- Add distro-aware install prompt system: detects Ubuntu/Debian/Fedora/
  Arch/openSUSE/Alpine/Void/NixOS/macOS and suggests the right install
  command for each missing LSP server at startup
- Add 6 new language servers: HTML, CSS, JSON, Bash, YAML, GDScript
- Add didClose notifications for proper file lifecycle
- Add code_action support (quick fixes, refactors)
- Add rename support (workspace-wide symbol renaming)
- Add signature_help (function signatures + parameter hints)
- Add code_lens (inline actionable hints)
- Add workspace_symbols (project-wide symbol search)
- Add workspaceFolders support in initialize handshake
- Advertise full capability set (code actions, rename, signatures,
  code lens, workspace symbols) to LSP servers
- Fix panic in lsp_discovery test when rust-analyzer is a rustup
  proxy stub for an uninstalled component

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:33 -05:00
TheArchitectit 562ee61466 fix: resolve cherry-pick conflicts and remove non-LSP artifacts
Remove SlashCommand::Setup (provider wizard), PROVIDER_FIELDS
(provider config), and stale imports that leaked in from the
feat/lsp-integration branch which included other PRs. Also fix
pre-existing clippy findings (Duration::from_hours, is_ok_and).
2026-06-10 16:49:32 -05:00
TheArchitectit a132953afc feat(lsp): add lspAutoStart config, remove unused LSP client/process/transport modules
- Add lsp_auto_start field to RuntimeFeatureConfig (default: true)
- Add lspAutoStart bool field validation in config_validate
- Parse lspAutoStart from config JSON
- Auto-start discovered LSP servers on REPL init when enabled
- Add /lsp toggle command to enable/disable auto-start at runtime
- Remove lsp_client.rs, lsp_process.rs, lsp_transport.rs (2831 lines)
  — functionality consolidated into discovery-based auto-start
- Show auto-start status in /lsp status output
2026-06-10 16:49:32 -05:00
TheArchitectit 4be1d43ada feat: auto-LSP integration with didOpen/didChange and diagnostic enrichment
Wire LSP into the Read/Edit/Write tool flow so the agent automatically
gets diagnostics after file operations:

- lsp_transport: Add LspServerMessage enum, read_message() for handling
  both responses and server-initiated notifications, notification queue
  with drain_notifications(), send_request now handles interleaved
  publishDiagnostics without breaking

- lsp_process: Add did_open(), did_change(), drain_diagnostics(),
  open file tracking (HashSet) and version counters for didChange,
  language_id_for_path() and severity_name() helpers

- lsp_client: Add notify_file_open(), notify_file_change(),
  fetch_diagnostics_for_file() with best-effort graceful fallback,
  registry-level open file tracking, diagnostic caching

- tools: Enrich run_read_file with didOpen + diagnostics, run_write_file
  and run_edit_file with didChange + diagnostics, format_diagnostic_appendix()
  for readable diagnostic output appended to tool results

All enrichment is non-blocking: if no LSP server is available, tools work
exactly as before. No errors propagate from the LSP layer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:32 -05:00
TheArchitectit 3fadbf4412 feat: full LSP (Language Server Protocol) integration
Implement complete LSP support for code intelligence tools:

- lsp_transport.rs: JSON-RPC 2.0 transport over stdio with Content-Length
  framing, async request/response handling, and graceful shutdown

- lsp_process.rs: LSP process manager with initialize handshake, and methods
  for hover, goto_definition, references, document_symbols, completion, format

- lsp_discovery.rs: Auto-discovery of installed LSP servers (rust-analyzer,
  clangd, gopls, pyright, typescript-language-server, etc.) with PATH lookup

- lsp_client.rs: Rewired LspRegistry to use real LSP processes instead of
  placeholder JSON, with lazy-start on first dispatch call

- config.rs: Added LspServerConfig for user-configured LSP servers

- config_validate.rs: Validation for lsp config section

- main.rs: CLI integration with server discovery at startup, /lsp slash
  command for status/start/stop/restart, and graceful shutdown on exit

- commands/src/lib.rs: Added SlashCommand::Lsp variant

The LSP tool is now available to the agent for hover, definition, references,
symbols, completion, and diagnostics queries. Servers are auto-discovered at
REPL startup and lazily started on first use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:32 -05:00
TheArchitectit 0d0055a39e fix: sync all bug fixes to combined branch
- compact.rs: fix panic when preserve_recent_messages=0
- main.rs: progressive 4-round auto-compact retry with session_mut fix
- main.rs: detect "no parseable body" as context window overflow
- anthropic.rs: remove debug eprintln
- error.rs: add "no parseable body" to CONTEXT_WINDOW_ERROR_MARKERS
- config.rs, lib.rs: conflict resolution fixes from merge

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-10 16:49:31 -05:00
TheArchitectit 763179877a feat: API timeout config, Retry-After header support, and configurable retry
- Add TimeoutConfig to HTTP client builder with connect_timeout (30s)
  and request_timeout (5min) defaults, configurable via
  CLAW_API_CONNECT_TIMEOUT and CLAW_API_REQUEST_TIMEOUT env vars
- Add with_timeout() builder to both AnthropicClient and
  OpenAiCompatClient for per-client timeout configuration
- Parse Retry-After header on 429 responses and use it to override
  exponential backoff delay when present
- Add ApiTimeoutConfig to runtime config with apiTimeout settings
  in ~/.claw/settings.json (connectTimeout, requestTimeout, maxRetries)
- Add retry_after field to ApiError::Api for propagating rate limit
  backoff hints through the retry pipeline
2026-06-10 16:49:31 -05:00
TheArchitectit 8b120a322d feat: Trident compaction pipeline (supersede + collapse + cluster)
Add the 3-stage Trident compaction strategy from R.A.D.1.C.A.L,
adapted for the Rust CLI session model:

Stage 1 - SUPERSEDE: Zero-cost factual pruning. If a file was read
and then later written/edited, the earlier read is obsolete and
removed. Earlier writes superseded by later writes are also dropped.

Stage 2 - COLLAPSE: Buffer short chatty exchanges (under 200 chars,
no tool calls) and collapse them into dense summary blocks when the
threshold is exceeded.

Stage 3 - CLUSTER: Group semantically similar messages (same tool
names, same file paths, similar lengths) using Jaccard-based
fingerprinting and collapse clusters into summary blocks.

All three stages run before the existing summary-based compaction,
so less data needs to be summarized. Wired into both /compact and
the auto-compact retry on context window errors.
2026-06-10 16:49:31 -05:00
TheArchitectit c28092d540 feat(lsp): add lspAutoStart config, remove unused LSP client/process/transport modules
- Add lsp_auto_start field to RuntimeFeatureConfig (default: true)
- Add lspAutoStart bool field validation in config_validate
- Parse lspAutoStart from config JSON
- Auto-start discovered LSP servers on REPL init when enabled
- Add /lsp toggle command to enable/disable auto-start at runtime
- Remove lsp_client.rs, lsp_process.rs, lsp_transport.rs (2831 lines)
  — functionality consolidated into discovery-based auto-start
- Show auto-start status in /lsp status output
2026-06-10 16:49:31 -05:00
TheArchitectit d610657cf0 refactor: split LSP modules under 500 lines each
Split the three large LSP files into module directories with sub-files:

lsp_transport/ (was 560 lines):
  - mod.rs (425) — types + LspTransport impl
  - tests.rs (134) — test module

lsp_process/ (was 929 lines):
  - mod.rs (436) — LspProcess struct + public methods + error types
  - parse.rs (311) — helper functions and LSP response parsers
  - tests.rs (194) — test module

lsp_client/ (was 1338 lines):
  - mod.rs (466) — LspRegistry struct + impl, re-exports from types
  - types.rs (103) — LspAction, LspDiagnostic, LspServerStatus, etc.
  - dispatch.rs (224) — LspRegistry::dispatch() method
  - tests.rs (273) — core registry tests
  - tests_lifecycle.rs (294) — lifecycle and integration tests

All files under 500 lines. All 501 runtime tests pass. Clippy clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:30 -05:00
TheArchitectit 5fee7fdf39 feat: auto-LSP integration with didOpen/didChange and diagnostic enrichment
Wire LSP into the Read/Edit/Write tool flow so the agent automatically
gets diagnostics after file operations:

- lsp_transport: Add LspServerMessage enum, read_message() for handling
  both responses and server-initiated notifications, notification queue
  with drain_notifications(), send_request now handles interleaved
  publishDiagnostics without breaking

- lsp_process: Add did_open(), did_change(), drain_diagnostics(),
  open file tracking (HashSet) and version counters for didChange,
  language_id_for_path() and severity_name() helpers

- lsp_client: Add notify_file_open(), notify_file_change(),
  fetch_diagnostics_for_file() with best-effort graceful fallback,
  registry-level open file tracking, diagnostic caching

- tools: Enrich run_read_file with didOpen + diagnostics, run_write_file
  and run_edit_file with didChange + diagnostics, format_diagnostic_appendix()
  for readable diagnostic output appended to tool results

All enrichment is non-blocking: if no LSP server is available, tools work
exactly as before. No errors propagate from the LSP layer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:30 -05:00
TheArchitectit 86cfae8c10 fix: LSP discovery finds rust-analyzer via rustup proxy
rust-analyzer installed through rustup exits non-zero on --version
("Unknown binary in official toolchain"), which caused discovery
to skip it. Changed command_exists_on_path to treat any successful
spawn as "found", regardless of exit code — only a failure to
spawn (command not found) means the server isn't available.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:30 -05:00
TheArchitectit e72368eaa5 feat: full LSP (Language Server Protocol) integration
Implement complete LSP support for code intelligence tools:

- lsp_transport.rs: JSON-RPC 2.0 transport over stdio with Content-Length
  framing, async request/response handling, and graceful shutdown

- lsp_process.rs: LSP process manager with initialize handshake, and methods
  for hover, goto_definition, references, document_symbols, completion, format

- lsp_discovery.rs: Auto-discovery of installed LSP servers (rust-analyzer,
  clangd, gopls, pyright, typescript-language-server, etc.) with PATH lookup

- lsp_client.rs: Rewired LspRegistry to use real LSP processes instead of
  placeholder JSON, with lazy-start on first dispatch call

- config.rs: Added LspServerConfig for user-configured LSP servers

- config_validate.rs: Validation for lsp config section

- main.rs: CLI integration with server discovery at startup, /lsp slash
  command for status/start/stop/restart, and graceful shutdown on exit

- commands/src/lib.rs: Added SlashCommand::Lsp variant

The LSP tool is now available to the agent for hover, definition, references,
symbols, completion, and diagnostics queries. Servers are auto-discovered at
REPL startup and lazily started on first use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:49:30 -05:00