Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ cc-sandbox = { path = "crates/cc-sandbox" }
cc-permissions = { path = "crates/cc-permissions" }
cc-browser = { path = "crates/cc-browser" }
cc-session = { path = "crates/cc-session" }
# Phase 6 / Phase 7 scaffolds (issues #75, #76).
cc-engine = { path = "crates/cc-engine" }
cc-query = { path = "crates/cc-query" }
cc-tools = { path = "crates/cc-tools" }
cc-lsp-service = { path = "crates/cc-lsp-service" }
cc-plugins = { path = "crates/cc-plugins" }
cc-teams = { path = "crates/cc-teams" }
cc-daemon = { path = "crates/cc-daemon" }
cc-commands = { path = "crates/cc-commands" }
cc-ipc = { path = "crates/cc-ipc" }

# Daemon HTTP server
axum = { version = "0.8", features = ["ws"] }
Expand Down
8 changes: 8 additions & 0 deletions crates/cc-commands/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "cc-commands"
version = "0.1.0"
edition = "2021"
description = "Slash-command implementations (53 commands: /commit, /review, /session, /memory, etc.). Phase 7 workspace split (scaffold)."

[dependencies]
cc-types = { workspace = true }
10 changes: 10 additions & 0 deletions crates/cc-commands/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! cc-commands — slash-command implementations (Phase 7 scaffold).
//!
//! Issue #76 (`[workspace-split] Phase 7`): target destination for
//! `crates/claude-code-rs/src/commands/` (53 commands, ~12.6k LOC — the
//! largest single-module extraction). This crate implements the
//! `CommandDispatcher` trait defined in cc-types::commands.
//!
//! Downstream deps (after full move): cc-engine, cc-plugins, cc-tools,
//! cc-teams, cc-browser, cc-compact, cc-session, cc-voice, cc-keybindings,
//! cc-mcp, cc-sandbox, cc-auth, cc-bootstrap, cc-skills, cc-utils.
8 changes: 8 additions & 0 deletions crates/cc-daemon/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "cc-daemon"
version = "0.1.0"
edition = "2021"
description = "KAIROS daemon: HTTP/SSE server, proactive tick, webhooks, team-memory proxy. Phase 7 workspace split (scaffold)."

[dependencies]
cc-types = { workspace = true }
5 changes: 5 additions & 0 deletions crates/cc-daemon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! cc-daemon — KAIROS daemon HTTP/SSE server (Phase 7 scaffold).
//!
//! Issue #76 (`[workspace-split] Phase 7`): target destination for
//! `crates/claude-code-rs/src/daemon/`. Depends on cc-engine, cc-config, and
//! cc-types.
50 changes: 50 additions & 0 deletions crates/cc-engine/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[package]
name = "cc-engine"
version = "0.1.0"
edition = "2021"
description = "QueryEngine + query loop + AppState + Tool trait + status-line runner (Phase 6 extraction)."

# Phase 6 is being landed incrementally:
#
# Step 1 (this crate, landed): publish an empty scaffold wired into the
# workspace.
#
# Step 2 (in progress): move `src/ui/status_line/` and
# `src/types/{tool, app_state, config}.rs` into this crate — these are the
# last runtime-free-ish items blocking `ToolUseContext` / `AppState` from
# leaving the root crate.
#
# Step 3 (follow-up): move `src/engine/` and `src/query/` into this crate.

[dependencies]
# Async
tokio = { workspace = true }
futures = { workspace = true }
async-trait = { workspace = true }

# Serialization
serde = { workspace = true }
serde_json = { workspace = true }

# Errors / logging
anyhow = { workspace = true }
tracing = { workspace = true }

# Shared primitives
chrono = { workspace = true }
uuid = { workspace = true }
parking_lot = { workspace = true }

# Git (for status-line payload repo lookups)
git2 = { workspace = true }

# Workspace siblings (only leaf / already-extracted crates)
cc-types = { workspace = true }
cc-config = { workspace = true }
cc-bootstrap = { workspace = true }
cc-compact = { workspace = true }
cc-keybindings = { workspace = true }

[dev-dependencies]
tempfile = { workspace = true }
serial_test = { workspace = true }
29 changes: 29 additions & 0 deletions crates/cc-engine/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//! cc-engine — QueryEngine, Agent tool, query-loop driver, and engine-level
//! shared state (Phase 6 — in progress).
//!
//! Issue #75 (`[workspace-split] Phase 6`): this crate is the target
//! destination for `crates/claude-code-rs/src/engine/` plus the engine-level
//! shared structures (`AppState`, `Tool` trait, `ToolUseContext`) and the
//! status-line runner.
//!
//! ## What lives here now
//!
//! - [`status_line`] — scriptable status-line payload + runner, moved from
//! `src/ui/status_line/`. Lives here because `AppState` holds a
//! `StatusLineRunner` handle.
//!
//! ## Coming in follow-up PRs
//!
//! - `types::{tool, app_state, config}` from the root crate
//! - The contents of `src/engine/` and `src/query/`
//!
//! See `docs/superpowers/specs/2026-04-20-workspace-split-design.md`.

pub mod status_line;
pub mod types;

// Re-export from cc-types so consumers can eventually write
// `use cc_engine::{HookRunner, CommandDispatcher}` once the engine types
// land here too.
#[allow(unused_imports)]
pub use cc_types::hooks::{HookRunner, NoopHookRunner};
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use std::path::{Path, PathBuf};
use git2::Repository;
use serde::{Deserialize, Serialize};

