Commit Graph

1095 Commits

Author SHA1 Message Date
bellman 8fd11e82c4 fix: track skill directory name for name/dir mismatch detection
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>
2026-06-05 00:26:42 +09:00
bellman 9f9b14a76d fix: add broad-cwd guard to resume path
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>
2026-06-05 00:23:28 +09:00
bellman 0e54ec4c04 fix: exit non-zero for acp serve and remove internal tracking IDs
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>
2026-06-05 00:11:31 +09:00
bellman 58a30f6ab8 fix: accept markdown agent definitions with YAML frontmatter
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>
2026-06-04 23:57:33 +09:00
bellman 453d8945bb fix: validate hook config entries partially
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>
2026-06-04 23:42:58 +09:00
TheArchitectit 9e50cb6e20 Merge remote-tracking branch 'upstream/main' into worktree-api-timeout-retry-v2
# Conflicts:
#	rust/crates/runtime/src/config.rs
#	rust/crates/runtime/src/lib.rs
2026-06-04 09:17:43 -05:00
TheArchitectit 346772a8b3 test: add exclude_id and 0-message filtering coverage; cargo fmt 2026-06-04 09:17:42 -05:00
TheArchitectit ef392e5938 Merge remote-tracking branch 'upstream/main' into worktree-session-resume-fixes 2026-06-04 09:15:19 -05:00
bellman 4619375c14 fix: load partial MCP configs
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 18:31:58 +09:00
bellman 10fe72498a fix: bound parent memory discovery
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 17:07:00 +09:00
bellman 5b22bc0480 fix: load Claw and Agents memory files
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 16:36:04 +09:00
bellman ae7da0ec74 fix: expose complete version provenance
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 15:55:08 +09:00
bellman 7dd17c6344 fix: scaffold safe init settings
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 15:34:15 +09:00
bellman d8535bf938 fix: keep failed resume side-effect free
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 15:08:56 +09:00
bellman b45c61eff9 fix: recover parser contract CI
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 14:13:53 +09:00
bellman 7cfd83f66a test: align compact CI contract
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 13:43:02 +09:00
bellman b5bead9028 fix: recover CLI parser CI
Generated with https://github.com/Yeachan-Heo/gajae-code

Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-04 13:25:15 +09:00
bellman 41678eb097 fix: type output format selection 2026-06-04 12:47:24 +09:00
bellman ecd3e4ceb9 fix: type allowed tools validation 2026-06-04 12:01:58 +09:00
bellman 22fdaeae2c fix: keep skills lifecycle local 2026-06-04 03:58:35 +09:00
TheArchitectit 41034bb3f3 fix: address CI test failure and add empty-session error message
- Fix latest_session_alias_resolves_most_recent_managed_session test:
  the test created sessions with 0 messages, which are now filtered out
  by the message_count > 0 check in latest_session_excluding(). Updated
  the test to call push_user_text() before saving so sessions have
  at least one message and are findable by /resume latest.

- Add distinct error message when all sessions are empty (0 messages).
  Previously, the same "no managed sessions found" message was returned
  whether there were zero sessions or all sessions had 0 messages. Now:
  - No sessions at all → "no managed sessions found in {path}. Start
    claw to create a session..."
  - Sessions exist but all empty → "all sessions are empty (0 messages)
    in {path}. This usually means a fresh claw session is running but
    no messages have been sent yet. Wait for a response in your other
    session, then try --resume latest again."

- Add test for the all-sessions-empty error path.

  Addresses reviewer feedback on #3216.
2026-06-03 13:44:20 -05:00
TheArchitectit 76783377ec fix: address CI failures and reviewer feedback on #3214
- Add missing retry_after: None field to ApiError::Api construction
  in main.rs test. This field was introduced by the Retry-After
  header support but was not added to the test's error initializer,
  causing a compile error under CI's strict mode.

- Remove duplicate #[must_use] attribute on retry_after() method
  in error.rs (lines 134+138 both had it; kept the outer one
  above the doc comment per convention).

- Cargo fmt --all run.

- Reviewer question "Are defaults preserved?" — answered yes:
  ApiTimeoutConfig defaults to 30s connect / 300s request / 8 retries.
  with_retry_policy() is opt-in. No behavior change without explicit
  configuration.
