1 Commits

Author SHA1 Message Date
Allegro
40e3e2edbc docs: Add REFERENCE.md - architectural study documentation 2026-03-31 20:56:07 +00:00
7 changed files with 206 additions and 1204 deletions

95
REFERENCE.md Normal file
View File

@@ -0,0 +1,95 @@
# 🎯 Claw Code - Reference Implementation
> **Clean-room Claude Code harness - mirrored for architectural study**
---
## ⚠️ IMPORTANT: Reference Only
This repository is a **mirror** of [instructkr/claw-code](https://github.com/instructkr/claw-code) for:
- ✅ Studying agent harness engineering patterns
- ✅ Comparing tool system architectures
- ✅ Learning clean-room implementation approaches
**Do NOT copy code directly.** Study patterns, then implement independently.
---
## 📊 Stats
| Metric | Value |
|--------|-------|
| **Python** | 2,138 LOC, 66 files |
| **Rust** | 7,619 LOC, 28+ files |
| **Total** | ~10K LOC |
| **Author** | Sigrid Jin (@instructkr) |
| **Origin** | WSJ-featured clean-room rewrite |
---
## 🏗️ Architecture
### Python (`src/`)
```
runtime.py → Agent runtime with routing
├── tools.py → Tool harness (Bash, File, MCP)
├── commands.py → Command system
├── query_engine.py → LLM orchestration
├── permissions.py → Tool permission contexts
└── bootstrap/ → Initialization
```
### Rust (`rust/crates/`)
```
api/ → Anthropic-compatible client
tools/ → Tool system
compat-harness/ → Compatibility layer
rusty-claude-cli/ → CLI interface
```
---
## 🔗 Key Patterns
### 1. Tool Permission Context
```python
@dataclass
class ToolPermissionContext:
deny_tools: set[str]
deny_prefixes: tuple[str, ...]
def blocks(self, tool_name: str) -> bool:
return tool_name in self.deny_tools or \
any(tool_name.startswith(p) for p in self.deny_prefixes)
```
### 2. Execution Registry
- Routes prompts to commands/tools
- Filters by permission context
- Handles execution lifecycle
### 3. Session Persistence
- JSON-based session store
- Turn-by-turn history
- Context preservation
---
## 📖 Branches
- `main` - Python-first implementation
- `dev/rust` - Rust port (active)
- `rcc/*` - Rust CLI components
---
## 🔗 External Links
- **Original Repo**: https://github.com/instructkr/claw-code
- **Author**: @instructkr (Sigrid Jin)
- **Context**: WSJ "The Trillion Dollar Race to Automate Our Entire Lives"
---
*Mirrored to Gitea: March 31, 2026*
*For: Timmy Foundation architectural reference*

View File

@@ -158,10 +158,7 @@ impl AnthropicClient {
.header("anthropic-version", ANTHROPIC_VERSION)
.header("content-type", "application/json");
let auth_header = self
.auth_token
.as_ref()
.map_or("<absent>", |_| "Bearer [REDACTED]");
let auth_header = self.auth_token.as_ref().map(|_| "Bearer [REDACTED]").unwrap_or("<absent>");
eprintln!("[anthropic-client] headers x-api-key=[REDACTED] authorization={auth_header} anthropic-version={ANTHROPIC_VERSION} content-type=application/json");
if let Some(auth_token) = &self.auth_token {
@@ -195,7 +192,8 @@ fn read_api_key() -> Result<String, ApiError> {
Ok(_) => Err(ApiError::MissingApiKey),
Err(std::env::VarError::NotPresent) => match std::env::var("ANTHROPIC_AUTH_TOKEN") {
Ok(api_key) if !api_key.is_empty() => Ok(api_key),
Ok(_) | Err(std::env::VarError::NotPresent) => Err(ApiError::MissingApiKey),
Ok(_) => Err(ApiError::MissingApiKey),
Err(std::env::VarError::NotPresent) => Err(ApiError::MissingApiKey),
Err(error) => Err(ApiError::from(error)),
},
Err(error) => Err(ApiError::from(error)),
@@ -305,22 +303,12 @@ struct AnthropicErrorBody {
#[cfg(test)]
mod tests {
use super::{ALT_REQUEST_ID_HEADER, REQUEST_ID_HEADER};
use std::sync::{Mutex, OnceLock};
use std::time::Duration;
use crate::types::{ContentBlockDelta, MessageRequest};
fn env_lock() -> std::sync::MutexGuard<'static, ()> {
static ENV_LOCK: OnceLock<Mutex<()>> = OnceLock::new();
ENV_LOCK
.get_or_init(|| Mutex::new(()))
.lock()
.expect("env lock should not be poisoned")
}
#[test]
fn read_api_key_requires_presence() {
let _guard = env_lock();
std::env::remove_var("ANTHROPIC_AUTH_TOKEN");
std::env::remove_var("ANTHROPIC_API_KEY");
let error = super::read_api_key().expect_err("missing key should error");
@@ -329,7 +317,6 @@ mod tests {
#[test]
fn read_api_key_requires_non_empty_value() {
let _guard = env_lock();
std::env::set_var("ANTHROPIC_AUTH_TOKEN", "");
std::env::remove_var("ANTHROPIC_API_KEY");
let error = super::read_api_key().expect_err("empty key should error");
@@ -338,7 +325,6 @@ mod tests {
#[test]
fn read_api_key_prefers_api_key_env() {
let _guard = env_lock();
std::env::set_var("ANTHROPIC_AUTH_TOKEN", "auth-token");
std::env::set_var("ANTHROPIC_API_KEY", "legacy-key");
assert_eq!(
@@ -351,7 +337,6 @@ mod tests {
#[test]
fn read_auth_token_reads_auth_token_env() {
let _guard = env_lock();
std::env::set_var("ANTHROPIC_AUTH_TOKEN", "auth-token");
assert_eq!(super::read_auth_token().as_deref(), Some("auth-token"));
std::env::remove_var("ANTHROPIC_AUTH_TOKEN");

View File

@@ -30,168 +30,6 @@ impl CommandRegistry {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SlashCommandSpec {
pub name: &'static str,
pub summary: &'static str,
pub argument_hint: Option<&'static str>,
pub resume_supported: bool,
}
const SLASH_COMMAND_SPECS: &[SlashCommandSpec] = &[
SlashCommandSpec {
name: "help",
summary: "Show available slash commands",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "status",
summary: "Show current session status",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "compact",
summary: "Compact local session history",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "model",
summary: "Show or switch the active model",
argument_hint: Some("[model]"),
resume_supported: false,
},
SlashCommandSpec {
name: "permissions",
summary: "Show or switch the active permission mode",
argument_hint: Some("[read-only|workspace-write|danger-full-access]"),
resume_supported: false,
},
SlashCommandSpec {
name: "clear",
summary: "Start a fresh local session",
argument_hint: Some("[--confirm]"),
resume_supported: true,
},
SlashCommandSpec {
name: "cost",
summary: "Show cumulative token usage for this session",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "resume",
summary: "Load a saved session into the REPL",
argument_hint: Some("<session-path>"),
resume_supported: false,
},
SlashCommandSpec {
name: "config",
summary: "Inspect discovered Claude config files",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "memory",
summary: "Inspect loaded Claude instruction memory files",
argument_hint: None,
resume_supported: true,
},
SlashCommandSpec {
name: "init",
summary: "Create a starter CLAUDE.md for this repo",
argument_hint: None,
resume_supported: true,
},
];
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SlashCommand {
Help,
Status,
Compact,
Model { model: Option<String> },
Permissions { mode: Option<String> },
Clear { confirm: bool },
Cost,
Resume { session_path: Option<String> },
Config,
Memory,
Init,
Unknown(String),
}
impl SlashCommand {
#[must_use]
pub fn parse(input: &str) -> Option<Self> {
let trimmed = input.trim();
if !trimmed.starts_with('/') {
return None;
}
let mut parts = trimmed.trim_start_matches('/').split_whitespace();
let command = parts.next().unwrap_or_default();
Some(match command {
"help" => Self::Help,
"status" => Self::Status,
"compact" => Self::Compact,
"model" => Self::Model {
model: parts.next().map(ToOwned::to_owned),
},
"permissions" => Self::Permissions {
mode: parts.next().map(ToOwned::to_owned),
},
"clear" => Self::Clear {
confirm: parts.next() == Some("--confirm"),
},
"cost" => Self::Cost,
"resume" => Self::Resume {
session_path: parts.next().map(ToOwned::to_owned),
},
"config" => Self::Config,
"memory" => Self::Memory,
"init" => Self::Init,
other => Self::Unknown(other.to_string()),
})
}
}
#[must_use]
pub fn slash_command_specs() -> &'static [SlashCommandSpec] {
SLASH_COMMAND_SPECS
}
#[must_use]
pub fn resume_supported_slash_commands() -> Vec<&'static SlashCommandSpec> {
slash_command_specs()
.iter()
.filter(|spec| spec.resume_supported)
.collect()
}
#[must_use]
pub fn render_slash_command_help() -> String {
let mut lines = vec![
"Available commands:".to_string(),
" (resume-safe commands are marked with [resume])".to_string(),
];
for spec in slash_command_specs() {
let name = match spec.argument_hint {
Some(argument_hint) => format!("/{} {}", spec.name, argument_hint),
None => format!("/{}", spec.name),
};
let resume = if spec.resume_supported {
" [resume]"
} else {
""
};
lines.push(format!(" {name:<20} {}{}", spec.summary, resume));
}
lines.join("\n")
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SlashCommandResult {
pub message: String,
@@ -204,8 +42,13 @@ pub fn handle_slash_command(
session: &Session,
compaction: CompactionConfig,
) -> Option<SlashCommandResult> {
match SlashCommand::parse(input)? {
SlashCommand::Compact => {
let trimmed = input.trim();
if !trimmed.starts_with('/') {
return None;
}
match trimmed.split_whitespace().next() {
Some("/compact") => {
let result = compact_session(session, compaction);
let message = if result.removed_message_count == 0 {
"Compaction skipped: session is below the compaction threshold.".to_string()
@@ -220,90 +63,15 @@ pub fn handle_slash_command(
session: result.compacted_session,
})
}
SlashCommand::Help => Some(SlashCommandResult {
message: render_slash_command_help(),
session: session.clone(),
}),
SlashCommand::Status
| SlashCommand::Model { .. }
| SlashCommand::Permissions { .. }
| SlashCommand::Clear { .. }
| SlashCommand::Cost
| SlashCommand::Resume { .. }
| SlashCommand::Config
| SlashCommand::Memory
| SlashCommand::Init
| SlashCommand::Unknown(_) => None,
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::{
handle_slash_command, render_slash_command_help, resume_supported_slash_commands,
slash_command_specs, SlashCommand,
};
use super::handle_slash_command;
use runtime::{CompactionConfig, ContentBlock, ConversationMessage, MessageRole, Session};
#[test]
fn parses_supported_slash_commands() {
assert_eq!(SlashCommand::parse("/help"), Some(SlashCommand::Help));
assert_eq!(SlashCommand::parse(" /status "), Some(SlashCommand::Status));
assert_eq!(
SlashCommand::parse("/model claude-opus"),
Some(SlashCommand::Model {
model: Some("claude-opus".to_string()),
})
);
assert_eq!(
SlashCommand::parse("/model"),
Some(SlashCommand::Model { model: None })
);
assert_eq!(
SlashCommand::parse("/permissions read-only"),
Some(SlashCommand::Permissions {
mode: Some("read-only".to_string()),
})
);
assert_eq!(
SlashCommand::parse("/clear"),
Some(SlashCommand::Clear { confirm: false })
);
assert_eq!(
SlashCommand::parse("/clear --confirm"),
Some(SlashCommand::Clear { confirm: true })
);
assert_eq!(SlashCommand::parse("/cost"), Some(SlashCommand::Cost));
assert_eq!(
SlashCommand::parse("/resume session.json"),
Some(SlashCommand::Resume {
session_path: Some("session.json".to_string()),
})
);
assert_eq!(SlashCommand::parse("/config"), Some(SlashCommand::Config));
assert_eq!(SlashCommand::parse("/memory"), Some(SlashCommand::Memory));
assert_eq!(SlashCommand::parse("/init"), Some(SlashCommand::Init));
}
#[test]
fn renders_help_from_shared_specs() {
let help = render_slash_command_help();
assert!(help.contains("resume-safe commands"));
assert!(help.contains("/help"));
assert!(help.contains("/status"));
assert!(help.contains("/compact"));
assert!(help.contains("/model [model]"));
assert!(help.contains("/permissions [read-only|workspace-write|danger-full-access]"));
assert!(help.contains("/clear [--confirm]"));
assert!(help.contains("/cost"));
assert!(help.contains("/resume <session-path>"));
assert!(help.contains("/config"));
assert!(help.contains("/memory"));
assert!(help.contains("/init"));
assert_eq!(slash_command_specs().len(), 11);
assert_eq!(resume_supported_slash_commands().len(), 8);
}
#[test]
fn compacts_sessions_via_slash_command() {
let session = Session {
@@ -335,40 +103,8 @@ mod tests {
}
#[test]
fn help_command_is_non_mutating() {
let session = Session::new();
let result = handle_slash_command("/help", &session, CompactionConfig::default())
.expect("help command should be handled");
assert_eq!(result.session, session);
assert!(result.message.contains("Available commands:"));
}
#[test]
fn ignores_unknown_or_runtime_bound_slash_commands() {
fn ignores_unknown_slash_commands() {
let session = Session::new();
assert!(handle_slash_command("/unknown", &session, CompactionConfig::default()).is_none());
assert!(handle_slash_command("/status", &session, CompactionConfig::default()).is_none());
assert!(
handle_slash_command("/model claude", &session, CompactionConfig::default()).is_none()
);
assert!(handle_slash_command(
"/permissions read-only",
&session,
CompactionConfig::default()
)
.is_none());
assert!(handle_slash_command("/clear", &session, CompactionConfig::default()).is_none());
assert!(
handle_slash_command("/clear --confirm", &session, CompactionConfig::default())
.is_none()
);
assert!(handle_slash_command("/cost", &session, CompactionConfig::default()).is_none());
assert!(handle_slash_command(
"/resume session.json",
&session,
CompactionConfig::default()
)
.is_none());
assert!(handle_slash_command("/config", &session, CompactionConfig::default()).is_none());
}
}

View File

@@ -24,10 +24,9 @@ impl UpstreamPaths {
.as_ref()
.canonicalize()
.unwrap_or_else(|_| workspace_dir.as_ref().to_path_buf());
let primary_repo_root = workspace_dir
let repo_root = workspace_dir
.parent()
.map_or_else(|| PathBuf::from(".."), Path::to_path_buf);
let repo_root = resolve_upstream_repo_root(&primary_repo_root);
Self { repo_root }
}
@@ -54,42 +53,6 @@ pub struct ExtractedManifest {
pub bootstrap: BootstrapPlan,
}
fn resolve_upstream_repo_root(primary_repo_root: &Path) -> PathBuf {
let candidates = upstream_repo_candidates(primary_repo_root);
candidates
.into_iter()
.find(|candidate| candidate.join("src/commands.ts").is_file())
.unwrap_or_else(|| primary_repo_root.to_path_buf())
}
fn upstream_repo_candidates(primary_repo_root: &Path) -> Vec<PathBuf> {
let mut candidates = vec![primary_repo_root.to_path_buf()];
if let Some(explicit) = std::env::var_os("CLAUDE_CODE_UPSTREAM") {
candidates.push(PathBuf::from(explicit));
}
for ancestor in primary_repo_root.ancestors().take(4) {
candidates.push(ancestor.join("claude-code"));
candidates.push(ancestor.join("clawd-code"));
}
candidates.push(
primary_repo_root
.join("reference-source")
.join("claude-code"),
);
candidates.push(primary_repo_root.join("vendor").join("claude-code"));
let mut deduped = Vec::new();
for candidate in candidates {
if !deduped.iter().any(|seen: &PathBuf| seen == &candidate) {
deduped.push(candidate);
}
}
deduped
}
pub fn extract_manifest(paths: &UpstreamPaths) -> std::io::Result<ExtractedManifest> {
let commands_source = fs::read_to_string(paths.commands_path())?;
let tools_source = fs::read_to_string(paths.tools_path())?;

View File

@@ -138,9 +138,9 @@ pub fn read_file(
let content = fs::read_to_string(&absolute_path)?;
let lines: Vec<&str> = content.lines().collect();
let start_index = offset.unwrap_or(0).min(lines.len());
let end_index = limit.map_or(lines.len(), |limit| {
start_index.saturating_add(limit).min(lines.len())
});
let end_index = limit
.map(|limit| start_index.saturating_add(limit).min(lines.len()))
.unwrap_or(lines.len());
let selected = lines[start_index..end_index].join("\n");
Ok(ReadFileOutput {
@@ -285,7 +285,7 @@ pub fn grep_search(input: &GrepSearchInput) -> io::Result<GrepSearchOutput> {
.output_mode
.clone()
.unwrap_or_else(|| String::from("files_with_matches"));
let context_window = input.context.or(input.context_short).unwrap_or(0);
let context = input.context.or(input.context_short).unwrap_or(0);
let mut filenames = Vec::new();
let mut content_lines = Vec::new();
@@ -296,12 +296,12 @@ pub fn grep_search(input: &GrepSearchInput) -> io::Result<GrepSearchOutput> {
continue;
}
let Ok(file_content) = fs::read_to_string(&file_path) else {
let Ok(content) = fs::read_to_string(&file_path) else {
continue;
};
if output_mode == "count" {
let count = regex.find_iter(&file_content).count();
let count = regex.find_iter(&content).count();
if count > 0 {
filenames.push(file_path.to_string_lossy().into_owned());
total_matches += count;
@@ -309,7 +309,7 @@ pub fn grep_search(input: &GrepSearchInput) -> io::Result<GrepSearchOutput> {
continue;
}
let lines: Vec<&str> = file_content.lines().collect();
let lines: Vec<&str> = content.lines().collect();
let mut matched_lines = Vec::new();
for (index, line) in lines.iter().enumerate() {
if regex.is_match(line) {
@@ -325,15 +325,15 @@ pub fn grep_search(input: &GrepSearchInput) -> io::Result<GrepSearchOutput> {
filenames.push(file_path.to_string_lossy().into_owned());
if output_mode == "content" {
for index in matched_lines {
let start = index.saturating_sub(input.before.unwrap_or(context_window));
let end = (index + input.after.unwrap_or(context_window) + 1).min(lines.len());
for (current, line_content) in lines.iter().enumerate().take(end).skip(start) {
let start = index.saturating_sub(input.before.unwrap_or(context));
let end = (index + input.after.unwrap_or(context) + 1).min(lines.len());
for current in start..end {
let prefix = if input.line_numbers.unwrap_or(true) {
format!("{}:{}:", file_path.to_string_lossy(), current + 1)
} else {
format!("{}:", file_path.to_string_lossy())
};
content_lines.push(format!("{prefix}{line_content}"));
content_lines.push(format!("{prefix}{}", lines[current]));
}
}
}
@@ -376,7 +376,8 @@ fn collect_search_files(base_path: &Path) -> io::Result<Vec<PathBuf>> {
let mut files = Vec::new();
for entry in WalkDir::new(base_path) {
let entry = entry.map_err(|error| io::Error::other(error.to_string()))?;
let entry =
entry.map_err(|error| io::Error::new(io::ErrorKind::Other, error.to_string()))?;
if entry.file_type().is_file() {
files.push(entry.path().to_path_buf());
}

File diff suppressed because it is too large Load Diff

View File

@@ -146,17 +146,11 @@ pub fn mvp_tool_specs() -> Vec<ToolSpec> {
pub fn execute_tool(name: &str, input: &Value) -> Result<String, String> {
match name {
"bash" => from_value::<BashCommandInput>(input).and_then(run_bash),
"read_file" => from_value::<ReadFileInput>(input).and_then(|input| run_read_file(&input)),
"write_file" => {
from_value::<WriteFileInput>(input).and_then(|input| run_write_file(&input))
}
"edit_file" => from_value::<EditFileInput>(input).and_then(|input| run_edit_file(&input)),
"glob_search" => {
from_value::<GlobSearchInputValue>(input).and_then(|input| run_glob_search(&input))
}
"grep_search" => {
from_value::<GrepSearchInput>(input).and_then(|input| run_grep_search(&input))
}
"read_file" => from_value::<ReadFileInput>(input).and_then(run_read_file),
"write_file" => from_value::<WriteFileInput>(input).and_then(run_write_file),
"edit_file" => from_value::<EditFileInput>(input).and_then(run_edit_file),
"glob_search" => from_value::<GlobSearchInputValue>(input).and_then(run_glob_search),
"grep_search" => from_value::<GrepSearchInput>(input).and_then(run_grep_search),
_ => Err(format!("unsupported tool: {name}")),
}
}
@@ -170,17 +164,15 @@ fn run_bash(input: BashCommandInput) -> Result<String, String> {
.map_err(|error| error.to_string())
}
fn run_read_file(input: &ReadFileInput) -> Result<String, String> {
to_pretty_json(
read_file(&input.path, input.offset, input.limit).map_err(|error| io_to_string(&error))?,
)
fn run_read_file(input: ReadFileInput) -> Result<String, String> {
to_pretty_json(read_file(&input.path, input.offset, input.limit).map_err(io_to_string)?)
}
fn run_write_file(input: &WriteFileInput) -> Result<String, String> {
to_pretty_json(write_file(&input.path, &input.content).map_err(|error| io_to_string(&error))?)
fn run_write_file(input: WriteFileInput) -> Result<String, String> {
to_pretty_json(write_file(&input.path, &input.content).map_err(io_to_string)?)
}
fn run_edit_file(input: &EditFileInput) -> Result<String, String> {
fn run_edit_file(input: EditFileInput) -> Result<String, String> {
to_pretty_json(
edit_file(
&input.path,
@@ -188,25 +180,23 @@ fn run_edit_file(input: &EditFileInput) -> Result<String, String> {
&input.new_string,
input.replace_all.unwrap_or(false),
)
.map_err(|error| io_to_string(&error))?,
.map_err(io_to_string)?,
)
}
fn run_glob_search(input: &GlobSearchInputValue) -> Result<String, String> {
to_pretty_json(
glob_search(&input.pattern, input.path.as_deref()).map_err(|error| io_to_string(&error))?,
)
fn run_glob_search(input: GlobSearchInputValue) -> Result<String, String> {
to_pretty_json(glob_search(&input.pattern, input.path.as_deref()).map_err(io_to_string)?)
}
fn run_grep_search(input: &GrepSearchInput) -> Result<String, String> {
to_pretty_json(grep_search(input).map_err(|error| io_to_string(&error))?)
fn run_grep_search(input: GrepSearchInput) -> Result<String, String> {
to_pretty_json(grep_search(&input).map_err(io_to_string)?)
}
fn to_pretty_json<T: serde::Serialize>(value: T) -> Result<String, String> {
serde_json::to_string_pretty(&value).map_err(|error| error.to_string())
}
fn io_to_string(error: &std::io::Error) -> String {
fn io_to_string(error: std::io::Error) -> String {
error.to_string()
}