use crate::bootstrap::model::ModelSetting;
use crate::compact::auto_compact::get_context_window_size;
use cc_bootstrap::model::ModelSetting;
use cc_compact::auto_compact::get_context_window_size;

/// Top-level payload piped to the user's status-line command on stdin.
///
Expand Down Expand Up @@ -169,6 +169,11 @@ pub struct WorktreeStatus {
}

/// Inputs needed to assemble a concrete status-line payload snapshot.
///
/// `resolved_output_style_name` and `worktree` are pre-computed by callers
/// because resolving them requires root-crate modules (`engine::output_style`
/// and `tools::worktree`) that cc-engine cannot reach. Callers that don't
/// need either field pass `None`.
pub struct StatusLineSnapshot<'a> {
pub session_id: Option<String>,
pub model_id: &'a str,
Expand All @@ -181,8 +186,13 @@ pub struct StatusLineSnapshot<'a> {
pub total_cost_usd: f64,
pub api_calls: u64,
pub session_duration_secs: Option<u64>,
pub output_style: Option<&'a str>,
/// Pre-resolved canonical output-style name. Callers compute this by
/// calling `crate::engine::output_style::resolve(style, cwd).name()`.
pub resolved_output_style_name: Option<String>,
pub editor_mode: Option<&'a str>,
/// Pre-built worktree status. Callers compute this from
/// `crate::tools::worktree::get_current_worktree_session()`.
pub worktree: Option<WorktreeStatus>,
pub streaming: bool,
pub message_count: usize,
}
Expand Down Expand Up @@ -220,9 +230,9 @@ pub fn build_payload_from_snapshot(snapshot: StatusLineSnapshot<'_>) -> StatusLi
api_calls: snapshot.api_calls,
session_duration_secs: snapshot.session_duration_secs,
});
payload.output_style = resolve_output_style_name(snapshot.output_style, snapshot.cwd);
payload.output_style = snapshot.resolved_output_style_name;
payload.vim = vim_status_from_editor_mode(snapshot.editor_mode);
payload.worktree = current_worktree_status();
payload.worktree = snapshot.worktree;
payload.streaming = snapshot.streaming;
payload.message_count = snapshot.message_count;
payload
Expand All @@ -244,16 +254,10 @@ pub fn model_info_from_runtime(model_id: &str, backend: Option<&str>) -> Option<
})
}

pub fn resolve_output_style_name(output_style: Option<&str>, cwd: &Path) -> Option<String> {
output_style
.map(str::trim)
.filter(|style| !style.is_empty())
.map(|style| {
crate::engine::output_style::resolve(style, cwd)
.name()
.to_string()
})
}
// `resolve_output_style_name` used to live here but touched
// `crate::engine::output_style::resolve` in the root crate. Callers now
// pre-resolve the canonical name and pass it via
// `StatusLineSnapshot::resolved_output_style_name`.

pub fn vim_status_from_editor_mode(editor_mode: Option<&str>) -> Option<VimStatus> {
match editor_mode.map(str::trim) {
Expand Down Expand Up @@ -316,27 +320,13 @@ pub fn workspace_status_from_path(cwd: &Path) -> Option<WorkspaceStatus> {
})
}

pub fn current_worktree_status() -> Option<WorktreeStatus> {
let session = crate::tools::worktree::get_current_worktree_session()?;
let name = session
.worktree_path
.file_name()
.and_then(|name| name.to_str())
.filter(|name| !name.is_empty())
.unwrap_or("worktree")
.to_string();

Some(WorktreeStatus {
name,
path: session.worktree_path.display().to_string(),
branch: Some(session.branch_name),
original_cwd: session.original_cwd.display().to_string(),
original_branch: None,
})
}
// `current_worktree_status` used to live here but read the
// `crate::tools::worktree::get_current_worktree_session()` global.
// Callers now build a `WorktreeStatus` themselves and pass it via
// `StatusLineSnapshot::worktree`.

fn project_dir_for_statusline(cwd: &Path, git_root: Option<&Path>) -> Option<PathBuf> {
let configured = crate::bootstrap::state::project_root();
let configured = cc_bootstrap::state::project_root();
if !configured.as_os_str().is_empty() {
return Some(configured);
}
Expand Down Expand Up @@ -470,8 +460,9 @@ mod tests {
total_cost_usd: 0.42,
api_calls: 3,
session_duration_secs: Some(9),
output_style: Some("default"),
resolved_output_style_name: Some("default".into()),
editor_mode: Some("vim"),
worktree: None,
streaming: true,
message_count: 5,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use tokio::task::{AbortHandle, JoinHandle};

use crate::config::settings::StatusLineSettings;
use cc_config::settings::StatusLineSettings;

use super::payload::StatusLinePayload;

Expand Down Expand Up @@ -310,7 +310,7 @@ pub fn payload_from_value(v: Value) -> Result<StatusLinePayload, serde_json::Err
#[cfg(test)]
mod tests {
use super::*;
use crate::config::settings::StatusLineSettings;
use cc_config::settings::StatusLineSettings;

fn make_settings(command: &str) -> StatusLineSettings {
StatusLineSettings {
Expand Down
Loading
Loading