From a867bbebf1715576a14100d93ac64613c3266e80 Mon Sep 17 00:00:00 2001 From: crsei Date: Mon, 20 Apr 2026 13:19:25 -0400 Subject: [PATCH 1/5] refactor(workspace): P0 convert to Cargo workspace (no code changes) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of #68. Closes (partial) #69. Converts the repository root from a single-crate layout to a Cargo workspace. No source code semantics change. Layout ------ - Root `Cargo.toml` is now a virtual `[workspace]` manifest with `members = ["crates/*"]` and a single `[workspace.dependencies]` section holding all shared dep versions. - The former single-crate sources move to `crates/claude-code-rs/` (preserving git history via `git mv`). - `crates/claude-code-rs/Cargo.toml` references every shared dep via `dep = { workspace = true }`, keeping crate-local feature layering (optional flags, extra features) where needed. - `build.rs` moves into the package (cargo has no notion of a workspace-level build script) and resolves `web-ui/` via `CARGO_MANIFEST_DIR` + `../..` so it keeps working from the new nested location. - `rust-embed`'s `#[folder]` and the settings-schema snapshot test pick up the new two-level offset to the workspace root. - `.cargo/config.toml`, `Cargo.lock`, `web-ui/`, `ui/`, `docs/`, and `architecture/` stay at the workspace root. Baseline -------- `docs/workspace-split-measurements.md` records pre-split incremental build times (steady-state, same target-dir, rust-lld linker): - `touch src/main.rs` → 6.74s - `touch src/tools/file_read.rs`→ 0.42s Per-phase rows will be appended as the split progresses. Verification ------------ - `cargo build` (dev) : ok, 5 warnings (same as pre-split). - `cargo build --release` : ok, 5 warnings (same as pre-split). - `cargo test --bin claude-code-rs --offline -- --test-threads=1` : 1856 / 1857 pass. One failure — `observability::sink::tests:: off_mode_skips_redaction` — is a pre-existing bug in `redact_value` (always redacts regardless of `RedactionMode::Off`); unrelated to this reshuffle, file was last touched in 856dc41. Without `--test-threads=1` up to ten additional tests flake on env /cwd races — also pre-existing. - `claude-code-rs --version` and `--help` produce identical output. Co-Authored-By: Claude Opus 4.7 --- Cargo.toml | 107 ++++-------- crates/claude-code-rs/Cargo.toml | 163 ++++++++++++++++++ build.rs => crates/claude-code-rs/build.rs | 49 ++++-- .../claude-code-rs/src}/api/bedrock.rs | 0 .../claude-code-rs/src}/api/client/mod.rs | 0 .../claude-code-rs/src}/api/client/stream.rs | 0 .../claude-code-rs/src}/api/client/tests.rs | 0 .../src}/api/google_provider.rs | 0 {src => crates/claude-code-rs/src}/api/mod.rs | 0 .../claude-code-rs/src}/api/model_mapping.rs | 0 .../claude-code-rs/src}/api/openai_compat.rs | 0 .../claude-code-rs/src}/api/pricing.rs | 0 .../claude-code-rs/src}/api/providers.rs | 0 .../claude-code-rs/src}/api/retry.rs | 0 .../claude-code-rs/src}/api/sigv4.rs | 0 .../src}/api/stream_provider.rs | 0 .../claude-code-rs/src}/api/streaming.rs | 0 .../claude-code-rs/src}/api/vertex.rs | 0 .../claude-code-rs/src}/auth/api_key.rs | 0 .../claude-code-rs/src}/auth/codex_cli.rs | 0 .../claude-code-rs/src}/auth/mod.rs | 0 .../claude-code-rs/src}/auth/oauth/client.rs | 0 .../claude-code-rs/src}/auth/oauth/config.rs | 0 .../claude-code-rs/src}/auth/oauth/mod.rs | 0 .../claude-code-rs/src}/auth/oauth/pkce.rs | 0 .../claude-code-rs/src}/auth/token.rs | 0 .../src}/bootstrap/diagnostics.rs | 0 .../claude-code-rs/src}/bootstrap/ids.rs | 0 .../claude-code-rs/src}/bootstrap/mod.rs | 0 .../claude-code-rs/src}/bootstrap/model.rs | 0 .../claude-code-rs/src}/bootstrap/signal.rs | 0 .../claude-code-rs/src}/bootstrap/state.rs | 0 .../claude-code-rs/src}/bootstrap/timing.rs | 0 .../claude-code-rs/src}/browser/common.rs | 0 .../claude-code-rs/src}/browser/detection.rs | 0 .../claude-code-rs/src}/browser/mcp_bridge.rs | 0 .../claude-code-rs/src}/browser/mod.rs | 0 .../src}/browser/native_host.rs | 0 .../src}/browser/permissions.rs | 0 .../claude-code-rs/src}/browser/prompt.rs | 0 .../claude-code-rs/src}/browser/session.rs | 0 .../claude-code-rs/src}/browser/setup.rs | 0 .../claude-code-rs/src}/browser/state.rs | 0 .../src}/browser/tool_rendering.rs | 0 .../claude-code-rs/src}/browser/transport.rs | 0 {src => crates/claude-code-rs/src}/cli.rs | 0 .../claude-code-rs/src}/commands/add_dir.rs | 0 .../src}/commands/agents_cmd.rs | 0 .../claude-code-rs/src}/commands/assistant.rs | 0 .../src}/commands/audit_export.rs | 0 .../claude-code-rs/src}/commands/branch.rs | 0 .../claude-code-rs/src}/commands/brief.rs | 0 .../claude-code-rs/src}/commands/channels.rs | 0 .../src}/commands/chrome_cmd.rs | 0 .../claude-code-rs/src}/commands/clear.rs | 0 .../claude-code-rs/src}/commands/commit.rs | 0 .../claude-code-rs/src}/commands/compact.rs | 0 .../src}/commands/config_cmd.rs | 0 .../claude-code-rs/src}/commands/context.rs | 0 .../claude-code-rs/src}/commands/copy.rs | 0 .../claude-code-rs/src}/commands/cost.rs | 0 .../src}/commands/daemon_cmd.rs | 0 .../claude-code-rs/src}/commands/diff.rs | 0 .../claude-code-rs/src}/commands/doctor.rs | 0 .../claude-code-rs/src}/commands/dream.rs | 0 .../claude-code-rs/src}/commands/effort.rs | 0 .../claude-code-rs/src}/commands/exit.rs | 0 .../claude-code-rs/src}/commands/export.rs | 0 .../src}/commands/extra_usage.rs | 0 .../claude-code-rs/src}/commands/fast.rs | 0 .../claude-code-rs/src}/commands/files.rs | 0 .../claude-code-rs/src}/commands/help.rs | 0 .../claude-code-rs/src}/commands/hooks_cmd.rs | 0 .../claude-code-rs/src}/commands/init.rs | 0 .../claude-code-rs/src}/commands/insights.rs | 0 .../src}/commands/keybindings_cmd.rs | 0 .../claude-code-rs/src}/commands/login.rs | 0 .../src}/commands/login_code.rs | 0 .../claude-code-rs/src}/commands/logout.rs | 0 .../claude-code-rs/src}/commands/mcp_cmd.rs | 0 .../claude-code-rs/src}/commands/memory.rs | 0 .../claude-code-rs/src}/commands/mod.rs | 0 .../claude-code-rs/src}/commands/model.rs | 0 .../claude-code-rs/src}/commands/model_add.rs | 0 .../claude-code-rs/src}/commands/notify.rs | 0 .../src}/commands/permissions_cmd.rs | 0 .../src}/commands/plugin_cmd.rs | 0 .../src}/commands/rate_limit.rs | 0 .../claude-code-rs/src}/commands/recap.rs | 0 .../claude-code-rs/src}/commands/rename.rs | 0 .../claude-code-rs/src}/commands/resume.rs | 0 .../claude-code-rs/src}/commands/review.rs | 0 .../claude-code-rs/src}/commands/rewind.rs | 0 .../src}/commands/sandbox_cmd.rs | 0 .../src}/commands/security_review.rs | 0 .../claude-code-rs/src}/commands/session.rs | 0 .../src}/commands/session_export.rs | 0 .../src}/commands/skills_cmd.rs | 0 .../claude-code-rs/src}/commands/sleep_cmd.rs | 0 .../claude-code-rs/src}/commands/status.rs | 0 .../src}/commands/statusline_cmd.rs | 0 .../claude-code-rs/src}/commands/tasks_cmd.rs | 0 .../claude-code-rs/src}/commands/team_cmd.rs | 0 .../src}/commands/terminal_setup.rs | 0 .../claude-code-rs/src}/commands/version.rs | 0 .../claude-code-rs/src}/commands/voice_cmd.rs | 0 .../src}/compact/auto_compact.rs | 0 .../claude-code-rs/src}/compact/compaction.rs | 0 .../claude-code-rs/src}/compact/messages.rs | 0 .../src}/compact/microcompact.rs | 0 .../claude-code-rs/src}/compact/mod.rs | 0 .../claude-code-rs/src}/compact/pipeline.rs | 0 .../claude-code-rs/src}/compact/snip.rs | 0 .../src}/compact/tool_result_budget.rs | 0 .../src}/computer_use/detection.rs | 0 .../src}/computer_use/input/darwin.rs | 0 .../src}/computer_use/input/linux.rs | 0 .../src}/computer_use/input/mod.rs | 0 .../src}/computer_use/input/win32.rs | 0 .../claude-code-rs/src}/computer_use/mod.rs | 0 .../src}/computer_use/screenshot/darwin.rs | 0 .../src}/computer_use/screenshot/linux.rs | 0 .../src}/computer_use/screenshot/mod.rs | 0 .../src}/computer_use/screenshot/win32.rs | 0 .../claude-code-rs/src}/computer_use/setup.rs | 0 .../claude-code-rs/src}/computer_use/tools.rs | 0 .../claude-code-rs/src}/config/claude_md.rs | 0 .../claude-code-rs/src}/config/constants.rs | 0 .../claude-code-rs/src}/config/features.rs | 0 .../claude-code-rs/src}/config/mod.rs | 0 .../claude-code-rs/src}/config/paths.rs | 0 .../claude-code-rs/src}/config/settings.rs | 3 + .../claude-code-rs/src}/config/validation.rs | 0 .../claude-code-rs/src}/daemon/channels.rs | 0 .../claude-code-rs/src}/daemon/memory_log.rs | 0 .../claude-code-rs/src}/daemon/mod.rs | 0 .../src}/daemon/notification.rs | 0 .../claude-code-rs/src}/daemon/routes.rs | 0 .../claude-code-rs/src}/daemon/server.rs | 0 .../claude-code-rs/src}/daemon/sse.rs | 0 .../claude-code-rs/src}/daemon/state.rs | 0 .../src}/daemon/team_memory_proxy.rs | 0 .../claude-code-rs/src}/daemon/tick.rs | 0 .../claude-code-rs/src}/daemon/webhook.rs | 0 .../claude-code-rs/src}/dashboard.rs | 0 .../claude-code-rs/src}/engine/codex_exec.rs | 0 .../claude-code-rs/src}/engine/effort.rs | 0 .../src}/engine/input_processing.rs | 0 .../src}/engine/lifecycle/deps.rs | 0 .../src}/engine/lifecycle/helpers.rs | 0 .../src}/engine/lifecycle/mod.rs | 0 .../src}/engine/lifecycle/submit_message.rs | 0 .../src}/engine/lifecycle/tests.rs | 0 .../src}/engine/lifecycle/types.rs | 0 .../claude-code-rs/src}/engine/mod.rs | 0 .../src}/engine/output_style.rs | 0 .../src}/engine/prompt_sections.rs | 0 .../claude-code-rs/src}/engine/result.rs | 0 .../claude-code-rs/src}/engine/sdk_types.rs | 0 .../src}/engine/system_prompt.rs | 0 .../claude-code-rs/src}/ipc/agent_channel.rs | 0 .../claude-code-rs/src}/ipc/agent_events.rs | 0 .../claude-code-rs/src}/ipc/agent_handlers.rs | 0 .../claude-code-rs/src}/ipc/agent_tree.rs | 0 .../claude-code-rs/src}/ipc/agent_types.rs | 0 .../claude-code-rs/src}/ipc/callbacks.rs | 0 .../claude-code-rs/src}/ipc/headless.rs | 0 .../claude-code-rs/src}/ipc/ingress.rs | 0 {src => crates/claude-code-rs/src}/ipc/mod.rs | 0 .../claude-code-rs/src}/ipc/protocol/agent.rs | 0 .../claude-code-rs/src}/ipc/protocol/base.rs | 0 .../claude-code-rs/src}/ipc/protocol/mod.rs | 0 .../src}/ipc/protocol/subsystem.rs | 0 .../claude-code-rs/src}/ipc/protocol/team.rs | 0 .../claude-code-rs/src}/ipc/query_runner.rs | 0 .../claude-code-rs/src}/ipc/runtime.rs | 0 .../claude-code-rs/src}/ipc/sdk_mapper.rs | 0 .../claude-code-rs/src}/ipc/sink.rs | 0 .../src}/ipc/subsystem_events.rs | 0 .../src}/ipc/subsystem_handlers.rs | 0 .../src}/ipc/subsystem_types.rs | 0 .../claude-code-rs/src}/keybindings/action.rs | 0 .../claude-code-rs/src}/keybindings/config.rs | 0 .../src}/keybindings/context.rs | 0 .../src}/keybindings/defaults.rs | 0 .../src}/keybindings/keystroke.rs | 0 .../claude-code-rs/src}/keybindings/mod.rs | 0 .../src}/keybindings/registry.rs | 0 .../claude-code-rs/src}/lsp_service/client.rs | 0 .../src}/lsp_service/conversions/mod.rs | 0 .../src}/lsp_service/conversions/tests.rs | 0 .../claude-code-rs/src}/lsp_service/mod.rs | 0 .../src}/lsp_service/transport.rs | 0 {src => crates/claude-code-rs/src}/main.rs | 0 .../claude-code-rs/src}/mcp/channel.rs | 0 .../claude-code-rs/src}/mcp/client.rs | 0 .../claude-code-rs/src}/mcp/client_tests.rs | 0 .../claude-code-rs/src}/mcp/discovery.rs | 0 .../claude-code-rs/src}/mcp/manager.rs | 0 {src => crates/claude-code-rs/src}/mcp/mod.rs | 0 .../claude-code-rs/src}/mcp/tools.rs | 0 .../claude-code-rs/src}/mcp/transport.rs | 0 .../src}/observability/context.rs | 0 .../src}/observability/event.rs | 0 .../claude-code-rs/src}/observability/mod.rs | 0 .../claude-code-rs/src}/observability/sink.rs | 0 .../src}/permissions/bash_matcher.rs | 0 .../src}/permissions/dangerous.rs | 0 .../src}/permissions/decision.rs | 0 .../claude-code-rs/src}/permissions/mod.rs | 0 .../src}/permissions/path_validation.rs | 0 .../claude-code-rs/src}/permissions/rules.rs | 0 .../claude-code-rs/src}/plugins/loader.rs | 0 .../claude-code-rs/src}/plugins/manifest.rs | 0 .../claude-code-rs/src}/plugins/mod.rs | 0 .../claude-code-rs/src}/plugins/tools.rs | 0 .../claude-code-rs/src}/query/deps.rs | 0 .../claude-code-rs/src}/query/loop_helpers.rs | 0 .../claude-code-rs/src}/query/loop_impl.rs | 0 .../claude-code-rs/src}/query/loop_tests.rs | 0 .../claude-code-rs/src}/query/mod.rs | 0 .../claude-code-rs/src}/query/stop_hooks.rs | 0 .../claude-code-rs/src}/query/token_budget.rs | 0 .../src}/sandbox/availability.rs | 0 .../claude-code-rs/src}/sandbox/errors.rs | 0 .../claude-code-rs/src}/sandbox/filesystem.rs | 0 .../claude-code-rs/src}/sandbox/mod.rs | 0 .../claude-code-rs/src}/sandbox/mode.rs | 0 .../claude-code-rs/src}/sandbox/network.rs | 0 .../claude-code-rs/src}/sandbox/policy.rs | 0 .../claude-code-rs/src}/sandbox/runner.rs | 0 .../src}/services/langfuse/client.rs | 0 .../src}/services/langfuse/convert.rs | 0 .../src}/services/langfuse/mod.rs | 0 .../src}/services/langfuse/sanitize.rs | 0 .../src}/services/langfuse/stub.rs | 0 .../src}/services/langfuse/tracing.rs | 0 .../src}/services/lsp_lifecycle.rs | 0 .../claude-code-rs/src}/services/mod.rs | 0 .../src}/services/prompt_suggestion.rs | 0 .../src}/services/session_analytics.rs | 0 .../src}/services/session_memory.rs | 0 .../src}/services/tool_use_summary.rs | 0 .../src}/session/audit_export.rs | 0 .../claude-code-rs/src}/session/export.rs | 0 .../claude-code-rs/src}/session/memdir.rs | 0 .../claude-code-rs/src}/session/migrations.rs | 0 .../claude-code-rs/src}/session/mod.rs | 0 .../claude-code-rs/src}/session/resume.rs | 0 .../src}/session/session_export/builders.rs | 0 .../session/session_export/compression.rs | 0 .../src}/session/session_export/mod.rs | 0 .../src}/session/session_export/tests.rs | 0 .../claude-code-rs/src}/session/storage.rs | 0 .../claude-code-rs/src}/session/transcript.rs | 0 .../claude-code-rs/src}/shutdown.rs | 0 .../claude-code-rs/src}/skills/bundled.rs | 0 .../claude-code-rs/src}/skills/loader.rs | 0 .../claude-code-rs/src}/skills/mod.rs | 0 .../claude-code-rs/src}/startup/fast_paths.rs | 0 .../claude-code-rs/src}/startup/logging.rs | 0 .../claude-code-rs/src}/startup/mod.rs | 0 .../claude-code-rs/src}/startup/modes.rs | 0 .../src}/startup/runtime_config.rs | 0 .../claude-code-rs/src}/teams/backend.rs | 0 .../claude-code-rs/src}/teams/constants.rs | 0 .../claude-code-rs/src}/teams/context.rs | 0 .../claude-code-rs/src}/teams/helpers.rs | 0 .../claude-code-rs/src}/teams/identity.rs | 0 .../claude-code-rs/src}/teams/in_process.rs | 0 .../claude-code-rs/src}/teams/mailbox.rs | 0 .../claude-code-rs/src}/teams/mod.rs | 0 .../claude-code-rs/src}/teams/protocol.rs | 0 .../claude-code-rs/src}/teams/runner.rs | 0 .../claude-code-rs/src}/teams/types.rs | 0 .../claude-code-rs/src}/tools/ARCHITECTURE.md | 0 .../src}/tools/agent/dispatch.rs | 0 .../claude-code-rs/src}/tools/agent/mod.rs | 0 .../claude-code-rs/src}/tools/agent/tests.rs | 0 .../src}/tools/agent/tool_impl.rs | 0 .../src}/tools/agent/worktree.rs | 0 .../claude-code-rs/src}/tools/ask_user.rs | 0 .../src}/tools/background_agents.rs | 0 .../claude-code-rs/src}/tools/brief.rs | 0 .../claude-code-rs/src}/tools/config_tool.rs | 0 .../claude-code-rs/src}/tools/exec/bash.rs | 0 .../claude-code-rs/src}/tools/exec/mod.rs | 0 .../src}/tools/exec/powershell.rs | 0 .../claude-code-rs/src}/tools/exec/repl.rs | 0 .../claude-code-rs/src}/tools/exec/sleep.rs | 0 .../src}/tools/execution/coordinator.rs | 0 .../src}/tools/execution/mod.rs | 0 .../src}/tools/execution/pipeline.rs | 0 .../src}/tools/execution/security.rs | 0 .../src}/tools/execution/tests.rs | 0 crates/claude-code-rs/src/tools/file_read.rs | 0 .../claude-code-rs/src}/tools/fs/file_edit.rs | 0 .../claude-code-rs/src}/tools/fs/file_read.rs | 0 .../src}/tools/fs/file_write.rs | 0 .../claude-code-rs/src}/tools/fs/glob_tool.rs | 0 .../claude-code-rs/src}/tools/fs/grep.rs | 0 .../claude-code-rs/src}/tools/fs/mod.rs | 0 .../src}/tools/hooks/execution.rs | 0 .../claude-code-rs/src}/tools/hooks/mod.rs | 0 .../src}/tools/hooks/post_tool.rs | 0 .../src}/tools/hooks/pre_tool.rs | 0 .../claude-code-rs/src}/tools/lsp.rs | 0 .../claude-code-rs/src}/tools/mod.rs | 0 .../src}/tools/orchestration.rs | 0 .../claude-code-rs/src}/tools/plan_mode.rs | 0 .../claude-code-rs/src}/tools/registry.rs | 0 .../claude-code-rs/src}/tools/send_message.rs | 0 .../src}/tools/send_user_message.rs | 0 .../claude-code-rs/src}/tools/skill.rs | 0 .../src}/tools/structured_output.rs | 0 .../src}/tools/system_status.rs | 0 .../claude-code-rs/src}/tools/tasks.rs | 0 .../claude-code-rs/src}/tools/team_spawn.rs | 0 .../claude-code-rs/src}/tools/web_fetch.rs | 0 .../src}/tools/web_search/mod.rs | 0 .../src}/tools/web_search/providers.rs | 0 .../src}/tools/web_search/tests.rs | 0 .../src}/tools/web_search/tool.rs | 0 .../claude-code-rs/src}/tools/worktree.rs | 0 .../claude-code-rs/src}/types/app_state.rs | 0 .../claude-code-rs/src}/types/config.rs | 0 .../claude-code-rs/src}/types/message.rs | 0 .../claude-code-rs/src}/types/mod.rs | 0 .../claude-code-rs/src}/types/state.rs | 0 .../claude-code-rs/src}/types/tool.rs | 0 .../claude-code-rs/src}/types/transitions.rs | 0 {src => crates/claude-code-rs/src}/ui/app.rs | 0 .../claude-code-rs/src}/ui/browser.rs | 0 {src => crates/claude-code-rs/src}/ui/diff.rs | 0 .../claude-code-rs/src}/ui/keybindings.rs | 0 .../claude-code-rs/src}/ui/markdown.rs | 0 .../claude-code-rs/src}/ui/messages.rs | 0 {src => crates/claude-code-rs/src}/ui/mod.rs | 0 .../claude-code-rs/src}/ui/permissions.rs | 0 .../claude-code-rs/src}/ui/prompt_input.rs | 0 .../claude-code-rs/src}/ui/spinner.rs | 0 .../claude-code-rs/src}/ui/status_line/mod.rs | 0 .../src}/ui/status_line/payload.rs | 0 .../src}/ui/status_line/runner.rs | 0 .../claude-code-rs/src}/ui/terminal_env.rs | 0 .../claude-code-rs/src}/ui/theme.rs | 0 .../claude-code-rs/src}/ui/transcript.rs | 0 {src => crates/claude-code-rs/src}/ui/tui.rs | 0 {src => crates/claude-code-rs/src}/ui/vim.rs | 0 .../claude-code-rs/src}/ui/virtual_scroll.rs | 0 .../claude-code-rs/src}/ui/welcome.rs | 0 .../claude-code-rs/src}/utils/abort.rs | 0 .../claude-code-rs/src}/utils/bash.rs | 0 .../claude-code-rs/src}/utils/cwd.rs | 0 .../src}/utils/file_state_cache.rs | 0 .../claude-code-rs/src}/utils/git.rs | 0 .../claude-code-rs/src}/utils/messages.rs | 0 .../claude-code-rs/src}/utils/mod.rs | 0 .../claude-code-rs/src}/utils/shell.rs | 0 .../claude-code-rs/src}/utils/tokens.rs | 0 .../claude-code-rs/src}/voice/audio.rs | 0 .../claude-code-rs/src}/voice/controller.rs | 0 .../claude-code-rs/src}/voice/feasibility.rs | 0 .../claude-code-rs/src}/voice/language.rs | 0 .../claude-code-rs/src}/voice/mod.rs | 0 .../claude-code-rs/src}/voice/stt.rs | 0 .../claude-code-rs/src}/web/handlers.rs | 0 {src => crates/claude-code-rs/src}/web/mod.rs | 0 {src => crates/claude-code-rs/src}/web/sse.rs | 0 .../claude-code-rs/src}/web/state.rs | 0 .../claude-code-rs/src}/web/static_files.rs | 5 +- .../tests}/cc_rust_home_subprocess.rs | 0 .../claude-code-rs/tests}/conftest.py | 0 .../claude-code-rs/tests}/dashboard_verify.ts | 0 .../claude-code-rs/tests}/docs/README.md | 0 .../claude-code-rs/tests}/docs/e2e.md | 0 .../claude-code-rs/tests}/docs/pty.md | 0 .../claude-code-rs/tests}/e2e_audit_export.rs | 0 .../claude-code-rs/tests}/e2e_browser_mcp.rs | 0 .../tests}/e2e_chrome_mcp_bridge.rs | 0 .../tests}/e2e_chrome_native_host.rs | 0 .../tests}/e2e_chrome_subsystem.rs | 0 .../claude-code-rs/tests}/e2e_cli.rs | 0 .../claude-code-rs/tests}/e2e_compact.rs | 0 .../claude-code-rs/tests}/e2e_env.rs | 0 .../claude-code-rs/tests}/e2e_hooks.rs | 0 .../claude-code-rs/tests}/e2e_keybindings.rs | 0 .../claude-code-rs/tests}/e2e_live_api.rs | 0 .../claude-code-rs/tests}/e2e_lsp.rs | 0 .../tests}/e2e_model_effort_style.rs | 0 .../claude-code-rs/tests}/e2e_permissions.rs | 0 .../claude-code-rs/tests}/e2e_plugin_tools.rs | 0 .../claude-code-rs/tests}/e2e_pty.rs | 0 .../claude-code-rs/tests}/e2e_sandbox.rs | 0 .../claude-code-rs/tests}/e2e_services.rs | 0 .../tests}/e2e_session_export.rs | 0 .../claude-code-rs/tests}/e2e_settings.rs | 0 .../claude-code-rs/tests}/e2e_statusline.rs | 0 .../tests}/e2e_terminal/commands.rs | 0 .../tests}/e2e_terminal/helpers.rs | 0 .../tests}/e2e_terminal/live.rs | 0 .../tests}/e2e_terminal/main.rs | 0 .../tests}/e2e_terminal/offline.rs | 0 .../tests}/e2e_terminal/permission.rs | 0 .../tests}/e2e_terminal/subagent.rs | 0 .../tests}/e2e_terminal/tool_display.rs | 0 .../tests}/e2e_terminal/usage.rs | 0 .../claude-code-rs/tests}/e2e_terminal_ux.rs | 0 .../claude-code-rs/tests}/e2e_tools.rs | 0 .../claude-code-rs/tests}/e2e_voice.rs | 0 .../tests}/message_suite/.gitignore | 0 .../tests}/message_suite/assertions.py | 0 .../cases/coding/bash-stdout-stderr.yaml | 0 .../cases/coding/edit-error-recovery.yaml | 0 .../cases/coding/edit-preview.yaml | 0 .../cases/coding/glob-grep-chain.yaml | 0 .../cases/coding/long-bash-streaming.yaml | 0 .../cases/coding/parallel-reads.yaml | 0 .../cases/coding/read-single.yaml | 0 .../cases/coding/write-new-file.yaml | 0 .../cases/smoke/deepseek-chat.yaml | 0 .../message_suite/cases/smoke/version.yaml | 0 .../cases/subagent/abort-mid-flight.yaml | 0 .../cases/subagent/background.yaml | 0 .../message_suite/cases/subagent/explore.yaml | 0 .../cases/subagent/general-purpose.yaml | 0 .../message_suite/cases/subagent/nested.yaml | 0 .../cases/subagent/worktree-isolation.yaml | 0 .../cases/workspace/add-dir-nonexistent.yaml | 0 .../cases/workspace/add-dir.yaml | 0 .../cases/workspace/multi-parallel.yaml | 0 .../cases/workspace/session-scoping.yaml | 0 .../cases/workspace/single-cwd.yaml | 0 .../tests}/message_suite/defaults.yaml | 0 .../tests}/message_suite/protocol.py | 0 .../tests}/message_suite/runner.py | 0 .../claude-code-rs/tests}/pty_ui/commands.rs | 0 .../claude-code-rs/tests}/pty_ui/fast_path.rs | 0 .../claude-code-rs/tests}/pty_ui/harness.rs | 0 .../claude-code-rs/tests}/pty_ui/input.rs | 0 .../claude-code-rs/tests}/pty_ui/main.rs | 0 .../tests}/pty_ui/multi_turn.rs | 0 .../claude-code-rs/tests}/pty_ui/resize.rs | 0 .../tests}/pty_ui/screenshot.rs | 0 .../claude-code-rs/tests}/pty_ui/streaming.rs | 0 .../claude-code-rs/tests}/pty_ui/welcome.rs | 0 .../claude-code-rs/tests}/pytest.ini | 0 .../claude-code-rs/tests}/test_e2e_smoke.py | 0 .../claude-code-rs/tests}/test_workspace.rs | 0 docs/workspace-split-measurements.md | 60 +++++++ 450 files changed, 293 insertions(+), 94 deletions(-) create mode 100644 crates/claude-code-rs/Cargo.toml rename build.rs => crates/claude-code-rs/build.rs (63%) rename {src => crates/claude-code-rs/src}/api/bedrock.rs (100%) rename {src => crates/claude-code-rs/src}/api/client/mod.rs (100%) rename {src => crates/claude-code-rs/src}/api/client/stream.rs (100%) rename {src => crates/claude-code-rs/src}/api/client/tests.rs (100%) rename {src => crates/claude-code-rs/src}/api/google_provider.rs (100%) rename {src => crates/claude-code-rs/src}/api/mod.rs (100%) rename {src => crates/claude-code-rs/src}/api/model_mapping.rs (100%) rename {src => crates/claude-code-rs/src}/api/openai_compat.rs (100%) rename {src => crates/claude-code-rs/src}/api/pricing.rs (100%) rename {src => crates/claude-code-rs/src}/api/providers.rs (100%) rename {src => crates/claude-code-rs/src}/api/retry.rs (100%) rename {src => crates/claude-code-rs/src}/api/sigv4.rs (100%) rename {src => crates/claude-code-rs/src}/api/stream_provider.rs (100%) rename {src => crates/claude-code-rs/src}/api/streaming.rs (100%) rename {src => crates/claude-code-rs/src}/api/vertex.rs (100%) rename {src => crates/claude-code-rs/src}/auth/api_key.rs (100%) rename {src => crates/claude-code-rs/src}/auth/codex_cli.rs (100%) rename {src => crates/claude-code-rs/src}/auth/mod.rs (100%) rename {src => crates/claude-code-rs/src}/auth/oauth/client.rs (100%) rename {src => crates/claude-code-rs/src}/auth/oauth/config.rs (100%) rename {src => crates/claude-code-rs/src}/auth/oauth/mod.rs (100%) rename {src => crates/claude-code-rs/src}/auth/oauth/pkce.rs (100%) rename {src => crates/claude-code-rs/src}/auth/token.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/diagnostics.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/ids.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/mod.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/model.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/signal.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/state.rs (100%) rename {src => crates/claude-code-rs/src}/bootstrap/timing.rs (100%) rename {src => crates/claude-code-rs/src}/browser/common.rs (100%) rename {src => crates/claude-code-rs/src}/browser/detection.rs (100%) rename {src => crates/claude-code-rs/src}/browser/mcp_bridge.rs (100%) rename {src => crates/claude-code-rs/src}/browser/mod.rs (100%) rename {src => crates/claude-code-rs/src}/browser/native_host.rs (100%) rename {src => crates/claude-code-rs/src}/browser/permissions.rs (100%) rename {src => crates/claude-code-rs/src}/browser/prompt.rs (100%) rename {src => crates/claude-code-rs/src}/browser/session.rs (100%) rename {src => crates/claude-code-rs/src}/browser/setup.rs (100%) rename {src => crates/claude-code-rs/src}/browser/state.rs (100%) rename {src => crates/claude-code-rs/src}/browser/tool_rendering.rs (100%) rename {src => crates/claude-code-rs/src}/browser/transport.rs (100%) rename {src => crates/claude-code-rs/src}/cli.rs (100%) rename {src => crates/claude-code-rs/src}/commands/add_dir.rs (100%) rename {src => crates/claude-code-rs/src}/commands/agents_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/assistant.rs (100%) rename {src => crates/claude-code-rs/src}/commands/audit_export.rs (100%) rename {src => crates/claude-code-rs/src}/commands/branch.rs (100%) rename {src => crates/claude-code-rs/src}/commands/brief.rs (100%) rename {src => crates/claude-code-rs/src}/commands/channels.rs (100%) rename {src => crates/claude-code-rs/src}/commands/chrome_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/clear.rs (100%) rename {src => crates/claude-code-rs/src}/commands/commit.rs (100%) rename {src => crates/claude-code-rs/src}/commands/compact.rs (100%) rename {src => crates/claude-code-rs/src}/commands/config_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/context.rs (100%) rename {src => crates/claude-code-rs/src}/commands/copy.rs (100%) rename {src => crates/claude-code-rs/src}/commands/cost.rs (100%) rename {src => crates/claude-code-rs/src}/commands/daemon_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/diff.rs (100%) rename {src => crates/claude-code-rs/src}/commands/doctor.rs (100%) rename {src => crates/claude-code-rs/src}/commands/dream.rs (100%) rename {src => crates/claude-code-rs/src}/commands/effort.rs (100%) rename {src => crates/claude-code-rs/src}/commands/exit.rs (100%) rename {src => crates/claude-code-rs/src}/commands/export.rs (100%) rename {src => crates/claude-code-rs/src}/commands/extra_usage.rs (100%) rename {src => crates/claude-code-rs/src}/commands/fast.rs (100%) rename {src => crates/claude-code-rs/src}/commands/files.rs (100%) rename {src => crates/claude-code-rs/src}/commands/help.rs (100%) rename {src => crates/claude-code-rs/src}/commands/hooks_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/init.rs (100%) rename {src => crates/claude-code-rs/src}/commands/insights.rs (100%) rename {src => crates/claude-code-rs/src}/commands/keybindings_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/login.rs (100%) rename {src => crates/claude-code-rs/src}/commands/login_code.rs (100%) rename {src => crates/claude-code-rs/src}/commands/logout.rs (100%) rename {src => crates/claude-code-rs/src}/commands/mcp_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/memory.rs (100%) rename {src => crates/claude-code-rs/src}/commands/mod.rs (100%) rename {src => crates/claude-code-rs/src}/commands/model.rs (100%) rename {src => crates/claude-code-rs/src}/commands/model_add.rs (100%) rename {src => crates/claude-code-rs/src}/commands/notify.rs (100%) rename {src => crates/claude-code-rs/src}/commands/permissions_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/plugin_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/rate_limit.rs (100%) rename {src => crates/claude-code-rs/src}/commands/recap.rs (100%) rename {src => crates/claude-code-rs/src}/commands/rename.rs (100%) rename {src => crates/claude-code-rs/src}/commands/resume.rs (100%) rename {src => crates/claude-code-rs/src}/commands/review.rs (100%) rename {src => crates/claude-code-rs/src}/commands/rewind.rs (100%) rename {src => crates/claude-code-rs/src}/commands/sandbox_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/security_review.rs (100%) rename {src => crates/claude-code-rs/src}/commands/session.rs (100%) rename {src => crates/claude-code-rs/src}/commands/session_export.rs (100%) rename {src => crates/claude-code-rs/src}/commands/skills_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/sleep_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/status.rs (100%) rename {src => crates/claude-code-rs/src}/commands/statusline_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/tasks_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/team_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/commands/terminal_setup.rs (100%) rename {src => crates/claude-code-rs/src}/commands/version.rs (100%) rename {src => crates/claude-code-rs/src}/commands/voice_cmd.rs (100%) rename {src => crates/claude-code-rs/src}/compact/auto_compact.rs (100%) rename {src => crates/claude-code-rs/src}/compact/compaction.rs (100%) rename {src => crates/claude-code-rs/src}/compact/messages.rs (100%) rename {src => crates/claude-code-rs/src}/compact/microcompact.rs (100%) rename {src => crates/claude-code-rs/src}/compact/mod.rs (100%) rename {src => crates/claude-code-rs/src}/compact/pipeline.rs (100%) rename {src => crates/claude-code-rs/src}/compact/snip.rs (100%) rename {src => crates/claude-code-rs/src}/compact/tool_result_budget.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/detection.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/input/darwin.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/input/linux.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/input/mod.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/input/win32.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/mod.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/screenshot/darwin.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/screenshot/linux.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/screenshot/mod.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/screenshot/win32.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/setup.rs (100%) rename {src => crates/claude-code-rs/src}/computer_use/tools.rs (100%) rename {src => crates/claude-code-rs/src}/config/claude_md.rs (100%) rename {src => crates/claude-code-rs/src}/config/constants.rs (100%) rename {src => crates/claude-code-rs/src}/config/features.rs (100%) rename {src => crates/claude-code-rs/src}/config/mod.rs (100%) rename {src => crates/claude-code-rs/src}/config/paths.rs (100%) rename {src => crates/claude-code-rs/src}/config/settings.rs (99%) rename {src => crates/claude-code-rs/src}/config/validation.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/channels.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/memory_log.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/mod.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/notification.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/routes.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/server.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/sse.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/state.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/team_memory_proxy.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/tick.rs (100%) rename {src => crates/claude-code-rs/src}/daemon/webhook.rs (100%) rename {src => crates/claude-code-rs/src}/dashboard.rs (100%) rename {src => crates/claude-code-rs/src}/engine/codex_exec.rs (100%) rename {src => crates/claude-code-rs/src}/engine/effort.rs (100%) rename {src => crates/claude-code-rs/src}/engine/input_processing.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/deps.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/helpers.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/mod.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/submit_message.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/tests.rs (100%) rename {src => crates/claude-code-rs/src}/engine/lifecycle/types.rs (100%) rename {src => crates/claude-code-rs/src}/engine/mod.rs (100%) rename {src => crates/claude-code-rs/src}/engine/output_style.rs (100%) rename {src => crates/claude-code-rs/src}/engine/prompt_sections.rs (100%) rename {src => crates/claude-code-rs/src}/engine/result.rs (100%) rename {src => crates/claude-code-rs/src}/engine/sdk_types.rs (100%) rename {src => crates/claude-code-rs/src}/engine/system_prompt.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/agent_channel.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/agent_events.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/agent_handlers.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/agent_tree.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/agent_types.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/callbacks.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/headless.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/ingress.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/mod.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/protocol/agent.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/protocol/base.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/protocol/mod.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/protocol/subsystem.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/protocol/team.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/query_runner.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/runtime.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/sdk_mapper.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/sink.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/subsystem_events.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/subsystem_handlers.rs (100%) rename {src => crates/claude-code-rs/src}/ipc/subsystem_types.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/action.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/config.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/context.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/defaults.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/keystroke.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/mod.rs (100%) rename {src => crates/claude-code-rs/src}/keybindings/registry.rs (100%) rename {src => crates/claude-code-rs/src}/lsp_service/client.rs (100%) rename {src => crates/claude-code-rs/src}/lsp_service/conversions/mod.rs (100%) rename {src => crates/claude-code-rs/src}/lsp_service/conversions/tests.rs (100%) rename {src => crates/claude-code-rs/src}/lsp_service/mod.rs (100%) rename {src => crates/claude-code-rs/src}/lsp_service/transport.rs (100%) rename {src => crates/claude-code-rs/src}/main.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/channel.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/client.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/client_tests.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/discovery.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/manager.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/mod.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/tools.rs (100%) rename {src => crates/claude-code-rs/src}/mcp/transport.rs (100%) rename {src => crates/claude-code-rs/src}/observability/context.rs (100%) rename {src => crates/claude-code-rs/src}/observability/event.rs (100%) rename {src => crates/claude-code-rs/src}/observability/mod.rs (100%) rename {src => crates/claude-code-rs/src}/observability/sink.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/bash_matcher.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/dangerous.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/decision.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/mod.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/path_validation.rs (100%) rename {src => crates/claude-code-rs/src}/permissions/rules.rs (100%) rename {src => crates/claude-code-rs/src}/plugins/loader.rs (100%) rename {src => crates/claude-code-rs/src}/plugins/manifest.rs (100%) rename {src => crates/claude-code-rs/src}/plugins/mod.rs (100%) rename {src => crates/claude-code-rs/src}/plugins/tools.rs (100%) rename {src => crates/claude-code-rs/src}/query/deps.rs (100%) rename {src => crates/claude-code-rs/src}/query/loop_helpers.rs (100%) rename {src => crates/claude-code-rs/src}/query/loop_impl.rs (100%) rename {src => crates/claude-code-rs/src}/query/loop_tests.rs (100%) rename {src => crates/claude-code-rs/src}/query/mod.rs (100%) rename {src => crates/claude-code-rs/src}/query/stop_hooks.rs (100%) rename {src => crates/claude-code-rs/src}/query/token_budget.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/availability.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/errors.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/filesystem.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/mod.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/mode.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/network.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/policy.rs (100%) rename {src => crates/claude-code-rs/src}/sandbox/runner.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/client.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/convert.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/mod.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/sanitize.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/stub.rs (100%) rename {src => crates/claude-code-rs/src}/services/langfuse/tracing.rs (100%) rename {src => crates/claude-code-rs/src}/services/lsp_lifecycle.rs (100%) rename {src => crates/claude-code-rs/src}/services/mod.rs (100%) rename {src => crates/claude-code-rs/src}/services/prompt_suggestion.rs (100%) rename {src => crates/claude-code-rs/src}/services/session_analytics.rs (100%) rename {src => crates/claude-code-rs/src}/services/session_memory.rs (100%) rename {src => crates/claude-code-rs/src}/services/tool_use_summary.rs (100%) rename {src => crates/claude-code-rs/src}/session/audit_export.rs (100%) rename {src => crates/claude-code-rs/src}/session/export.rs (100%) rename {src => crates/claude-code-rs/src}/session/memdir.rs (100%) rename {src => crates/claude-code-rs/src}/session/migrations.rs (100%) rename {src => crates/claude-code-rs/src}/session/mod.rs (100%) rename {src => crates/claude-code-rs/src}/session/resume.rs (100%) rename {src => crates/claude-code-rs/src}/session/session_export/builders.rs (100%) rename {src => crates/claude-code-rs/src}/session/session_export/compression.rs (100%) rename {src => crates/claude-code-rs/src}/session/session_export/mod.rs (100%) rename {src => crates/claude-code-rs/src}/session/session_export/tests.rs (100%) rename {src => crates/claude-code-rs/src}/session/storage.rs (100%) rename {src => crates/claude-code-rs/src}/session/transcript.rs (100%) rename {src => crates/claude-code-rs/src}/shutdown.rs (100%) rename {src => crates/claude-code-rs/src}/skills/bundled.rs (100%) rename {src => crates/claude-code-rs/src}/skills/loader.rs (100%) rename {src => crates/claude-code-rs/src}/skills/mod.rs (100%) rename {src => crates/claude-code-rs/src}/startup/fast_paths.rs (100%) rename {src => crates/claude-code-rs/src}/startup/logging.rs (100%) rename {src => crates/claude-code-rs/src}/startup/mod.rs (100%) rename {src => crates/claude-code-rs/src}/startup/modes.rs (100%) rename {src => crates/claude-code-rs/src}/startup/runtime_config.rs (100%) rename {src => crates/claude-code-rs/src}/teams/backend.rs (100%) rename {src => crates/claude-code-rs/src}/teams/constants.rs (100%) rename {src => crates/claude-code-rs/src}/teams/context.rs (100%) rename {src => crates/claude-code-rs/src}/teams/helpers.rs (100%) rename {src => crates/claude-code-rs/src}/teams/identity.rs (100%) rename {src => crates/claude-code-rs/src}/teams/in_process.rs (100%) rename {src => crates/claude-code-rs/src}/teams/mailbox.rs (100%) rename {src => crates/claude-code-rs/src}/teams/mod.rs (100%) rename {src => crates/claude-code-rs/src}/teams/protocol.rs (100%) rename {src => crates/claude-code-rs/src}/teams/runner.rs (100%) rename {src => crates/claude-code-rs/src}/teams/types.rs (100%) rename {src => crates/claude-code-rs/src}/tools/ARCHITECTURE.md (100%) rename {src => crates/claude-code-rs/src}/tools/agent/dispatch.rs (100%) rename {src => crates/claude-code-rs/src}/tools/agent/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/agent/tests.rs (100%) rename {src => crates/claude-code-rs/src}/tools/agent/tool_impl.rs (100%) rename {src => crates/claude-code-rs/src}/tools/agent/worktree.rs (100%) rename {src => crates/claude-code-rs/src}/tools/ask_user.rs (100%) rename {src => crates/claude-code-rs/src}/tools/background_agents.rs (100%) rename {src => crates/claude-code-rs/src}/tools/brief.rs (100%) rename {src => crates/claude-code-rs/src}/tools/config_tool.rs (100%) rename {src => crates/claude-code-rs/src}/tools/exec/bash.rs (100%) rename {src => crates/claude-code-rs/src}/tools/exec/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/exec/powershell.rs (100%) rename {src => crates/claude-code-rs/src}/tools/exec/repl.rs (100%) rename {src => crates/claude-code-rs/src}/tools/exec/sleep.rs (100%) rename {src => crates/claude-code-rs/src}/tools/execution/coordinator.rs (100%) rename {src => crates/claude-code-rs/src}/tools/execution/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/execution/pipeline.rs (100%) rename {src => crates/claude-code-rs/src}/tools/execution/security.rs (100%) rename {src => crates/claude-code-rs/src}/tools/execution/tests.rs (100%) create mode 100644 crates/claude-code-rs/src/tools/file_read.rs rename {src => crates/claude-code-rs/src}/tools/fs/file_edit.rs (100%) rename {src => crates/claude-code-rs/src}/tools/fs/file_read.rs (100%) rename {src => crates/claude-code-rs/src}/tools/fs/file_write.rs (100%) rename {src => crates/claude-code-rs/src}/tools/fs/glob_tool.rs (100%) rename {src => crates/claude-code-rs/src}/tools/fs/grep.rs (100%) rename {src => crates/claude-code-rs/src}/tools/fs/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/hooks/execution.rs (100%) rename {src => crates/claude-code-rs/src}/tools/hooks/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/hooks/post_tool.rs (100%) rename {src => crates/claude-code-rs/src}/tools/hooks/pre_tool.rs (100%) rename {src => crates/claude-code-rs/src}/tools/lsp.rs (100%) rename {src => crates/claude-code-rs/src}/tools/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/orchestration.rs (100%) rename {src => crates/claude-code-rs/src}/tools/plan_mode.rs (100%) rename {src => crates/claude-code-rs/src}/tools/registry.rs (100%) rename {src => crates/claude-code-rs/src}/tools/send_message.rs (100%) rename {src => crates/claude-code-rs/src}/tools/send_user_message.rs (100%) rename {src => crates/claude-code-rs/src}/tools/skill.rs (100%) rename {src => crates/claude-code-rs/src}/tools/structured_output.rs (100%) rename {src => crates/claude-code-rs/src}/tools/system_status.rs (100%) rename {src => crates/claude-code-rs/src}/tools/tasks.rs (100%) rename {src => crates/claude-code-rs/src}/tools/team_spawn.rs (100%) rename {src => crates/claude-code-rs/src}/tools/web_fetch.rs (100%) rename {src => crates/claude-code-rs/src}/tools/web_search/mod.rs (100%) rename {src => crates/claude-code-rs/src}/tools/web_search/providers.rs (100%) rename {src => crates/claude-code-rs/src}/tools/web_search/tests.rs (100%) rename {src => crates/claude-code-rs/src}/tools/web_search/tool.rs (100%) rename {src => crates/claude-code-rs/src}/tools/worktree.rs (100%) rename {src => crates/claude-code-rs/src}/types/app_state.rs (100%) rename {src => crates/claude-code-rs/src}/types/config.rs (100%) rename {src => crates/claude-code-rs/src}/types/message.rs (100%) rename {src => crates/claude-code-rs/src}/types/mod.rs (100%) rename {src => crates/claude-code-rs/src}/types/state.rs (100%) rename {src => crates/claude-code-rs/src}/types/tool.rs (100%) rename {src => crates/claude-code-rs/src}/types/transitions.rs (100%) rename {src => crates/claude-code-rs/src}/ui/app.rs (100%) rename {src => crates/claude-code-rs/src}/ui/browser.rs (100%) rename {src => crates/claude-code-rs/src}/ui/diff.rs (100%) rename {src => crates/claude-code-rs/src}/ui/keybindings.rs (100%) rename {src => crates/claude-code-rs/src}/ui/markdown.rs (100%) rename {src => crates/claude-code-rs/src}/ui/messages.rs (100%) rename {src => crates/claude-code-rs/src}/ui/mod.rs (100%) rename {src => crates/claude-code-rs/src}/ui/permissions.rs (100%) rename {src => crates/claude-code-rs/src}/ui/prompt_input.rs (100%) rename {src => crates/claude-code-rs/src}/ui/spinner.rs (100%) rename {src => crates/claude-code-rs/src}/ui/status_line/mod.rs (100%) rename {src => crates/claude-code-rs/src}/ui/status_line/payload.rs (100%) rename {src => crates/claude-code-rs/src}/ui/status_line/runner.rs (100%) rename {src => crates/claude-code-rs/src}/ui/terminal_env.rs (100%) rename {src => crates/claude-code-rs/src}/ui/theme.rs (100%) rename {src => crates/claude-code-rs/src}/ui/transcript.rs (100%) rename {src => crates/claude-code-rs/src}/ui/tui.rs (100%) rename {src => crates/claude-code-rs/src}/ui/vim.rs (100%) rename {src => crates/claude-code-rs/src}/ui/virtual_scroll.rs (100%) rename {src => crates/claude-code-rs/src}/ui/welcome.rs (100%) rename {src => crates/claude-code-rs/src}/utils/abort.rs (100%) rename {src => crates/claude-code-rs/src}/utils/bash.rs (100%) rename {src => crates/claude-code-rs/src}/utils/cwd.rs (100%) rename {src => crates/claude-code-rs/src}/utils/file_state_cache.rs (100%) rename {src => crates/claude-code-rs/src}/utils/git.rs (100%) rename {src => crates/claude-code-rs/src}/utils/messages.rs (100%) rename {src => crates/claude-code-rs/src}/utils/mod.rs (100%) rename {src => crates/claude-code-rs/src}/utils/shell.rs (100%) rename {src => crates/claude-code-rs/src}/utils/tokens.rs (100%) rename {src => crates/claude-code-rs/src}/voice/audio.rs (100%) rename {src => crates/claude-code-rs/src}/voice/controller.rs (100%) rename {src => crates/claude-code-rs/src}/voice/feasibility.rs (100%) rename {src => crates/claude-code-rs/src}/voice/language.rs (100%) rename {src => crates/claude-code-rs/src}/voice/mod.rs (100%) rename {src => crates/claude-code-rs/src}/voice/stt.rs (100%) rename {src => crates/claude-code-rs/src}/web/handlers.rs (100%) rename {src => crates/claude-code-rs/src}/web/mod.rs (100%) rename {src => crates/claude-code-rs/src}/web/sse.rs (100%) rename {src => crates/claude-code-rs/src}/web/state.rs (100%) rename {src => crates/claude-code-rs/src}/web/static_files.rs (91%) rename {tests => crates/claude-code-rs/tests}/cc_rust_home_subprocess.rs (100%) rename {tests => crates/claude-code-rs/tests}/conftest.py (100%) rename {tests => crates/claude-code-rs/tests}/dashboard_verify.ts (100%) rename {tests => crates/claude-code-rs/tests}/docs/README.md (100%) rename {tests => crates/claude-code-rs/tests}/docs/e2e.md (100%) rename {tests => crates/claude-code-rs/tests}/docs/pty.md (100%) rename {tests => crates/claude-code-rs/tests}/e2e_audit_export.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_browser_mcp.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_chrome_mcp_bridge.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_chrome_native_host.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_chrome_subsystem.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_cli.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_compact.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_env.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_hooks.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_keybindings.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_live_api.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_lsp.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_model_effort_style.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_permissions.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_plugin_tools.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_pty.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_sandbox.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_services.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_session_export.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_settings.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_statusline.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/commands.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/helpers.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/live.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/main.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/offline.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/permission.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/subagent.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/tool_display.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal/usage.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_terminal_ux.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_tools.rs (100%) rename {tests => crates/claude-code-rs/tests}/e2e_voice.rs (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/.gitignore (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/assertions.py (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/bash-stdout-stderr.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/edit-error-recovery.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/edit-preview.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/glob-grep-chain.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/long-bash-streaming.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/parallel-reads.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/read-single.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/coding/write-new-file.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/smoke/deepseek-chat.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/smoke/version.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/abort-mid-flight.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/background.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/explore.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/general-purpose.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/nested.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/subagent/worktree-isolation.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/workspace/add-dir-nonexistent.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/workspace/add-dir.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/workspace/multi-parallel.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/workspace/session-scoping.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/cases/workspace/single-cwd.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/defaults.yaml (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/protocol.py (100%) rename {tests => crates/claude-code-rs/tests}/message_suite/runner.py (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/commands.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/fast_path.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/harness.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/input.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/main.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/multi_turn.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/resize.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/screenshot.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/streaming.rs (100%) rename {tests => crates/claude-code-rs/tests}/pty_ui/welcome.rs (100%) rename {tests => crates/claude-code-rs/tests}/pytest.ini (100%) rename {tests => crates/claude-code-rs/tests}/test_e2e_smoke.py (100%) rename {tests => crates/claude-code-rs/tests}/test_workspace.rs (100%) create mode 100644 docs/workspace-split-measurements.md diff --git a/Cargo.toml b/Cargo.toml index 61c44236..82237332 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,43 +1,17 @@ -[package] -name = "claude-code-rs" -version = "0.1.0" -edition = "2021" -description = "Claude Code CLI - Rust implementation (lite)" +[workspace] +resolver = "2" +members = ["crates/*"] # ============================================================ -# Features +# Shared dependency versions. +# ------------------------------------------------------------ +# All member crates declare deps via `dep.workspace = true`, so +# versions live in one place. Features remain crate-local: a +# crate adds `features = [...]` on top of the workspace entry. # ============================================================ -# -# default — minimal build: no telemetry, no embedded web assets, -# no image/syntect/tree-sitter pulls. Keeps `cargo build` -# fast and avoids heavy native deps (onig, tonic/prost). -# -# Opt-in: -# telemetry — Langfuse + OpenTelemetry export (pulls tonic/prost). -# web-ui — Embed the React SPA (rust-embed) into the binary. -# image — Image decoding (png/jpeg only). -# syntect — Syntax highlighting via fancy-regex (no onig C dep). -# tree-sitter — AST parsing. - -[features] -default = [] -telemetry = [ - "dep:tracing-opentelemetry", - "dep:opentelemetry", - "dep:opentelemetry_sdk", - "dep:opentelemetry-langfuse", -] -web-ui = ["dep:rust-embed"] -image = ["dep:image"] -syntect = ["dep:syntect"] -tree-sitter = ["dep:tree-sitter"] -# ============================================================ -# 核心类型 + 状态机 -# ============================================================ - -[dependencies] -# 异步运行时 — 按需选择 tokio 子模块,避免 `full` 带来的编译开销 +[workspace.dependencies] +# 异步运行时 tokio = { version = "1", default-features = false, features = [ "rt-multi-thread", "macros", @@ -80,27 +54,21 @@ lru = "0.12" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-appender = "0.2" -# Telemetry stack (Langfuse + OpenTelemetry) — optional, enable via `telemetry` feature. -# Pulls in tonic/prost et al., which is why it is off by default. -tracing-opentelemetry = { version = "0.32.1", optional = true } -opentelemetry = { version = "0.31", features = ["trace"], optional = true } -opentelemetry_sdk = { version = "0.31.0", features = ["trace", "rt-tokio", "experimental_trace_batch_span_processor_with_async_runtime"], optional = true } -opentelemetry-langfuse = { version = "0.6.1", optional = true } +tracing-opentelemetry = "0.32.1" +opentelemetry = { version = "0.31", features = ["trace"] } +opentelemetry_sdk = { version = "0.31.0", features = ["trace", "rt-tokio", "experimental_trace_batch_span_processor_with_async_runtime"] } +opentelemetry-langfuse = "0.6.1" # LSP 协议类型 lsp-types = "0.97" -# ============================================================ -# 本地工具系统 -# ============================================================ - # 文件搜索 & 路径 glob = "0.3" ignore = "0.4" walkdir = "2" dirs = "6" -# 正则表达式 +# 正则 regex = "1" # Git 操作 @@ -112,15 +80,12 @@ similar = "2" # 进程管理 shell-words = "1" -# ============================================================ # 终端 UI -# ============================================================ - ratatui = "0.29" crossterm = "0.28" -# 语法高亮 — optional,启用 default-fancy 用 fancy-regex 代替 onig (避免 C 编译) -syntect = { version = "5", default-features = false, features = ["default-fancy"], optional = true } +# 语法高亮 +syntect = { version = "5", default-features = false, features = ["default-fancy"] } # 文本处理 textwrap = "0.16" @@ -130,7 +95,7 @@ strip-ansi-escapes = "0.2" # Markdown 渲染 pulldown-cmark = "0.12" -# 哈希 (审计记录完整性) +# 哈希 sha2 = "0.10" hex = "0.4" rand = "0.8" @@ -142,11 +107,7 @@ url = "2" urlencoding = "2" semver = "1" -# ============================================================ -# 网络 / API / 认证 -# ============================================================ - -# 网络 — native-tls works with Clash TUN/fake-ip environments +# 网络 reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "native-tls"] } tokio-tungstenite = { version = "0.26", features = ["rustls-tls-webpki-roots"] } eventsource-stream = "0.2" @@ -155,47 +116,39 @@ eventsource-stream = "0.2" keyring = "3" dotenvy = "0.15.7" -# 同步原语 (无 lock poisoning) +# 同步原语 parking_lot = "0.12" -# Daemon HTTP server (KAIROS) + Web UI server +# Daemon HTTP server axum = { version = "0.8", features = ["ws"] } tower = "0.5" tower-http = { version = "0.6", features = ["cors", "trace"] } hmac = "0.12" notify-rust = "4" -# Web UI: embed React SPA dist/ at compile time — optional, enable via `web-ui` feature. -rust-embed = { version = "8", optional = true } +# Web UI +rust-embed = "8" mime_guess = "2" -# AST / 图像 — optional,默认不编译 (目前无使用点) -tree-sitter = { version = "0.24", optional = true } -image = { version = "0.25", default-features = false, features = ["png", "jpeg"], optional = true } +# AST / 图像 +tree-sitter = "0.24" +image = { version = "0.25", default-features = false, features = ["png", "jpeg"] } -# ============================================================ -# E2E 测试 -# ============================================================ +# POSIX syscalls +libc = "0.2" -[dev-dependencies] +# Dev / test assert_cmd = "2" predicates = "3" assert_fs = "1" tempfile = "3" -sha2 = "0.10" -hex = "0.4" -serde_json = "1" portable-pty = "0.9" vt100 = "0.15" which = "7" serial_test = "3" -# POSIX syscalls (Unix socket permissions, PID liveness for Chrome native host #5) -[target.'cfg(unix)'.dependencies] -libc = "0.2" - # ============================================================ -# 构建配置 - 压缩 Windows 下 pdb 体积 +# Profiles (apply to the whole workspace) # ============================================================ [profile.dev] diff --git a/crates/claude-code-rs/Cargo.toml b/crates/claude-code-rs/Cargo.toml new file mode 100644 index 00000000..3e774389 --- /dev/null +++ b/crates/claude-code-rs/Cargo.toml @@ -0,0 +1,163 @@ +[package] +name = "claude-code-rs" +version = "0.1.0" +edition = "2021" +description = "Claude Code CLI - Rust implementation (lite)" +build = "build.rs" + +# ============================================================ +# Features +# ============================================================ +# +# default — minimal build: no telemetry, no embedded web assets, +# no image/syntect/tree-sitter pulls. Keeps `cargo build` +# fast and avoids heavy native deps (onig, tonic/prost). +# +# Opt-in: +# telemetry — Langfuse + OpenTelemetry export (pulls tonic/prost). +# web-ui — Embed the React SPA (rust-embed) into the binary. +# image — Image decoding (png/jpeg only). +# syntect — Syntax highlighting via fancy-regex (no onig C dep). +# tree-sitter — AST parsing. + +[features] +default = [] +telemetry = [ + "dep:tracing-opentelemetry", + "dep:opentelemetry", + "dep:opentelemetry_sdk", + "dep:opentelemetry-langfuse", +] +web-ui = ["dep:rust-embed"] +image = ["dep:image"] +syntect = ["dep:syntect"] +tree-sitter = ["dep:tree-sitter"] + +[dependencies] +# 异步运行时 +tokio = { workspace = true } +futures = { workspace = true } +async-trait = { workspace = true } +async-stream = { workspace = true } +tokio-stream = { workspace = true } +tokio-util = { workspace = true } + +# 序列化 +serde = { workspace = true } +serde_json = { workspace = true } + +# 错误处理 +anyhow = { workspace = true } +thiserror = { workspace = true } + +# CLI +clap = { workspace = true } + +# UUID +uuid = { workspace = true } + +# 时间 +chrono = { workspace = true } + +# LRU +lru = { workspace = true } + +# 日志 +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +tracing-appender = { workspace = true } +tracing-opentelemetry = { workspace = true, optional = true } +opentelemetry = { workspace = true, optional = true } +opentelemetry_sdk = { workspace = true, optional = true } +opentelemetry-langfuse = { workspace = true, optional = true } + +# LSP +lsp-types = { workspace = true } + +# 文件 & 路径 +glob = { workspace = true } +ignore = { workspace = true } +walkdir = { workspace = true } +dirs = { workspace = true } + +# 正则 +regex = { workspace = true } + +# Git +git2 = { workspace = true } + +# Diff +similar = { workspace = true } + +# 进程 +shell-words = { workspace = true } + +# 终端 UI +ratatui = { workspace = true } +crossterm = { workspace = true } + +# 语法高亮 +syntect = { workspace = true, optional = true } + +# 文本 +textwrap = { workspace = true } +unicode-width = { workspace = true } +strip-ansi-escapes = { workspace = true } + +# Markdown +pulldown-cmark = { workspace = true } + +# 哈希 +sha2 = { workspace = true } +hex = { workspace = true } +rand = { workspace = true } + +# 编码 +base64 = { workspace = true } +bytes = { workspace = true } +url = { workspace = true } +urlencoding = { workspace = true } +semver = { workspace = true } + +# 网络 +reqwest = { workspace = true } +tokio-tungstenite = { workspace = true } +eventsource-stream = { workspace = true } + +# 认证 +keyring = { workspace = true } +dotenvy = { workspace = true } + +# 同步原语 +parking_lot = { workspace = true } + +# Daemon +axum = { workspace = true } +tower = { workspace = true } +tower-http = { workspace = true } +hmac = { workspace = true } +notify-rust = { workspace = true } + +# Web UI embed +rust-embed = { workspace = true, optional = true } +mime_guess = { workspace = true } + +# AST / 图像 +tree-sitter = { workspace = true, optional = true } +image = { workspace = true, optional = true } + +[dev-dependencies] +assert_cmd = { workspace = true } +predicates = { workspace = true } +assert_fs = { workspace = true } +tempfile = { workspace = true } +sha2 = { workspace = true } +hex = { workspace = true } +serde_json = { workspace = true } +portable-pty = { workspace = true } +vt100 = { workspace = true } +which = { workspace = true } +serial_test = { workspace = true } + +[target.'cfg(unix)'.dependencies] +libc = { workspace = true } diff --git a/build.rs b/crates/claude-code-rs/build.rs similarity index 63% rename from build.rs rename to crates/claude-code-rs/build.rs index 3a89135e..497f8d51 100644 --- a/build.rs +++ b/crates/claude-code-rs/build.rs @@ -1,32 +1,51 @@ //! Build script: auto-build web-ui if dist/ is missing or stale. //! -//! - Checks if `web-ui/dist/index.html` exists +//! - Checks if `/web-ui/dist/index.html` exists //! - If missing or `FORCE_WEB_BUILD` is set, runs `npm run build` //! - If npm is unavailable, prints a warning (TUI still works, --web won't) //! - Sets cargo:rerun-if-changed so rebuilds are triggered on source changes +//! +//! Paths are resolved relative to the workspace root, which lives two levels +//! above this crate's manifest directory (`/crates/claude-code-rs`). -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::Command; +fn workspace_root() -> PathBuf { + // CARGO_MANIFEST_DIR = /crates/claude-code-rs + let manifest_dir = std::env::var_os("CARGO_MANIFEST_DIR") + .expect("CARGO_MANIFEST_DIR must be set by cargo"); + let manifest_dir = PathBuf::from(manifest_dir); + manifest_dir + .parent() // /crates + .and_then(|p| p.parent()) // + .map(Path::to_path_buf) + .expect("CARGO_MANIFEST_DIR is not nested under /crates/") +} + fn main() { - let dist_index = Path::new("web-ui/dist/index.html"); + let root = workspace_root(); + let web_ui = root.join("web-ui"); + let dist_index = web_ui.join("dist").join("index.html"); let force = std::env::var("FORCE_WEB_BUILD").is_ok(); - // Rerun if frontend source changes - println!("cargo:rerun-if-changed=web-ui/src/"); - println!("cargo:rerun-if-changed=web-ui/package.json"); - println!("cargo:rerun-if-changed=web-ui/index.html"); - println!("cargo:rerun-if-changed=web-ui/vite.config.ts"); - println!("cargo:rerun-if-changed=web-ui/tailwind.config.js"); + // Rerun if frontend source changes. + for rel in [ + "web-ui/src/", + "web-ui/package.json", + "web-ui/index.html", + "web-ui/vite.config.ts", + "web-ui/tailwind.config.js", + ] { + println!("cargo:rerun-if-changed={}", root.join(rel).display()); + } if dist_index.exists() && !force { - // dist/ is fresh, nothing to do return; } println!("cargo:warning=Building web-ui frontend..."); - // Check if npm is available let npm_cmd = if cfg!(target_os = "windows") { "npm.cmd" } else { @@ -42,13 +61,12 @@ fn main() { return; } - // Install dependencies if node_modules is missing - let node_modules = Path::new("web-ui/node_modules"); + let node_modules = web_ui.join("node_modules"); if !node_modules.exists() { println!("cargo:warning=Installing web-ui dependencies..."); let install = Command::new(npm_cmd) .arg("install") - .current_dir("web-ui") + .current_dir(&web_ui) .status(); match install { Ok(s) if s.success() => {} @@ -66,11 +84,10 @@ fn main() { } } - // Build println!("cargo:warning=Running npm run build..."); let build = Command::new(npm_cmd) .args(["run", "build"]) - .current_dir("web-ui") + .current_dir(&web_ui) .status(); match build { diff --git a/src/api/bedrock.rs b/crates/claude-code-rs/src/api/bedrock.rs similarity index 100% rename from src/api/bedrock.rs rename to crates/claude-code-rs/src/api/bedrock.rs diff --git a/src/api/client/mod.rs b/crates/claude-code-rs/src/api/client/mod.rs similarity index 100% rename from src/api/client/mod.rs rename to crates/claude-code-rs/src/api/client/mod.rs diff --git a/src/api/client/stream.rs b/crates/claude-code-rs/src/api/client/stream.rs similarity index 100% rename from src/api/client/stream.rs rename to crates/claude-code-rs/src/api/client/stream.rs diff --git a/src/api/client/tests.rs b/crates/claude-code-rs/src/api/client/tests.rs similarity index 100% rename from src/api/client/tests.rs rename to crates/claude-code-rs/src/api/client/tests.rs diff --git a/src/api/google_provider.rs b/crates/claude-code-rs/src/api/google_provider.rs similarity index 100% rename from src/api/google_provider.rs rename to crates/claude-code-rs/src/api/google_provider.rs diff --git a/src/api/mod.rs b/crates/claude-code-rs/src/api/mod.rs similarity index 100% rename from src/api/mod.rs rename to crates/claude-code-rs/src/api/mod.rs diff --git a/src/api/model_mapping.rs b/crates/claude-code-rs/src/api/model_mapping.rs similarity index 100% rename from src/api/model_mapping.rs rename to crates/claude-code-rs/src/api/model_mapping.rs diff --git a/src/api/openai_compat.rs b/crates/claude-code-rs/src/api/openai_compat.rs similarity index 100% rename from src/api/openai_compat.rs rename to crates/claude-code-rs/src/api/openai_compat.rs diff --git a/src/api/pricing.rs b/crates/claude-code-rs/src/api/pricing.rs similarity index 100% rename from src/api/pricing.rs rename to crates/claude-code-rs/src/api/pricing.rs diff --git a/src/api/providers.rs b/crates/claude-code-rs/src/api/providers.rs similarity index 100% rename from src/api/providers.rs rename to crates/claude-code-rs/src/api/providers.rs diff --git a/src/api/retry.rs b/crates/claude-code-rs/src/api/retry.rs similarity index 100% rename from src/api/retry.rs rename to crates/claude-code-rs/src/api/retry.rs diff --git a/src/api/sigv4.rs b/crates/claude-code-rs/src/api/sigv4.rs similarity index 100% rename from src/api/sigv4.rs rename to crates/claude-code-rs/src/api/sigv4.rs diff --git a/src/api/stream_provider.rs b/crates/claude-code-rs/src/api/stream_provider.rs similarity index 100% rename from src/api/stream_provider.rs rename to crates/claude-code-rs/src/api/stream_provider.rs diff --git a/src/api/streaming.rs b/crates/claude-code-rs/src/api/streaming.rs similarity index 100% rename from src/api/streaming.rs rename to crates/claude-code-rs/src/api/streaming.rs diff --git a/src/api/vertex.rs b/crates/claude-code-rs/src/api/vertex.rs similarity index 100% rename from src/api/vertex.rs rename to crates/claude-code-rs/src/api/vertex.rs diff --git a/src/auth/api_key.rs b/crates/claude-code-rs/src/auth/api_key.rs similarity index 100% rename from src/auth/api_key.rs rename to crates/claude-code-rs/src/auth/api_key.rs diff --git a/src/auth/codex_cli.rs b/crates/claude-code-rs/src/auth/codex_cli.rs similarity index 100% rename from src/auth/codex_cli.rs rename to crates/claude-code-rs/src/auth/codex_cli.rs diff --git a/src/auth/mod.rs b/crates/claude-code-rs/src/auth/mod.rs similarity index 100% rename from src/auth/mod.rs rename to crates/claude-code-rs/src/auth/mod.rs diff --git a/src/auth/oauth/client.rs b/crates/claude-code-rs/src/auth/oauth/client.rs similarity index 100% rename from src/auth/oauth/client.rs rename to crates/claude-code-rs/src/auth/oauth/client.rs diff --git a/src/auth/oauth/config.rs b/crates/claude-code-rs/src/auth/oauth/config.rs similarity index 100% rename from src/auth/oauth/config.rs rename to crates/claude-code-rs/src/auth/oauth/config.rs diff --git a/src/auth/oauth/mod.rs b/crates/claude-code-rs/src/auth/oauth/mod.rs similarity index 100% rename from src/auth/oauth/mod.rs rename to crates/claude-code-rs/src/auth/oauth/mod.rs diff --git a/src/auth/oauth/pkce.rs b/crates/claude-code-rs/src/auth/oauth/pkce.rs similarity index 100% rename from src/auth/oauth/pkce.rs rename to crates/claude-code-rs/src/auth/oauth/pkce.rs diff --git a/src/auth/token.rs b/crates/claude-code-rs/src/auth/token.rs similarity index 100% rename from src/auth/token.rs rename to crates/claude-code-rs/src/auth/token.rs diff --git a/src/bootstrap/diagnostics.rs b/crates/claude-code-rs/src/bootstrap/diagnostics.rs similarity index 100% rename from src/bootstrap/diagnostics.rs rename to crates/claude-code-rs/src/bootstrap/diagnostics.rs diff --git a/src/bootstrap/ids.rs b/crates/claude-code-rs/src/bootstrap/ids.rs similarity index 100% rename from src/bootstrap/ids.rs rename to crates/claude-code-rs/src/bootstrap/ids.rs diff --git a/src/bootstrap/mod.rs b/crates/claude-code-rs/src/bootstrap/mod.rs similarity index 100% rename from src/bootstrap/mod.rs rename to crates/claude-code-rs/src/bootstrap/mod.rs diff --git a/src/bootstrap/model.rs b/crates/claude-code-rs/src/bootstrap/model.rs similarity index 100% rename from src/bootstrap/model.rs rename to crates/claude-code-rs/src/bootstrap/model.rs diff --git a/src/bootstrap/signal.rs b/crates/claude-code-rs/src/bootstrap/signal.rs similarity index 100% rename from src/bootstrap/signal.rs rename to crates/claude-code-rs/src/bootstrap/signal.rs diff --git a/src/bootstrap/state.rs b/crates/claude-code-rs/src/bootstrap/state.rs similarity index 100% rename from src/bootstrap/state.rs rename to crates/claude-code-rs/src/bootstrap/state.rs diff --git a/src/bootstrap/timing.rs b/crates/claude-code-rs/src/bootstrap/timing.rs similarity index 100% rename from src/bootstrap/timing.rs rename to crates/claude-code-rs/src/bootstrap/timing.rs diff --git a/src/browser/common.rs b/crates/claude-code-rs/src/browser/common.rs similarity index 100% rename from src/browser/common.rs rename to crates/claude-code-rs/src/browser/common.rs diff --git a/src/browser/detection.rs b/crates/claude-code-rs/src/browser/detection.rs similarity index 100% rename from src/browser/detection.rs rename to crates/claude-code-rs/src/browser/detection.rs diff --git a/src/browser/mcp_bridge.rs b/crates/claude-code-rs/src/browser/mcp_bridge.rs similarity index 100% rename from src/browser/mcp_bridge.rs rename to crates/claude-code-rs/src/browser/mcp_bridge.rs diff --git a/src/browser/mod.rs b/crates/claude-code-rs/src/browser/mod.rs similarity index 100% rename from src/browser/mod.rs rename to crates/claude-code-rs/src/browser/mod.rs diff --git a/src/browser/native_host.rs b/crates/claude-code-rs/src/browser/native_host.rs similarity index 100% rename from src/browser/native_host.rs rename to crates/claude-code-rs/src/browser/native_host.rs diff --git a/src/browser/permissions.rs b/crates/claude-code-rs/src/browser/permissions.rs similarity index 100% rename from src/browser/permissions.rs rename to crates/claude-code-rs/src/browser/permissions.rs diff --git a/src/browser/prompt.rs b/crates/claude-code-rs/src/browser/prompt.rs similarity index 100% rename from src/browser/prompt.rs rename to crates/claude-code-rs/src/browser/prompt.rs diff --git a/src/browser/session.rs b/crates/claude-code-rs/src/browser/session.rs similarity index 100% rename from src/browser/session.rs rename to crates/claude-code-rs/src/browser/session.rs diff --git a/src/browser/setup.rs b/crates/claude-code-rs/src/browser/setup.rs similarity index 100% rename from src/browser/setup.rs rename to crates/claude-code-rs/src/browser/setup.rs diff --git a/src/browser/state.rs b/crates/claude-code-rs/src/browser/state.rs similarity index 100% rename from src/browser/state.rs rename to crates/claude-code-rs/src/browser/state.rs diff --git a/src/browser/tool_rendering.rs b/crates/claude-code-rs/src/browser/tool_rendering.rs similarity index 100% rename from src/browser/tool_rendering.rs rename to crates/claude-code-rs/src/browser/tool_rendering.rs diff --git a/src/browser/transport.rs b/crates/claude-code-rs/src/browser/transport.rs similarity index 100% rename from src/browser/transport.rs rename to crates/claude-code-rs/src/browser/transport.rs diff --git a/src/cli.rs b/crates/claude-code-rs/src/cli.rs similarity index 100% rename from src/cli.rs rename to crates/claude-code-rs/src/cli.rs diff --git a/src/commands/add_dir.rs b/crates/claude-code-rs/src/commands/add_dir.rs similarity index 100% rename from src/commands/add_dir.rs rename to crates/claude-code-rs/src/commands/add_dir.rs diff --git a/src/commands/agents_cmd.rs b/crates/claude-code-rs/src/commands/agents_cmd.rs similarity index 100% rename from src/commands/agents_cmd.rs rename to crates/claude-code-rs/src/commands/agents_cmd.rs diff --git a/src/commands/assistant.rs b/crates/claude-code-rs/src/commands/assistant.rs similarity index 100% rename from src/commands/assistant.rs rename to crates/claude-code-rs/src/commands/assistant.rs diff --git a/src/commands/audit_export.rs b/crates/claude-code-rs/src/commands/audit_export.rs similarity index 100% rename from src/commands/audit_export.rs rename to crates/claude-code-rs/src/commands/audit_export.rs diff --git a/src/commands/branch.rs b/crates/claude-code-rs/src/commands/branch.rs similarity index 100% rename from src/commands/branch.rs rename to crates/claude-code-rs/src/commands/branch.rs diff --git a/src/commands/brief.rs b/crates/claude-code-rs/src/commands/brief.rs similarity index 100% rename from src/commands/brief.rs rename to crates/claude-code-rs/src/commands/brief.rs diff --git a/src/commands/channels.rs b/crates/claude-code-rs/src/commands/channels.rs similarity index 100% rename from src/commands/channels.rs rename to crates/claude-code-rs/src/commands/channels.rs diff --git a/src/commands/chrome_cmd.rs b/crates/claude-code-rs/src/commands/chrome_cmd.rs similarity index 100% rename from src/commands/chrome_cmd.rs rename to crates/claude-code-rs/src/commands/chrome_cmd.rs diff --git a/src/commands/clear.rs b/crates/claude-code-rs/src/commands/clear.rs similarity index 100% rename from src/commands/clear.rs rename to crates/claude-code-rs/src/commands/clear.rs diff --git a/src/commands/commit.rs b/crates/claude-code-rs/src/commands/commit.rs similarity index 100% rename from src/commands/commit.rs rename to crates/claude-code-rs/src/commands/commit.rs diff --git a/src/commands/compact.rs b/crates/claude-code-rs/src/commands/compact.rs similarity index 100% rename from src/commands/compact.rs rename to crates/claude-code-rs/src/commands/compact.rs diff --git a/src/commands/config_cmd.rs b/crates/claude-code-rs/src/commands/config_cmd.rs similarity index 100% rename from src/commands/config_cmd.rs rename to crates/claude-code-rs/src/commands/config_cmd.rs diff --git a/src/commands/context.rs b/crates/claude-code-rs/src/commands/context.rs similarity index 100% rename from src/commands/context.rs rename to crates/claude-code-rs/src/commands/context.rs diff --git a/src/commands/copy.rs b/crates/claude-code-rs/src/commands/copy.rs similarity index 100% rename from src/commands/copy.rs rename to crates/claude-code-rs/src/commands/copy.rs diff --git a/src/commands/cost.rs b/crates/claude-code-rs/src/commands/cost.rs similarity index 100% rename from src/commands/cost.rs rename to crates/claude-code-rs/src/commands/cost.rs diff --git a/src/commands/daemon_cmd.rs b/crates/claude-code-rs/src/commands/daemon_cmd.rs similarity index 100% rename from src/commands/daemon_cmd.rs rename to crates/claude-code-rs/src/commands/daemon_cmd.rs diff --git a/src/commands/diff.rs b/crates/claude-code-rs/src/commands/diff.rs similarity index 100% rename from src/commands/diff.rs rename to crates/claude-code-rs/src/commands/diff.rs diff --git a/src/commands/doctor.rs b/crates/claude-code-rs/src/commands/doctor.rs similarity index 100% rename from src/commands/doctor.rs rename to crates/claude-code-rs/src/commands/doctor.rs diff --git a/src/commands/dream.rs b/crates/claude-code-rs/src/commands/dream.rs similarity index 100% rename from src/commands/dream.rs rename to crates/claude-code-rs/src/commands/dream.rs diff --git a/src/commands/effort.rs b/crates/claude-code-rs/src/commands/effort.rs similarity index 100% rename from src/commands/effort.rs rename to crates/claude-code-rs/src/commands/effort.rs diff --git a/src/commands/exit.rs b/crates/claude-code-rs/src/commands/exit.rs similarity index 100% rename from src/commands/exit.rs rename to crates/claude-code-rs/src/commands/exit.rs diff --git a/src/commands/export.rs b/crates/claude-code-rs/src/commands/export.rs similarity index 100% rename from src/commands/export.rs rename to crates/claude-code-rs/src/commands/export.rs diff --git a/src/commands/extra_usage.rs b/crates/claude-code-rs/src/commands/extra_usage.rs similarity index 100% rename from src/commands/extra_usage.rs rename to crates/claude-code-rs/src/commands/extra_usage.rs diff --git a/src/commands/fast.rs b/crates/claude-code-rs/src/commands/fast.rs similarity index 100% rename from src/commands/fast.rs rename to crates/claude-code-rs/src/commands/fast.rs diff --git a/src/commands/files.rs b/crates/claude-code-rs/src/commands/files.rs similarity index 100% rename from src/commands/files.rs rename to crates/claude-code-rs/src/commands/files.rs diff --git a/src/commands/help.rs b/crates/claude-code-rs/src/commands/help.rs similarity index 100% rename from src/commands/help.rs rename to crates/claude-code-rs/src/commands/help.rs diff --git a/src/commands/hooks_cmd.rs b/crates/claude-code-rs/src/commands/hooks_cmd.rs similarity index 100% rename from src/commands/hooks_cmd.rs rename to crates/claude-code-rs/src/commands/hooks_cmd.rs diff --git a/src/commands/init.rs b/crates/claude-code-rs/src/commands/init.rs similarity index 100% rename from src/commands/init.rs rename to crates/claude-code-rs/src/commands/init.rs diff --git a/src/commands/insights.rs b/crates/claude-code-rs/src/commands/insights.rs similarity index 100% rename from src/commands/insights.rs rename to crates/claude-code-rs/src/commands/insights.rs diff --git a/src/commands/keybindings_cmd.rs b/crates/claude-code-rs/src/commands/keybindings_cmd.rs similarity index 100% rename from src/commands/keybindings_cmd.rs rename to crates/claude-code-rs/src/commands/keybindings_cmd.rs diff --git a/src/commands/login.rs b/crates/claude-code-rs/src/commands/login.rs similarity index 100% rename from src/commands/login.rs rename to crates/claude-code-rs/src/commands/login.rs diff --git a/src/commands/login_code.rs b/crates/claude-code-rs/src/commands/login_code.rs similarity index 100% rename from src/commands/login_code.rs rename to crates/claude-code-rs/src/commands/login_code.rs diff --git a/src/commands/logout.rs b/crates/claude-code-rs/src/commands/logout.rs similarity index 100% rename from src/commands/logout.rs rename to crates/claude-code-rs/src/commands/logout.rs diff --git a/src/commands/mcp_cmd.rs b/crates/claude-code-rs/src/commands/mcp_cmd.rs similarity index 100% rename from src/commands/mcp_cmd.rs rename to crates/claude-code-rs/src/commands/mcp_cmd.rs diff --git a/src/commands/memory.rs b/crates/claude-code-rs/src/commands/memory.rs similarity index 100% rename from src/commands/memory.rs rename to crates/claude-code-rs/src/commands/memory.rs diff --git a/src/commands/mod.rs b/crates/claude-code-rs/src/commands/mod.rs similarity index 100% rename from src/commands/mod.rs rename to crates/claude-code-rs/src/commands/mod.rs diff --git a/src/commands/model.rs b/crates/claude-code-rs/src/commands/model.rs similarity index 100% rename from src/commands/model.rs rename to crates/claude-code-rs/src/commands/model.rs diff --git a/src/commands/model_add.rs b/crates/claude-code-rs/src/commands/model_add.rs similarity index 100% rename from src/commands/model_add.rs rename to crates/claude-code-rs/src/commands/model_add.rs diff --git a/src/commands/notify.rs b/crates/claude-code-rs/src/commands/notify.rs similarity index 100% rename from src/commands/notify.rs rename to crates/claude-code-rs/src/commands/notify.rs diff --git a/src/commands/permissions_cmd.rs b/crates/claude-code-rs/src/commands/permissions_cmd.rs similarity index 100% rename from src/commands/permissions_cmd.rs rename to crates/claude-code-rs/src/commands/permissions_cmd.rs diff --git a/src/commands/plugin_cmd.rs b/crates/claude-code-rs/src/commands/plugin_cmd.rs similarity index 100% rename from src/commands/plugin_cmd.rs rename to crates/claude-code-rs/src/commands/plugin_cmd.rs diff --git a/src/commands/rate_limit.rs b/crates/claude-code-rs/src/commands/rate_limit.rs similarity index 100% rename from src/commands/rate_limit.rs rename to crates/claude-code-rs/src/commands/rate_limit.rs diff --git a/src/commands/recap.rs b/crates/claude-code-rs/src/commands/recap.rs similarity index 100% rename from src/commands/recap.rs rename to crates/claude-code-rs/src/commands/recap.rs diff --git a/src/commands/rename.rs b/crates/claude-code-rs/src/commands/rename.rs similarity index 100% rename from src/commands/rename.rs rename to crates/claude-code-rs/src/commands/rename.rs diff --git a/src/commands/resume.rs b/crates/claude-code-rs/src/commands/resume.rs similarity index 100% rename from src/commands/resume.rs rename to crates/claude-code-rs/src/commands/resume.rs diff --git a/src/commands/review.rs b/crates/claude-code-rs/src/commands/review.rs similarity index 100% rename from src/commands/review.rs rename to crates/claude-code-rs/src/commands/review.rs diff --git a/src/commands/rewind.rs b/crates/claude-code-rs/src/commands/rewind.rs similarity index 100% rename from src/commands/rewind.rs rename to crates/claude-code-rs/src/commands/rewind.rs diff --git a/src/commands/sandbox_cmd.rs b/crates/claude-code-rs/src/commands/sandbox_cmd.rs similarity index 100% rename from src/commands/sandbox_cmd.rs rename to crates/claude-code-rs/src/commands/sandbox_cmd.rs diff --git a/src/commands/security_review.rs b/crates/claude-code-rs/src/commands/security_review.rs similarity index 100% rename from src/commands/security_review.rs rename to crates/claude-code-rs/src/commands/security_review.rs diff --git a/src/commands/session.rs b/crates/claude-code-rs/src/commands/session.rs similarity index 100% rename from src/commands/session.rs rename to crates/claude-code-rs/src/commands/session.rs diff --git a/src/commands/session_export.rs b/crates/claude-code-rs/src/commands/session_export.rs similarity index 100% rename from src/commands/session_export.rs rename to crates/claude-code-rs/src/commands/session_export.rs diff --git a/src/commands/skills_cmd.rs b/crates/claude-code-rs/src/commands/skills_cmd.rs similarity index 100% rename from src/commands/skills_cmd.rs rename to crates/claude-code-rs/src/commands/skills_cmd.rs diff --git a/src/commands/sleep_cmd.rs b/crates/claude-code-rs/src/commands/sleep_cmd.rs similarity index 100% rename from src/commands/sleep_cmd.rs rename to crates/claude-code-rs/src/commands/sleep_cmd.rs diff --git a/src/commands/status.rs b/crates/claude-code-rs/src/commands/status.rs similarity index 100% rename from src/commands/status.rs rename to crates/claude-code-rs/src/commands/status.rs diff --git a/src/commands/statusline_cmd.rs b/crates/claude-code-rs/src/commands/statusline_cmd.rs similarity index 100% rename from src/commands/statusline_cmd.rs rename to crates/claude-code-rs/src/commands/statusline_cmd.rs diff --git a/src/commands/tasks_cmd.rs b/crates/claude-code-rs/src/commands/tasks_cmd.rs similarity index 100% rename from src/commands/tasks_cmd.rs rename to crates/claude-code-rs/src/commands/tasks_cmd.rs diff --git a/src/commands/team_cmd.rs b/crates/claude-code-rs/src/commands/team_cmd.rs similarity index 100% rename from src/commands/team_cmd.rs rename to crates/claude-code-rs/src/commands/team_cmd.rs diff --git a/src/commands/terminal_setup.rs b/crates/claude-code-rs/src/commands/terminal_setup.rs similarity index 100% rename from src/commands/terminal_setup.rs rename to crates/claude-code-rs/src/commands/terminal_setup.rs diff --git a/src/commands/version.rs b/crates/claude-code-rs/src/commands/version.rs similarity index 100% rename from src/commands/version.rs rename to crates/claude-code-rs/src/commands/version.rs diff --git a/src/commands/voice_cmd.rs b/crates/claude-code-rs/src/commands/voice_cmd.rs similarity index 100% rename from src/commands/voice_cmd.rs rename to crates/claude-code-rs/src/commands/voice_cmd.rs diff --git a/src/compact/auto_compact.rs b/crates/claude-code-rs/src/compact/auto_compact.rs similarity index 100% rename from src/compact/auto_compact.rs rename to crates/claude-code-rs/src/compact/auto_compact.rs diff --git a/src/compact/compaction.rs b/crates/claude-code-rs/src/compact/compaction.rs similarity index 100% rename from src/compact/compaction.rs rename to crates/claude-code-rs/src/compact/compaction.rs diff --git a/src/compact/messages.rs b/crates/claude-code-rs/src/compact/messages.rs similarity index 100% rename from src/compact/messages.rs rename to crates/claude-code-rs/src/compact/messages.rs diff --git a/src/compact/microcompact.rs b/crates/claude-code-rs/src/compact/microcompact.rs similarity index 100% rename from src/compact/microcompact.rs rename to crates/claude-code-rs/src/compact/microcompact.rs diff --git a/src/compact/mod.rs b/crates/claude-code-rs/src/compact/mod.rs similarity index 100% rename from src/compact/mod.rs rename to crates/claude-code-rs/src/compact/mod.rs diff --git a/src/compact/pipeline.rs b/crates/claude-code-rs/src/compact/pipeline.rs similarity index 100% rename from src/compact/pipeline.rs rename to crates/claude-code-rs/src/compact/pipeline.rs diff --git a/src/compact/snip.rs b/crates/claude-code-rs/src/compact/snip.rs similarity index 100% rename from src/compact/snip.rs rename to crates/claude-code-rs/src/compact/snip.rs diff --git a/src/compact/tool_result_budget.rs b/crates/claude-code-rs/src/compact/tool_result_budget.rs similarity index 100% rename from src/compact/tool_result_budget.rs rename to crates/claude-code-rs/src/compact/tool_result_budget.rs diff --git a/src/computer_use/detection.rs b/crates/claude-code-rs/src/computer_use/detection.rs similarity index 100% rename from src/computer_use/detection.rs rename to crates/claude-code-rs/src/computer_use/detection.rs diff --git a/src/computer_use/input/darwin.rs b/crates/claude-code-rs/src/computer_use/input/darwin.rs similarity index 100% rename from src/computer_use/input/darwin.rs rename to crates/claude-code-rs/src/computer_use/input/darwin.rs diff --git a/src/computer_use/input/linux.rs b/crates/claude-code-rs/src/computer_use/input/linux.rs similarity index 100% rename from src/computer_use/input/linux.rs rename to crates/claude-code-rs/src/computer_use/input/linux.rs diff --git a/src/computer_use/input/mod.rs b/crates/claude-code-rs/src/computer_use/input/mod.rs similarity index 100% rename from src/computer_use/input/mod.rs rename to crates/claude-code-rs/src/computer_use/input/mod.rs diff --git a/src/computer_use/input/win32.rs b/crates/claude-code-rs/src/computer_use/input/win32.rs similarity index 100% rename from src/computer_use/input/win32.rs rename to crates/claude-code-rs/src/computer_use/input/win32.rs diff --git a/src/computer_use/mod.rs b/crates/claude-code-rs/src/computer_use/mod.rs similarity index 100% rename from src/computer_use/mod.rs rename to crates/claude-code-rs/src/computer_use/mod.rs diff --git a/src/computer_use/screenshot/darwin.rs b/crates/claude-code-rs/src/computer_use/screenshot/darwin.rs similarity index 100% rename from src/computer_use/screenshot/darwin.rs rename to crates/claude-code-rs/src/computer_use/screenshot/darwin.rs diff --git a/src/computer_use/screenshot/linux.rs b/crates/claude-code-rs/src/computer_use/screenshot/linux.rs similarity index 100% rename from src/computer_use/screenshot/linux.rs rename to crates/claude-code-rs/src/computer_use/screenshot/linux.rs diff --git a/src/computer_use/screenshot/mod.rs b/crates/claude-code-rs/src/computer_use/screenshot/mod.rs similarity index 100% rename from src/computer_use/screenshot/mod.rs rename to crates/claude-code-rs/src/computer_use/screenshot/mod.rs diff --git a/src/computer_use/screenshot/win32.rs b/crates/claude-code-rs/src/computer_use/screenshot/win32.rs similarity index 100% rename from src/computer_use/screenshot/win32.rs rename to crates/claude-code-rs/src/computer_use/screenshot/win32.rs diff --git a/src/computer_use/setup.rs b/crates/claude-code-rs/src/computer_use/setup.rs similarity index 100% rename from src/computer_use/setup.rs rename to crates/claude-code-rs/src/computer_use/setup.rs diff --git a/src/computer_use/tools.rs b/crates/claude-code-rs/src/computer_use/tools.rs similarity index 100% rename from src/computer_use/tools.rs rename to crates/claude-code-rs/src/computer_use/tools.rs diff --git a/src/config/claude_md.rs b/crates/claude-code-rs/src/config/claude_md.rs similarity index 100% rename from src/config/claude_md.rs rename to crates/claude-code-rs/src/config/claude_md.rs diff --git a/src/config/constants.rs b/crates/claude-code-rs/src/config/constants.rs similarity index 100% rename from src/config/constants.rs rename to crates/claude-code-rs/src/config/constants.rs diff --git a/src/config/features.rs b/crates/claude-code-rs/src/config/features.rs similarity index 100% rename from src/config/features.rs rename to crates/claude-code-rs/src/config/features.rs diff --git a/src/config/mod.rs b/crates/claude-code-rs/src/config/mod.rs similarity index 100% rename from src/config/mod.rs rename to crates/claude-code-rs/src/config/mod.rs diff --git a/src/config/paths.rs b/crates/claude-code-rs/src/config/paths.rs similarity index 100% rename from src/config/paths.rs rename to crates/claude-code-rs/src/config/paths.rs diff --git a/src/config/settings.rs b/crates/claude-code-rs/src/config/settings.rs similarity index 99% rename from src/config/settings.rs rename to crates/claude-code-rs/src/config/settings.rs index 85753f48..adc59a16 100644 --- a/src/config/settings.rs +++ b/crates/claude-code-rs/src/config/settings.rs @@ -1423,7 +1423,10 @@ mod tests { /// `cargo test schema_file_matches_runtime -- --ignored` (then update). #[test] fn schema_file_matches_runtime() { + // docs/ lives at the workspace root, two levels above the crate. let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("..") .join("docs") .join("schemas") .join("settings.schema.json"); diff --git a/src/config/validation.rs b/crates/claude-code-rs/src/config/validation.rs similarity index 100% rename from src/config/validation.rs rename to crates/claude-code-rs/src/config/validation.rs diff --git a/src/daemon/channels.rs b/crates/claude-code-rs/src/daemon/channels.rs similarity index 100% rename from src/daemon/channels.rs rename to crates/claude-code-rs/src/daemon/channels.rs diff --git a/src/daemon/memory_log.rs b/crates/claude-code-rs/src/daemon/memory_log.rs similarity index 100% rename from src/daemon/memory_log.rs rename to crates/claude-code-rs/src/daemon/memory_log.rs diff --git a/src/daemon/mod.rs b/crates/claude-code-rs/src/daemon/mod.rs similarity index 100% rename from src/daemon/mod.rs rename to crates/claude-code-rs/src/daemon/mod.rs diff --git a/src/daemon/notification.rs b/crates/claude-code-rs/src/daemon/notification.rs similarity index 100% rename from src/daemon/notification.rs rename to crates/claude-code-rs/src/daemon/notification.rs diff --git a/src/daemon/routes.rs b/crates/claude-code-rs/src/daemon/routes.rs similarity index 100% rename from src/daemon/routes.rs rename to crates/claude-code-rs/src/daemon/routes.rs diff --git a/src/daemon/server.rs b/crates/claude-code-rs/src/daemon/server.rs similarity index 100% rename from src/daemon/server.rs rename to crates/claude-code-rs/src/daemon/server.rs diff --git a/src/daemon/sse.rs b/crates/claude-code-rs/src/daemon/sse.rs similarity index 100% rename from src/daemon/sse.rs rename to crates/claude-code-rs/src/daemon/sse.rs diff --git a/src/daemon/state.rs b/crates/claude-code-rs/src/daemon/state.rs similarity index 100% rename from src/daemon/state.rs rename to crates/claude-code-rs/src/daemon/state.rs diff --git a/src/daemon/team_memory_proxy.rs b/crates/claude-code-rs/src/daemon/team_memory_proxy.rs similarity index 100% rename from src/daemon/team_memory_proxy.rs rename to crates/claude-code-rs/src/daemon/team_memory_proxy.rs diff --git a/src/daemon/tick.rs b/crates/claude-code-rs/src/daemon/tick.rs similarity index 100% rename from src/daemon/tick.rs rename to crates/claude-code-rs/src/daemon/tick.rs diff --git a/src/daemon/webhook.rs b/crates/claude-code-rs/src/daemon/webhook.rs similarity index 100% rename from src/daemon/webhook.rs rename to crates/claude-code-rs/src/daemon/webhook.rs diff --git a/src/dashboard.rs b/crates/claude-code-rs/src/dashboard.rs similarity index 100% rename from src/dashboard.rs rename to crates/claude-code-rs/src/dashboard.rs diff --git a/src/engine/codex_exec.rs b/crates/claude-code-rs/src/engine/codex_exec.rs similarity index 100% rename from src/engine/codex_exec.rs rename to crates/claude-code-rs/src/engine/codex_exec.rs diff --git a/src/engine/effort.rs b/crates/claude-code-rs/src/engine/effort.rs similarity index 100% rename from src/engine/effort.rs rename to crates/claude-code-rs/src/engine/effort.rs diff --git a/src/engine/input_processing.rs b/crates/claude-code-rs/src/engine/input_processing.rs similarity index 100% rename from src/engine/input_processing.rs rename to crates/claude-code-rs/src/engine/input_processing.rs diff --git a/src/engine/lifecycle/deps.rs b/crates/claude-code-rs/src/engine/lifecycle/deps.rs similarity index 100% rename from src/engine/lifecycle/deps.rs rename to crates/claude-code-rs/src/engine/lifecycle/deps.rs diff --git a/src/engine/lifecycle/helpers.rs b/crates/claude-code-rs/src/engine/lifecycle/helpers.rs similarity index 100% rename from src/engine/lifecycle/helpers.rs rename to crates/claude-code-rs/src/engine/lifecycle/helpers.rs diff --git a/src/engine/lifecycle/mod.rs b/crates/claude-code-rs/src/engine/lifecycle/mod.rs similarity index 100% rename from src/engine/lifecycle/mod.rs rename to crates/claude-code-rs/src/engine/lifecycle/mod.rs diff --git a/src/engine/lifecycle/submit_message.rs b/crates/claude-code-rs/src/engine/lifecycle/submit_message.rs similarity index 100% rename from src/engine/lifecycle/submit_message.rs rename to crates/claude-code-rs/src/engine/lifecycle/submit_message.rs diff --git a/src/engine/lifecycle/tests.rs b/crates/claude-code-rs/src/engine/lifecycle/tests.rs similarity index 100% rename from src/engine/lifecycle/tests.rs rename to crates/claude-code-rs/src/engine/lifecycle/tests.rs diff --git a/src/engine/lifecycle/types.rs b/crates/claude-code-rs/src/engine/lifecycle/types.rs similarity index 100% rename from src/engine/lifecycle/types.rs rename to crates/claude-code-rs/src/engine/lifecycle/types.rs diff --git a/src/engine/mod.rs b/crates/claude-code-rs/src/engine/mod.rs similarity index 100% rename from src/engine/mod.rs rename to crates/claude-code-rs/src/engine/mod.rs diff --git a/src/engine/output_style.rs b/crates/claude-code-rs/src/engine/output_style.rs similarity index 100% rename from src/engine/output_style.rs rename to crates/claude-code-rs/src/engine/output_style.rs diff --git a/src/engine/prompt_sections.rs b/crates/claude-code-rs/src/engine/prompt_sections.rs similarity index 100% rename from src/engine/prompt_sections.rs rename to crates/claude-code-rs/src/engine/prompt_sections.rs diff --git a/src/engine/result.rs b/crates/claude-code-rs/src/engine/result.rs similarity index 100% rename from src/engine/result.rs rename to crates/claude-code-rs/src/engine/result.rs diff --git a/src/engine/sdk_types.rs b/crates/claude-code-rs/src/engine/sdk_types.rs similarity index 100% rename from src/engine/sdk_types.rs rename to crates/claude-code-rs/src/engine/sdk_types.rs diff --git a/src/engine/system_prompt.rs b/crates/claude-code-rs/src/engine/system_prompt.rs similarity index 100% rename from src/engine/system_prompt.rs rename to crates/claude-code-rs/src/engine/system_prompt.rs diff --git a/src/ipc/agent_channel.rs b/crates/claude-code-rs/src/ipc/agent_channel.rs similarity index 100% rename from src/ipc/agent_channel.rs rename to crates/claude-code-rs/src/ipc/agent_channel.rs diff --git a/src/ipc/agent_events.rs b/crates/claude-code-rs/src/ipc/agent_events.rs similarity index 100% rename from src/ipc/agent_events.rs rename to crates/claude-code-rs/src/ipc/agent_events.rs diff --git a/src/ipc/agent_handlers.rs b/crates/claude-code-rs/src/ipc/agent_handlers.rs similarity index 100% rename from src/ipc/agent_handlers.rs rename to crates/claude-code-rs/src/ipc/agent_handlers.rs diff --git a/src/ipc/agent_tree.rs b/crates/claude-code-rs/src/ipc/agent_tree.rs similarity index 100% rename from src/ipc/agent_tree.rs rename to crates/claude-code-rs/src/ipc/agent_tree.rs diff --git a/src/ipc/agent_types.rs b/crates/claude-code-rs/src/ipc/agent_types.rs similarity index 100% rename from src/ipc/agent_types.rs rename to crates/claude-code-rs/src/ipc/agent_types.rs diff --git a/src/ipc/callbacks.rs b/crates/claude-code-rs/src/ipc/callbacks.rs similarity index 100% rename from src/ipc/callbacks.rs rename to crates/claude-code-rs/src/ipc/callbacks.rs diff --git a/src/ipc/headless.rs b/crates/claude-code-rs/src/ipc/headless.rs similarity index 100% rename from src/ipc/headless.rs rename to crates/claude-code-rs/src/ipc/headless.rs diff --git a/src/ipc/ingress.rs b/crates/claude-code-rs/src/ipc/ingress.rs similarity index 100% rename from src/ipc/ingress.rs rename to crates/claude-code-rs/src/ipc/ingress.rs diff --git a/src/ipc/mod.rs b/crates/claude-code-rs/src/ipc/mod.rs similarity index 100% rename from src/ipc/mod.rs rename to crates/claude-code-rs/src/ipc/mod.rs diff --git a/src/ipc/protocol/agent.rs b/crates/claude-code-rs/src/ipc/protocol/agent.rs similarity index 100% rename from src/ipc/protocol/agent.rs rename to crates/claude-code-rs/src/ipc/protocol/agent.rs diff --git a/src/ipc/protocol/base.rs b/crates/claude-code-rs/src/ipc/protocol/base.rs similarity index 100% rename from src/ipc/protocol/base.rs rename to crates/claude-code-rs/src/ipc/protocol/base.rs diff --git a/src/ipc/protocol/mod.rs b/crates/claude-code-rs/src/ipc/protocol/mod.rs similarity index 100% rename from src/ipc/protocol/mod.rs rename to crates/claude-code-rs/src/ipc/protocol/mod.rs diff --git a/src/ipc/protocol/subsystem.rs b/crates/claude-code-rs/src/ipc/protocol/subsystem.rs similarity index 100% rename from src/ipc/protocol/subsystem.rs rename to crates/claude-code-rs/src/ipc/protocol/subsystem.rs diff --git a/src/ipc/protocol/team.rs b/crates/claude-code-rs/src/ipc/protocol/team.rs similarity index 100% rename from src/ipc/protocol/team.rs rename to crates/claude-code-rs/src/ipc/protocol/team.rs diff --git a/src/ipc/query_runner.rs b/crates/claude-code-rs/src/ipc/query_runner.rs similarity index 100% rename from src/ipc/query_runner.rs rename to crates/claude-code-rs/src/ipc/query_runner.rs diff --git a/src/ipc/runtime.rs b/crates/claude-code-rs/src/ipc/runtime.rs similarity index 100% rename from src/ipc/runtime.rs rename to crates/claude-code-rs/src/ipc/runtime.rs diff --git a/src/ipc/sdk_mapper.rs b/crates/claude-code-rs/src/ipc/sdk_mapper.rs similarity index 100% rename from src/ipc/sdk_mapper.rs rename to crates/claude-code-rs/src/ipc/sdk_mapper.rs diff --git a/src/ipc/sink.rs b/crates/claude-code-rs/src/ipc/sink.rs similarity index 100% rename from src/ipc/sink.rs rename to crates/claude-code-rs/src/ipc/sink.rs diff --git a/src/ipc/subsystem_events.rs b/crates/claude-code-rs/src/ipc/subsystem_events.rs similarity index 100% rename from src/ipc/subsystem_events.rs rename to crates/claude-code-rs/src/ipc/subsystem_events.rs diff --git a/src/ipc/subsystem_handlers.rs b/crates/claude-code-rs/src/ipc/subsystem_handlers.rs similarity index 100% rename from src/ipc/subsystem_handlers.rs rename to crates/claude-code-rs/src/ipc/subsystem_handlers.rs diff --git a/src/ipc/subsystem_types.rs b/crates/claude-code-rs/src/ipc/subsystem_types.rs similarity index 100% rename from src/ipc/subsystem_types.rs rename to crates/claude-code-rs/src/ipc/subsystem_types.rs diff --git a/src/keybindings/action.rs b/crates/claude-code-rs/src/keybindings/action.rs similarity index 100% rename from src/keybindings/action.rs rename to crates/claude-code-rs/src/keybindings/action.rs diff --git a/src/keybindings/config.rs b/crates/claude-code-rs/src/keybindings/config.rs similarity index 100% rename from src/keybindings/config.rs rename to crates/claude-code-rs/src/keybindings/config.rs diff --git a/src/keybindings/context.rs b/crates/claude-code-rs/src/keybindings/context.rs similarity index 100% rename from src/keybindings/context.rs rename to crates/claude-code-rs/src/keybindings/context.rs diff --git a/src/keybindings/defaults.rs b/crates/claude-code-rs/src/keybindings/defaults.rs similarity index 100% rename from src/keybindings/defaults.rs rename to crates/claude-code-rs/src/keybindings/defaults.rs diff --git a/src/keybindings/keystroke.rs b/crates/claude-code-rs/src/keybindings/keystroke.rs similarity index 100% rename from src/keybindings/keystroke.rs rename to crates/claude-code-rs/src/keybindings/keystroke.rs diff --git a/src/keybindings/mod.rs b/crates/claude-code-rs/src/keybindings/mod.rs similarity index 100% rename from src/keybindings/mod.rs rename to crates/claude-code-rs/src/keybindings/mod.rs diff --git a/src/keybindings/registry.rs b/crates/claude-code-rs/src/keybindings/registry.rs similarity index 100% rename from src/keybindings/registry.rs rename to crates/claude-code-rs/src/keybindings/registry.rs diff --git a/src/lsp_service/client.rs b/crates/claude-code-rs/src/lsp_service/client.rs similarity index 100% rename from src/lsp_service/client.rs rename to crates/claude-code-rs/src/lsp_service/client.rs diff --git a/src/lsp_service/conversions/mod.rs b/crates/claude-code-rs/src/lsp_service/conversions/mod.rs similarity index 100% rename from src/lsp_service/conversions/mod.rs rename to crates/claude-code-rs/src/lsp_service/conversions/mod.rs diff --git a/src/lsp_service/conversions/tests.rs b/crates/claude-code-rs/src/lsp_service/conversions/tests.rs similarity index 100% rename from src/lsp_service/conversions/tests.rs rename to crates/claude-code-rs/src/lsp_service/conversions/tests.rs diff --git a/src/lsp_service/mod.rs b/crates/claude-code-rs/src/lsp_service/mod.rs similarity index 100% rename from src/lsp_service/mod.rs rename to crates/claude-code-rs/src/lsp_service/mod.rs diff --git a/src/lsp_service/transport.rs b/crates/claude-code-rs/src/lsp_service/transport.rs similarity index 100% rename from src/lsp_service/transport.rs rename to crates/claude-code-rs/src/lsp_service/transport.rs diff --git a/src/main.rs b/crates/claude-code-rs/src/main.rs similarity index 100% rename from src/main.rs rename to crates/claude-code-rs/src/main.rs diff --git a/src/mcp/channel.rs b/crates/claude-code-rs/src/mcp/channel.rs similarity index 100% rename from src/mcp/channel.rs rename to crates/claude-code-rs/src/mcp/channel.rs diff --git a/src/mcp/client.rs b/crates/claude-code-rs/src/mcp/client.rs similarity index 100% rename from src/mcp/client.rs rename to crates/claude-code-rs/src/mcp/client.rs diff --git a/src/mcp/client_tests.rs b/crates/claude-code-rs/src/mcp/client_tests.rs similarity index 100% rename from src/mcp/client_tests.rs rename to crates/claude-code-rs/src/mcp/client_tests.rs diff --git a/src/mcp/discovery.rs b/crates/claude-code-rs/src/mcp/discovery.rs similarity index 100% rename from src/mcp/discovery.rs rename to crates/claude-code-rs/src/mcp/discovery.rs diff --git a/src/mcp/manager.rs b/crates/claude-code-rs/src/mcp/manager.rs similarity index 100% rename from src/mcp/manager.rs rename to crates/claude-code-rs/src/mcp/manager.rs diff --git a/src/mcp/mod.rs b/crates/claude-code-rs/src/mcp/mod.rs similarity index 100% rename from src/mcp/mod.rs rename to crates/claude-code-rs/src/mcp/mod.rs diff --git a/src/mcp/tools.rs b/crates/claude-code-rs/src/mcp/tools.rs similarity index 100% rename from src/mcp/tools.rs rename to crates/claude-code-rs/src/mcp/tools.rs diff --git a/src/mcp/transport.rs b/crates/claude-code-rs/src/mcp/transport.rs similarity index 100% rename from src/mcp/transport.rs rename to crates/claude-code-rs/src/mcp/transport.rs diff --git a/src/observability/context.rs b/crates/claude-code-rs/src/observability/context.rs similarity index 100% rename from src/observability/context.rs rename to crates/claude-code-rs/src/observability/context.rs diff --git a/src/observability/event.rs b/crates/claude-code-rs/src/observability/event.rs similarity index 100% rename from src/observability/event.rs rename to crates/claude-code-rs/src/observability/event.rs diff --git a/src/observability/mod.rs b/crates/claude-code-rs/src/observability/mod.rs similarity index 100% rename from src/observability/mod.rs rename to crates/claude-code-rs/src/observability/mod.rs diff --git a/src/observability/sink.rs b/crates/claude-code-rs/src/observability/sink.rs similarity index 100% rename from src/observability/sink.rs rename to crates/claude-code-rs/src/observability/sink.rs diff --git a/src/permissions/bash_matcher.rs b/crates/claude-code-rs/src/permissions/bash_matcher.rs similarity index 100% rename from src/permissions/bash_matcher.rs rename to crates/claude-code-rs/src/permissions/bash_matcher.rs diff --git a/src/permissions/dangerous.rs b/crates/claude-code-rs/src/permissions/dangerous.rs similarity index 100% rename from src/permissions/dangerous.rs rename to crates/claude-code-rs/src/permissions/dangerous.rs diff --git a/src/permissions/decision.rs b/crates/claude-code-rs/src/permissions/decision.rs similarity index 100% rename from src/permissions/decision.rs rename to crates/claude-code-rs/src/permissions/decision.rs diff --git a/src/permissions/mod.rs b/crates/claude-code-rs/src/permissions/mod.rs similarity index 100% rename from src/permissions/mod.rs rename to crates/claude-code-rs/src/permissions/mod.rs diff --git a/src/permissions/path_validation.rs b/crates/claude-code-rs/src/permissions/path_validation.rs similarity index 100% rename from src/permissions/path_validation.rs rename to crates/claude-code-rs/src/permissions/path_validation.rs diff --git a/src/permissions/rules.rs b/crates/claude-code-rs/src/permissions/rules.rs similarity index 100% rename from src/permissions/rules.rs rename to crates/claude-code-rs/src/permissions/rules.rs diff --git a/src/plugins/loader.rs b/crates/claude-code-rs/src/plugins/loader.rs similarity index 100% rename from src/plugins/loader.rs rename to crates/claude-code-rs/src/plugins/loader.rs diff --git a/src/plugins/manifest.rs b/crates/claude-code-rs/src/plugins/manifest.rs similarity index 100% rename from src/plugins/manifest.rs rename to crates/claude-code-rs/src/plugins/manifest.rs diff --git a/src/plugins/mod.rs b/crates/claude-code-rs/src/plugins/mod.rs similarity index 100% rename from src/plugins/mod.rs rename to crates/claude-code-rs/src/plugins/mod.rs diff --git a/src/plugins/tools.rs b/crates/claude-code-rs/src/plugins/tools.rs similarity index 100% rename from src/plugins/tools.rs rename to crates/claude-code-rs/src/plugins/tools.rs diff --git a/src/query/deps.rs b/crates/claude-code-rs/src/query/deps.rs similarity index 100% rename from src/query/deps.rs rename to crates/claude-code-rs/src/query/deps.rs diff --git a/src/query/loop_helpers.rs b/crates/claude-code-rs/src/query/loop_helpers.rs similarity index 100% rename from src/query/loop_helpers.rs rename to crates/claude-code-rs/src/query/loop_helpers.rs diff --git a/src/query/loop_impl.rs b/crates/claude-code-rs/src/query/loop_impl.rs similarity index 100% rename from src/query/loop_impl.rs rename to crates/claude-code-rs/src/query/loop_impl.rs diff --git a/src/query/loop_tests.rs b/crates/claude-code-rs/src/query/loop_tests.rs similarity index 100% rename from src/query/loop_tests.rs rename to crates/claude-code-rs/src/query/loop_tests.rs diff --git a/src/query/mod.rs b/crates/claude-code-rs/src/query/mod.rs similarity index 100% rename from src/query/mod.rs rename to crates/claude-code-rs/src/query/mod.rs diff --git a/src/query/stop_hooks.rs b/crates/claude-code-rs/src/query/stop_hooks.rs similarity index 100% rename from src/query/stop_hooks.rs rename to crates/claude-code-rs/src/query/stop_hooks.rs diff --git a/src/query/token_budget.rs b/crates/claude-code-rs/src/query/token_budget.rs similarity index 100% rename from src/query/token_budget.rs rename to crates/claude-code-rs/src/query/token_budget.rs diff --git a/src/sandbox/availability.rs b/crates/claude-code-rs/src/sandbox/availability.rs similarity index 100% rename from src/sandbox/availability.rs rename to crates/claude-code-rs/src/sandbox/availability.rs diff --git a/src/sandbox/errors.rs b/crates/claude-code-rs/src/sandbox/errors.rs similarity index 100% rename from src/sandbox/errors.rs rename to crates/claude-code-rs/src/sandbox/errors.rs diff --git a/src/sandbox/filesystem.rs b/crates/claude-code-rs/src/sandbox/filesystem.rs similarity index 100% rename from src/sandbox/filesystem.rs rename to crates/claude-code-rs/src/sandbox/filesystem.rs diff --git a/src/sandbox/mod.rs b/crates/claude-code-rs/src/sandbox/mod.rs similarity index 100% rename from src/sandbox/mod.rs rename to crates/claude-code-rs/src/sandbox/mod.rs diff --git a/src/sandbox/mode.rs b/crates/claude-code-rs/src/sandbox/mode.rs similarity index 100% rename from src/sandbox/mode.rs rename to crates/claude-code-rs/src/sandbox/mode.rs diff --git a/src/sandbox/network.rs b/crates/claude-code-rs/src/sandbox/network.rs similarity index 100% rename from src/sandbox/network.rs rename to crates/claude-code-rs/src/sandbox/network.rs diff --git a/src/sandbox/policy.rs b/crates/claude-code-rs/src/sandbox/policy.rs similarity index 100% rename from src/sandbox/policy.rs rename to crates/claude-code-rs/src/sandbox/policy.rs diff --git a/src/sandbox/runner.rs b/crates/claude-code-rs/src/sandbox/runner.rs similarity index 100% rename from src/sandbox/runner.rs rename to crates/claude-code-rs/src/sandbox/runner.rs diff --git a/src/services/langfuse/client.rs b/crates/claude-code-rs/src/services/langfuse/client.rs similarity index 100% rename from src/services/langfuse/client.rs rename to crates/claude-code-rs/src/services/langfuse/client.rs diff --git a/src/services/langfuse/convert.rs b/crates/claude-code-rs/src/services/langfuse/convert.rs similarity index 100% rename from src/services/langfuse/convert.rs rename to crates/claude-code-rs/src/services/langfuse/convert.rs diff --git a/src/services/langfuse/mod.rs b/crates/claude-code-rs/src/services/langfuse/mod.rs similarity index 100% rename from src/services/langfuse/mod.rs rename to crates/claude-code-rs/src/services/langfuse/mod.rs diff --git a/src/services/langfuse/sanitize.rs b/crates/claude-code-rs/src/services/langfuse/sanitize.rs similarity index 100% rename from src/services/langfuse/sanitize.rs rename to crates/claude-code-rs/src/services/langfuse/sanitize.rs diff --git a/src/services/langfuse/stub.rs b/crates/claude-code-rs/src/services/langfuse/stub.rs similarity index 100% rename from src/services/langfuse/stub.rs rename to crates/claude-code-rs/src/services/langfuse/stub.rs diff --git a/src/services/langfuse/tracing.rs b/crates/claude-code-rs/src/services/langfuse/tracing.rs similarity index 100% rename from src/services/langfuse/tracing.rs rename to crates/claude-code-rs/src/services/langfuse/tracing.rs diff --git a/src/services/lsp_lifecycle.rs b/crates/claude-code-rs/src/services/lsp_lifecycle.rs similarity index 100% rename from src/services/lsp_lifecycle.rs rename to crates/claude-code-rs/src/services/lsp_lifecycle.rs diff --git a/src/services/mod.rs b/crates/claude-code-rs/src/services/mod.rs similarity index 100% rename from src/services/mod.rs rename to crates/claude-code-rs/src/services/mod.rs diff --git a/src/services/prompt_suggestion.rs b/crates/claude-code-rs/src/services/prompt_suggestion.rs similarity index 100% rename from src/services/prompt_suggestion.rs rename to crates/claude-code-rs/src/services/prompt_suggestion.rs diff --git a/src/services/session_analytics.rs b/crates/claude-code-rs/src/services/session_analytics.rs similarity index 100% rename from src/services/session_analytics.rs rename to crates/claude-code-rs/src/services/session_analytics.rs diff --git a/src/services/session_memory.rs b/crates/claude-code-rs/src/services/session_memory.rs similarity index 100% rename from src/services/session_memory.rs rename to crates/claude-code-rs/src/services/session_memory.rs diff --git a/src/services/tool_use_summary.rs b/crates/claude-code-rs/src/services/tool_use_summary.rs similarity index 100% rename from src/services/tool_use_summary.rs rename to crates/claude-code-rs/src/services/tool_use_summary.rs diff --git a/src/session/audit_export.rs b/crates/claude-code-rs/src/session/audit_export.rs similarity index 100% rename from src/session/audit_export.rs rename to crates/claude-code-rs/src/session/audit_export.rs diff --git a/src/session/export.rs b/crates/claude-code-rs/src/session/export.rs similarity index 100% rename from src/session/export.rs rename to crates/claude-code-rs/src/session/export.rs diff --git a/src/session/memdir.rs b/crates/claude-code-rs/src/session/memdir.rs similarity index 100% rename from src/session/memdir.rs rename to crates/claude-code-rs/src/session/memdir.rs diff --git a/src/session/migrations.rs b/crates/claude-code-rs/src/session/migrations.rs similarity index 100% rename from src/session/migrations.rs rename to crates/claude-code-rs/src/session/migrations.rs diff --git a/src/session/mod.rs b/crates/claude-code-rs/src/session/mod.rs similarity index 100% rename from src/session/mod.rs rename to crates/claude-code-rs/src/session/mod.rs diff --git a/src/session/resume.rs b/crates/claude-code-rs/src/session/resume.rs similarity index 100% rename from src/session/resume.rs rename to crates/claude-code-rs/src/session/resume.rs diff --git a/src/session/session_export/builders.rs b/crates/claude-code-rs/src/session/session_export/builders.rs similarity index 100% rename from src/session/session_export/builders.rs rename to crates/claude-code-rs/src/session/session_export/builders.rs diff --git a/src/session/session_export/compression.rs b/crates/claude-code-rs/src/session/session_export/compression.rs similarity index 100% rename from src/session/session_export/compression.rs rename to crates/claude-code-rs/src/session/session_export/compression.rs diff --git a/src/session/session_export/mod.rs b/crates/claude-code-rs/src/session/session_export/mod.rs similarity index 100% rename from src/session/session_export/mod.rs rename to crates/claude-code-rs/src/session/session_export/mod.rs diff --git a/src/session/session_export/tests.rs b/crates/claude-code-rs/src/session/session_export/tests.rs similarity index 100% rename from src/session/session_export/tests.rs rename to crates/claude-code-rs/src/session/session_export/tests.rs diff --git a/src/session/storage.rs b/crates/claude-code-rs/src/session/storage.rs similarity index 100% rename from src/session/storage.rs rename to crates/claude-code-rs/src/session/storage.rs diff --git a/src/session/transcript.rs b/crates/claude-code-rs/src/session/transcript.rs similarity index 100% rename from src/session/transcript.rs rename to crates/claude-code-rs/src/session/transcript.rs diff --git a/src/shutdown.rs b/crates/claude-code-rs/src/shutdown.rs similarity index 100% rename from src/shutdown.rs rename to crates/claude-code-rs/src/shutdown.rs diff --git a/src/skills/bundled.rs b/crates/claude-code-rs/src/skills/bundled.rs similarity index 100% rename from src/skills/bundled.rs rename to crates/claude-code-rs/src/skills/bundled.rs diff --git a/src/skills/loader.rs b/crates/claude-code-rs/src/skills/loader.rs similarity index 100% rename from src/skills/loader.rs rename to crates/claude-code-rs/src/skills/loader.rs diff --git a/src/skills/mod.rs b/crates/claude-code-rs/src/skills/mod.rs similarity index 100% rename from src/skills/mod.rs rename to crates/claude-code-rs/src/skills/mod.rs diff --git a/src/startup/fast_paths.rs b/crates/claude-code-rs/src/startup/fast_paths.rs similarity index 100% rename from src/startup/fast_paths.rs rename to crates/claude-code-rs/src/startup/fast_paths.rs diff --git a/src/startup/logging.rs b/crates/claude-code-rs/src/startup/logging.rs similarity index 100% rename from src/startup/logging.rs rename to crates/claude-code-rs/src/startup/logging.rs diff --git a/src/startup/mod.rs b/crates/claude-code-rs/src/startup/mod.rs similarity index 100% rename from src/startup/mod.rs rename to crates/claude-code-rs/src/startup/mod.rs diff --git a/src/startup/modes.rs b/crates/claude-code-rs/src/startup/modes.rs similarity index 100% rename from src/startup/modes.rs rename to crates/claude-code-rs/src/startup/modes.rs diff --git a/src/startup/runtime_config.rs b/crates/claude-code-rs/src/startup/runtime_config.rs similarity index 100% rename from src/startup/runtime_config.rs rename to crates/claude-code-rs/src/startup/runtime_config.rs diff --git a/src/teams/backend.rs b/crates/claude-code-rs/src/teams/backend.rs similarity index 100% rename from src/teams/backend.rs rename to crates/claude-code-rs/src/teams/backend.rs diff --git a/src/teams/constants.rs b/crates/claude-code-rs/src/teams/constants.rs similarity index 100% rename from src/teams/constants.rs rename to crates/claude-code-rs/src/teams/constants.rs diff --git a/src/teams/context.rs b/crates/claude-code-rs/src/teams/context.rs similarity index 100% rename from src/teams/context.rs rename to crates/claude-code-rs/src/teams/context.rs diff --git a/src/teams/helpers.rs b/crates/claude-code-rs/src/teams/helpers.rs similarity index 100% rename from src/teams/helpers.rs rename to crates/claude-code-rs/src/teams/helpers.rs diff --git a/src/teams/identity.rs b/crates/claude-code-rs/src/teams/identity.rs similarity index 100% rename from src/teams/identity.rs rename to crates/claude-code-rs/src/teams/identity.rs diff --git a/src/teams/in_process.rs b/crates/claude-code-rs/src/teams/in_process.rs similarity index 100% rename from src/teams/in_process.rs rename to crates/claude-code-rs/src/teams/in_process.rs diff --git a/src/teams/mailbox.rs b/crates/claude-code-rs/src/teams/mailbox.rs similarity index 100% rename from src/teams/mailbox.rs rename to crates/claude-code-rs/src/teams/mailbox.rs diff --git a/src/teams/mod.rs b/crates/claude-code-rs/src/teams/mod.rs similarity index 100% rename from src/teams/mod.rs rename to crates/claude-code-rs/src/teams/mod.rs diff --git a/src/teams/protocol.rs b/crates/claude-code-rs/src/teams/protocol.rs similarity index 100% rename from src/teams/protocol.rs rename to crates/claude-code-rs/src/teams/protocol.rs diff --git a/src/teams/runner.rs b/crates/claude-code-rs/src/teams/runner.rs similarity index 100% rename from src/teams/runner.rs rename to crates/claude-code-rs/src/teams/runner.rs diff --git a/src/teams/types.rs b/crates/claude-code-rs/src/teams/types.rs similarity index 100% rename from src/teams/types.rs rename to crates/claude-code-rs/src/teams/types.rs diff --git a/src/tools/ARCHITECTURE.md b/crates/claude-code-rs/src/tools/ARCHITECTURE.md similarity index 100% rename from src/tools/ARCHITECTURE.md rename to crates/claude-code-rs/src/tools/ARCHITECTURE.md diff --git a/src/tools/agent/dispatch.rs b/crates/claude-code-rs/src/tools/agent/dispatch.rs similarity index 100% rename from src/tools/agent/dispatch.rs rename to crates/claude-code-rs/src/tools/agent/dispatch.rs diff --git a/src/tools/agent/mod.rs b/crates/claude-code-rs/src/tools/agent/mod.rs similarity index 100% rename from src/tools/agent/mod.rs rename to crates/claude-code-rs/src/tools/agent/mod.rs diff --git a/src/tools/agent/tests.rs b/crates/claude-code-rs/src/tools/agent/tests.rs similarity index 100% rename from src/tools/agent/tests.rs rename to crates/claude-code-rs/src/tools/agent/tests.rs diff --git a/src/tools/agent/tool_impl.rs b/crates/claude-code-rs/src/tools/agent/tool_impl.rs similarity index 100% rename from src/tools/agent/tool_impl.rs rename to crates/claude-code-rs/src/tools/agent/tool_impl.rs diff --git a/src/tools/agent/worktree.rs b/crates/claude-code-rs/src/tools/agent/worktree.rs similarity index 100% rename from src/tools/agent/worktree.rs rename to crates/claude-code-rs/src/tools/agent/worktree.rs diff --git a/src/tools/ask_user.rs b/crates/claude-code-rs/src/tools/ask_user.rs similarity index 100% rename from src/tools/ask_user.rs rename to crates/claude-code-rs/src/tools/ask_user.rs diff --git a/src/tools/background_agents.rs b/crates/claude-code-rs/src/tools/background_agents.rs similarity index 100% rename from src/tools/background_agents.rs rename to crates/claude-code-rs/src/tools/background_agents.rs diff --git a/src/tools/brief.rs b/crates/claude-code-rs/src/tools/brief.rs similarity index 100% rename from src/tools/brief.rs rename to crates/claude-code-rs/src/tools/brief.rs diff --git a/src/tools/config_tool.rs b/crates/claude-code-rs/src/tools/config_tool.rs similarity index 100% rename from src/tools/config_tool.rs rename to crates/claude-code-rs/src/tools/config_tool.rs diff --git a/src/tools/exec/bash.rs b/crates/claude-code-rs/src/tools/exec/bash.rs similarity index 100% rename from src/tools/exec/bash.rs rename to crates/claude-code-rs/src/tools/exec/bash.rs diff --git a/src/tools/exec/mod.rs b/crates/claude-code-rs/src/tools/exec/mod.rs similarity index 100% rename from src/tools/exec/mod.rs rename to crates/claude-code-rs/src/tools/exec/mod.rs diff --git a/src/tools/exec/powershell.rs b/crates/claude-code-rs/src/tools/exec/powershell.rs similarity index 100% rename from src/tools/exec/powershell.rs rename to crates/claude-code-rs/src/tools/exec/powershell.rs diff --git a/src/tools/exec/repl.rs b/crates/claude-code-rs/src/tools/exec/repl.rs similarity index 100% rename from src/tools/exec/repl.rs rename to crates/claude-code-rs/src/tools/exec/repl.rs diff --git a/src/tools/exec/sleep.rs b/crates/claude-code-rs/src/tools/exec/sleep.rs similarity index 100% rename from src/tools/exec/sleep.rs rename to crates/claude-code-rs/src/tools/exec/sleep.rs diff --git a/src/tools/execution/coordinator.rs b/crates/claude-code-rs/src/tools/execution/coordinator.rs similarity index 100% rename from src/tools/execution/coordinator.rs rename to crates/claude-code-rs/src/tools/execution/coordinator.rs diff --git a/src/tools/execution/mod.rs b/crates/claude-code-rs/src/tools/execution/mod.rs similarity index 100% rename from src/tools/execution/mod.rs rename to crates/claude-code-rs/src/tools/execution/mod.rs diff --git a/src/tools/execution/pipeline.rs b/crates/claude-code-rs/src/tools/execution/pipeline.rs similarity index 100% rename from src/tools/execution/pipeline.rs rename to crates/claude-code-rs/src/tools/execution/pipeline.rs diff --git a/src/tools/execution/security.rs b/crates/claude-code-rs/src/tools/execution/security.rs similarity index 100% rename from src/tools/execution/security.rs rename to crates/claude-code-rs/src/tools/execution/security.rs diff --git a/src/tools/execution/tests.rs b/crates/claude-code-rs/src/tools/execution/tests.rs similarity index 100% rename from src/tools/execution/tests.rs rename to crates/claude-code-rs/src/tools/execution/tests.rs diff --git a/crates/claude-code-rs/src/tools/file_read.rs b/crates/claude-code-rs/src/tools/file_read.rs new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/fs/file_edit.rs b/crates/claude-code-rs/src/tools/fs/file_edit.rs similarity index 100% rename from src/tools/fs/file_edit.rs rename to crates/claude-code-rs/src/tools/fs/file_edit.rs diff --git a/src/tools/fs/file_read.rs b/crates/claude-code-rs/src/tools/fs/file_read.rs similarity index 100% rename from src/tools/fs/file_read.rs rename to crates/claude-code-rs/src/tools/fs/file_read.rs diff --git a/src/tools/fs/file_write.rs b/crates/claude-code-rs/src/tools/fs/file_write.rs similarity index 100% rename from src/tools/fs/file_write.rs rename to crates/claude-code-rs/src/tools/fs/file_write.rs diff --git a/src/tools/fs/glob_tool.rs b/crates/claude-code-rs/src/tools/fs/glob_tool.rs similarity index 100% rename from src/tools/fs/glob_tool.rs rename to crates/claude-code-rs/src/tools/fs/glob_tool.rs diff --git a/src/tools/fs/grep.rs b/crates/claude-code-rs/src/tools/fs/grep.rs similarity index 100% rename from src/tools/fs/grep.rs rename to crates/claude-code-rs/src/tools/fs/grep.rs diff --git a/src/tools/fs/mod.rs b/crates/claude-code-rs/src/tools/fs/mod.rs similarity index 100% rename from src/tools/fs/mod.rs rename to crates/claude-code-rs/src/tools/fs/mod.rs diff --git a/src/tools/hooks/execution.rs b/crates/claude-code-rs/src/tools/hooks/execution.rs similarity index 100% rename from src/tools/hooks/execution.rs rename to crates/claude-code-rs/src/tools/hooks/execution.rs diff --git a/src/tools/hooks/mod.rs b/crates/claude-code-rs/src/tools/hooks/mod.rs similarity index 100% rename from src/tools/hooks/mod.rs rename to crates/claude-code-rs/src/tools/hooks/mod.rs diff --git a/src/tools/hooks/post_tool.rs b/crates/claude-code-rs/src/tools/hooks/post_tool.rs similarity index 100% rename from src/tools/hooks/post_tool.rs rename to crates/claude-code-rs/src/tools/hooks/post_tool.rs diff --git a/src/tools/hooks/pre_tool.rs b/crates/claude-code-rs/src/tools/hooks/pre_tool.rs similarity index 100% rename from src/tools/hooks/pre_tool.rs rename to crates/claude-code-rs/src/tools/hooks/pre_tool.rs diff --git a/src/tools/lsp.rs b/crates/claude-code-rs/src/tools/lsp.rs similarity index 100% rename from src/tools/lsp.rs rename to crates/claude-code-rs/src/tools/lsp.rs diff --git a/src/tools/mod.rs b/crates/claude-code-rs/src/tools/mod.rs similarity index 100% rename from src/tools/mod.rs rename to crates/claude-code-rs/src/tools/mod.rs diff --git a/src/tools/orchestration.rs b/crates/claude-code-rs/src/tools/orchestration.rs similarity index 100% rename from src/tools/orchestration.rs rename to crates/claude-code-rs/src/tools/orchestration.rs diff --git a/src/tools/plan_mode.rs b/crates/claude-code-rs/src/tools/plan_mode.rs similarity index 100% rename from src/tools/plan_mode.rs rename to crates/claude-code-rs/src/tools/plan_mode.rs diff --git a/src/tools/registry.rs b/crates/claude-code-rs/src/tools/registry.rs similarity index 100% rename from src/tools/registry.rs rename to crates/claude-code-rs/src/tools/registry.rs diff --git a/src/tools/send_message.rs b/crates/claude-code-rs/src/tools/send_message.rs similarity index 100% rename from src/tools/send_message.rs rename to crates/claude-code-rs/src/tools/send_message.rs diff --git a/src/tools/send_user_message.rs b/crates/claude-code-rs/src/tools/send_user_message.rs similarity index 100% rename from src/tools/send_user_message.rs rename to crates/claude-code-rs/src/tools/send_user_message.rs diff --git a/src/tools/skill.rs b/crates/claude-code-rs/src/tools/skill.rs similarity index 100% rename from src/tools/skill.rs rename to crates/claude-code-rs/src/tools/skill.rs diff --git a/src/tools/structured_output.rs b/crates/claude-code-rs/src/tools/structured_output.rs similarity index 100% rename from src/tools/structured_output.rs rename to crates/claude-code-rs/src/tools/structured_output.rs diff --git a/src/tools/system_status.rs b/crates/claude-code-rs/src/tools/system_status.rs similarity index 100% rename from src/tools/system_status.rs rename to crates/claude-code-rs/src/tools/system_status.rs diff --git a/src/tools/tasks.rs b/crates/claude-code-rs/src/tools/tasks.rs similarity index 100% rename from src/tools/tasks.rs rename to crates/claude-code-rs/src/tools/tasks.rs diff --git a/src/tools/team_spawn.rs b/crates/claude-code-rs/src/tools/team_spawn.rs similarity index 100% rename from src/tools/team_spawn.rs rename to crates/claude-code-rs/src/tools/team_spawn.rs diff --git a/src/tools/web_fetch.rs b/crates/claude-code-rs/src/tools/web_fetch.rs similarity index 100% rename from src/tools/web_fetch.rs rename to crates/claude-code-rs/src/tools/web_fetch.rs diff --git a/src/tools/web_search/mod.rs b/crates/claude-code-rs/src/tools/web_search/mod.rs similarity index 100% rename from src/tools/web_search/mod.rs rename to crates/claude-code-rs/src/tools/web_search/mod.rs diff --git a/src/tools/web_search/providers.rs b/crates/claude-code-rs/src/tools/web_search/providers.rs similarity index 100% rename from src/tools/web_search/providers.rs rename to crates/claude-code-rs/src/tools/web_search/providers.rs diff --git a/src/tools/web_search/tests.rs b/crates/claude-code-rs/src/tools/web_search/tests.rs similarity index 100% rename from src/tools/web_search/tests.rs rename to crates/claude-code-rs/src/tools/web_search/tests.rs diff --git a/src/tools/web_search/tool.rs b/crates/claude-code-rs/src/tools/web_search/tool.rs similarity index 100% rename from src/tools/web_search/tool.rs rename to crates/claude-code-rs/src/tools/web_search/tool.rs diff --git a/src/tools/worktree.rs b/crates/claude-code-rs/src/tools/worktree.rs similarity index 100% rename from src/tools/worktree.rs rename to crates/claude-code-rs/src/tools/worktree.rs diff --git a/src/types/app_state.rs b/crates/claude-code-rs/src/types/app_state.rs similarity index 100% rename from src/types/app_state.rs rename to crates/claude-code-rs/src/types/app_state.rs diff --git a/src/types/config.rs b/crates/claude-code-rs/src/types/config.rs similarity index 100% rename from src/types/config.rs rename to crates/claude-code-rs/src/types/config.rs diff --git a/src/types/message.rs b/crates/claude-code-rs/src/types/message.rs similarity index 100% rename from src/types/message.rs rename to crates/claude-code-rs/src/types/message.rs diff --git a/src/types/mod.rs b/crates/claude-code-rs/src/types/mod.rs similarity index 100% rename from src/types/mod.rs rename to crates/claude-code-rs/src/types/mod.rs diff --git a/src/types/state.rs b/crates/claude-code-rs/src/types/state.rs similarity index 100% rename from src/types/state.rs rename to crates/claude-code-rs/src/types/state.rs diff --git a/src/types/tool.rs b/crates/claude-code-rs/src/types/tool.rs similarity index 100% rename from src/types/tool.rs rename to crates/claude-code-rs/src/types/tool.rs diff --git a/src/types/transitions.rs b/crates/claude-code-rs/src/types/transitions.rs similarity index 100% rename from src/types/transitions.rs rename to crates/claude-code-rs/src/types/transitions.rs diff --git a/src/ui/app.rs b/crates/claude-code-rs/src/ui/app.rs similarity index 100% rename from src/ui/app.rs rename to crates/claude-code-rs/src/ui/app.rs diff --git a/src/ui/browser.rs b/crates/claude-code-rs/src/ui/browser.rs similarity index 100% rename from src/ui/browser.rs rename to crates/claude-code-rs/src/ui/browser.rs diff --git a/src/ui/diff.rs b/crates/claude-code-rs/src/ui/diff.rs similarity index 100% rename from src/ui/diff.rs rename to crates/claude-code-rs/src/ui/diff.rs diff --git a/src/ui/keybindings.rs b/crates/claude-code-rs/src/ui/keybindings.rs similarity index 100% rename from src/ui/keybindings.rs rename to crates/claude-code-rs/src/ui/keybindings.rs diff --git a/src/ui/markdown.rs b/crates/claude-code-rs/src/ui/markdown.rs similarity index 100% rename from src/ui/markdown.rs rename to crates/claude-code-rs/src/ui/markdown.rs diff --git a/src/ui/messages.rs b/crates/claude-code-rs/src/ui/messages.rs similarity index 100% rename from src/ui/messages.rs rename to crates/claude-code-rs/src/ui/messages.rs diff --git a/src/ui/mod.rs b/crates/claude-code-rs/src/ui/mod.rs similarity index 100% rename from src/ui/mod.rs rename to crates/claude-code-rs/src/ui/mod.rs diff --git a/src/ui/permissions.rs b/crates/claude-code-rs/src/ui/permissions.rs similarity index 100% rename from src/ui/permissions.rs rename to crates/claude-code-rs/src/ui/permissions.rs diff --git a/src/ui/prompt_input.rs b/crates/claude-code-rs/src/ui/prompt_input.rs similarity index 100% rename from src/ui/prompt_input.rs rename to crates/claude-code-rs/src/ui/prompt_input.rs diff --git a/src/ui/spinner.rs b/crates/claude-code-rs/src/ui/spinner.rs similarity index 100% rename from src/ui/spinner.rs rename to crates/claude-code-rs/src/ui/spinner.rs diff --git a/src/ui/status_line/mod.rs b/crates/claude-code-rs/src/ui/status_line/mod.rs similarity index 100% rename from src/ui/status_line/mod.rs rename to crates/claude-code-rs/src/ui/status_line/mod.rs diff --git a/src/ui/status_line/payload.rs b/crates/claude-code-rs/src/ui/status_line/payload.rs similarity index 100% rename from src/ui/status_line/payload.rs rename to crates/claude-code-rs/src/ui/status_line/payload.rs diff --git a/src/ui/status_line/runner.rs b/crates/claude-code-rs/src/ui/status_line/runner.rs similarity index 100% rename from src/ui/status_line/runner.rs rename to crates/claude-code-rs/src/ui/status_line/runner.rs diff --git a/src/ui/terminal_env.rs b/crates/claude-code-rs/src/ui/terminal_env.rs similarity index 100% rename from src/ui/terminal_env.rs rename to crates/claude-code-rs/src/ui/terminal_env.rs diff --git a/src/ui/theme.rs b/crates/claude-code-rs/src/ui/theme.rs similarity index 100% rename from src/ui/theme.rs rename to crates/claude-code-rs/src/ui/theme.rs diff --git a/src/ui/transcript.rs b/crates/claude-code-rs/src/ui/transcript.rs similarity index 100% rename from src/ui/transcript.rs rename to crates/claude-code-rs/src/ui/transcript.rs diff --git a/src/ui/tui.rs b/crates/claude-code-rs/src/ui/tui.rs similarity index 100% rename from src/ui/tui.rs rename to crates/claude-code-rs/src/ui/tui.rs diff --git a/src/ui/vim.rs b/crates/claude-code-rs/src/ui/vim.rs similarity index 100% rename from src/ui/vim.rs rename to crates/claude-code-rs/src/ui/vim.rs diff --git a/src/ui/virtual_scroll.rs b/crates/claude-code-rs/src/ui/virtual_scroll.rs similarity index 100% rename from src/ui/virtual_scroll.rs rename to crates/claude-code-rs/src/ui/virtual_scroll.rs diff --git a/src/ui/welcome.rs b/crates/claude-code-rs/src/ui/welcome.rs similarity index 100% rename from src/ui/welcome.rs rename to crates/claude-code-rs/src/ui/welcome.rs diff --git a/src/utils/abort.rs b/crates/claude-code-rs/src/utils/abort.rs similarity index 100% rename from src/utils/abort.rs rename to crates/claude-code-rs/src/utils/abort.rs diff --git a/src/utils/bash.rs b/crates/claude-code-rs/src/utils/bash.rs similarity index 100% rename from src/utils/bash.rs rename to crates/claude-code-rs/src/utils/bash.rs diff --git a/src/utils/cwd.rs b/crates/claude-code-rs/src/utils/cwd.rs similarity index 100% rename from src/utils/cwd.rs rename to crates/claude-code-rs/src/utils/cwd.rs diff --git a/src/utils/file_state_cache.rs b/crates/claude-code-rs/src/utils/file_state_cache.rs similarity index 100% rename from src/utils/file_state_cache.rs rename to crates/claude-code-rs/src/utils/file_state_cache.rs diff --git a/src/utils/git.rs b/crates/claude-code-rs/src/utils/git.rs similarity index 100% rename from src/utils/git.rs rename to crates/claude-code-rs/src/utils/git.rs diff --git a/src/utils/messages.rs b/crates/claude-code-rs/src/utils/messages.rs similarity index 100% rename from src/utils/messages.rs rename to crates/claude-code-rs/src/utils/messages.rs diff --git a/src/utils/mod.rs b/crates/claude-code-rs/src/utils/mod.rs similarity index 100% rename from src/utils/mod.rs rename to crates/claude-code-rs/src/utils/mod.rs diff --git a/src/utils/shell.rs b/crates/claude-code-rs/src/utils/shell.rs similarity index 100% rename from src/utils/shell.rs rename to crates/claude-code-rs/src/utils/shell.rs diff --git a/src/utils/tokens.rs b/crates/claude-code-rs/src/utils/tokens.rs similarity index 100% rename from src/utils/tokens.rs rename to crates/claude-code-rs/src/utils/tokens.rs diff --git a/src/voice/audio.rs b/crates/claude-code-rs/src/voice/audio.rs similarity index 100% rename from src/voice/audio.rs rename to crates/claude-code-rs/src/voice/audio.rs diff --git a/src/voice/controller.rs b/crates/claude-code-rs/src/voice/controller.rs similarity index 100% rename from src/voice/controller.rs rename to crates/claude-code-rs/src/voice/controller.rs diff --git a/src/voice/feasibility.rs b/crates/claude-code-rs/src/voice/feasibility.rs similarity index 100% rename from src/voice/feasibility.rs rename to crates/claude-code-rs/src/voice/feasibility.rs diff --git a/src/voice/language.rs b/crates/claude-code-rs/src/voice/language.rs similarity index 100% rename from src/voice/language.rs rename to crates/claude-code-rs/src/voice/language.rs diff --git a/src/voice/mod.rs b/crates/claude-code-rs/src/voice/mod.rs similarity index 100% rename from src/voice/mod.rs rename to crates/claude-code-rs/src/voice/mod.rs diff --git a/src/voice/stt.rs b/crates/claude-code-rs/src/voice/stt.rs similarity index 100% rename from src/voice/stt.rs rename to crates/claude-code-rs/src/voice/stt.rs diff --git a/src/web/handlers.rs b/crates/claude-code-rs/src/web/handlers.rs similarity index 100% rename from src/web/handlers.rs rename to crates/claude-code-rs/src/web/handlers.rs diff --git a/src/web/mod.rs b/crates/claude-code-rs/src/web/mod.rs similarity index 100% rename from src/web/mod.rs rename to crates/claude-code-rs/src/web/mod.rs diff --git a/src/web/sse.rs b/crates/claude-code-rs/src/web/sse.rs similarity index 100% rename from src/web/sse.rs rename to crates/claude-code-rs/src/web/sse.rs diff --git a/src/web/state.rs b/crates/claude-code-rs/src/web/state.rs similarity index 100% rename from src/web/state.rs rename to crates/claude-code-rs/src/web/state.rs diff --git a/src/web/static_files.rs b/crates/claude-code-rs/src/web/static_files.rs similarity index 91% rename from src/web/static_files.rs rename to crates/claude-code-rs/src/web/static_files.rs index 0b921bd4..798879fd 100644 --- a/src/web/static_files.rs +++ b/crates/claude-code-rs/src/web/static_files.rs @@ -13,9 +13,12 @@ use axum::{ #[cfg(feature = "web-ui")] use rust_embed::Embed; +// The `folder` attribute is resolved relative to the crate's manifest dir. +// With the workspace split, `web-ui/dist` lives two levels up at the +// workspace root. #[cfg(feature = "web-ui")] #[derive(Embed)] -#[folder = "web-ui/dist"] +#[folder = "../../web-ui/dist"] struct WebAssets; /// Fallback handler: serve embedded static files or SPA index.html. diff --git a/tests/cc_rust_home_subprocess.rs b/crates/claude-code-rs/tests/cc_rust_home_subprocess.rs similarity index 100% rename from tests/cc_rust_home_subprocess.rs rename to crates/claude-code-rs/tests/cc_rust_home_subprocess.rs diff --git a/tests/conftest.py b/crates/claude-code-rs/tests/conftest.py similarity index 100% rename from tests/conftest.py rename to crates/claude-code-rs/tests/conftest.py diff --git a/tests/dashboard_verify.ts b/crates/claude-code-rs/tests/dashboard_verify.ts similarity index 100% rename from tests/dashboard_verify.ts rename to crates/claude-code-rs/tests/dashboard_verify.ts diff --git a/tests/docs/README.md b/crates/claude-code-rs/tests/docs/README.md similarity index 100% rename from tests/docs/README.md rename to crates/claude-code-rs/tests/docs/README.md diff --git a/tests/docs/e2e.md b/crates/claude-code-rs/tests/docs/e2e.md similarity index 100% rename from tests/docs/e2e.md rename to crates/claude-code-rs/tests/docs/e2e.md diff --git a/tests/docs/pty.md b/crates/claude-code-rs/tests/docs/pty.md similarity index 100% rename from tests/docs/pty.md rename to crates/claude-code-rs/tests/docs/pty.md diff --git a/tests/e2e_audit_export.rs b/crates/claude-code-rs/tests/e2e_audit_export.rs similarity index 100% rename from tests/e2e_audit_export.rs rename to crates/claude-code-rs/tests/e2e_audit_export.rs diff --git a/tests/e2e_browser_mcp.rs b/crates/claude-code-rs/tests/e2e_browser_mcp.rs similarity index 100% rename from tests/e2e_browser_mcp.rs rename to crates/claude-code-rs/tests/e2e_browser_mcp.rs diff --git a/tests/e2e_chrome_mcp_bridge.rs b/crates/claude-code-rs/tests/e2e_chrome_mcp_bridge.rs similarity index 100% rename from tests/e2e_chrome_mcp_bridge.rs rename to crates/claude-code-rs/tests/e2e_chrome_mcp_bridge.rs diff --git a/tests/e2e_chrome_native_host.rs b/crates/claude-code-rs/tests/e2e_chrome_native_host.rs similarity index 100% rename from tests/e2e_chrome_native_host.rs rename to crates/claude-code-rs/tests/e2e_chrome_native_host.rs diff --git a/tests/e2e_chrome_subsystem.rs b/crates/claude-code-rs/tests/e2e_chrome_subsystem.rs similarity index 100% rename from tests/e2e_chrome_subsystem.rs rename to crates/claude-code-rs/tests/e2e_chrome_subsystem.rs diff --git a/tests/e2e_cli.rs b/crates/claude-code-rs/tests/e2e_cli.rs similarity index 100% rename from tests/e2e_cli.rs rename to crates/claude-code-rs/tests/e2e_cli.rs diff --git a/tests/e2e_compact.rs b/crates/claude-code-rs/tests/e2e_compact.rs similarity index 100% rename from tests/e2e_compact.rs rename to crates/claude-code-rs/tests/e2e_compact.rs diff --git a/tests/e2e_env.rs b/crates/claude-code-rs/tests/e2e_env.rs similarity index 100% rename from tests/e2e_env.rs rename to crates/claude-code-rs/tests/e2e_env.rs diff --git a/tests/e2e_hooks.rs b/crates/claude-code-rs/tests/e2e_hooks.rs similarity index 100% rename from tests/e2e_hooks.rs rename to crates/claude-code-rs/tests/e2e_hooks.rs diff --git a/tests/e2e_keybindings.rs b/crates/claude-code-rs/tests/e2e_keybindings.rs similarity index 100% rename from tests/e2e_keybindings.rs rename to crates/claude-code-rs/tests/e2e_keybindings.rs diff --git a/tests/e2e_live_api.rs b/crates/claude-code-rs/tests/e2e_live_api.rs similarity index 100% rename from tests/e2e_live_api.rs rename to crates/claude-code-rs/tests/e2e_live_api.rs diff --git a/tests/e2e_lsp.rs b/crates/claude-code-rs/tests/e2e_lsp.rs similarity index 100% rename from tests/e2e_lsp.rs rename to crates/claude-code-rs/tests/e2e_lsp.rs diff --git a/tests/e2e_model_effort_style.rs b/crates/claude-code-rs/tests/e2e_model_effort_style.rs similarity index 100% rename from tests/e2e_model_effort_style.rs rename to crates/claude-code-rs/tests/e2e_model_effort_style.rs diff --git a/tests/e2e_permissions.rs b/crates/claude-code-rs/tests/e2e_permissions.rs similarity index 100% rename from tests/e2e_permissions.rs rename to crates/claude-code-rs/tests/e2e_permissions.rs diff --git a/tests/e2e_plugin_tools.rs b/crates/claude-code-rs/tests/e2e_plugin_tools.rs similarity index 100% rename from tests/e2e_plugin_tools.rs rename to crates/claude-code-rs/tests/e2e_plugin_tools.rs diff --git a/tests/e2e_pty.rs b/crates/claude-code-rs/tests/e2e_pty.rs similarity index 100% rename from tests/e2e_pty.rs rename to crates/claude-code-rs/tests/e2e_pty.rs diff --git a/tests/e2e_sandbox.rs b/crates/claude-code-rs/tests/e2e_sandbox.rs similarity index 100% rename from tests/e2e_sandbox.rs rename to crates/claude-code-rs/tests/e2e_sandbox.rs diff --git a/tests/e2e_services.rs b/crates/claude-code-rs/tests/e2e_services.rs similarity index 100% rename from tests/e2e_services.rs rename to crates/claude-code-rs/tests/e2e_services.rs diff --git a/tests/e2e_session_export.rs b/crates/claude-code-rs/tests/e2e_session_export.rs similarity index 100% rename from tests/e2e_session_export.rs rename to crates/claude-code-rs/tests/e2e_session_export.rs diff --git a/tests/e2e_settings.rs b/crates/claude-code-rs/tests/e2e_settings.rs similarity index 100% rename from tests/e2e_settings.rs rename to crates/claude-code-rs/tests/e2e_settings.rs diff --git a/tests/e2e_statusline.rs b/crates/claude-code-rs/tests/e2e_statusline.rs similarity index 100% rename from tests/e2e_statusline.rs rename to crates/claude-code-rs/tests/e2e_statusline.rs diff --git a/tests/e2e_terminal/commands.rs b/crates/claude-code-rs/tests/e2e_terminal/commands.rs similarity index 100% rename from tests/e2e_terminal/commands.rs rename to crates/claude-code-rs/tests/e2e_terminal/commands.rs diff --git a/tests/e2e_terminal/helpers.rs b/crates/claude-code-rs/tests/e2e_terminal/helpers.rs similarity index 100% rename from tests/e2e_terminal/helpers.rs rename to crates/claude-code-rs/tests/e2e_terminal/helpers.rs diff --git a/tests/e2e_terminal/live.rs b/crates/claude-code-rs/tests/e2e_terminal/live.rs similarity index 100% rename from tests/e2e_terminal/live.rs rename to crates/claude-code-rs/tests/e2e_terminal/live.rs diff --git a/tests/e2e_terminal/main.rs b/crates/claude-code-rs/tests/e2e_terminal/main.rs similarity index 100% rename from tests/e2e_terminal/main.rs rename to crates/claude-code-rs/tests/e2e_terminal/main.rs diff --git a/tests/e2e_terminal/offline.rs b/crates/claude-code-rs/tests/e2e_terminal/offline.rs similarity index 100% rename from tests/e2e_terminal/offline.rs rename to crates/claude-code-rs/tests/e2e_terminal/offline.rs diff --git a/tests/e2e_terminal/permission.rs b/crates/claude-code-rs/tests/e2e_terminal/permission.rs similarity index 100% rename from tests/e2e_terminal/permission.rs rename to crates/claude-code-rs/tests/e2e_terminal/permission.rs diff --git a/tests/e2e_terminal/subagent.rs b/crates/claude-code-rs/tests/e2e_terminal/subagent.rs similarity index 100% rename from tests/e2e_terminal/subagent.rs rename to crates/claude-code-rs/tests/e2e_terminal/subagent.rs diff --git a/tests/e2e_terminal/tool_display.rs b/crates/claude-code-rs/tests/e2e_terminal/tool_display.rs similarity index 100% rename from tests/e2e_terminal/tool_display.rs rename to crates/claude-code-rs/tests/e2e_terminal/tool_display.rs diff --git a/tests/e2e_terminal/usage.rs b/crates/claude-code-rs/tests/e2e_terminal/usage.rs similarity index 100% rename from tests/e2e_terminal/usage.rs rename to crates/claude-code-rs/tests/e2e_terminal/usage.rs diff --git a/tests/e2e_terminal_ux.rs b/crates/claude-code-rs/tests/e2e_terminal_ux.rs similarity index 100% rename from tests/e2e_terminal_ux.rs rename to crates/claude-code-rs/tests/e2e_terminal_ux.rs diff --git a/tests/e2e_tools.rs b/crates/claude-code-rs/tests/e2e_tools.rs similarity index 100% rename from tests/e2e_tools.rs rename to crates/claude-code-rs/tests/e2e_tools.rs diff --git a/tests/e2e_voice.rs b/crates/claude-code-rs/tests/e2e_voice.rs similarity index 100% rename from tests/e2e_voice.rs rename to crates/claude-code-rs/tests/e2e_voice.rs diff --git a/tests/message_suite/.gitignore b/crates/claude-code-rs/tests/message_suite/.gitignore similarity index 100% rename from tests/message_suite/.gitignore rename to crates/claude-code-rs/tests/message_suite/.gitignore diff --git a/tests/message_suite/assertions.py b/crates/claude-code-rs/tests/message_suite/assertions.py similarity index 100% rename from tests/message_suite/assertions.py rename to crates/claude-code-rs/tests/message_suite/assertions.py diff --git a/tests/message_suite/cases/coding/bash-stdout-stderr.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/bash-stdout-stderr.yaml similarity index 100% rename from tests/message_suite/cases/coding/bash-stdout-stderr.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/bash-stdout-stderr.yaml diff --git a/tests/message_suite/cases/coding/edit-error-recovery.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/edit-error-recovery.yaml similarity index 100% rename from tests/message_suite/cases/coding/edit-error-recovery.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/edit-error-recovery.yaml diff --git a/tests/message_suite/cases/coding/edit-preview.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/edit-preview.yaml similarity index 100% rename from tests/message_suite/cases/coding/edit-preview.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/edit-preview.yaml diff --git a/tests/message_suite/cases/coding/glob-grep-chain.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/glob-grep-chain.yaml similarity index 100% rename from tests/message_suite/cases/coding/glob-grep-chain.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/glob-grep-chain.yaml diff --git a/tests/message_suite/cases/coding/long-bash-streaming.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/long-bash-streaming.yaml similarity index 100% rename from tests/message_suite/cases/coding/long-bash-streaming.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/long-bash-streaming.yaml diff --git a/tests/message_suite/cases/coding/parallel-reads.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/parallel-reads.yaml similarity index 100% rename from tests/message_suite/cases/coding/parallel-reads.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/parallel-reads.yaml diff --git a/tests/message_suite/cases/coding/read-single.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/read-single.yaml similarity index 100% rename from tests/message_suite/cases/coding/read-single.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/read-single.yaml diff --git a/tests/message_suite/cases/coding/write-new-file.yaml b/crates/claude-code-rs/tests/message_suite/cases/coding/write-new-file.yaml similarity index 100% rename from tests/message_suite/cases/coding/write-new-file.yaml rename to crates/claude-code-rs/tests/message_suite/cases/coding/write-new-file.yaml diff --git a/tests/message_suite/cases/smoke/deepseek-chat.yaml b/crates/claude-code-rs/tests/message_suite/cases/smoke/deepseek-chat.yaml similarity index 100% rename from tests/message_suite/cases/smoke/deepseek-chat.yaml rename to crates/claude-code-rs/tests/message_suite/cases/smoke/deepseek-chat.yaml diff --git a/tests/message_suite/cases/smoke/version.yaml b/crates/claude-code-rs/tests/message_suite/cases/smoke/version.yaml similarity index 100% rename from tests/message_suite/cases/smoke/version.yaml rename to crates/claude-code-rs/tests/message_suite/cases/smoke/version.yaml diff --git a/tests/message_suite/cases/subagent/abort-mid-flight.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/abort-mid-flight.yaml similarity index 100% rename from tests/message_suite/cases/subagent/abort-mid-flight.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/abort-mid-flight.yaml diff --git a/tests/message_suite/cases/subagent/background.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/background.yaml similarity index 100% rename from tests/message_suite/cases/subagent/background.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/background.yaml diff --git a/tests/message_suite/cases/subagent/explore.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/explore.yaml similarity index 100% rename from tests/message_suite/cases/subagent/explore.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/explore.yaml diff --git a/tests/message_suite/cases/subagent/general-purpose.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/general-purpose.yaml similarity index 100% rename from tests/message_suite/cases/subagent/general-purpose.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/general-purpose.yaml diff --git a/tests/message_suite/cases/subagent/nested.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/nested.yaml similarity index 100% rename from tests/message_suite/cases/subagent/nested.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/nested.yaml diff --git a/tests/message_suite/cases/subagent/worktree-isolation.yaml b/crates/claude-code-rs/tests/message_suite/cases/subagent/worktree-isolation.yaml similarity index 100% rename from tests/message_suite/cases/subagent/worktree-isolation.yaml rename to crates/claude-code-rs/tests/message_suite/cases/subagent/worktree-isolation.yaml diff --git a/tests/message_suite/cases/workspace/add-dir-nonexistent.yaml b/crates/claude-code-rs/tests/message_suite/cases/workspace/add-dir-nonexistent.yaml similarity index 100% rename from tests/message_suite/cases/workspace/add-dir-nonexistent.yaml rename to crates/claude-code-rs/tests/message_suite/cases/workspace/add-dir-nonexistent.yaml diff --git a/tests/message_suite/cases/workspace/add-dir.yaml b/crates/claude-code-rs/tests/message_suite/cases/workspace/add-dir.yaml similarity index 100% rename from tests/message_suite/cases/workspace/add-dir.yaml rename to crates/claude-code-rs/tests/message_suite/cases/workspace/add-dir.yaml diff --git a/tests/message_suite/cases/workspace/multi-parallel.yaml b/crates/claude-code-rs/tests/message_suite/cases/workspace/multi-parallel.yaml similarity index 100% rename from tests/message_suite/cases/workspace/multi-parallel.yaml rename to crates/claude-code-rs/tests/message_suite/cases/workspace/multi-parallel.yaml diff --git a/tests/message_suite/cases/workspace/session-scoping.yaml b/crates/claude-code-rs/tests/message_suite/cases/workspace/session-scoping.yaml similarity index 100% rename from tests/message_suite/cases/workspace/session-scoping.yaml rename to crates/claude-code-rs/tests/message_suite/cases/workspace/session-scoping.yaml diff --git a/tests/message_suite/cases/workspace/single-cwd.yaml b/crates/claude-code-rs/tests/message_suite/cases/workspace/single-cwd.yaml similarity index 100% rename from tests/message_suite/cases/workspace/single-cwd.yaml rename to crates/claude-code-rs/tests/message_suite/cases/workspace/single-cwd.yaml diff --git a/tests/message_suite/defaults.yaml b/crates/claude-code-rs/tests/message_suite/defaults.yaml similarity index 100% rename from tests/message_suite/defaults.yaml rename to crates/claude-code-rs/tests/message_suite/defaults.yaml diff --git a/tests/message_suite/protocol.py b/crates/claude-code-rs/tests/message_suite/protocol.py similarity index 100% rename from tests/message_suite/protocol.py rename to crates/claude-code-rs/tests/message_suite/protocol.py diff --git a/tests/message_suite/runner.py b/crates/claude-code-rs/tests/message_suite/runner.py similarity index 100% rename from tests/message_suite/runner.py rename to crates/claude-code-rs/tests/message_suite/runner.py diff --git a/tests/pty_ui/commands.rs b/crates/claude-code-rs/tests/pty_ui/commands.rs similarity index 100% rename from tests/pty_ui/commands.rs rename to crates/claude-code-rs/tests/pty_ui/commands.rs diff --git a/tests/pty_ui/fast_path.rs b/crates/claude-code-rs/tests/pty_ui/fast_path.rs similarity index 100% rename from tests/pty_ui/fast_path.rs rename to crates/claude-code-rs/tests/pty_ui/fast_path.rs diff --git a/tests/pty_ui/harness.rs b/crates/claude-code-rs/tests/pty_ui/harness.rs similarity index 100% rename from tests/pty_ui/harness.rs rename to crates/claude-code-rs/tests/pty_ui/harness.rs diff --git a/tests/pty_ui/input.rs b/crates/claude-code-rs/tests/pty_ui/input.rs similarity index 100% rename from tests/pty_ui/input.rs rename to crates/claude-code-rs/tests/pty_ui/input.rs diff --git a/tests/pty_ui/main.rs b/crates/claude-code-rs/tests/pty_ui/main.rs similarity index 100% rename from tests/pty_ui/main.rs rename to crates/claude-code-rs/tests/pty_ui/main.rs diff --git a/tests/pty_ui/multi_turn.rs b/crates/claude-code-rs/tests/pty_ui/multi_turn.rs similarity index 100% rename from tests/pty_ui/multi_turn.rs rename to crates/claude-code-rs/tests/pty_ui/multi_turn.rs diff --git a/tests/pty_ui/resize.rs b/crates/claude-code-rs/tests/pty_ui/resize.rs similarity index 100% rename from tests/pty_ui/resize.rs rename to crates/claude-code-rs/tests/pty_ui/resize.rs diff --git a/tests/pty_ui/screenshot.rs b/crates/claude-code-rs/tests/pty_ui/screenshot.rs similarity index 100% rename from tests/pty_ui/screenshot.rs rename to crates/claude-code-rs/tests/pty_ui/screenshot.rs diff --git a/tests/pty_ui/streaming.rs b/crates/claude-code-rs/tests/pty_ui/streaming.rs similarity index 100% rename from tests/pty_ui/streaming.rs rename to crates/claude-code-rs/tests/pty_ui/streaming.rs diff --git a/tests/pty_ui/welcome.rs b/crates/claude-code-rs/tests/pty_ui/welcome.rs similarity index 100% rename from tests/pty_ui/welcome.rs rename to crates/claude-code-rs/tests/pty_ui/welcome.rs diff --git a/tests/pytest.ini b/crates/claude-code-rs/tests/pytest.ini similarity index 100% rename from tests/pytest.ini rename to crates/claude-code-rs/tests/pytest.ini diff --git a/tests/test_e2e_smoke.py b/crates/claude-code-rs/tests/test_e2e_smoke.py similarity index 100% rename from tests/test_e2e_smoke.py rename to crates/claude-code-rs/tests/test_e2e_smoke.py diff --git a/tests/test_workspace.rs b/crates/claude-code-rs/tests/test_workspace.rs similarity index 100% rename from tests/test_workspace.rs rename to crates/claude-code-rs/tests/test_workspace.rs diff --git a/docs/workspace-split-measurements.md b/docs/workspace-split-measurements.md new file mode 100644 index 00000000..8e6ee346 --- /dev/null +++ b/docs/workspace-split-measurements.md @@ -0,0 +1,60 @@ +# Workspace Split — Build Time Measurements + +Baseline and per-phase build-time measurements for the workspace-split refactor +(design doc: [2026-04-20-workspace-split-design.md](superpowers/specs/2026-04-20-workspace-split-design.md)). + +## Protocol + +All timings recorded on the same workstation, same target-dir +(`F:/cargo-target/cc-rust`), with the existing `.cargo/config.toml` settings +(rust-lld linker on Windows MSVC). Each incremental row is taken in "steady +state" — immediately after a no-op build, then `touch` the file and rebuild. + +```bash +# Incremental +touch && cargo build --offline 2>&1 | tail -2 + +# Cold release +cargo clean && cargo build --offline --release 2>&1 | tail -1 +``` + +Times come from cargo's own `Finished ... in Xs` line (wall-clock inside cargo). + +## Baseline — pre-split (single crate) + +Recorded 2026-04-20 on branch `workspace-split` at commit `8f048c4` (same tree +as `rust-lite`). Host: Windows 11, rustc 1.91.1, cargo 1.91.1. + +| Scenario | Time | +|---|---| +| Incremental after `touch src/main.rs` | **6.74s** | +| Incremental after `touch src/tools/file_read.rs` | **0.42s** | +| Cold `cargo build --release` | *(pending — see note)* | + +### Observations + +- The incremental gap between `main.rs` (6.74s) and `tools/file_read.rs` (0.42s) + is large (~16×). Cargo sub-divides the single crate into rustc codegen units; + `main.rs` sits in a codegen unit with many sibling modules (wide module tree), + while `tools/file_read.rs` sits in a smaller unit. The workspace split is + expected to reduce the `main.rs` case the most, since splitting hub modules + into crates eliminates the cross-codegen-unit re-link each time. +- Link time dominates both numbers; `rust-lld` is already in use (see + `.cargo/config.toml`). + +### Note on cold release + +Cold `cargo clean && cargo build --release` was not run in the baseline commit: +the shared target-dir (`F:/cargo-target/cc-rust`) is used by other +worktrees/branches in-flight, and `cargo clean` would invalidate caches +unrelated to this measurement. We will capture the cold release figure on a +dedicated measurement commit later in the phase sequence (Phase 8), where a +full rebuild is required anyway. + +## Per-phase timings + +Appended as each phase lands on `rust-lite`. + +| Phase | Date | Commit | `touch main.rs` | `touch file_read.rs` | Cold release | +|---|---|---|---|---|---| +| Baseline (P0 pre-move) | 2026-04-20 | `8f048c4` | 6.74s | 0.42s | — | From 9fd7229b4b8af7e6b9eaae4dd0ec057dc7162ad1 Mon Sep 17 00:00:00 2001 From: crsei Date: Mon, 20 Apr 2026 14:14:22 -0400 Subject: [PATCH 2/5] refactor(workspace): P1.1 extract cc-keybindings leaf crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move `src/keybindings/` (2,362 LOC, 7 files) out of `claude-code-rs` into its own `cc-keybindings` workspace member. Zero internal deps — the module only used std, parking_lot, crossterm, serde, serde_json, tracing, so the extraction is purely mechanical. Root crate keeps the `crate::keybindings::…` path working via `use cc_keybindings as keybindings;` at crate root, so no call-site edits were needed in main.rs, ui/app.rs, types/app_state.rs, or commands/keybindings_cmd.rs. All 51 keybinding unit tests pass in the new crate. Full workspace build clean. Part of #68 / Closes first acceptance item of #70. --- Cargo.lock | 13 +++++++++++++ Cargo.toml | 3 +++ crates/cc-keybindings/Cargo.toml | 15 +++++++++++++++ .../keybindings => cc-keybindings/src}/action.rs | 0 .../keybindings => cc-keybindings/src}/config.rs | 0 .../keybindings => cc-keybindings/src}/context.rs | 0 .../src}/defaults.rs | 0 .../src}/keystroke.rs | 0 .../mod.rs => cc-keybindings/src/lib.rs} | 0 .../src}/registry.rs | 0 crates/claude-code-rs/Cargo.toml | 3 +++ crates/claude-code-rs/src/main.rs | 4 +++- 12 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 crates/cc-keybindings/Cargo.toml rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/action.rs (100%) rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/config.rs (100%) rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/context.rs (100%) rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/defaults.rs (100%) rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/keystroke.rs (100%) rename crates/{claude-code-rs/src/keybindings/mod.rs => cc-keybindings/src/lib.rs} (100%) rename crates/{claude-code-rs/src/keybindings => cc-keybindings/src}/registry.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index bc9e2e01..bc1e37f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,18 @@ dependencies = [ "shlex", ] +[[package]] +name = "cc-keybindings" +version = "0.1.0" +dependencies = [ + "crossterm", + "parking_lot", + "serde", + "serde_json", + "tempfile", + "tracing", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -557,6 +569,7 @@ dependencies = [ "axum", "base64", "bytes", + "cc-keybindings", "chrono", "clap", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 82237332..c51f1b66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,6 +119,9 @@ dotenvy = "0.15.7" # 同步原语 parking_lot = "0.12" +# 内部 crates (workspace split) +cc-keybindings = { path = "crates/cc-keybindings" } + # Daemon HTTP server axum = { version = "0.8", features = ["ws"] } tower = "0.5" diff --git a/crates/cc-keybindings/Cargo.toml b/crates/cc-keybindings/Cargo.toml new file mode 100644 index 00000000..9da75771 --- /dev/null +++ b/crates/cc-keybindings/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cc-keybindings" +version = "0.1.0" +edition = "2021" +description = "Keybinding system for cc-rust: action vocabulary + JSON config + hot reload" + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } +parking_lot = { workspace = true } +crossterm = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +tempfile = { workspace = true } diff --git a/crates/claude-code-rs/src/keybindings/action.rs b/crates/cc-keybindings/src/action.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/action.rs rename to crates/cc-keybindings/src/action.rs diff --git a/crates/claude-code-rs/src/keybindings/config.rs b/crates/cc-keybindings/src/config.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/config.rs rename to crates/cc-keybindings/src/config.rs diff --git a/crates/claude-code-rs/src/keybindings/context.rs b/crates/cc-keybindings/src/context.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/context.rs rename to crates/cc-keybindings/src/context.rs diff --git a/crates/claude-code-rs/src/keybindings/defaults.rs b/crates/cc-keybindings/src/defaults.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/defaults.rs rename to crates/cc-keybindings/src/defaults.rs diff --git a/crates/claude-code-rs/src/keybindings/keystroke.rs b/crates/cc-keybindings/src/keystroke.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/keystroke.rs rename to crates/cc-keybindings/src/keystroke.rs diff --git a/crates/claude-code-rs/src/keybindings/mod.rs b/crates/cc-keybindings/src/lib.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/mod.rs rename to crates/cc-keybindings/src/lib.rs diff --git a/crates/claude-code-rs/src/keybindings/registry.rs b/crates/cc-keybindings/src/registry.rs similarity index 100% rename from crates/claude-code-rs/src/keybindings/registry.rs rename to crates/cc-keybindings/src/registry.rs diff --git a/crates/claude-code-rs/Cargo.toml b/crates/claude-code-rs/Cargo.toml index 3e774389..474306e3 100644 --- a/crates/claude-code-rs/Cargo.toml +++ b/crates/claude-code-rs/Cargo.toml @@ -131,6 +131,9 @@ dotenvy = { workspace = true } # 同步原语 parking_lot = { workspace = true } +# 内部 workspace crates (P1) +cc-keybindings = { workspace = true } + # Daemon axum = { workspace = true } tower = { workspace = true } diff --git a/crates/claude-code-rs/src/main.rs b/crates/claude-code-rs/src/main.rs index 7fa63fe7..44908cc0 100644 --- a/crates/claude-code-rs/src/main.rs +++ b/crates/claude-code-rs/src/main.rs @@ -24,7 +24,9 @@ mod commands; mod computer_use; mod config; mod engine; -mod keybindings; +// `keybindings` lives in its own crate (`cc-keybindings`). Re-alias at the +// crate root so existing `crate::keybindings::...` paths continue to resolve. +use cc_keybindings as keybindings; mod permissions; mod query; mod sandbox; From 3c6c1761d5eb62161e264fa401ae3d769f90a7f4 Mon Sep 17 00:00:00 2001 From: crsei Date: Tue, 21 Apr 2026 01:40:29 -0400 Subject: [PATCH 3/5] ci(workspace): fix CI failures after Phase 0 workspace split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three failures on PR #79 / branch workspace-split: 1. test-windows: `failed to create directory F:/cargo-target` The repo-level .cargo/config.toml had `target-dir = "F:/cargo-target/cc-rust"`, a developer-local absolute path. Removed; reminder comment points devs to ~/.cargo/config.toml or CARGO_TARGET_DIR for per-machine overrides. 2. test-rust-offline: `COPY src/` in Dockerfile.ci fails — Phase 0 moved src/ and tests/ into crates/claude-code-rs/. Replace the old "empty-shell cache layer" trick (which only worked for a single crate) with a straight workspace copy: Cargo.toml + Cargo.lock + crates/. 3. test-ui: same src/ → crates/ move applied to ui/Dockerfile.test. Target-dir at workspace root stays as the default `target/`, so the binary path `/build/target/release/claude-code-rs` used by the downstream Docker stages is unchanged. --- .cargo/config.toml | 15 +++++++++++++-- Dockerfile.ci | 17 ++++++++--------- ui/Dockerfile.test | 8 ++++---- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index b23c2259..324da49e 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,8 +2,19 @@ LIB = { value = "", force = true } INCLUDE = { value = "", force = true } -[build] -target-dir = "F:/cargo-target/cc-rust" +# ============================================================ +# target-dir 为什么不在这里 +# ------------------------------------------------------------ +# 绝对路径(如 F:/cargo-target/cc-rust)会污染 CI,报 +# "failed to create directory F:/cargo-target" +# 需要把构建产物放到其他盘的话,在你**自己的** ~/.cargo/config.toml +# 里加: +# +# [build] +# target-dir = "F:/cargo-target/cc-rust" +# +# 或用环境变量 CARGO_TARGET_DIR。两者都会覆盖仓库级配置。 +# ============================================================ # ============================================================ # 链接器加速: 使用 rust-lld 替换 MSVC link.exe diff --git a/Dockerfile.ci b/Dockerfile.ci index f7013bcc..265ac335 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -5,16 +5,15 @@ FROM rust:latest AS builder WORKDIR /build -# Dependency cache layer: copy only Cargo manifests, build with dummy src +# Workspace layout (after Phase 0 of the workspace split): +# /build/Cargo.toml — workspace manifest +# /build/crates/claude-code-rs/ — the bin crate (src/, tests/) +# +# The old "empty-shell src cache layer" trick doesn't fit a workspace +# cleanly (would need every crate's Cargo.toml + dummy src). We rely on +# Docker BuildKit's registry cache / layer cache instead. COPY Cargo.toml Cargo.lock ./ -RUN mkdir src && \ - echo "fn main() {}" > src/main.rs && \ - cargo build --release 2>/dev/null || true && \ - rm -rf src - -# Full source copy -COPY src/ src/ -COPY tests/ tests/ +COPY crates/ crates/ # Build binary RUN cargo build --release diff --git a/ui/Dockerfile.test b/ui/Dockerfile.test index 3507815c..8ea31d9e 100644 --- a/ui/Dockerfile.test +++ b/ui/Dockerfile.test @@ -16,11 +16,11 @@ FROM rust:latest AS rust-builder WORKDIR /build -COPY Cargo.toml Cargo.lock ./ -RUN mkdir src && echo "fn main() {}" > src/main.rs && \ - cargo build --release 2>/dev/null || true && rm -rf src -COPY src/ src/ +# Workspace layout (after Phase 0 of the workspace split): +# copy manifest + every crate, then a straight `cargo build` at the root. +COPY Cargo.toml Cargo.lock ./ +COPY crates/ crates/ RUN cargo build --release # ── Stage 2: UI test runner ────────────────────────────────── From e36deb4b3986c4a874bc91f8a074bdc4dc76d3cb Mon Sep 17 00:00:00 2001 From: crsei Date: Tue, 21 Apr 2026 01:49:29 -0400 Subject: [PATCH 4/5] fix(linux): 3 long-standing Linux-only compile errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These errors have been red on rust-lite CI for some time, previously hidden behind the target-dir / Dockerfile-path issues that my prior commit fixed. None are regressions from Phase 0 of the workspace split. 1. sandbox/availability.rs:89 — `which::which` used in non-test code but `which` was declared only in [dev-dependencies]. Promote to regular [dependencies]. Affects all Linux builds. 2. computer_use/screenshot/linux.rs:13,18 — `or_else` on an async future can't short-circuit across awaits; the chain produced `Result<(), ..>` vs `Result, ..>` in the two arms, tripping E0277 ("() is not a future") and E0308 (mismatched types). Replace with a straightforward `match .. .await`. 3. computer_use/input/linux.rs:132 — E0515. `p.to_lowercase().as_str()` produced an `&str` borrowing a temporary `String` that drops at the end of the match arm. Rebind to a local and return owned `String`s; unknown keys pass through preserving original case. Only test-windows in CI exercises host code on these paths; test-rust-offline (Linux Docker) was the one catching these. --- crates/claude-code-rs/Cargo.toml | 4 +- .../src/computer_use/input/linux.rs | 49 ++++++++++--------- .../src/computer_use/screenshot/linux.rs | 17 +++---- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/crates/claude-code-rs/Cargo.toml b/crates/claude-code-rs/Cargo.toml index 474306e3..631f2433 100644 --- a/crates/claude-code-rs/Cargo.toml +++ b/crates/claude-code-rs/Cargo.toml @@ -149,6 +149,9 @@ mime_guess = { workspace = true } tree-sitter = { workspace = true, optional = true } image = { workspace = true, optional = true } +# 可执行文件查找 (sandbox/availability.rs 用它探测 bwrap/sandbox-exec) +which = { workspace = true } + [dev-dependencies] assert_cmd = { workspace = true } predicates = { workspace = true } @@ -159,7 +162,6 @@ hex = { workspace = true } serde_json = { workspace = true } portable-pty = { workspace = true } vt100 = { workspace = true } -which = { workspace = true } serial_test = { workspace = true } [target.'cfg(unix)'.dependencies] diff --git a/crates/claude-code-rs/src/computer_use/input/linux.rs b/crates/claude-code-rs/src/computer_use/input/linux.rs index 26b1d9e2..7130a3e4 100644 --- a/crates/claude-code-rs/src/computer_use/input/linux.rs +++ b/crates/claude-code-rs/src/computer_use/input/linux.rs @@ -105,31 +105,36 @@ async fn run_xdotool(args: &[&str]) -> anyhow::Result { } fn map_key_to_xdotool(key: &str) -> String { - // xdotool uses X11 keysym names and "+" for combos - // Most common keys map directly + // xdotool uses X11 keysym names and "+" for combos. + // Most common keys map directly; unknowns pass through as-is. let parts: Vec<&str> = key.split('+').collect(); parts .iter() - .map(|p| match p.to_lowercase().as_str() { - "ctrl" | "control" => "ctrl", - "alt" => "alt", - "shift" => "shift", - "super" | "cmd" | "command" | "meta" => "super", - "return" | "enter" => "Return", - "escape" | "esc" => "Escape", - "tab" => "Tab", - "backspace" | "back" => "BackSpace", - "delete" | "del" => "Delete", - "space" => "space", - "up" => "Up", - "down" => "Down", - "left" => "Left", - "right" => "Right", - "home" => "Home", - "end" => "End", - "pageup" | "page_up" => "Prior", - "pagedown" | "page_down" => "Next", - other => other, + .map(|p| { + // Rebind to a named local so `as_str()`'s borrow lives long enough. + let p_lower = p.to_lowercase(); + match p_lower.as_str() { + "ctrl" | "control" => "ctrl".to_string(), + "alt" => "alt".to_string(), + "shift" => "shift".to_string(), + "super" | "cmd" | "command" | "meta" => "super".to_string(), + "return" | "enter" => "Return".to_string(), + "escape" | "esc" => "Escape".to_string(), + "tab" => "Tab".to_string(), + "backspace" | "back" => "BackSpace".to_string(), + "delete" | "del" => "Delete".to_string(), + "space" => "space".to_string(), + "up" => "Up".to_string(), + "down" => "Down".to_string(), + "left" => "Left".to_string(), + "right" => "Right".to_string(), + "home" => "Home".to_string(), + "end" => "End".to_string(), + "pageup" | "page_up" => "Prior".to_string(), + "pagedown" | "page_down" => "Next".to_string(), + // Unknown: preserve original case from the input. + _ => (*p).to_string(), + } }) .collect::>() .join("+") diff --git a/crates/claude-code-rs/src/computer_use/screenshot/linux.rs b/crates/claude-code-rs/src/computer_use/screenshot/linux.rs index 3de31a24..2c498784 100644 --- a/crates/claude-code-rs/src/computer_use/screenshot/linux.rs +++ b/crates/claude-code-rs/src/computer_use/screenshot/linux.rs @@ -7,17 +7,12 @@ pub async fn capture_full_screen() -> anyhow::Result { let tmp_file = tmp_dir.join(format!("cc_rust_screenshot_{}.png", std::process::id())); let tmp_path = tmp_file.to_str().unwrap(); - // Try grim (Wayland) first, then scrot (X11) - let result = try_grim(tmp_path).await.or_else(|_| { - // try_scrot is sync-returning a future, so wrap - Ok::<_, anyhow::Error>(try_scrot(tmp_path)) - }); - - // If grim succeeded, result is Ok(Ok(())). If grim failed, try scrot. - let _capture_result = match result { - Ok(fut) => fut.await, - Err(e) => Err(e), - }?; + // Try grim (Wayland) first, then scrot (X11). + // `or_else` can't short-circuit across awaits, so we dispatch manually. + match try_grim(tmp_path).await { + Ok(()) => {} + Err(_) => try_scrot(tmp_path).await?, + } let png_bytes = tokio::fs::read(&tmp_file).await?; let _ = tokio::fs::remove_file(&tmp_file).await; From ef45df3fb9595efd11d78dabdb29ddebf3e98b9e Mon Sep 17 00:00:00 2001 From: crsei Date: Tue, 21 Apr 2026 02:21:48 -0400 Subject: [PATCH 5/5] refactor(workspace): P1.2 extract cc-observability leaf crate Move observability/ (context/event/sink, 990 LOC) into a new `cc-observability` workspace crate. Breaks the one remaining tie to the root crate by injecting `runs_dir` into `AuditSink::init` (previously called `crate::config::paths::runs_dir` directly). main.rs keeps the `use cc_observability as observability;` alias so all existing `crate::observability::...` paths resolve unchanged. Acceptance (Phase 1, #70): - crates/cc-observability/ created - src/observability/ removed from root crate - cargo build + cargo test pass (1794 bin tests, 10 cc-observability tests; 1 pre-existing flake `off_mode_skips_redaction` unchanged) Co-Authored-By: Claude Opus 4.7 --- Cargo.lock | 14 ++++++++++++++ Cargo.toml | 1 + crates/cc-observability/Cargo.toml | 14 ++++++++++++++ .../src}/context.rs | 0 .../src}/event.rs | 0 .../mod.rs => cc-observability/src/lib.rs} | 0 .../src}/sink.rs | 19 +++++++++++++------ crates/claude-code-rs/Cargo.toml | 1 + crates/claude-code-rs/src/main.rs | 8 +++++--- 9 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 crates/cc-observability/Cargo.toml rename crates/{claude-code-rs/src/observability => cc-observability/src}/context.rs (100%) rename crates/{claude-code-rs/src/observability => cc-observability/src}/event.rs (100%) rename crates/{claude-code-rs/src/observability/mod.rs => cc-observability/src/lib.rs} (100%) rename crates/{claude-code-rs/src/observability => cc-observability/src}/sink.rs (95%) diff --git a/Cargo.lock b/Cargo.lock index bc1e37f9..83f349ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -491,6 +491,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "cc-observability" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "parking_lot", + "serde", + "serde_json", + "tracing", + "uuid", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -570,6 +583,7 @@ dependencies = [ "base64", "bytes", "cc-keybindings", + "cc-observability", "chrono", "clap", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index c51f1b66..249545fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,6 +121,7 @@ parking_lot = "0.12" # 内部 crates (workspace split) cc-keybindings = { path = "crates/cc-keybindings" } +cc-observability = { path = "crates/cc-observability" } # Daemon HTTP server axum = { version = "0.8", features = ["ws"] } diff --git a/crates/cc-observability/Cargo.toml b/crates/cc-observability/Cargo.toml new file mode 100644 index 00000000..b8357c5a --- /dev/null +++ b/crates/cc-observability/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cc-observability" +version = "0.1.0" +edition = "2021" +description = "Runtime audit event logging for cc-rust (single source of truth for traceable logs)" + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } +anyhow = { workspace = true } +chrono = { workspace = true } +uuid = { workspace = true } +parking_lot = { workspace = true } +tracing = { workspace = true } diff --git a/crates/claude-code-rs/src/observability/context.rs b/crates/cc-observability/src/context.rs similarity index 100% rename from crates/claude-code-rs/src/observability/context.rs rename to crates/cc-observability/src/context.rs diff --git a/crates/claude-code-rs/src/observability/event.rs b/crates/cc-observability/src/event.rs similarity index 100% rename from crates/claude-code-rs/src/observability/event.rs rename to crates/cc-observability/src/event.rs diff --git a/crates/claude-code-rs/src/observability/mod.rs b/crates/cc-observability/src/lib.rs similarity index 100% rename from crates/claude-code-rs/src/observability/mod.rs rename to crates/cc-observability/src/lib.rs diff --git a/crates/claude-code-rs/src/observability/sink.rs b/crates/cc-observability/src/sink.rs similarity index 95% rename from crates/claude-code-rs/src/observability/sink.rs rename to crates/cc-observability/src/sink.rs index 2fb0f122..feea263b 100644 --- a/crates/claude-code-rs/src/observability/sink.rs +++ b/crates/cc-observability/src/sink.rs @@ -108,19 +108,26 @@ impl AuditSink { /// Initialize the audit sink for a session. /// /// Creates: - /// - `~/.cc-rust/runs//events.ndjson` - /// - `~/.cc-rust/runs//meta.json` - /// - `~/.cc-rust/runs//artifacts/` + /// - `/events.ndjson` + /// - `/meta.json` + /// - `/artifacts/` + /// + /// `runs_dir` is the per-session output directory (resolved by the caller, + /// typically `~/.cc-rust/runs//`). Injecting it here keeps this + /// crate free of any dependency on the root config module. /// /// Returns `Ok(sink)` even if the directory cannot be created (sink becomes /// a no-op so the process can still run). - pub fn init(session_id: &str, meta: &SessionMeta, config: AuditConfig) -> Result { + pub fn init( + session_id: &str, + runs_dir: PathBuf, + meta: &SessionMeta, + config: AuditConfig, + ) -> Result { if !config.enabled { return Ok(Self::noop(config)); } - let runs_dir = crate::config::paths::runs_dir(session_id); - std::fs::create_dir_all(&runs_dir) .with_context(|| format!("Failed to create runs directory {}", runs_dir.display()))?; diff --git a/crates/claude-code-rs/Cargo.toml b/crates/claude-code-rs/Cargo.toml index 631f2433..6e02621d 100644 --- a/crates/claude-code-rs/Cargo.toml +++ b/crates/claude-code-rs/Cargo.toml @@ -133,6 +133,7 @@ parking_lot = { workspace = true } # 内部 workspace crates (P1) cc-keybindings = { workspace = true } +cc-observability = { workspace = true } # Daemon axum = { workspace = true } diff --git a/crates/claude-code-rs/src/main.rs b/crates/claude-code-rs/src/main.rs index 44908cc0..ac10b37c 100644 --- a/crates/claude-code-rs/src/main.rs +++ b/crates/claude-code-rs/src/main.rs @@ -72,8 +72,9 @@ mod web; // Phase I: Shutdown and cleanup mod shutdown; -// Observability: runtime audit event logging -mod observability; +// Observability lives in its own crate (`cc-observability`). Re-alias at the +// crate root so existing `crate::observability::...` paths continue to resolve. +use cc_observability as observability; // IPC headless mode mod ipc; @@ -602,7 +603,8 @@ async fn run_full_init(cli: Cli) -> anyhow::Result { source: source_mode.to_string(), }; - match AuditSink::init(engine.session_id.as_str(), &meta, audit_config) { + let runs_dir = crate::config::paths::runs_dir(engine.session_id.as_str()); + match AuditSink::init(engine.session_id.as_str(), runs_dir, &meta, audit_config) { Ok(sink) => { let ctx = AuditContext::new(engine.session_id.as_str(), source_mode, sink); // Emit session.start