Commit Graph

1122 Commits

Author SHA1 Message Date
TheArchitectit a263895f0b
Merge 6ee9e03617 into 08106b0c37 2026-08-16 13:20:03 +07:00
YeonGyu-Kim 08106b0c37 docs: add hierarchical AGENTS.md knowledge base
Root knowledge base plus complexity-scored subdirectory files for the
rust/ workspace, its five highest-mass crates (runtime, rusty-claude-cli,
api, tools, commands, plugins), and the src/ Python porting workspace.

Generated via init-deep: 13 parallel explore agents, LSP/ast-grep code
map, centrality-scored placement. Snapshot in .omo/init-deep.json (local).
2026-08-16 15:18:33 +09:00
code-yeongyu 525035b51b fix(sandbox): probe the full launcher shape, not just the mapping
The startup probe validated only the mapping flags against the trivial
program `true`, but the real launcher always adds
--mount --ipc --pid --uts --fork. On environments where the user
namespace is created but mount propagation inside it is restricted
(e.g. AppArmor-restricted CI runners), the fallback mapping passed the
probe and the sandbox activated, yet every sandboxed command died with
"cannot change root filesystem propagation: Permission denied",
silently returning empty tool output and breaking the mock parity
suite.

The candidates now define the complete static launcher shape (mapping
flags + namespace flags), so probe success implies launch success; the
launcher reuses the candidate instead of re-appending the namespace
flags, keeping probe and launch as one source of truth. The
order-guarding test asserts the namespace flags are present in every
candidate.

Co-authored-by: linkst <2024023709@m.scnu.edu.cn>
2026-08-06 19:41:27 +09:00
linkst 9cbe6d9a8c docs(sandbox): document newuidmap/newgidmap dependency for --map-auto fallback
The fallback candidate relies on the setuid newuidmap/newgidmap helpers
(uidmap package) plus a subuid/subgid range for the current user. Note in
the candidate docs that the startup probe rejects the candidate when those
are missing, so the plain --map-root-user form is used instead.
2026-08-01 15:21:56 +08:00
linkst 277fdda894 fix(sandbox): fall back to --map-auto when root-user mapping is restricted
Plain `unshare --user --map-root-user` fails on kernels and containers
that block unprivileged writes to /proc/self/uid_map (e.g. GitHub Actions,
restricted AppArmor profiles). On those systems util-linux delegates to the
setuid newuidmap/newgidmap helpers when --map-auto is also present.

Add the combined form as a fallback candidate and build the launcher args
from the probed mapping, so systems without newuidmap/newgidmap or a
/etc/subuid range keep using the plain form.
2026-07-31 17:09:00 +08:00
linkst 1c8338ea66 refactor(sandbox): extract unshare mapping probe into cached helper
No behavior change. Move the inline probe out of
unshare_user_namespace_works into a reusable unshare_probe helper and a
cached working_unshare_mapping() that picks the first working candidate
from UNSHARE_MAPPING_CANDIDATES, so the launcher and the capability probe
share one code path.
2026-07-31 17:08:51 +08:00
TheArchitectit 6ee9e03617 fix: restore workspace unsafe_code=forbid, fix TaskClaim TOCTOU, remove TUI deps
Review fixes for PR #3250:

1. Restore workspace-level unsafe_code = "forbid" (was downgraded to
   "warn" for TUI support). The per-crate [lints.rust] unsafe_code =
   "allow" on rusty-claude-cli already overrides it where needed.

2. Fix TaskClaim TOCTOU race in claim_task(). Replace exists()-then-write
   with OpenOptions::create_new(true) which atomically fails if the lock
   file already exists, eliminating the race window between the check and
   the write.

3. Remove TUI scaffolding deps (ratatui, tui-textarea, gag, crossbeam-channel,
   libc, unicode-width) and the /tui slash command spec — these belong in
   a future TUI PR and are unused in the current source.

Also updates the provider chain precedence test to reflect the new behavior
where the caller's resolved model is the chain primary.

Co-Authored-By: Claw <noreply@openclaw.ai>
2026-07-28 07:42:30 -05:00
TheArchitectit 30ff4edf79 test: add subagentModel accessor chain tests
Adds 3 unit tests covering the original silent-drop bug:
- camelCase 'subagentModel' key reads end-to-end
- snake_case 'subagent_model' key reads end-to-end
- blank value returns None (falls back to default model)