2026-06-03 13:19:25 -05:00
bellman 4522490bd5 fix: make dump-manifests self-contained 2026-06-04 02:46:44 +09:00
bellman cd58c054ca fix: add global cwd override 2026-06-04 02:20:09 +09:00
bellman 94579eace5 fix: default to workspace-write permissions 2026-06-04 01:51:21 +09:00
bellman 2ab2f44e1d fix: keep session help local 2026-06-04 00:50:17 +09:00
bellman fa35018769 fix: validate env model selection 2026-06-04 00:30:13 +09:00
bellman 94be902ce1 fix: attribute config precedence in JSON 2026-06-03 23:47:27 +09:00
bellman bcc5bfde9c fix: route local OpenAI-compatible models 2026-06-03 23:16:46 +09:00
bellman 9522674c87 fix: read prompt subcommand input from stdin 2026-06-03 22:39:16 +09:00
bellman c91a3062d5 fix: normalize Anthropic model routing 2026-06-03 22:20:23 +09:00
bellman 54d785d0c0 fix: preserve DeepSeek V4 thinking history 2026-06-03 21:53:54 +09:00
bellman 36218ac1b1 fix: report config file load statuses 2026-06-03 21:46:47 +09:00
bellman 6388a2ba3f fix: parse object-style hook config 2026-06-03 21:23:00 +09:00
bellman 9c8375da99 feat: import project instruction rules 2026-06-03 21:01:48 +09:00
Heo, Sung 0cef5390f7
fix: resolve clippy pedantic warnings
Apply the bounded clippy pedantic cleanup from PR #3009.
2026-06-03 20:39:05 +09:00
bellman 1bd18be372 feat: add GitShow output formats 2026-06-03 20:28:12 +09:00
bellman d07664b44c fix: keep hooks clean and close bash stdin 2026-06-03 20:20:04 +09:00
bellman ce116d9dfa fix: expose binary provenance in local JSON 2026-06-03 20:03:39 +09:00
bellman 78f446f68e test: add argv-safe dogfood probes 2026-06-03 19:26:55 +09:00
bellman 55da189315 fix: keep JSON control surfaces local 2026-06-03 19:12:20 +09:00
bellman e752b05425 fix: load common instruction files and typed unknown commands 2026-06-03 18:54:36 +09:00
bellman 0c83a26dc7 test: cover resumed unknown slash command 2026-06-03 18:40:37 +09:00
bellman f529fb0e55 fix: classify mcp show missing server argument 2026-06-03 18:22:23 +09:00
TheArchitectit e459a727e9 fix: session resume — skip current empty session, unify cross-workspace loading
Three improvements to the /resume command:

1. /resume latest now skips the current empty session
   When a new session is created on startup (with 0 messages), /resume
   latest previously returned that empty session. Now it skips sessions
   with message_count == 0 and excludes the current session ID via the
   new exclude_id parameter, so it finds the previous session with
   actual conversation history.

2. Unified load_session_excluding() replaces load_session_loose()
   The previous load_session_loose() only handled cross-workspace
   resume for aliases. The new load_session_excluding() combines the
   loose workspace validation logic with the exclude_id parameter,
   simplifying the call chain and ensuring all resume paths skip the
   current empty session when appropriate.

3. All existing session scanning paths (global root + project-local
   .claw/sessions/) are already in place from prior commits, and now
   the exclude_id filter is applied consistently across both local
   and global session scans.

Changes:
- session_control.rs: Add resolve_reference_excluding() that delegates
  from resolve_reference(), adding optional exclude_id filtering for
  alias references.
- session_control.rs: Add latest_session_excluding() that delegates
  from latest_session(), filtering out excluded session IDs and
  sessions with 0 messages in both local and global scan paths.
- session_control.rs: Add load_session_excluding() that replaces
  load_session_loose(), combining cross-workspace alias handling with
  the exclude_id parameter.
- main.rs: Add load_session_reference_excluding() that delegates from
  load_session_reference(), using the new store method.
- main.rs: Wire LiveCli::resume_session() to pass the current session
  ID as the exclude_id so /resume latest skips the current empty
  session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 15:49:21 -05:00
