- 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>
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>
- 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>
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>
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>
- 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>
- 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
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.
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.
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
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>
- 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>
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>
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>
- 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>
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).
- 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
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>
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>
- 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
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.
- 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
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>
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>
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>
Ctrl+P now inserts a sentinel char (\x01) that the highlighter renders
as a cyan "[Provider Swap]" prompt. User presses Enter to confirm and
launch the setup wizard. Returns ReadOutcome::ProviderSwap so the REPL
loop can hot-swap the model and reprint the connection line.
Also fixes clippy warnings: merged duplicate match arms in
provider_config_value, doc_markdown on ProviderKind, map_unwrap_or
idioms in setup_wizard.rs, and pre-existing clippy issues in main.rs
and commands/lib.rs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds an interactive setup wizard that lets users configure their provider,
API key, base URL, and model without setting environment variables.
Configuration is persisted to ~/.claw/settings.json (with 0600 permissions).
New features:
- `claw setup` CLI subcommand runs the wizard from the terminal
- `/setup` slash command runs the wizard inside the REPL (hot-swaps model)
- Ctrl+P hotkey in the REPL triggers /setup for in-session provider swap
- Stored provider config used as fallback when env vars are absent
- Three-tier auth resolution: env var > .env file > stored config
- RuntimeProviderConfig struct and validation in settings schema
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- OLLAMA_HOST takes priority over OPENAI_BASE_URL for local Ollama instances
- No API key required; placeholder token used for Authorization header
- Model names like 'qwen3:8b' bypass strict provider/model syntax validation
- detect_provider_kind() checks OLLAMA_HOST first in routing cascade
- ProviderClient dispatch uses from_ollama_env() when OLLAMA_HOST is set
- Updated USAGE.md and docs with OLLAMA_HOST as preferred env var
- Added OLLAMA_CONFIG constant and from_ollama_env() to openai_compat
- Added test_ollama_host_bypasses_model_validation unit test
- Supersedes PR #3213 (which had a duplicate if-let bug in mod.rs)
- Update slash_command_specs().len() assertion from 139 to 140.
The /setup command added by this PR increased the spec count by 1
but the test's expected count was not updated, causing CI failure.
- Add assert!(help.contains("/setup")) to the
renders_help_from_shared_specs test so the new command is
verified in the help output.
Fixes CI Build ❌ and Test ❌ on #3218.
The setup wizard was merged in PR #3017 but was orphaned -- it was not
declared as a module in main.rs, making it unreachable. Additionally,
the setup_wizard.rs imports RuntimeProviderConfig which did not exist
on upstream/main. This commit makes the wizard accessible and adds the
necessary RuntimeProviderConfig type.
Changes:
- Add RuntimeProviderConfig struct to runtime/src/config.rs with
kind(), api_key(), base_url(), model() accessors.
- Add parse_optional_provider_config() to parse the provider object
from merged settings JSON.
- Add provider() method to RuntimeConfig and RuntimeFeatureConfig.
- Export RuntimeProviderConfig, save_user_provider_settings,
clear_user_provider_settings, and default_config_home from runtime
crate public API (runtime/src/lib.rs).
- Add mod setup_wizard to rusty-claude-cli/src/main.rs.
- Add claw setup CLI subcommand.
- Add /setup slash command.
- Add Setup variant to SlashCommand enum.
- Add Setup to LocalHelpTopic enum.
- Add setup to diagnostic subcommand matching.
- Add subagentModel to TOP_LEVEL_FIELDS in config_validate.rs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Updated the agents_and_skills_usage_support_help_and_unexpected_args
test to match the new skills help text that includes [--project].
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Session save_to_path now wraps ENOENT errors from rotate and atomic
write with a clear "possible concurrent modification" message instead
of surfacing raw OS errno. Helps operators debugging race conditions
when multiple claw invocations touch the same session file.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
SessionLifecycleSummary now collects all matching tmux panes into an
all_panes field and includes them in the JSON output. Previously the
status command returned on the first non-idle pane, losing all other
active panes in the same workspace/session.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
401 and 403 errors now include a hint explaining which env vars to
check for each provider (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
and suggesting claw doctor for credential verification.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
claw skills install --project <path> now installs to .claw/skills/
in the current project instead of the user-level registry. Skills
installed at project level are already discovered by the existing
registry system. Both text and JSON handlers updated.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
MCP server config now expands ${VAR} environment variable references
and ~/ home directory prefix in command, args, and url fields. Previously
these values were passed verbatim to execve/URL-parse, causing silent
"No such file or directory" failures for standard config patterns.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
deep_merge_objects now concatenates arrays when both layers provide
the same key. Previously permissions.allow, hooks.PreToolUse, etc.
from earlier config layers (e.g. ~/.claw/settings.json) were silently
discarded when a later layer (e.g. project .claw/settings.json) set
the same key. Now arrays are merged additively across layers.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
PermissionRule::parse now normalizes tool_name to lowercase, matching
the runtime convention. Previously "Bash(rm:*)" would never match
because the runtime tool name is lowercase "bash". Same fix applied
to denied_tools list.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
/resume mode /clear now preserves the original session_id instead of
generating a new one. This prevents the filename/meta-header divergence
where /session list reported an id that --resume couldn't find.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
/session switch and /session fork now return structured JSON with
kind:error, error_kind:unsupported_resumed_command, and actionable
hint instead of a raw error string that resume callers couldn't parse.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Add friendly_cwd() helper that strips /private prefix on macOS so
status, doctor, and diff JSON output matches user-visible invocation
cwd instead of the canonicalized /private/tmp path.
Applied to status_context() and render_doctor_report().
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
/model was in the unsupported resume group but is a read-only command
that can safely return model configuration. Now returns default_model,
configured_model, resolved_model, and requested_model in JSON mode.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
--compact was silently ignored when used with non-prompt commands like
claw --compact status or claw --compact config. Now returns a typed
error with guidance on proper usage.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
/tasks was marked resume_supported but rejected in resume mode.
Now returns a structured JSON response with kind:'tasks' and note
that background tasks are only available in the interactive REPL.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
- /config help now returns available_sections array and loaded_keys
count instead of treating 'help' as an unsupported section
- Updated test to exclude 'help' from unsupported sections test
- Added new test config_help_returns_structured_section_list_344
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
/config help now returns a list of available config sections in both
text and JSON mode instead of treating 'help' as an unsupported section.
Text mode shows available sections with descriptions.
JSON mode returns available_sections array with loaded_keys count.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Top-level 'claw --output-format json help' now includes a 'commands'
array with name, summary, and resume_supported for each registered
slash command, plus 'total_commands' count.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
plugins enable now checks if the plugin was already enabled before
setting reload_runtime:true. Same for disable. Returns 'already enabled'
or 'already disabled' in the message when no state change occurred.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Add GitOperation enum to detect mid-operation git states from the
branch header in git status --short --branch output.
- Rebase: 'rebasing ...' in branch header
- Merge: '[merge-in-progress]' tag
- Cherry-pick: 'cherry-pick-in-progress' tag
- Bisect: 'bisect-in-progress' tag
Operation state appears in:
- status text: 'rebase-in-progress, dirty · 3 files · ...'
- status JSON: 'git_operation' field (null when no operation)
- git_state headline includes operation prefix
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
--base-commit now rejects non-hex strings and strings outside 7-64
character range. Matches the pattern used by --reasoning-effort.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
The --cwd validation added in #99 rejects non-existent paths, but the
test used /tmp/project which doesn't exist on CI Linux runners. Changed
to /tmp which exists everywhere.
Also marks ROADMAP #123 DONE (--allowedTools normalization verified).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
MCP server details JSON now redacts args (shows count only),
strips URL query params which may contain tokens, and shows
headers_helper as configured/not-configured boolean instead of
the raw command string. env_keys and header_keys still exposed
(key names only, not values).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
status/doctor JSON now reports git_state:'no_git_repo' when
project_root is None, instead of the misleading 'clean' which
implied a git repo was present with zero changes.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
bootstrap-plan --output-format json now returns phases as structured
objects with id, label, description, and order fields instead of
raw Rust enum variant name strings. Also exposes total_phases count.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
--cwd now validates the path exists and is a directory before passing
it to the system prompt renderer. --date rejects values with newlines
or >20 chars to prevent prompt injection.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Changed resumed_help_command_emits_structured_json to assert 'message'
field instead of 'text', matching the #338 fix for help JSON field
consistency.
Also marked ROADMAP #340 and #345 DONE with direct runtime evidence:
340: resume /session help now routes JSON to stdout (verified)
345: resume /config <section> now returns section-specific JSON (verified)
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
#327: mcp help now includes .claw.json in documented sources list
#328: agents help now includes ~/.codex/agents in documented sources list
#408: added is_clean boolean to status JSON workspace for unambiguous
dirty-state detection; changed_files documented as total non-clean count
#338: resume help field consistency (committed earlier)
Also marked 52 items with explicit done/verified evidence as DONE
in ROADMAP.md, including product principles (1-6) and items with
confirmed fix text (13-75, 96, 200).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
#410: Added field to mcp list and skills list JSON for
polymorphic consumption parity with agents list. All three sibling
list commands now expose a canonical integer field alongside
their command-specific details.
#338: Changed resume JSON from to field for
consistency with top-level .
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
#683-#692: help topic JSON now includes usage, purpose, formats,
related, local_only, requires_credentials, and aliases extracted
from help prose. Export and doctor keep their custom structured
responses.
#466: new check_base_url_health() validates ANTHROPIC_BASE_URL,
OPENAI_BASE_URL, XAI_BASE_URL, and DASHSCOPE_BASE_URL for basic
HTTP(S) URL format. Non-http schemes and empty values produce a
warn-level diagnostic.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
status --output-format json now exposes duplicate_flags array listing
any --model, --output-format, or --permission-mode flags specified
more than once. Uses a module-level static for cross-function access.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
render_config_json now includes a 'merged' object with actual
key-value pairs from the resolved runtime configuration, not just
the count.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
check_auth_health data fields now include openai_key_present alongside
api_key_present and auth_token_present. any_auth_present already
includes OPENAI_API_KEY for prompt_ready status.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__ is now filtered from the sections
array in JSON output. boundary_index field exposed for callers that
need the static/dynamic split point.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
The catch-all in render_mcp_report_json_for now returns
render_mcp_unsupported_action_json with ok:false and
error_kind:unsupported_action instead of help JSON with exit 0.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Only fire the slash-command guard for multi-word commands when the
first token is a known CLI subcommand (help, version, status, etc.).
Slash commands with additional arguments (explain this, cost list)
are treated as prompts.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
When input is a prefix of a candidate (e.g., mcp → mcpServers), return
the prefix match directly instead of relying on edit-distance which
would incorrectly suggest env (distance 3) over mcpServers (distance 7).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Changed rest.len() != 1 guard to rest.is_empty() so claw cost list,
claw model list, claw permissions show, etc. now reach the
bare_slash_command_guidance guard and emit typed slash-command
guidance instead of falling through to CliAction::Prompt.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Added specific handler for --help when rest contains --resume, so
claw --resume --help shows resume help instead of consuming --help
as a session-id literal.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
The status_context function now filters loader.discover() to only count
paths that exist on disk, matching the check_config_health behavior.
Both config.discovered_files_count and workspace.discovered_config_files
now report the same number.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Added list to KNOWN_SUBCOMMANDS so claw list is caught by typo
suggestion instead of falling through to CliAction::Prompt. Also
verified #455 (missing_credentials hint already newline-delimited).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Added prompt_ready:bool and prompt_blocked_reason:string|null to the
auth check in doctor --output-format json. prompt_ready is true when
any auth credential is present, false otherwise. prompt_blocked_reason
is auth_missing when prompt_ready is false.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Added dedicated CliAction::SessionList variant for claw session list so
it no longer requires API credentials. run_session_list() calls
list_managed_sessions() directly without instantiating an API client.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Added requested field (alias for enabled) and active_components object
with namespace/network/filesystem booleans for precise subsystem visibility.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
The enforce_broad_cwd_policy function was sending JSON error envelopes
to stderr instead of stdout. Fixed to use println! for JSON mode,
matching the main error handler and all resume error paths.
Also closed ROADMAP #446 (config warning deduplication already handled
by emit_config_warning_once) and #447 (JSON errors already routed to
stdout in main handler).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Skill discovery now tracks dir_name alongside frontmatter name and detects
when they differ. skills list --output-format json includes metadata_drift
array and reports degraded status when drift entries exist.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Adds dir_name field to SkillSummary to enable detection of skills where
the SKILL.md frontmatter name differs from the parent directory name.
Also adds SkillMetadataDrift struct for tracking mismatches (used by
skills JSON output in follow-up).
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
claw --resume now enforces the same broad-cwd safety policy as claw prompt
and the interactive REPL. Running from /, $HOME, or other broad directories
blocks execution unless --allow-broad-cwd is passed.
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
claw acp serve now exits 2 (not implemented) instead of 0, so automation
pipelines can detect the no-op via exit code gating.
Key changes:
- acp serve exits 2 instead of 0
- Removed discoverability_tracking, tracking, recommended_workflows from JSON
- Removed phase, exit_code, serve_alias_only fields from JSON
- Status changed from unsupported/discoverability_only to not_implemented
- Error kind for unsupported ACP invocations uses typed prefix
- Updated tests to match new exit code and JSON structure
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Agent discovery now loads .md files with YAML frontmatter alongside .toml
files, matching the Claude Code agent definition convention. Markdown
agent files must have ----delimited YAML frontmatter with at least name
or description fields.
Key changes:
- parse_agent_frontmatter extracts name, description, model, model_reasoning_effort
- load_agents_from_roots_with_invalids collects both valid and invalid agents
- InvalidAgentConfig tracks rejected .md files with reason
- AgentCollection groups valid agents with invalid entries
- agents JSON output includes valid_count, invalid_count, invalid_agents
- Status is degraded when invalid agents exist
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
Hook config now supports the Claude Code structured hook format with
partial validation. Invalid hook entries are recorded in invalid_hooks
while valid siblings are retained, following the same pattern as MCP
partial validation (#440).
Key changes:
- RuntimeInvalidHookConfig now includes typed kind field (invalid_hooks_config
or unknown_hook_event) for machine-readable error classification
- Hook parsing collects all invalid entries instead of halting at first error
- Unknown hook event names recorded as invalid without rejecting valid hooks
- Legacy bare-string hooks still load with deprecation warnings
- Claude Code documented format loads without error (matcher + nested hooks)
- config/status/doctor JSON surfaces hook_validation metadata
- classify_error_kind maps hook errors to invalid_hooks_config
Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>