Requested by @1716775457damn in PR review.
2026-07-25 03:50:38 -05:00
TheArchitectit e9e5104a73 fix: model_token_limit catch-all returns None for unknown models
Restores the fix from @Offwhite-Del that was lost during rebase.
Unknown models now return None so preflight skips the context-window
check and lets the API enforce its own limits.
2026-07-25 00:47:42 -05:00
TheArchitectit 951d1bb677 cargo fmt 2026-07-25 00:44:56 -05:00
TheArchitectit 224aff8450 feat(team): team enhancements, subagentModel, parallel tool exec
Port the agent-team enhancement layer onto upstream/main so the model
can spin up coordinated sub-agent teams for parallel work.

subagentModel config wiring (fix):
- Add subagent_model field to RuntimeFeatureConfig + RuntimeConfig::subagent_model()
  accessor so the subagentModel setting (already validated by config_validate.rs)
  is now actually read and stored.
- Agent tool's resolve_agent_model falls back to subagentModel from config
  when no explicit model is passed.

Provider namespace separation:
- New 'custom-openai' provider kind with dedicated env vars
  (CLAWCUSTOMOPENAI_API_KEY / CLAWCUSTOMOPENAI_BASE_URL)
- /setup wizard saves kind: 'custom-openai' for option 5
- Bare model name normalized to 'custom/' prefix to avoid proxy 404s
- Sub-agents inherit /setup-saved provider config via inject_config_as_env_fallbacks

Parallel tool execution:
- Override execute_batch to classify read-only tools as parallel-safe
  and run them concurrently via std:🧵:scope
- Results return in original model order

Team coordination layer:
- AgentMessage, TaskClaim, TeamStatus tools + shared mailbox directory
- Mode presets (tiny/1x ... mega/6x) + enriched TeamCreate/Agent descriptions
- Background team watcher
- /team slash command: on/off/status/toggle

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 16:29:58 -05:00
TheArchitectit 0c339e7b4e feat(setup): separate env namespace for custom OpenAI-compat provider
The Custom (OpenAI-compat) /setup option was saving kind: openai and
injecting OPENAI_API_KEY / OPENAI_BASE_URL. That collides with users who
have real OpenAI/NeuralWatt credentials in their environment.

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

- CLAWCUSTOMOPENAI_API_KEY
- CLAWCUSTOMOPENAI_BASE_URL

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

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

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

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

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