TheArchitectit 04bc5f5788 feat: API timeout config, Retry-After header, configurable retry, and 400 transient retry
Cherry-picked from PR #2816 onto current upstream/main, resolving
conflicts from PR #3015's merge (which added retry_after to ApiError
but some construction sites were missing it).

Commits preserved:
- ade85398: API timeout config, Retry-After header, configurable retry
  - TimeoutConfig in HTTP client builder (connect 30s, request 5min)
  - CLAW_API_CONNECT_TIMEOUT and CLAW_API_REQUEST_TIMEOUT env vars
  - Retry-After header parsing on 429 responses
  - ApiTimeoutConfig in runtime config (settings.json)
- 8a883430: retry 400 responses with transient gateway error bodies
  - Detects known gateway phrases in 400 response bodies
  - Marks them as retryable instead of hard-failing
- ed91a61e: add 'no parseable body' to CONTEXT_WINDOW_ERROR_MARKERS
  - Some providers return 400 with 'no parseable body' for oversized
    requests instead of a proper context_length_exceeded error

Commits skipped (already in upstream via PR #3015):
- 453ab642: optional id field (already merged)
- baa8d1ba: HTML detection in streaming (already merged)
- 33d2f789: JSON error detection in streaming (already merged)

8 files changed, 299 insertions, 80 deletions
2026-06-02 15:35:29 -05:00
TheArchitectit 571d3cdc0f fix: add "no parseable body" to CONTEXT_WINDOW_ERROR_MARKERS
Some OpenAI-compat backends (e.g. glm-5.1-fast) return 400 with
"no parseable body" when the request payload is too large to parse,
rather than a proper context_length_exceeded error. Without this marker,
is_context_window_error() returns false and the auto-compact retry
loop never triggers — the user just sees an opaque 400 error.

💘 Generated with Crush

Assisted-by: GLM 5.1 FP8 via Crush <crush@charm.land>
2026-06-02 15:31:04 -05:00
TheArchitectit 414a1aca4f fix: retry 400 responses with transient gateway error bodies
Some providers/proxies return HTTP 400 with bodies like "no parseable
body" or "connection reset" during transient network blips. These are
not real bad requests — they're gateway errors wearing a 400 mask.
Detect known gateway error phrases in 400 response bodies and mark
them as retryable so the existing exponential backoff handles them.
2026-06-02 15:30:41 -05:00
TheArchitectit d8c57ed317 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-02 15:30:22 -05:00
Sam Lamrabte e8c8ef1142 Harden permission enforcement against sandbox bypasses
Close two ways the permission system could be bypassed:

- Workspace path traversal: normalize `.`/`..` lexically before the
  boundary prefix comparison so paths like `/workspace/../../etc` can no
  longer escape the sandbox. Fixed in both the runtime enforcer and the
  duplicate check in the tools PowerShell path classifier.
- read-only mode no longer trusts the leading token alone: reject shell
  metacharacters (chaining/substitution/redirect/pipe/subshell), drop
  interpreters and build drivers (python/node/ruby/cargo/rustc) from the
  allow-list, gate `git` to non-mutating subcommands, and reject `find`
  actions that execute or delete.

Adds regression tests for both holes. The pre-existing, unrelated
worker_boot git-metadata test failure is not affected by this change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 13:26:39 +02:00
YeonGyu-Kim ac5b19dee1
fix: interactive_only hint omits --resume for non-resume-safe commands (#829)
Commands like /commit, /pr, /issue, /bughunter, /ultraplan are
interactive-only and NOT resume-safe. Previously the generic
interactive_only error always suggested 'claw --resume SESSION.jsonl
/commit', which would just re-trigger interactive_only.

Fix: check commands::resume_supported_slash_commands() in the
SlashCommand::Ok(Some(cmd)) arm. Resume-safe commands get the full
--resume suggestion; non-resume-safe commands only say 'Start claw'.

Also update two existing unit tests whose assertions checked for the old
'interactive-only' substring (now 'interactive_only:' prefix).

Two new integration tests:
- non_resume_safe_interactive_only_hint_omits_resume_suggestion
- resume_safe_interactive_only_hint_includes_resume_suggestion

572 tests pass, 1 pre-existing worker_boot failure unrelated.
2026-05-29 16:55:57 +09:00
YeonGyu-Kim 187aebd74f
fix: /approve and /deny outside REPL emit interactive_only error_kind (#828)
/approve, /yes, /deny, /no (and /y, /n) are valid REPL-only slash
commands. Outside the REPL they were falling through to
format_unknown_direct_slash_command -> error_kind:unknown_slash_command.

Fix: intercept them in the SlashCommand::Unknown arm and emit
interactive_only: prefix so classify_error_kind returns the correct kind.

One new test: approve_deny_outside_repl_emits_interactive_only (covers
/approve, /yes, /deny, /no)

572 tests pass, 1 pre-existing worker_boot failure unrelated.
2026-05-29 16:36:54 +09:00
YeonGyu-Kim 9d05573f24
fix: unknown slash command emits unknown_slash_command error_kind (#827)
Both direct-slash CLI path (claw /boguscommand) and resume slash path
(claw --resume session /boguscommand) previously emitted error_kind:unknown
(opaque fallback). Machine consumers could not distinguish unrecognized
slash commands from other error classes.

Fix:
- format_unknown_direct_slash_command: prefix with 'unknown_slash_command:'
- format_unknown_slash_command (resume path): prefix with 'unknown_slash_command:'
- Add classifier arm for 'unknown_slash_command:' prefix

One new regression test: direct_unknown_slash_command_emits_typed_error_kind
Uses the direct-slash CLI path (no session load needed; reproducible on CI).

572 tests pass, 1 pre-existing worker_boot failure unrelated.
2026-05-29 16:00:37 +09:00
YeonGyu-Kim d47b015100
fix: unknown single-word subcommand emits command_not_found (#825/#826)
Single-word all-alpha/dash tokens that don't match any known subcommand
now always emit command_not_found (with or without fuzzy suggestions).

Multi-word cases fall through to CliAction::Prompt (natural language
prompt passthrough like 'claw explain this' must still work). The
multi-word gap is documented as ROADMAP #826 (known limitation).

Tests:
- unknown_subcommand_json_emits_command_not_found (new)
- unknown_subcommand_text_emits_command_not_found_on_stderr (new)
- unknown_subcommand_typo_with_suggestions_json_emits_command_not_found (new)
- multi_word_unknown_subcommand_falls_through_to_prompt_826 (documents gap)

572 tests pass, 1 pre-existing worker_boot failure unrelated.
2026-05-29 14:58:07 +09:00
YeonGyu-Kim 70d64be033
fix: unknown single-word subcommand emits command_not_found instead of missing_credentials (#825)
When looks_like_subcommand_typo fires on a single word with no close
fuzzy matches, the fallthrough reached CliAction::Prompt → provider
startup → misleading missing_credentials error.

Fix: always return Err with command_not_found: prefix from the typo
guard (with or without suggestions). Added command_not_found classifier
arm in classify_error_kind. Unified existing unknown_subcommand kind
under command_not_found in #825.

Three new regression tests in output_format_contract.rs:
- unknown_subcommand_json_emits_command_not_found
- unknown_subcommand_text_emits_command_not_found_on_stderr
- unknown_subcommand_typo_with_suggestions_json_emits_command_not_found

Updated pre-existing unit test assertion (starts_with → contains) and
classifier unit test (unknown_subcommand → command_not_found).

572 tests pass, 1 pre-existing worker_boot failure unrelated.
2026-05-29 14:37:29 +09:00
YeonGyu-Kim de7edd5bb1
fix: suppress config deprecation stderr in JSON mode globally (#824)
Add SUPPRESS_CONFIG_WARNINGS_STDERR AtomicBool flag in runtime/config.rs
and expose suppress_config_warnings_for_json_mode() via runtime crate.

In main.rs, scan raw argv for --output-format json before parse_args
and activate the flag so no settings-load warnings reach stderr on any
JSON-mode surface (status, sandbox, system-prompt, mcp list, skills list,
agents list, --resume /config*, etc.).

Text-mode surfaces are unaffected; prose deprecation warnings continue
to appear on stderr.

All 572+ tests pass (one pre-existing worker_boot failure unrelated).
2026-05-29 14:00:32 +09:00
YeonGyu-Kim b4b1ba10f6
fix: route all JSON-mode abort envelopes to stdout (#819 #820 #823) (#3197)
* fix: route all JSON-mode abort envelopes to stdout (#819 #820 #823)

All handled errors in --output-format json mode now write the structured
abort envelope to stdout (rc=1) and keep stderr empty. Previously the
top-level error handler and resume_session JSON branches used eprintln!
which sent the envelope to stderr, breaking machine consumers that read
stdout for command payloads.

Surfaces fixed:
- Top-level abort handler (main.rs): export --session <missing>,
  session <subcommand>, prompt (no text), unknown subcommand fallthrough,
  flag errors, and all other run() failures
- resume_session JSON branches: session load errors, unsupported commands,
  parse errors, command execution errors

Test changes: updated 24 failing contract tests to assert JSON envelopes
on stdout. Added stderr-clean assertions where appropriate. 70 contract
tests pass (was 68; 2 additional from regression coverage).

ROADMAP: #819 (export session-not-found), #820 (interactive_only class),
#823 (missing prompt)

* style: cargo fmt on main.rs after eprintln->println fix

* fix(tests): fmt + update compact_output test for stdout abort envelope routing

* fix(tests): update resume_slash_commands stub test for stdout envelope routing
2026-05-29 13:30:35 +09:00
Bellman 0800d7ae88
Route plugins list JSON parse errors to stdout (#3194) 2026-05-28 22:35:58 +09:00
Bellman 9494e3c26f
Suppress config warnings on JSON local surfaces (#3192) 2026-05-28 20:34:18 +09:00
Bellman 89e7f415a9
Avoid duplicate config warnings for JSON consumers (#3190)
JSON config output already carries collected config diagnostics in warnings[], so prose stderr emission must be reserved for text/local paths. Lazy permission-mode default resolution prevents an earlier config load from leaking the same deprecation before the JSON renderer runs.\n\nConstraint: ROADMAP #815 requires text mode to keep human stderr warnings while JSON config/list suppresses duplicate app-level config prose.\nRejected: Filtering all stderr in JSON mode | would hide cargo/compiler or unrelated diagnostics outside the app config warning path.\nConfidence: high\nScope-risk: narrow\nDirective: Keep load_collecting_warnings side-effect-free; use load() for human stderr emission.\nTested: cargo fmt; cargo test -p rusty-claude-cli --test output_format_contract config_json_reports_deprecations_structurally_without_stderr_duplicate_815; cargo test -p rusty-claude-cli --test output_format_contract; manual target/debug/claw JSON config fixture.\nNot-tested: cargo clippy -p rusty-claude-cli --all-targets -- -D warnings is blocked by pre-existing runtime dead_code/trident warnings.
2026-05-28 18:09:59 +09:00
Bellman b7ea04661a
test: cover doctor help JSON flag order (#3185) 2026-05-28 14:34:19 +09:00
Bellman 73d8d6e638
Keep doctor help machine-discoverable locally (#3184)
Doctor help was already on the local help path in current source, but the exact #702 dogfood surface lacked a focused guard and the JSON help envelope was still too prose-oriented for wrappers. Strengthen the JSON contract while preserving text help.\n\nConstraint: Preserve unrelated dirty rust/Cargo.lock from prior #701 work.\nRejected: Starting runtime/provider/session to inspect doctor semantics | help must be local and credential-free.\nConfidence: high\nScope-risk: narrow\nDirective: Keep doctor help routed through parse_local_help_action and print_help_topic; do not call run_doctor for --help.\nTested: cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract doctor_help -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract help -- --nocapture; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml -p rusty-claude-cli; timeout 5s cargo run -q --bin claw -- --output-format json doctor --help; timeout 5s cargo run -q --bin claw -- doctor --help.\nNot-tested: full workspace test suite.
2026-05-28 13:31:39 +09:00
Petter Reinholdtsen 1d516be779 fix: recover from llama.cpp context overflow and reqwest SSE decode failures
Extend auto-compaction error detection to handle additional error patterns
from llama.cpp backends: 'Context size has been exceeded',
'exceed_context_size_error', 'exceeds the available context size'. Also
recover from reqwest 'error decoding response body' errors — some
llama.cpp instances return a non-SSE plaintext HTTP 500 on context overflow,
causing the SSE deserializer to fail.

Add dynamic threshold adaptation: parse server-reported context window
size from error messages (e.g., '(81920 tokens)') and set the auto-
compaction trigger at 70% of that value. This replaces the need for a
hardcoded threshold, adapting automatically to any backend's limits.

This patch was developed with assistance from OpenCode and local Qwen 3.6
API server.
2026-05-27 16:57:59 +02:00
YeonGyu-Kim 87b7e74770 fix(#806): plugins show <not-found> in text mode returned empty success instead of error 2026-05-27 22:34:10 +09:00
Bellman ae6a207d4e
fix(#3129): handle trailing json format for diff errors (#3161)
Keep malformed diff invocations with trailing JSON format flags on the parser error path and lock the contract with focused output-format regressions.

Constraint: Do not touch tracked .omx state files.

Rejected: Repeating direct binary smoke loops | local auth/provider configuration intercepts those invocations and obscures parser behavior.

Confidence: high

Scope-risk: narrow

Tested: git diff --check; cargo fmt --check; cargo test -p rusty-claude-cli diff_extra_args_have_typed_error_kind_and_hint_766 --test output_format_contract; cargo test -p rusty-claude-cli diff_trailing_json_after_malformed_args_is_bounded_json_3129 --test output_format_contract; cargo test -p rusty-claude-cli diff_non_git_dir_has_error_kind_and_hint_801 --test output_format_contract
2026-05-27 21:57:26 +09:00
YeonGyu-Kim efd34c151a fix(#805): skills show <not-found> in text mode silently returned empty success instead of error 2026-05-27 21:05:41 +09:00
YeonGyu-Kim 2c3c0f60e7 fix(#804): agents/skills show <name> <extra> in text mode returned wrong error instead of unexpected_extra_args 2026-05-27 20:05:39 +09:00
YeonGyu-Kim bad1b97f8e fix(#803): agents/skills/plugins list --flag in text mode silently returned empty success 2026-05-27 19:38:31 +09:00
YeonGyu-Kim fcebf64468 fix(#802): four resume-mode and broad-cwd error envelopes now include hint field 2026-05-27 19:04:15 +09:00
YeonGyu-Kim 53953a8157 fix(#801): diff non-git-dir error envelope now includes error_kind, hint, and message fields 2026-05-27 18:34:58 +09:00
YeonGyu-Kim 6ee67d6c61 test: add unit test coverage for invalid_history_count and unknown_option classifier arms
Two classifier arms had no corresponding assert_eq! in
test_classify_error_kind_returns_correct_discriminants: invalid_history_count
(both prefix and contains paths) and unknown_option (#790). Now 49/39 = full
coverage of all classify_error_kind return values.
2026-05-27 18:05:33 +09:00
YeonGyu-Kim efb1542a39 fix: empty-prompt error now returns non-null hint via newline-delimited usage string
claw '' and claw '   ' returned empty_prompt + hint:null because the
error message had no newline delimiter. Added usage hint. 61 CLI
contract tests pass.
2026-05-27 16:34:37 +09:00
YeonGyu-Kim bff370003b fix: plugins extra-arg errors now return non-null hint via newline-delimited usage string
Parity with #791 (config extra-arg fix). The plugins arg parser emitted
'unexpected extra arguments after claw plugins show ...' with no newline
delimiter, so split_error_hint returned None. Added usage hint after newline.
60 CLI contract tests pass.
2026-05-27 15:04:03 +09:00
YeonGyu-Kim 9976585f87 fix(#796): agents/skills show <name> <extra> returned wrong not-found instead of unexpected_extra_args 2026-05-27 14:07:04 +09:00
YeonGyu-Kim 18b4cee5fd fix(#795): skill_not_found and unsupported_skills_action now return non-null hints via fallback table 2026-05-27 13:34:09 +09:00
YeonGyu-Kim 491f179a03 fix(#794): plugins install not-found path returns typed plugin_source_not_found instead of unknown+null 2026-05-27 13:08:14 +09:00
YeonGyu-Kim 57a57ef771 fix(#793): plugins list --flag silent success + uninstall not-found hint:null 2026-05-27 12:34:35 +09:00
YeonGyu-Kim abfa2e4cf7 fix(#792): agents/skills list --flag silently returned empty success; now returns unknown_option error 2026-05-27 11:39:44 +09:00
YeonGyu-Kim 93a159dca5 fix(#791): config extra-arg errors now return non-null hint via \n-delimited usage string 2026-05-27 11:04:50 +09:00
YeonGyu-Kim 9968a27e92 fix(#790): system-prompt unknown-option errors now return typed unknown_option kind + non-null hint 2026-05-27 10:36:12 +09:00
YeonGyu-Kim e4c3c1aa80 fix(#789): agents show and plugins show not-found now exit 1; parity with skills (#788) and mcp (#68) 2026-05-27 10:07:51 +09:00
YeonGyu-Kim abdbf61acf fix(#788): skills show not-found emitted duplicate JSON error envelope; use exit(1) instead of Err propagation 2026-05-27 09:36:11 +09:00
YeonGyu-Kim 113145a42a fix(#787): --resume with directory path returns session_path_is_directory kind + hint; wire fallback_hint_for_error_kind into both resume error emission sites 2026-05-27 09:06:28 +09:00
YeonGyu-Kim 22b423b651 fix(#786): dump-manifests --manifests-dir missing-value errors now return typed missing_flag_value kind + non-null hint 2026-05-27 08:39:11 +09:00
YeonGyu-Kim 87f4334728 fix(#785): add unknown_subcommand classifier arm for unknown subcommand: prose prefix 2026-05-27 08:36:41 +09:00
YeonGyu-Kim e628b4bb68 fix(#784): export --output missing-value and extra-positional errors now return typed error_kind + non-null hint 2026-05-27 08:07:32 +09:00
YeonGyu-Kim 81fe0ccbb7 fix(#783): init JSON envelope now includes hint and already_initialized fields for orchestrator parity 2026-05-27 08:04:15 +09:00
YeonGyu-Kim 32c9276fdb fix(#782): acp unsupported invocation now returns non-null hint with newline-delimited remediation text 2026-05-27 07:37:26 +09:00
YeonGyu-Kim 16c1117af6 fix(#781): sub-classify api_auth_error/api_rate_limit_error from api_http_error; add fallback_hint_for_error_kind for hint-less API errors 2026-05-27 07:34:57 +09:00
YeonGyu-Kim d9844cfe8d fix(#780): classifier arm ordering bug — legacy_session_no_workspace_binding and no_managed_sessions shadowed by generic session_load_failed arm 2026-05-27 05:34:49 +09:00
YeonGyu-Kim 364e7909f4 fix(#779): resumed /skills invocation returns interactive_only error_kind + non-null hint 2026-05-27 05:09:07 +09:00
YeonGyu-Kim fded4f6b11 fix(#778): doctor check JSON objects now include hint field with stable remediation text for warn/fail checks 2026-05-27 05:07:02 +09:00
YeonGyu-Kim e02030364d fix(#777): resumed /plugins mutations return interactive_only error_kind + non-null hint instead of unknown+null 2026-05-27 04:44:06 +09:00
YeonGyu-Kim 2684737d9e fix(#776): resume command errors now return typed error_kind + non-null hint (invalid_history_count, session action errors) 2026-05-27 04:39:43 +09:00
YeonGyu-Kim 028998d040 test(#775): integration tests for #769-#771 interactive-only guards and #774 hint fields; fix stale classifier unit test string 2026-05-27 04:03:52 +09:00
YeonGyu-Kim c760a49c47 fix(#774): agents/plugins/mcp unknown-subcommand errors now include non-null hint 2026-05-27 03:37:00 +09:00
YeonGyu-Kim 727a1ea4a3 fix(#773): config --output-format json now surfaces deprecation warnings in warnings[] array instead of only stderr text 2026-05-27 03:05:14 +09:00
YeonGyu-Kim 212f0b2ad4 fix(#772): slash command aliases now resolve to canonical forms in interactive_only guidance 2026-05-27 02:37:17 +09:00
YeonGyu-Kim bf212b986d fix(#771): init rejects extra args; usage/stats/fork return interactive_only instead of credential check 2026-05-27 02:33:55 +09:00
YeonGyu-Kim 3a1d88386c fix(#770): cost/clear/memory/ultraplan/model with args now return interactive_only instead of falling to credential check 2026-05-27 02:10:41 +09:00