This is a process-level env injection (set_var), so it only affects
the current claw process and its children, not the parent shell.
2026-06-30 09:43:39 -05:00
YeonGyu-Kim d229a9b022
Merge pull request #3227 from TheArchitectit/worktree-wizard-entry-points
feat: wizard entry points — /setup command, claw setup subcommand (rebased)
2026-06-08 15:06:11 +09:00
YeonGyu-Kim 05f0201ec7 fix: preserve runtime config validation compatibility 2026-06-08 15:01:48 +09:00
YeonGyu-Kim 01f4dd48a3 docs: mention local Ollama reasoning setup 2026-06-08 10:08:44 +09:00
YeonGyu-Kim 222faabd7f fix(cli): hint Ollama for Qwen tags 2026-06-08 10:08:38 +09:00
YeonGyu-Kim 7503c1c031 fix(providers): parse Ollama reasoning fields 2026-06-08 10:08:32 +09:00
YeonGyu-Kim a1da1ca8e6 test(cli): serialize env-sensitive model alias checks 2026-06-08 01:37:28 +09:00
YeonGyu-Kim 27acfe1014 test(runtime): isolate session and git metadata checks 2026-06-08 01:23:32 +09:00
YeonGyu-Kim c1646613d1 fix(providers): preserve OpenAI-compatible reasoning history 2026-06-08 01:23:13 +09:00
Ajinkya-Ghuge 0755ddff3c fix(providers): strip provider prefix from model names for openai_compat endpoints 2026-06-06 22:29:59 +05:30
bellman be8112f5f5 feat: add native Ollama provider support via OLLAMA_HOST env var
- 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)
2026-06-05 12:12:56 +09:00
TheArchitectit d58197cca4 fix: update slash command count and add /setup assertion in test
- 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.
2026-06-04 22:06:32 -05:00
Your Name 3845040b9d feat: wizard entry points -- /setup command, claw setup subcommand, and RuntimeProviderConfig
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>
2026-06-04 21:52:48 -05:00
bellman 503d515f38 style: cargo fmt after merged PRs (#3164, #3209, #3214, #3216)
Fix formatting inconsistencies introduced by merged external PRs.

Generated with https://github.com/Yeachan-Heo/gajae-code
Co-authored-by: Gajae Code <dev@gajae-code.com>
2026-06-05 10:52:37 +09:00
Bellman 114c2da9fc
Merge pull request #3216 from TheArchitectit/worktree-session-resume-fixes
fix: session resume — scan all workspaces, skip current empty session
2026-06-05 10:38:19 +09:00
Bellman b90f18f75a
Merge pull request #3214 from TheArchitectit/worktree-api-timeout-retry-v2
feat: API timeout config, Retry-After header, configurable retry, and 400 transient retry
2026-06-05 10:33:35 +09:00
Bellman 5b15197117
Merge pull request #3209 from Sam0urr/harden-permission-enforcer
Harden permission enforcement against sandbox bypasses
2026-06-05 10:32:50 +09:00
Bellman ef0d0c30a4
Merge pull request #3164 from petterreinholdtsen/llama.cpp-errors
fix: recover from llama.cpp context overflow and reqwest SSE decode failures
2026-06-05 10:25:54 +09:00
bellman 7305e5509a fix: update skills help test assertions for --project flag (#95 CI fix)
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>
2026-06-05 10:23:36 +09:00
bellman 2f0b5b36eb fix: wrap concurrent ENOENT as domain-specific session error (#112)
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>
2026-06-05 10:19:43 +09:00
bellman c848eeb768 fix: status JSON reports all workspace panes not just the first (#326)
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>
2026-06-05 10:15:23 +09:00
bellman d4aad7103e fix: add actionable auth hint to 401/403 API errors (#28)
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>
2026-06-05 10:10:24 +09:00
bellman b60cbebb3a feat: skills install --project flag for project-level scope (#95)
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>
2026-06-05 10:05:36 +09:00
bellman 7c4bcd92b6 fix: expand ${VAR} and ~/ in MCP config fields (#92)
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>
2026-06-05 10:00:45 +09:00
bellman f8822aabdb fix: config merge concatenates arrays instead of replacing (#106)
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>
2026-06-05 09:57:22 +09:00
bellman aca6584fd5 fix: normalize permission rule tool names to lowercase (#94)
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>
2026-06-05 09:53:26 +09:00
bellman b8cbb1834f fix: /clear preserves session_id to prevent resume divergence (#114)
/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>
2026-06-05 09:47:37 +09:00
bellman cb027adf65 fix: /session switch and /session fork return structured JSON in resume mode (#113)
/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>
2026-06-05 09:42:16 +09:00
bellman 04f18862a8 fix: strip macOS /private symlink prefix from JSON cwd (#421)
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>
2026-06-05 09:08:09 +09:00
bellman 0cab03df75 fix: /model returns structured JSON in resume mode (#343)
/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>
2026-06-05 08:54:11 +09:00
bellman eb86f4d2c3 fix: reject --compact for non-prompt subcommands (#98)
--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>
2026-06-05 07:25:49 +09:00
bellman 6c3d7be370 fix: /tasks returns structured JSON in resume mode (#341)
/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>
2026-06-05 07:15:36 +09:00
bellman e3ffaefba1 fix: /config help returns structured section list (#344)
- /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>
2026-06-05 07:09:48 +09:00
bellman cd18cf5385 fix: /config help returns structured section list (#344)
/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>
2026-06-05 07:05:16 +09:00
bellman 2f3120e70a fix: add structured command list to top-level help JSON (#325)
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>
2026-06-05 06:57:51 +09:00
bellman f1a16398fe fix: plugins enable/disable only reloads when state changes (#411)
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>
2026-06-05 06:49:01 +09:00
bellman b04b1d6ac8 feat: detect git rebase/merge/cherry-pick/bisect states (#89)
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>
2026-06-05 06:31:33 +09:00