From 68c91359130fef51a757c91f8eac990e28d6b999 Mon Sep 17 00:00:00 2001 From: "Dhanji R. Prasanna" Date: Sat, 10 Jan 2026 15:20:40 +1100 Subject: [PATCH] Fix research tool UI: remove duplicate header, add footer spacing, remove spinner, widen command display - Remove duplicate tool header (lib.rs already prints it) - Add newline before timing footer for visual separation - Remove spinner animation (incompatible with update_tool_output_line) - Change shell command format to " > `cmd` ..." with 60 char width --- crates/g3-cli/src/ui_writer_impl.rs | 2 + crates/g3-core/src/tools/research.rs | 298 +- docs/tools.md | 20 +- tmp/adam_streaming_proxy.html | 793 +++ tmp/anthropic_best_practices.html | 37 + tmp/async_stream_docs.html | 413 ++ tmp/biriukov_backpressure.html | 590 ++ tmp/changelog_search.html | 25 + tmp/claude_code_docs.html | 121 + tmp/claude_code_product.html | 9857 ++++++++++++++++++++++++++ tmp/duckduckgo_reqwest.html | 25 + tmp/duckduckgo_results.html | 25 + tmp/github_claude_code.html | 1923 +++++ tmp/introl_guide.html | 4964 +++++++++++++ tmp/npm_claude_code.html | 41 + tmp/poespas_streaming.html | 129 + tmp/rust_homepage.html | 380 + tmp/rust_release.html | 231 + tmp/search_results.html | 25 + tmp/tokio_channels.html | 335 + tmp/tokio_stream_docs.html | 344 + tmp/venturebeat_claude_code.html | 304 + 22 files changed, 20843 insertions(+), 39 deletions(-) create mode 100644 tmp/adam_streaming_proxy.html create mode 100644 tmp/anthropic_best_practices.html create mode 100644 tmp/async_stream_docs.html create mode 100644 tmp/biriukov_backpressure.html create mode 100644 tmp/changelog_search.html create mode 100644 tmp/claude_code_docs.html create mode 100644 tmp/claude_code_product.html create mode 100644 tmp/duckduckgo_reqwest.html create mode 100644 tmp/duckduckgo_results.html create mode 100644 tmp/github_claude_code.html create mode 100644 tmp/introl_guide.html create mode 100644 tmp/npm_claude_code.html create mode 100644 tmp/poespas_streaming.html create mode 100644 tmp/rust_homepage.html create mode 100644 tmp/rust_release.html create mode 100644 tmp/search_results.html create mode 100644 tmp/tokio_channels.html create mode 100644 tmp/tokio_stream_docs.html create mode 100644 tmp/venturebeat_claude_code.html diff --git a/crates/g3-cli/src/ui_writer_impl.rs b/crates/g3-cli/src/ui_writer_impl.rs index 191cc24..96e2ed4 100644 --- a/crates/g3-cli/src/ui_writer_impl.rs +++ b/crates/g3-cli/src/ui_writer_impl.rs @@ -231,6 +231,8 @@ impl UiWriter for ConsoleUiWriter { } fn print_tool_timing(&self, duration_str: &str, tokens_delta: u32, context_percentage: f32) { + // Add blank line before footer for visual separation + println!(); // Parse the duration string to determine color // Format is like "1.5s", "500ms", "2m 30.0s" let color_code = if duration_str.ends_with("ms") { diff --git a/crates/g3-core/src/tools/research.rs b/crates/g3-core/src/tools/research.rs index 424aa08..14181a0 100644 --- a/crates/g3-core/src/tools/research.rs +++ b/crates/g3-core/src/tools/research.rs @@ -14,12 +14,134 @@ use super::executor::ToolContext; const REPORT_START_MARKER: &str = "---SCOUT_REPORT_START---"; const REPORT_END_MARKER: &str = "---SCOUT_REPORT_END---"; -/// Execute the research tool by spawning a scout agent. +/// Translate scout agent output lines into friendly progress messages. /// -/// This tool: -/// 1. Spawns `g3 --agent scout` with the query -/// 2. Captures stdout and extracts the report between delimiter markers -/// 3. Returns the report content directly +/// Parses tool call headers from the scout output and returns human-readable +/// progress messages. Returns None for lines that should be suppressed. +fn translate_progress(line: &str) -> Option { + // Strip ANSI codes first for pattern matching + let clean_line = strip_ansi_codes(line); + let trimmed = clean_line.trim(); + + // Tool call header pattern: "┌─ tool_name" or "┌─ tool_name | args" + if !trimmed.starts_with("┌─") { + return None; + } + + // Extract tool name and optional args after the box drawing char + let after_prefix = trimmed.trim_start_matches("┌─").trim(); + + // Split on " | " to separate tool name from args + let (tool_name, args) = if let Some(pipe_pos) = after_prefix.find(" | ") { + let name = after_prefix[..pipe_pos].trim(); + let arg = after_prefix[pipe_pos + 3..].trim(); + (name, Some(arg)) + } else { + (after_prefix.trim(), None) + }; + + // Translate tool names to friendly messages + match tool_name { + "webdriver_start" => Some("🌐 Launching browser...".to_string()), + + "webdriver_navigate" => { + if let Some(url) = args { + // Extract domain from URL for cleaner display + let display_url = extract_domain(url).unwrap_or(url); + Some(format!("🔗 Navigating to {}...", display_url)) + } else { + Some("🔗 Navigating...".to_string()) + } + } + + "webdriver_get_page_source" => { + if let Some(arg) = args { + // arg might be max_length or file path + if arg.contains('/') || arg.ends_with(".html") || arg.ends_with(".md") { + let filename = arg.rsplit('/').next().unwrap_or(arg); + Some(format!("📥 Downloading {}...", filename)) + } else { + Some("📄 Reading page content...".to_string()) + } + } else { + Some("📄 Reading page content...".to_string()) + } + } + + "webdriver_find_element" | "webdriver_find_elements" => { + Some("🔍 Searching page...".to_string()) + } + + "webdriver_click" => Some("👆 Clicking element...".to_string()), + + "webdriver_quit" => Some("✅ Closing browser...".to_string()), + + "read_file" => { + if let Some(path) = args { + // Check if there's a range specified (format: "filename [start..end]") + if let Some(bracket_pos) = path.find(" [") { + let filename = path[..bracket_pos].rsplit('/').next().unwrap_or(&path[..bracket_pos]); + let range = &path[bracket_pos + 1..]; // includes "[start..end]" + Some(format!("📖 Reading {} slice {}...", filename, range.trim_end_matches(']').trim_start_matches('['))) + } else { + let filename = path.rsplit('/').next().unwrap_or(path); + Some(format!("📖 Reading {}...", filename)) + } + } else { + Some("📖 Reading file...".to_string()) + } + } + + "write_file" => { + if let Some(path) = args { + let filename = path.rsplit('/').next().unwrap_or(path); + Some(format!("💾 Writing {}...", filename)) + } else { + Some("💾 Writing file...".to_string()) + } + } + + "shell" => { + if let Some(cmd) = args { + // Show a truncated snippet of the command with wider display + let snippet = truncate_command_snippet(cmd, 60); + Some(format!(" > `{}` ...", snippet)) + } else { + Some("⚙️ Running command...".to_string()) + } + } + + // Suppress unknown tools - don't show raw output + _ => None, + } +} + +/// Extract domain from a URL for cleaner display. +fn extract_domain(url: &str) -> Option<&str> { + // Remove protocol + let without_protocol = url + .strip_prefix("https://") + .or_else(|| url.strip_prefix("http://")) + .unwrap_or(url); + + // Get just the domain (before any path) + without_protocol.split('/').next() +} + +/// Truncate a command to a maximum length for display. +/// Preserves the beginning of the command and adds "..." if truncated. +fn truncate_command_snippet(cmd: &str, max_len: usize) -> String { + // Take just the first line if multi-line + let first_line = cmd.lines().next().unwrap_or(cmd); + + if first_line.chars().count() <= max_len { + first_line.to_string() + } else { + let truncated: String = first_line.chars().take(max_len - 3).collect(); + format!("{}...", truncated) + } +} + pub async fn execute_research( tool_call: &ToolCall, ctx: &mut ToolContext<'_, W>, @@ -30,9 +152,6 @@ pub async fn execute_research( .and_then(|v| v.as_str()) .ok_or_else(|| anyhow::anyhow!("Missing required 'query' parameter"))?; - ctx.ui_writer.print_tool_header("research", None); - ctx.ui_writer.print_tool_arg("query", query); - // Find the g3 executable path let g3_path = std::env::current_exe() .unwrap_or_else(|_| std::path::PathBuf::from("g3")); @@ -57,13 +176,15 @@ pub async fn execute_research( let mut reader = BufReader::new(stdout).lines(); let mut all_output = Vec::new(); - // Print a header for the scout output - ctx.ui_writer.println("\n📡 Scout agent researching..."); - - // Collect all lines + // Collect all lines, showing only translated progress messages while let Some(line) = reader.next_line().await? { - ctx.ui_writer.println(&format!(" {}", line)); - all_output.push(line); + all_output.push(line.clone()); + + // Show translated progress for tool calls + if let Some(progress_msg) = translate_progress(&line) { + // Update the status line in-place (no spinner) + ctx.ui_writer.update_tool_output_line(&progress_msg); + } } // Wait for the process to complete @@ -77,15 +198,23 @@ pub async fn execute_research( // Join all output and extract the report between markers let full_output = all_output.join("\n"); - extract_report(&full_output) + let report = extract_report(&full_output)?; + + // Print the research brief to the console for scrollback reference + // The report is printed without stripping ANSI codes to preserve formatting + ctx.ui_writer.println(""); + ctx.ui_writer.println(&report); + ctx.ui_writer.println(""); + + Ok(report) } /// Extract the research report from scout output. /// /// Looks for content between SCOUT_REPORT_START and SCOUT_REPORT_END markers. -/// Strips ANSI escape codes from the extracted content. +/// Preserves ANSI escape codes in the extracted content for terminal formatting. fn extract_report(output: &str) -> Result { - // Strip ANSI codes from the entire output first + // Strip ANSI codes only for finding markers, but preserve them in the output let clean_output = strip_ansi_codes(output); // Find the start marker @@ -106,9 +235,16 @@ fn extract_report(output: &str) -> Result { return Err(anyhow::anyhow!("Invalid report format: end marker before start marker")); } - // Extract content between markers - let report_start = start_pos + REPORT_START_MARKER.len(); - let report_content = clean_output[report_start..end_pos].trim(); + // Now find the same markers in the original output to preserve ANSI codes + // We need to find the marker positions accounting for ANSI codes + let original_start = find_marker_position(output, REPORT_START_MARKER) + .ok_or_else(|| anyhow::anyhow!("Could not find start marker in original output"))?; + let original_end = find_marker_position(output, REPORT_END_MARKER) + .ok_or_else(|| anyhow::anyhow!("Could not find end marker in original output"))?; + + // Extract content between markers from original (with ANSI codes) + let report_start = original_start + REPORT_START_MARKER.len(); + let report_content = output[report_start..original_end].trim(); if report_content.is_empty() { return Ok("❌ Scout agent returned an empty report.".to_string()); @@ -117,6 +253,20 @@ fn extract_report(output: &str) -> Result { Ok(format!("📋 Research Report:\n\n{}", report_content)) } +/// Find the position of a marker in text that may contain ANSI codes. +/// Searches by stripping ANSI codes character by character to find the true position. +fn find_marker_position(text: &str, marker: &str) -> Option { + // Simple approach: search for the marker directly first + // The markers themselves shouldn't contain ANSI codes + if let Some(pos) = text.find(marker) { + return Some(pos); + } + + // If not found directly, the marker might be split by ANSI codes + // This is unlikely for our use case, but handle it gracefully + None +} + /// Strip ANSI escape codes from a string. /// /// Handles common ANSI sequences like: @@ -237,4 +387,112 @@ Some trailing text"#; let result = extract_report(output).unwrap(); assert!(result.contains("empty report")); } + + #[test] + fn test_extract_domain() { + assert_eq!(extract_domain("https://www.rust-lang.org/"), Some("www.rust-lang.org")); + assert_eq!(extract_domain("https://python.org/downloads"), Some("python.org")); + assert_eq!(extract_domain("http://example.com"), Some("example.com")); + assert_eq!(extract_domain("example.com/path"), Some("example.com")); + } + + #[test] + fn test_translate_progress_webdriver_start() { + let line = "┌─ webdriver_start"; + assert_eq!(translate_progress(line), Some("🌐 Launching browser...".to_string())); + } + + #[test] + fn test_translate_progress_webdriver_navigate() { + let line = "┌─ webdriver_navigate | https://www.rust-lang.org/"; + assert_eq!(translate_progress(line), Some("🔗 Navigating to www.rust-lang.org...".to_string())); + } + + #[test] + fn test_translate_progress_webdriver_get_page_source() { + // With max_length arg (number) + let line = "┌─ webdriver_get_page_source | 15000"; + assert_eq!(translate_progress(line), Some("📄 Reading page content...".to_string())); + + // With file path + let line = "┌─ webdriver_get_page_source | tmp/rust_release.html"; + assert_eq!(translate_progress(line), Some("📥 Downloading rust_release.html...".to_string())); + } + + #[test] + fn test_translate_progress_webdriver_find_elements() { + let line = "┌─ webdriver_find_elements | .download-os-source, .download-for-current-os"; + assert_eq!(translate_progress(line), Some("🔍 Searching page...".to_string())); + } + + #[test] + fn test_translate_progress_webdriver_quit() { + let line = "┌─ webdriver_quit"; + assert_eq!(translate_progress(line), Some("✅ Closing browser...".to_string())); + } + + #[test] + fn test_translate_progress_read_file() { + // Without range + let line = "┌─ read_file | /path/to/file.rs"; + assert_eq!(translate_progress(line), Some("📖 Reading file.rs...".to_string())); + + // With range (file slice) + let line = "┌─ read_file | /path/to/file.rs [1000..2000]"; + assert_eq!(translate_progress(line), Some("📖 Reading file.rs slice 1000..2000...".to_string())); + } + + #[test] + fn test_translate_progress_write_file() { + let line = "┌─ write_file | output.md"; + assert_eq!(translate_progress(line), Some("💾 Writing output.md...".to_string())); + } + + #[test] + fn test_translate_progress_shell() { + let line = "┌─ shell | ls -la"; + assert_eq!(translate_progress(line), Some(" > `ls -la` ...".to_string())); + } + + #[test] + fn test_translate_progress_with_ansi_codes() { + // Real output from scout agent has ANSI codes + let line = "\x1b[1;38;5;69m┌─ webdriver_start\x1b[0m"; + assert_eq!(translate_progress(line), Some("🌐 Launching browser...".to_string())); + + let line = "\x1b[1;38;5;69m┌─ webdriver_navigate\x1b[0m\x1b[35m | https://www.python.org/\x1b[0m"; + assert_eq!(translate_progress(line), Some("🔗 Navigating to www.python.org...".to_string())); + } + + #[test] + fn test_translate_progress_suppresses_non_tool_lines() { + assert_eq!(translate_progress("Some random output"), None); + assert_eq!(translate_progress("│ Page source (59851 chars)"), None); + assert_eq!(translate_progress("└─ ⚡️ 1.5s"), None); + assert_eq!(translate_progress(""), None); + } + + #[test] + fn test_truncate_command_snippet() { + // Short command - no truncation + assert_eq!(truncate_command_snippet("ls -la", 40), "ls -la"); + + // Long command - truncated + let long_cmd = "grep -r 'some very long search pattern' --include='*.rs' /path/to/directory"; + let result = truncate_command_snippet(long_cmd, 40); + assert!(result.len() <= 40); + assert!(result.ends_with("...")); + + // Multi-line command - only first line + let multi_line = "echo 'line1'\necho 'line2'"; + assert_eq!(truncate_command_snippet(multi_line, 40), "echo 'line1'"); + } + + #[test] + fn test_translate_progress_shell_long_command() { + let line = "┌─ shell | grep -r 'some very long search pattern that exceeds the limit' --include='*.rs'"; + let result = translate_progress(line).unwrap(); + assert!(result.starts_with(" > `grep")); + assert!(result.contains("...")); + } } diff --git a/docs/tools.md b/docs/tools.md index 0a87b38..0386186 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -11,7 +11,7 @@ This document describes all tools available to the G3 agent. Tools are the prima | Category | Tools | Enabled By | |----------|-------|------------| -| **Core** | shell, read_file, write_file, str_replace, final_output, background_process | Always | +| **Core** | shell, read_file, write_file, str_replace, background_process | Always | | **Images** | read_image, take_screenshot | Always | | **Task Management** | todo_read, todo_write | Always | | **Code Intelligence** | code_search, code_coverage | Always | @@ -151,24 +151,6 @@ Apply a unified diff to a file. --- -### final_output - -Signal task completion with a summary. - -**Parameters**: -- `summary` (string, required): Markdown summary of what was accomplished - -**Example**: -```json -{"tool": "final_output", "args": {"summary": "## Completed\n\n- Created user authentication module\n- Added unit tests\n- Updated documentation"}} -``` - -**Notes**: -- Ends the current task -- Summary is displayed to the user -- In autonomous mode, triggers coach review - ---- ## Image & Screenshot Tools diff --git a/tmp/adam_streaming_proxy.html b/tmp/adam_streaming_proxy.html new file mode 100644 index 0000000..71c822f --- /dev/null +++ b/tmp/adam_streaming_proxy.html @@ -0,0 +1,793 @@ + + + + + + + + + + + + + + + + + + + Static streams for faster async proxies + + + + + + + + + + + + + Skip to content +
+
+

+ Adam Chalmers +

+ +
+
+ + +
+
+

Static streams for faster async proxies

+
+ + + +
+

Last week in Tokio's Discord chat server someone asked a really interesting question: how can you stream a multipart body from an incoming request into an outgoing request? My struggle to answer this really helped me understand Rust async lifetimes. We'll explore why this is tricky, then design and benchmark a solution.

+ +

Note: all the code is in a full GitHub example.

+
+

The question was:

+
+

I'm rather new to Rust, so perhaps I'm trying to bite off more than I can chew, but I can't find any way to stream an axum::extract::multipart::Field to the body of a PUT request made with reqwest. Obviously, waiting for all the bytes works just fine, as in this test handler:

+
+
use axum::{extract, Extension};
+use reqwest::StatusCode;
+
+/// An Axum request handler. 
+async fn upload(
+    // The request body should be a Multipart.
+    mut multipart: extract::Multipart,
+    // The server should set a reqwest::Client in the extensions.
+    Extension(client): Extension<reqwest::Client>,
+// If this function succeeds, return HTTP 200 and the Ok string as the body.
+// If it fails, return the given status code and the Err string as the body.
+) -> Result<String, (StatusCode, String)> {
+
+    // Get the first field of the multipart request.
+    if let Some(field) = multipart.next_field().await.unwrap() {
+        client
+            .put(url::Url::parse("https://example.com/file").unwrap())
+            .body(field.bytes().await.unwrap())
+            .send()
+            .await
+            .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Oops".to_string()))
+            .map(|_| "Yay".to_string())
+    } else {
+        Err((StatusCode::INTERNAL_SERVER_ERROR, "Oh no".to_string()))
+    }
+}
+
+
+

Everything I've found for using a stream as the request body requires that the stream be 'static, which of course the fields I'm getting from multipart aren't.

+
+

The problem sounded very simple -- the server should stream a request in, and stream a request out -- so I figured I'd help this person out, for two reasons:

+
    +
  1. It's nice to help people and I am Very Nice
  2. +
  3. My dayjob is writing a streaming HTTP proxy in Rust, so this would be good practice.
  4. +
+

But it turned out to be harder than I thought.

+

Why streaming instead of buffering?

+

Why not just buffer the whole body into memory? Is streaming really that important? Well, yeah -- if you're building a proxy, streaming is worth the extra headache, for two reasons:

+

First, latency is worse with buffering. Your proxy has to buffer the entire request from the client before sending it to the server. This doubles the latency of requests (assuming all three hosts are equidistant). You have to wait n seconds for the request to reach the proxy, then n seconds to transmit it to the server. But if your proxy used streams, you could get the first few bytes from the client, and send them to the server while you waited for the next few bytes from the client.

+

Second, memory overhead is huge with buffering. Say you're proxying a 10gb MacOS system update file. If you buffer every request into memory, your server can't handle many parallel requests (probably <10). But with streaming, you can get the first n bytes the client, proxy them to the server, and then free them. No more crashing the process because it ran out of memory.

+

So we really want our proxy server to stream requests. There's just one problem. Our HTTP server and HTTP client seem to have contradictory lifetimes.

+

The problem

+

Axum's Multipart extractor owns the incoming request body. It has a method next_field that returns a Field type. That Field is a view into the data from the main Multipart body. It just borrows part of the multipart data. This means the Field is actually Field<'a> where 'a is the lifetime of the Multipart that created it.

+

Field borrows from Multipart

+

Clearly the field can't outlive the Multipart, because then Field would be pointing at data that is no longer there. Rust borrow checker stops us from doing that. So far so good.

+

You can read data from a stream, either by reading the whole thing into memory (as above), or using the Stream trait. This trait is defined by the Futures crate here and implemented here. Streams are basically asynchronous iterators. When you try to get the next value from them, it might not be ready yet, so you have to .await. This is perfect for reading HTTP request bodies, because you can start processing the body as it comes in piece-by-piece. If the next bytes aren't available, your runtime (e.g. Tokio) will switch to a different task until the data arrives.

+

This means you don't have to wait for the entire body to be available, saving time and maybe RAM, if you don't actually need to store the entire body.

+

So, now we know how to stream data out of the body. What about streaming data into a new request's body?

+

We'll use reqwest as the HTTP client. Reqwest can send various things as HTTP bodies -- strings, vectors of bytes, and even streams, using the wrap_stream method. The problem is, the stream has to be 'static, a special lifetime which means "either it's not borrowed, or it's borrowed for the entire length of the program". This means we can't use Field as a reqwest body, because it's not 'static. It's borrowed, and it's only valid for as long as the Multipart that owns it.

+

Why does reqwest only allow static streams to be bodies? I asked its creator Sean McArthur.

+
+

Sean: Internally the connection is in a separate task, to manage connection-level stuff (keep alive, if http2: pings, settings, and flow control). The body gets sent to that connection task

+
+
+

Adam: So basically the connection task takes ownership of all request bodies? And therefore bodies have to be 'static because they need to be moved into that task?

+
+
+

Sean: Exactly

+
+

But there is a solution. The field type is Field<'a>, so it's generic over various possible lifetimes. We just need to make sure that the specific lifetime our server uses is 'static.

+

The solution

+

Note that the Multipart object itself is 'static. Why? Because it's not borrowed. The next_field type signature is next_field(&mut self) -> Field<'_>. What's that '_? That's an elided lifetime. Basically these two signatures are equivalent:

+
fn next_field(&'a mut self) -> Field<'a>
+fn next_field(&mut self) -> Field<'_>
+
+

So, the field type is Field<'a>, but that 'a is generic. Its definition works for any possible lifetime. We just have to make sure that when our server's handler is compiled, it knows that 'a is 'static.

+

The key insight is that, if you want to use a stream as a reqwest body, it can't borrow anything. Because if it borrowed data from some other thread which owns data, what happens if the owning thread dies? Your body would keep reading from the freed memory, and Rust won't let that happen. This means the stream has to own all the data being streamed.

+

So, the stream needs to own the Multipart! After all, the multipart owns the data, and the stream has to own the data. So the stream has to own the multipart.

+

Once I realized that, the solution emerged. We'll define a new type of Stream that owns a Multipart and streams data out of its fields.

+
use axum::{body::Bytes, extract, extract::multipart::MultipartError};
+use futures::prelude::Stream;
+
+/// Wrapper for axum's Multipart type. 
+struct MultipartStream(extract::Multipart);
+
+impl MultipartStream {
+    /// Stream every byte from every field.
+    fn into_stream(mut self) -> impl Stream<Item = Result<Bytes, MultipartError>> {
+        // Create a stream using crates.io/crates/async-stream
+        async_stream::stream! {
+            while let Some(field) = self.0.next_field().await.unwrap() {
+                // Special syntax from the stream! macro.
+                // Basically streams items out of the `field` stream.
+                for await value in field {
+                    yield value;
+                }
+            }
+        }
+    }
+}
+
+

We make a newtype for converting a Multipart into a Stream. I'm Very Creative so I chose the imaginative name MultipartStream. It owns the Multipart, and its into_stream method consumes (aka takes ownership of) self, so that method also owns the Multipart. This means the Multipart is 'static. The method creates a stream, using the stream! macro from the async-stream crate. And that stream then takes ownership of self and therefore the Multipart.

+

All this means that the stream doesn't borrow anything. It owns all its data -- both the multipart and its fields -- so the stream is 'static. Now you can pass it to reqweset::Body::wrap_stream.

+

Note: the into_stream example is very rudimentary -- it concatenates all the fields together. This probably wouldn't be useful. In a real server you might want to only stream certain fields, or maybe filter out fields, or maybe only stream the nth field.

+

The last thing to do is actually use this MultipartStream wrapper in our endpoint.

+
/// State for the proxy server.
+/// See https://docs.rs/axum/0.6.0-rc.1/axum/extract/struct.State.html
+#[derive(Clone)]
+struct ProxyState {
+    dst_port: u16,
+    client: reqwest::Client,
+}
+
+async fn proxy_upload_streaming(
+    // the State parameter can be destructed right here in the function signature, so let's
+    // destructure it and unpack its two fields.
+    State(ProxyState { dst_port, client }): State<ProxyState>,
+    // The incoming request's multipart body.
+    incoming_body: extract::Multipart,
+) -> Result<String, (StatusCode, String)> {
+
+    // Stream the incoming request's body, into the outgoing request's body.
+    let stream = MultipartStream(incoming_body).into_stream();
+    let outgoing_body = reqwest::Body::wrap_stream(stream);
+
+    // Send the outgoing request
+    client
+        .post(url::Url::parse(&format!("http://127.0.0.1:{dst_port}/")).unwrap())
+        .body(outgoing_body)
+        .send()
+        .await
+        .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))
+        .map(|_| format!("All OK\n"))
+}
+
+

Note, this example uses Axum 0.6.0-rc.1 with its new State types. It's possible that it might change a little before the final 0.6 release. See the announcement for more. State is basically like an Axum extension where the compiler can guarantee it's always set. This perfectly solves the problem my previous post about Axum complained about, where I know the extension is always set, but the compiler doesn't, so I need a dubious .unwrap()

+

Benchmarks

+

I ran some benchmarks on the repo. Basically I used curl to send the proxy server a Multipart body with 20 copies of the Unix wordlist. Then the server proxied it to a second server, which prints it. I compared the streaming proxy above, with a proxy that buffers everything. You can see the full setup in the GitHub example.

+

Because I ran this all locally, I don't expect much difference in total time. After all, the latency between processes running on my Macbook is pretty low. So doubling the latency won't matter much, because the latency is nearly zero anyway. But I expect the RAM usage to be very different.

+ + + +
Time (seconds)RAM (mb)
Streaming0.1016
Buffering0.32128
+

Yep, streaming saves a lot of memory.

+

Takeaways

+
    +
  • reqwest connections are handled in their own thread, so they need to own their bodies. +
      +
    • This is just a design choice -- other HTTP libraries could work differently, although tide and actix web client also require streaming bodies be 'static.
    • +
    • I think this is partly because of the Tokio runtime, and other runtimes might not require 'static, see this talk from the creator of glommio.
    • +
    +
  • +
  • 'static means "this value either isn't borrowed, or is borrowed for the entire runtime of the program"
  • +
  • A static stream can't borrow any data
  • +
  • Implementing your own streams with async-stream is pretty easy
  • +
+
+ +
+
+ +
+ + + + +
+ + +
+
+

+ © Adam Chalmers 2026
+ Powered by Zola, Theme Anpu. +

+

+ + +

+
+
+ + + + \ No newline at end of file diff --git a/tmp/anthropic_best_practices.html b/tmp/anthropic_best_practices.html new file mode 100644 index 0000000..f18ea96 --- /dev/null +++ b/tmp/anthropic_best_practices.html @@ -0,0 +1,37 @@ +
Engineering at Anthropic

Claude Code: Best practices for agentic coding

We recently released Claude Code, a command line tool for agentic coding. Developed as a research project, Claude Code gives Anthropic engineers and researchers a more native way to integrate Claude into their coding workflows.

Claude Code is intentionally low-level and unopinionated, providing close to raw model access without forcing specific workflows. This design philosophy creates a flexible, customizable, scriptable, and safe power tool. While powerful, this flexibility presents a learning curve for engineers new to agentic coding tools—at least until they develop their own best practices.

This post outlines general patterns that have proven effective, both for Anthropic's internal teams and for external engineers using Claude Code across various codebases, languages, and environments. Nothing in this list is set in stone nor universally applicable; consider these suggestions as starting points. We encourage you to experiment and find what works best for you!

Looking for more detailed information? Our comprehensive documentation at claude.ai/code covers all the features mentioned in this post and provides additional examples, implementation details, and advanced techniques.

1. Customize your setup

Claude Code is an agentic coding assistant that automatically pulls context into prompts. This context gathering consumes time and tokens, but you can optimize it through environment tuning.

a. Create CLAUDE.md files

CLAUDE.md is a special file that Claude automatically pulls into context when starting a conversation. This makes it an ideal place for documenting:

  • Common bash commands
  • Core files and utility functions
  • Code style guidelines
  • Testing instructions
  • Repository etiquette (e.g., branch naming, merge vs. rebase, etc.)
  • Developer environment setup (e.g., pyenv use, which compilers work)
  • Any unexpected behaviors or warnings particular to the project
  • Other information you want Claude to remember

There’s no required format for CLAUDE.md files. We recommend keeping them concise and human-readable. For example:

# Bash commands
+- npm run build: Build the project
+- npm run typecheck: Run the typechecker
+
+# Code style
+- Use ES modules (import/export) syntax, not CommonJS (require)
+- Destructure imports when possible (eg. import { foo } from 'bar')
+
+# Workflow
+- Be sure to typecheck when you’re done making a series of code changes
+- Prefer running single tests, and not the whole test suite, for performance

You can place CLAUDE.md files in several locations:

  • The root of your repo, or wherever you run claude from (the most common usage). Name it CLAUDE.md and check it into git so that you can share it across sessions and with your team (recommended), or name it CLAUDE.local.md and .gitignore it
  • Any parent of the directory where you run claude. This is most useful for monorepos, where you might run claude from root/foo, and have CLAUDE.md files in both root/CLAUDE.md and root/foo/CLAUDE.md. Both of these will be pulled into context automatically
  • Any child of the directory where you run claude. This is the inverse of the above, and in this case, Claude will pull in CLAUDE.md files on demand when you work with files in child directories
  • Your home folder (~/.claude/CLAUDE.md), which applies it to all your claude sessions

When you run the /init command, Claude will automatically generate a CLAUDE.md for you.

b. Tune your CLAUDE.md files

Your CLAUDE.md files become part of Claude’s prompts, so they should be refined like any frequently used prompt. A common mistake is adding extensive content without iterating on its effectiveness. Take time to experiment and determine what produces the best instruction following from the model.

You can add content to your CLAUDE.md manually or press the # key to give Claude an instruction that it will automatically incorporate into the relevant CLAUDE.md. Many engineers use # frequently to document commands, files, and style guidelines while coding, then include CLAUDE.md changes in commits so team members benefit as well.

At Anthropic, we occasionally run CLAUDE.md files through the prompt improver and often tune instructions (e.g. adding emphasis with "IMPORTANT" or "YOU MUST") to improve adherence.

Claude Code tool allowlist

c. Curate Claude's list of allowed tools

By default, Claude Code requests permission for any action that might modify your system: file writes, many bash commands, MCP tools, etc. We designed Claude Code with this deliberately conservative approach to prioritize safety. You can customize the allowlist to permit additional tools that you know are safe, or to allow potentially unsafe tools that are easy to undo (e.g., file editing, git commit).

There are four ways to manage allowed tools:

  • Select "Always allow" when prompted during a session.
  • Use the /permissions command after starting Claude Code to add or remove tools from the allowlist. For example, you can add Edit to always allow file edits, Bash(git commit:*) to allow git commits, or mcp__puppeteer__puppeteer_navigate to allow navigating with the Puppeteer MCP server.
  • Manually edit your .claude/settings.json or ~/.claude.json (we recommend checking the former into source control to share with your team).
  • Use the --allowedTools CLI flag for session-specific permissions.

d. If using GitHub, install the gh CLI

Claude knows how to use the gh CLI to interact with GitHub for creating issues, opening pull requests, reading comments, and more. Without gh installed, Claude can still use the GitHub API or MCP server (if you have it installed).

2. Give Claude more tools

Claude has access to your shell environment, where you can build up sets of convenience scripts and functions for it just like you would for yourself. It can also leverage more complex tools through MCP and REST APIs.

a. Use Claude with bash tools

Claude Code inherits your bash environment, giving it access to all your tools. While Claude knows common utilities like unix tools and gh, it won't know about your custom bash tools without instructions:

  1. Tell Claude the tool name with usage examples
  2. Tell Claude to run --help to see tool documentation
  3. Document frequently used tools in CLAUDE.md

b. Use Claude with MCP

Claude Code functions as both an MCP server and client. As a client, it can connect to any number of MCP servers to access their tools in three ways:

  • In project config (available when running Claude Code in that directory)
  • In global config (available in all projects)
  • In a checked-in .mcp.json file (available to anyone working in your codebase). For example, you can add Puppeteer and Sentry servers to your .mcp.json, so that every engineer working on your repo can use these out of the box.

When working with MCP, it can also be helpful to launch Claude with the --mcp-debug flag to help identify configuration issues.

c. Use custom slash commands

For repeated workflows—debugging loops, log analysis, etc.—store prompt templates in Markdown files within the .claude/commands folder. These become available through the slash commands menu when you type /. You can check these commands into git to make them available for the rest of your team.

Custom slash commands can include the special keyword $ARGUMENTS to pass parameters from command invocation.

For example, here’s a slash command that you could use to automatically pull and fix a Github issue:

Please analyze and fix the GitHub issue: $ARGUMENTS.
+
+Follow these steps:
+
+1. Use `gh issue view` to get the issue details
+2. Understand the problem described in the issue
+3. Search the codebase for relevant files
+4. Implement the necessary changes to fix the issue
+5. Write and run tests to verify the fix
+6. Ensure code passes linting and type checking
+7. Create a descriptive commit message
+8. Push and create a PR
+
+Remember to use the GitHub CLI (`gh`) for all GitHub-related tasks.

Putting the above content into .claude/commands/fix-github-issue.md makes it available as the /project:fix-github-issue command in Claude Code. You could then for example use /project:fix-github-issue 1234 to have Claude fix issue #1234. Similarly, you can add your own personal commands to the ~/.claude/commands folder for commands you want available in all of your sessions.

3. Try common workflows

Claude Code doesn’t impose a specific workflow, giving you the flexibility to use it how you want. Within the space this flexibility affords, several successful patterns for effectively using Claude Code have emerged across our community of users:

a. Explore, plan, code, commit

This versatile workflow suits many problems:

  1. Ask Claude to read relevant files, images, or URLs, providing either general pointers ("read the file that handles logging") or specific filenames ("read logging.py"), but explicitly tell it not to write any code just yet.
    1. This is the part of the workflow where you should consider strong use of subagents, especially for complex problems. Telling Claude to use subagents to verify details or investigate particular questions it might have, especially early on in a conversation or task, tends to preserve context availability without much downside in terms of lost efficiency.
  2. Ask Claude to make a plan for how to approach a specific problem. We recommend using the word "think" to trigger extended thinking mode, which gives Claude additional computation time to evaluate alternatives more thoroughly. These specific phrases are mapped directly to increasing levels of thinking budget in the system: "think" < "think hard" < "think harder" < "ultrathink." Each level allocates progressively more thinking budget for Claude to use.
    1. If the results of this step seem reasonable, you can have Claude create a document or a GitHub issue with its plan so that you can reset to this spot if the implementation (step 3) isn’t what you want.
  3. Ask Claude to implement its solution in code. This is also a good place to ask it to explicitly verify the reasonableness of its solution as it implements pieces of the solution.
  4. Ask Claude to commit the result and create a pull request. If relevant, this is also a good time to have Claude update any READMEs or changelogs with an explanation of what it just did.

Steps #1-#2 are crucial—without them, Claude tends to jump straight to coding a solution. While sometimes that's what you want, asking Claude to research and plan first significantly improves performance for problems requiring deeper thinking upfront.

b. Write tests, commit; code, iterate, commit

This is an Anthropic-favorite workflow for changes that are easily verifiable with unit, integration, or end-to-end tests. Test-driven development (TDD) becomes even more powerful with agentic coding:

  1. Ask Claude to write tests based on expected input/output pairs. Be explicit about the fact that you’re doing test-driven development so that it avoids creating mock implementations, even for functionality that doesn’t exist yet in the codebase.
  2. Tell Claude to run the tests and confirm they fail. Explicitly telling it not to write any implementation code at this stage is often helpful.
  3. Ask Claude to commit the tests when you’re satisfied with them.
  4. Ask Claude to write code that passes the tests, instructing it not to modify the tests. Tell Claude to keep going until all tests pass. It will usually take a few iterations for Claude to write code, run the tests, adjust the code, and run the tests again.
    1. At this stage, it can help to ask it to verify with independent subagents that the implementation isn’t overfitting to the tests
  5. Ask Claude to commit the code once you’re satisfied with the changes.

Claude performs best when it has a clear target to iterate against—a visual mock, a test case, or another kind of output. By providing expected outputs like tests, Claude can make changes, evaluate results, and incrementally improve until it succeeds.

c. Write code, screenshot result, iterate

Similar to the testing workflow, you can provide Claude with visual targets:

  1. Give Claude a way to take browser screenshots (e.g., with the Puppeteer MCP server, an iOS simulator MCP server, or manually copy / paste screenshots into Claude).
  2. Give Claude a visual mock by copying / pasting or drag-dropping an image, or giving Claude the image file path.
  3. Ask Claude to implement the design in code, take screenshots of the result, and iterate until its result matches the mock.
  4. Ask Claude to commit when you're satisfied.

Like humans, Claude's outputs tend to improve significantly with iteration. While the first version might be good, after 2-3 iterations it will typically look much better. Give Claude the tools to see its outputs for best results.

Safe yolo mode

d. Safe YOLO mode

Instead of supervising Claude, you can use claude --dangerously-skip-permissions to bypass all permission checks and let Claude work uninterrupted until completion. This works well for workflows like fixing lint errors or generating boilerplate code.

Letting Claude run arbitrary commands is risky and can result in data loss, system corruption, or even data exfiltration (e.g., via prompt injection attacks). To minimize these risks, use --dangerously-skip-permissions in a container without internet access. You can follow this reference implementation using Docker Dev Containers.

e. Codebase Q&A

When onboarding to a new codebase, use Claude Code for learning and exploration. You can ask Claude the same sorts of questions you would ask another engineer on the project when pair programming. Claude can agentically search the codebase to answer general questions like:

  • How does logging work?
  • How do I make a new API endpoint?
  • What does async move { ... } do on line 134 of foo.rs?
  • What edge cases does CustomerOnboardingFlowImpl handle?
  • Why are we calling foo() instead of bar() on line 333?
  • What’s the equivalent of line 334 of baz.py in Java?

At Anthropic, using Claude Code in this way has become our core onboarding workflow, significantly improving ramp-up time and reducing load on other engineers. No special prompting is required! Simply ask questions, and Claude will explore the code to find answers.

Use Claude to interact with git

f. Use Claude to interact with git

Claude can effectively handle many git operations. Many Anthropic engineers use Claude for 90%+ of our git interactions:

  • Searching git history to answer questions like "What changes made it into v1.2.3?", "Who owns this particular feature?", or "Why was this API designed this way?" It helps to explicitly prompt Claude to look through git history to answer queries like these.
  • Writing commit messages. Claude will look at your changes and recent history automatically to compose a message taking all the relevant context into account
  • Handling complex git operations like reverting files, resolving rebase conflicts, and comparing and grafting patches

g. Use Claude to interact with GitHub

Claude Code can manage many GitHub interactions:

  • Creating pull requests: Claude understands the shorthand "pr" and will generate appropriate commit messages based on the diff and surrounding context.
  • Implementing one-shot resolutions for simple code review comments: just tell it to fix comments on your PR (optionally, give it more specific instructions) and push back to the PR branch when it's done.
  • Fixing failing builds or linter warnings
  • Categorizing and triaging open issues by asking Claude to loop over open GitHub issues

This eliminates the need to remember gh command line syntax while automating routine tasks.

h. Use Claude to work with Jupyter notebooks

Researchers and data scientists at Anthropic use Claude Code to read and write Jupyter notebooks. Claude can interpret outputs, including images, providing a fast way to explore and interact with data. There are no required prompts or workflows, but a workflow we recommend is to have Claude Code and a .ipynb file open side-by-side in VS Code.

You can also ask Claude to clean up or make aesthetic improvements to your Jupyter notebook before you show it to colleagues. Specifically telling it to make the notebook or its data visualizations “aesthetically pleasing” tends to help remind it that it’s optimizing for a human viewing experience.

4. Optimize your workflow

The suggestions below apply across all workflows:

a. Be specific in your instructions

Claude Code’s success rate improves significantly with more specific instructions, especially on first attempts. Giving clear directions upfront reduces the need for course corrections later.

For example:

PoorGood
add tests for foo.pywrite a new test case for foo.py, covering the edge case where the user is logged out. avoid mocks
why does ExecutionFactory have such a weird api?look through ExecutionFactory's git history and summarize how its api came to be
add a calendar widgetlook at how existing widgets are implemented on the home page to understand the patterns and specifically how code and interfaces are separated out. HotDogWidget.php is a good example to start with. then, follow the pattern to implement a new calendar widget that lets the user select a month and paginate forwards/backwards to pick a year. Build from scratch without libraries other than the ones already used in the rest of the codebase.

Claude can infer intent, but it can't read minds. Specificity leads to better alignment with expectations.

Give Claude images

b. Give Claude images

Claude excels with images and diagrams through several methods:

  • Paste screenshots (pro tip: hit cmd+ctrl+shift+4 in macOS to screenshot to clipboard and ctrl+v to paste. Note that this is not cmd+v like you would usually use to paste on mac and does not work remotely.)
  • Drag and drop images directly into the prompt input
  • Provide file paths for images

This is particularly useful when working with design mocks as reference points for UI development, and visual charts for analysis and debugging. If you are not adding visuals to context, it can still be helpful to be clear with Claude about how important it is for the result to be visually appealing.

Mention files you want Claude to look at or work on

c. Mention files you want Claude to look at or work on

Use tab-completion to quickly reference files or folders anywhere in your repository, helping Claude find or update the right resources.

Give Claude URLs

d. Give Claude URLs

Paste specific URLs alongside your prompts for Claude to fetch and read. To avoid permission prompts for the same domains (e.g., docs.foo.com), use /permissions to add domains to your allowlist.

e. Course correct early and often

While auto-accept mode (shift+tab to toggle) lets Claude work autonomously, you'll typically get better results by being an active collaborator and guiding Claude's approach. You can get the best results by thoroughly explaining the task to Claude at the beginning, but you can also course correct Claude at any time.

These four tools help with course correction:

  • Ask Claude to make a plan before coding. Explicitly tell it not to code until you’ve confirmed its plan looks good.
  • Press Escape to interrupt Claude during any phase (thinking, tool calls, file edits), preserving context so you can redirect or expand instructions.
  • Double-tap Escape to jump back in history, edit a previous prompt, and explore a different direction. You can edit the prompt and repeat until you get the result you're looking for.
  • Ask Claude to undo changes, often in conjunction with option #2 to take a different approach.

Though Claude Code occasionally solves problems perfectly on the first attempt, using these correction tools generally produces better solutions faster.

f. Use /clear to keep context focused

During long sessions, Claude's context window can fill with irrelevant conversation, file contents, and commands. This can reduce performance and sometimes distract Claude. Use the /clear command frequently between tasks to reset the context window.

g. Use checklists and scratchpads for complex workflows

For large tasks with multiple steps or requiring exhaustive solutions—like code migrations, fixing numerous lint errors, or running complex build scripts—improve performance by having Claude use a Markdown file (or even a GitHub issue!) as a checklist and working scratchpad:

For example, to fix a large number of lint issues, you can do the following:

  1. Tell Claude to run the lint command and write all resulting errors (with filenames and line numbers) to a Markdown checklist
  2. Instruct Claude to address each issue one by one, fixing and verifying before checking it off and moving to the next

h. Pass data into Claude

Several methods exist for providing data to Claude:

  • Copy and paste directly into your prompt (most common approach)
  • Pipe into Claude Code (e.g., cat foo.txt | claude), particularly useful for logs, CSVs, and large data
  • Tell Claude to pull data via bash commands, MCP tools, or custom slash commands
  • Ask Claude to read files or fetch URLs (works for images too)

Most sessions involve a combination of these approaches. For example, you can pipe in a log file, then tell Claude to use a tool to pull in additional context to debug the logs.

5. Use headless mode to automate your infra

Claude Code includes headless mode for non-interactive contexts like CI, pre-commit hooks, build scripts, and automation. Use the -p flag with a prompt to enable headless mode, and --output-format stream-json for streaming JSON output.

Note that headless mode does not persist between sessions. You have to trigger it each session.

a. Use Claude for issue triage

Headless mode can power automations triggered by GitHub events, such as when a new issue is created in your repository. For example, the public Claude Code repository uses Claude to inspect new issues as they come in and assign appropriate labels.

b. Use Claude as a linter

Claude Code can provide subjective code reviews beyond what traditional linting tools detect, identifying issues like typos, stale comments, misleading function or variable names, and more.

6. Uplevel with multi-Claude workflows

Beyond standalone usage, some of the most powerful applications involve running multiple Claude instances in parallel:

a. Have one Claude write code; use another Claude to verify

A simple but effective approach is to have one Claude write code while another reviews or tests it. Similar to working with multiple engineers, sometimes having separate context is beneficial:

  1. Use Claude to write code
  2. Run /clear or start a second Claude in another terminal
  3. Have the second Claude review the first Claude's work
  4. Start another Claude (or /clear again) to read both the code and review feedback
  5. Have this Claude edit the code based on the feedback

You can do something similar with tests: have one Claude write tests, then have another Claude write code to make the tests pass. You can even have your Claude instances communicate with each other by giving them separate working scratchpads and telling them which one to write to and which one to read from.

This separation often yields better results than having a single Claude handle everything.

b. Have multiple checkouts of your repo

Rather than waiting for Claude to complete each step, something many engineers at Anthropic do is:

  1. Create 3-4 git checkouts in separate folders
  2. Open each folder in separate terminal tabs
  3. Start Claude in each folder with different tasks
  4. Cycle through to check progress and approve/deny permission requests

c. Use git worktrees

This approach shines for multiple independent tasks, offering a lighter-weight alternative to multiple checkouts. Git worktrees allow you to check out multiple branches from the same repository into separate directories. Each worktree has its own working directory with isolated files, while sharing the same Git history and reflog.

Using git worktrees enables you to run multiple Claude sessions simultaneously on different parts of your project, each focused on its own independent task. For instance, you might have one Claude refactoring your authentication system while another builds a completely unrelated data visualization component. Since the tasks don't overlap, each Claude can work at full speed without waiting for the other's changes or dealing with merge conflicts:

  1. Create worktrees: git worktree add ../project-feature-a feature-a
  2. Launch Claude in each worktree: cd ../project-feature-a && claude
  3. Create additional worktrees as needed (repeat steps 1-2 in new terminal tabs)

Some tips:

  • Use consistent naming conventions
  • Maintain one terminal tab per worktree
  • If you’re using iTerm2 on Mac, set up notifications for when Claude needs attention
  • Use separate IDE windows for different worktrees
  • Clean up when finished: git worktree remove ../project-feature-a

d. Use headless mode with a custom harness

claude -p (headless mode) integrates Claude Code programmatically into larger workflows while leveraging its built-in tools and system prompt. There are two primary patterns for using headless mode:

1. Fanning out handles large migrations or analyses (e.g., analyzing sentiment in hundreds of logs or analyzing thousands of CSVs):

  1. Have Claude write a script to generate a task list. For example, generate a list of 2k files that need to be migrated from framework A to framework B.
  2. Loop through tasks, calling Claude programmatically for each and giving it a task and a set of tools it can use. For example: claude -p “migrate foo.py from React to Vue. When you are done, you MUST return the string OK if you succeeded, or FAIL if the task failed.” --allowedTools Edit Bash(git commit:*)
  3. Run the script several times and refine your prompt to get the desired outcome.

2. Pipelining integrates Claude into existing data/processing pipelines:

  1. Call claude -p “<your prompt>” --json | your_command, where your_command is the next step of your processing pipeline
  2. That’s it! JSON output (optional) can help provide structure for easier automated processing.

For both of these use cases, it can be helpful to use the --verbose flag for debugging the Claude invocation. We generally recommend turning verbose mode off in production for cleaner output.

What are your tips and best practices for working with Claude Code? Tag @AnthropicAI so we can see what you're building!

Acknowledgements

Written by Boris Cherny. This work draws upon best practices from across the broader Claude Code user community, whose creative approaches and workflows continue to inspire us. Special thanks also to Daisy Hollman, Ashwin Bhat, Cat Wu, Sid Bidasaria, Cal Rueb, Nodir Turakulov, Barry Zhang, Drew Hodun and many other Anthropic engineers whose valuable insights and practical experience with Claude Code helped shape these recommendations.

Get the developer newsletter

Product updates, how-tos, community spotlights, and more. Delivered monthly to your inbox.

Please provide your email address if you’d like to receive our monthly developer newsletter. You can unsubscribe at any time.

Claude Code Best Practices \ Anthropic \ No newline at end of file diff --git a/tmp/async_stream_docs.html b/tmp/async_stream_docs.html new file mode 100644 index 0000000..8b652fb --- /dev/null +++ b/tmp/async_stream_docs.html @@ -0,0 +1,413 @@ +async_stream - Rust + + + +
+
+ + + + +
+ Settings +
+
+ Help +
+

Crate async_stream

Crate async_stream 

Source +
+ Search +
+
+ Settings +
+
+ Help +
+
Expand description

Asynchronous stream of elements.

+

Provides two macros, stream! and try_stream!, allowing the caller to +define asynchronous streams of elements. These are implemented using async +& await notation. This crate works without unstable features.

+

The stream! macro returns an anonymous type implementing the Stream +trait. The Item associated type is the type of the values yielded from the +stream. The try_stream! also returns an anonymous type implementing the +Stream trait, but the Item associated type is Result<T, Error>. The +try_stream! macro supports using ? notation as part of the +implementation.

+

§Usage

+

A basic stream yielding numbers. Values are yielded using the yield +keyword. The stream block must return ().

+ +
use async_stream::stream;
+
+use futures_util::pin_mut;
+use futures_util::stream::StreamExt;
+
+#[tokio::main]
+async fn main() {
+    let s = stream! {
+        for i in 0..3 {
+            yield i;
+        }
+    };
+
+    pin_mut!(s); // needed for iteration
+
+    while let Some(value) = s.next().await {
+        println!("got {}", value);
+    }
+}
+

Streams may be returned by using impl Stream<Item = T>:

+ +
use async_stream::stream;
+
+use futures_core::stream::Stream;
+use futures_util::pin_mut;
+use futures_util::stream::StreamExt;
+
+fn zero_to_three() -> impl Stream<Item = u32> {
+    stream! {
+        for i in 0..3 {
+            yield i;
+        }
+    }
+}
+
+#[tokio::main]
+async fn main() {
+    let s = zero_to_three();
+    pin_mut!(s); // needed for iteration
+
+    while let Some(value) = s.next().await {
+        println!("got {}", value);
+    }
+}
+

Streams may be implemented in terms of other streams - async-stream provides for await +syntax to assist with this:

+ +
use async_stream::stream;
+
+use futures_core::stream::Stream;
+use futures_util::pin_mut;
+use futures_util::stream::StreamExt;
+
+fn zero_to_three() -> impl Stream<Item = u32> {
+    stream! {
+        for i in 0..3 {
+            yield i;
+        }
+    }
+}
+
+fn double<S: Stream<Item = u32>>(input: S)
+    -> impl Stream<Item = u32>
+{
+    stream! {
+        for await value in input {
+            yield value * 2;
+        }
+    }
+}
+
+#[tokio::main]
+async fn main() {
+    let s = double(zero_to_three());
+    pin_mut!(s); // needed for iteration
+
+    while let Some(value) = s.next().await {
+        println!("got {}", value);
+    }
+}
+

Rust try notation (?) can be used with the try_stream! macro. The Item +of the returned stream is Result with Ok being the value yielded and +Err the error type returned by ?.

+ +
use tokio::net::{TcpListener, TcpStream};
+
+use async_stream::try_stream;
+use futures_core::stream::Stream;
+
+use std::io;
+use std::net::SocketAddr;
+
+fn bind_and_accept(addr: SocketAddr)
+    -> impl Stream<Item = io::Result<TcpStream>>
+{
+    try_stream! {
+        let mut listener = TcpListener::bind(addr).await?;
+
+        loop {
+            let (stream, addr) = listener.accept().await?;
+            println!("received on {:?}", addr);
+            yield stream;
+        }
+    }
+}

§Implementation

+

The stream! and try_stream! macros are implemented using proc macros. +The macro searches the syntax tree for instances of yield $expr and +transforms them into sender.send($expr).await.

+

The stream uses a lightweight sender to send values from the stream +implementation to the caller. When entering the stream, an Option<T> is +stored on the stack. A pointer to the cell is stored in a thread local and +poll is called on the async block. When poll returns. +sender.send(value) stores the value that cell and yields back to the +caller.

+

Macros§

stream
Asynchronous stream
try_stream
Asynchronous fallible stream
\ No newline at end of file diff --git a/tmp/biriukov_backpressure.html b/tmp/biriukov_backpressure.html new file mode 100644 index 0000000..1c4d4d6 --- /dev/null +++ b/tmp/biriukov_backpressure.html @@ -0,0 +1,590 @@ + + + + + + + + + + + + + +Async Rust with Tokio I/O Streams: Backpressure, Concurrency, and Ergonomics | Viacheslav Biriukov + + + + + + + + + + + + + + + + + + +
+ + +
+
+ +
+ + + Async Rust with Tokio I/O Streams: Backpressure, Concurrency, and Ergonomics + + +
+ + + + +
+ + + +

+ Async Rust with Tokio I/O Streams: Backpressure, Concurrency, and Ergonomics + # +

+

+ + + +

+

Contents

+ +
+

There are many excellent, straightforward guides for getting started with Async Rust and Tokio. Most focus on the core building blocks: Tokio primitives, Rust futures, and concepts such as Pin/Unpin, and often finish with a simple TCP client-server sample. In fact, the typical tutorial example can usually be reduced to something as simple as:

+
loop {
+    tokio::select! {
+        Some(msg) = rx.recv() => {
+            stream.write_all(&msg).await?;
+            stream.flush().await?;
+        }
+
+        res = stream.read(&mut read_buf) => {
+            let n = res?;
+            if n == 0 {
+                // EOF - server closed connection
+                eprintln!("Server closed the connection.");
+                break; //exit
+            }
+            print!("{}", String::from_utf8_lossy(&read_buf[..n]));
+        }
+
+        else => break
+    }
+}
+

The code above is easy to read, straightforward, and idiomatic.

+

It uses a Tokio mpsc receiver rx whose incoming messages are written to the I/O stream (the remote peer in TCP terms). +On the other branch of the select!, it reads data into read_buf until reaching the end of file (EOF). +I’m sure you’ve seen many examples that follow exactly this pattern.

+

But if we think not only about the functionality of the above code, but also about the mechanics and design behind it, some crucial details emerge. +With the loop-select pattern we have concurrent reads and writes. +This means the Tokio runtime scheduler multiplexes them and runs sequentially one after another, and never truly in parallel on two OS threads or CPU cores (assuming the default multithreaded runtime with #[tokio::main]). +All branches of the select! are awaited for readiness and then run one by one in a pseudo-random order, unless the biased; argument is set, in which case they run in the provided order. +In our example, we have two branches:

+
    +
  • read from rx channel;
  • +
  • read from the I/O stream.
  • +
+

Async Rust implicitly generates a state machine to make the polling of futures easier. This allows select! to run its branches concurrently. But when we fall inside the first branch and explicitly await inside it, we ask Rust to move the task’s state machine into a state where the only possible wake signal for the task is a wake notification from the write_all() future (or flush() later). The code logic doesn’t allow us to await on write_all()/flush() and read() (from the second branch of the select!) at the same time .

+

Code written in this way naturally introduces backpressure. This side effect deserves careful attention and a clear understanding.

+

+ Backpressure + # +

+This is fine +

If a write() or flush() call becomes blocked for any reason, the entire loop-select is effectively blocked as well, meaning no reads will occur. +This can lead to read starvation and, if the remote peer continues writing, to an inflated receive socket buffer and eventual backpressure on the remote peer side.

+

Such backpressure can actually be useful when the code should avoid reading more data if it can’t send a timely response. +In client-server communication, this makes sense: your server might not want to start processing work, or buffer it in memory, if the client isn’t ready to read the response to its request.

+

But as usual, there’s no one-size-fits-all solution, it isn’t always the desired behavior. For example, if your code acts as a proxy or bridge, you’ll likely still want to continue draining the reader buffer, because, for example, the decision logic lives outside your module.

+

Another use case is when producing data doesn’t fully depend on what you read. +This often applies on the client side: a client may want to receive the response to a previously sent request as quickly as possible while concurrently sending a new, unrelated one.

+

More examples are protocols where reads unblock writes, where reads are crucial and should always be handled. For instance, TCP itself is such a protocol. TCP flow control sends window size updates with ACKs to notify the remote peer to continue sending and/or increase the amount of in-flight data. HTTP/2 also has a WINDOW_UPDATE frame used for the same purpose – the consumer controls the producer’s pace.

+

+ Experiment + # +

+

Let’s run a small experiment to reproduce TCP backpressure and explore a few related GNU/Linux tools.

+

We can write a TCP server that intentionally blocks its read calls. Also in order to trigger backpressure earlier, server sets its socket receive buffer to the minimum allowed value with setsockopt and SO_RCVBUF (the OS rounds it up to a small default value):

+
...
+let s2 = Socket::from(std_stream);
+s2.set_recv_buffer_size(1)?;
+...
+

If server doesn’t read data from buffer, its receive buffer fills up and pushes back on the TCP sender. +This effectively simulates slow request processing, for example, when the next request hits a slow database while the previous response is still being flushed to the socket to deliver to the client.

+
async fn handle_client(mut stream: TcpStream) -> std::io::Result<()> {
+    println!("start serving");
+
+    let mut i = 0;
+    loop {
+        // Don't read any data to emulate backpressure.
+        // let mut buf = [0u8; 1024];
+        // let n = stream.read(&mut buf).await?;
+        // if n == 0 {
+        //     break;
+        // }
+        // println!("Received {n} bytes");
+
+        i += 1;
+        sleep(Duration::from_millis(10)).await;
+
+        stream
+            .write_all(format!("message from server: {i}\n").as_bytes())
+            .await?;
+        stream.flush().await?;
+        println!("written: {i}");
+    }
+}
+

The full code can be found on github.

+

And run it:

+
$ cargo run --bin 1_server_recvbuf_set
+

In the other console window run the client:

+
$ cargo run --bin 1_client_simple
+

As you can see from the output logs, the client stops reading from the server even while the server keeps writing. Packets pile up in the client’s receive buffer, eventually filling it and forcing TCP to apply backpressure in the opposite direction.

+

In the tcpdump output you can see the server on port 8080 sending a zero-window (win 0) ACKs, notifying the client that its receive buffer is full.

+
$ sudo tcpdump -i any  -n -s0 port 8080
+...
+21:36:00.095027 lo    In  IP 127.0.0.1.8080 > 127.0.0.1.58090: Flags [P.], seq 5668:5693, ack 102401, win 0, options [nop,nop,TS val 2038288450 ecr 2038288438], length 25: HTTP
+...
+

The ss can help us too to find the stalled send buffer:

+
$ ss -tan | grep 127.0.0.1:58090
+State  Recv-Q Send-Q  Local Address:Port  Peer Address:Port
+ESTAB  102400 0           127.0.0.1:8080     127.0.0.1:58090
+ESTAB  869937 2628271     127.0.0.1:58090    127.0.0.1:8080
+

In simplified terms, the TCP connection behaves like a network of queues. Congestion control and flow control cooperate to size those queues, balance throughput, and protect each endpoint from overload.

+TCP buffers +
+ Figure 1. – TCP buffers for simplex communication +
+

Usually write calls to a socket complete almost instantly (0.5-5 µs depending on size) because they land in memory (userspace buffers such as BufWriter or the kernel’s TCP send buffer) without waiting for remote acknowledgements.

+

This asynchronous nature of writes can hide subtle problems: background write failures, timeouts, and uncertainty of delivery often surface only under congestion. In our toy setup, small writes and generous buffers mask pending backpressure.

+
+

Note:

+

A useful per-socket/system-wide setting to improve responsiveness and backpressure behavior is TCP_NOTSENT_LOWAT. Cloudflare has a good write-up.

+ +
+ +

+ Cancellation + # +

+

Another interesting part of the code is how to perform cancellation while backpressure is applied. We might need to stop processing for many reasons: restart, upstream/downstream abort, timeouts, or simply because the caller no longer needs the result.

+

In the code above, simply adding a cancellation branch to select! will not work if the task is blocked on write_all():

+
let cancel = CancellationToken::new();
+
+loop {
+    tokio::select! {
+        Some(msg) = rx.recv() => {
+            stream.write_all(&msg).await?;
+            stream.flush().await?;
+            println!("client's written");
+        }
+
+        res = stream.read(&mut read_buf) => {
+            let n = res?;
+            if n == 0 {
+                // EOF - server closed connection
+                eprintln!("Server closed the connection.");
+                break; //exit
+            }
+            print!("{}", String::from_utf8_lossy(&read_buf[..n]));
+        }
+
+        _ = cancel.cancelled() => break, // <---------------- cancellation
+
+        else => break
+    }
+}
+

At that point the state machine awaits only write_all(), remaining stuck in Poll::Pending inside the first branch.

+

The first idea is to apply the cancellation token through every await calls:

+
let cancel = CancellationToken::new();
+
+loop {
+    tokio::select! {
+        Some(msg) = rx.recv() => {
+            tokio::select! {
+                res = stream.write_all(&msg) => res,
+                _ = cancel.cancelled() => break
+            }?;
+            tokio::select! {
+                res = stream.flush() => res,
+                _ = cancel.cancelled() => break
+            }?;
+            println!("client's written");
+        }
+
+        res = stream.read(&mut read_buf) => {
+            let n = res?;
+            if n == 0 {
+                // EOF - server closed connection
+                eprintln!("Server closed the connection.");
+                break; //exit
+            }
+            print!("{}", String::from_utf8_lossy(&read_buf[..n]));
+        }
+
+        _ = cancel.cancelled() => break,
+
+        else => break
+    }
+}
+

This works, but it scales poorly: every new await point needs another nested select!, and readability drops fast.

+

Later in the post I’ll show a tidier cancellation pattern, especially if you need a simple “short-circuit” solution.

+ + + + + + + + Read next chapter → + + +
+ + + +
+ +
+ + + + + +
+ + + + + + + +
+ + + +
+ +
+ + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tmp/changelog_search.html b/tmp/changelog_search.html new file mode 100644 index 0000000..2ff7585 --- /dev/null +++ b/tmp/changelog_search.html @@ -0,0 +1,25 @@ +claude code CLI changelog release notes 2025 at DuckDuckGo
  1. 21 Dec 2025This changelog is maintained based on official release notes and community reports. For the most current information, always refer to the official Claude Code documentation and GitHub releases.
  2. 4 days agoLooking for the latest releases? This changelog documents Claude Code's version history through December 2025. For the most current updates, run claude --version in your terminal. v2.0.65 Model switching - Switch models mid-prompt with Alt+P (Option+P on Mac) Context info - View detailed context window information File suggestions - Added setting to configure file suggestion behavior Shell ...
  3. 3 days agoClaude Code Changelog Complete version history of Claude Code releases, from early beta versions to the latest stable release. Each version includes feature additions, bug fixes, and links to relevant documentation. Need to downgrade? See our Revert Claude Code Version guide.
  4. 19 Dec 2025Updates to the Claude Developer Platform, including the Claude API, client SDKs, and the Claude Console. For release notes on Claude Apps, see the Release notes for Claude Apps in the Claude Help Center. For updates to Claude Code, see the complete CHANGELOG.md in the claude-code repository.
  5. ClaudeCode - Main interface with session managementClaudeCode.Session - GenServer for CLI subprocess management ClaudeCode.CLI - Binary detection and command buildingClaudeCode.Options - Options validation and CLI conversionClaudeCode.Stream - Stream utilities for real-time processingClaudeCode.Message - Unified message parsingClaudeCode ...
  6. 30 Dec 2025I'm Oikon. I typically share Claude Code insights on X (Twitter). As this eventful year of 2025 draws to a close, I wanted to reflect on Claude Code. For me personally, 2025 was the year AI agents took a massive leap forward. More specifically, it was the year of Claude Code. The Claude Code CHANGELOG has been updated 176 times total. I have verified and tested every release since at least v1.0.x.
  7. 12 Dec 2025The December 2025 Claude Code CLI update transformed workflows from sequential to parallel processing. You can now run long tasks (build monitoring, log analysis) in the background while immediately starting main tasks, reducing development cycles by 20-30%.
  8. 21 Dec 2025July 2025 - Major Release Version 1.0.0 - Initial comprehensive release Complete guide for Cursor and Claude Code 200+ articles across all sections Enterprise development patterns MCP ecosystem integration Comprehensive appendices
  9. Generate answer for claude code CLI changelog release notes 2025
Custom date rangeX
\ No newline at end of file diff --git a/tmp/claude_code_docs.html b/tmp/claude_code_docs.html new file mode 100644 index 0000000..3841611 --- /dev/null +++ b/tmp/claude_code_docs.html @@ -0,0 +1,121 @@ +Not Found - Claude Docs
    \ No newline at end of file diff --git a/tmp/claude_code_product.html b/tmp/claude_code_product.html new file mode 100644 index 0000000..4cf905c --- /dev/null +++ b/tmp/claude_code_product.html @@ -0,0 +1,9857 @@ +Claude Code - AI coding agent for terminal & IDE | Claude + + + + + + + + + + + + + + + + + + +
    + +
    Debugging...

    Claude Code: AI-powered coding assistant for developers

    Built for
    develo

    Work with Claude directly in your codebase. Build, debug, and ship from your terminal, IDE, Slack, or the web. Describe what you need, and Claude handles the rest.

    +
    Or read the documentation
    Try Claude Code
    Developer docs

    Use Claude Code where you work

    Terminal

    Work with Claude directly in your terminal. Claude explores your codebase context, answers questions, and make changes. It can even use all your CLI tools.

    +
    Or read the documentation
    Try Claude Code
    Developer docs

    Pro

    Claude Code is included in your Pro plan. Perfect for short coding sprints in small codebases with access to both Sonnet 4.5 and Opus 4.5.

    $17

    Per month with annual subscription discount ($200 billed up front). $20 if billed monthly.

    Try Claude

    Max 5x

    Claude Code is included in your Max plan. Great value for everyday use in larger codebases.


    $100

    Per person billed monthly

    Try Claude

    Max 20x

    Even more Claude Code included in your Max plan. Great value for power users with the most access to Claude models.

    $200

    Per person billed monthly

    Try Claude

    Additional usage limits apply. Prices shown don’t include applicable tax.

    .
    This is some text inside of a div block.
    >
    I'm new to this codebase. Can you explain it to me?

    ⏺ I'll analyze the Excalidraw codebase structure and provide a high-level overview.

    ⏺ Analyze(what: "Excalidraw codebase structure and provide a high-level overview of what it is, its main components, and how they're organized. Focus on understanding the project's purpose, architecture, and key features.")

    Excalidraw is an open-source virtual whiteboard application with a hand-drawn style. It's designed for creating diagrams, wireframes, and collaborative drawings.

    ## Purpose

    - Web-based drawing tool with infinite canvas

    - Hand-drawn aesthetic with support for shapes, arrows, text

    - End-to-end encrypted collaboration

    - Works offline as a PWA (Progressive Web App)

    ## Architecture

    The project is organized as a monorepo with these main components:

    1. Core Package (packages/excalidraw)

    - React component library for embedding Excalidraw in any application

    - Handles drawing, rendering, and core functionality

    - Uses roughjs for the hand-drawn style

    - Includes export capabilities (PNG, SVG)

    2. Web Application (excalidraw-app/)

    - Full-featured web app at excalidraw.com

    - Built on top of the core package

    - Adds collaboration features, local storage, sharing

    3. Support Packages

    - common - Shared utilities and constants

    - element - Element manipulation and type definitions

    - math - Mathematical functions for drawing

    - utils - General utility functions

    4. Examples

    - Integration examples (Next.js, browser script)

    - Shows how to embed Excalidraw in different environments

    5. Documentation (dev-docs/)

    - API documentation

    - Integration guides

    - Component documentation

    ## Key Features

    - Real-time collaboration with end-to-end encryption

    - Export to various formats (PNG, SVG, JSON)

    - Customizable drawing tools (rectangle, circle, arrows, freehand)

    - Dark mode support

    - Localization

    - Library of shapes and components

    - Arrow bindings and labels

    - Image support

    ## Technology Stack

    - React for UI

    - TypeScript for type safety

    - Firebase for collaboration backend

    - Jotai for state management

    - Vite for development and building

    - IndexedDB/LocalStorage for offline storage

    The architecture allows for both using Excalidraw as a component in other applications and as a standalone web application with additional features.

    Code onboarding

    Claude Code maps and explains entire codebases in a few seconds. It uses agentic search to understand project structure and dependencies without you having to manually select context files.

    Turn issues into PRs

    Stop bouncing between tools. Claude Code integrates with GitHub, GitLab, and your command line tools to handle the entire workflow—reading issues, writing code, running tests, and submitting PRs—all from your terminal.

    Make powerful edits

    Claude Code’s understanding of your codebase and dependencies enables it to make powerful, multi-file edits that work.

    Kick off coding tasks in Slack
    Learn more
    Add to Slack

    What developers are saying

    Connects with your favorite command line tools

    Your terminal is where real work happens. Claude Code connects with the tools that power development—deployment, databases, monitoring, version control. Rather than adding another interface to juggle, it enhances your existing stack.

    Prev
    Next
    Prev
    Next

    Create what’s exciting. Maintain what’s essential.

    Use Claude Code where you work
    +
    Or read the documentation
    Try Claude Code
    Developer docs

    Get the developer newsletter

    Product updates, how-tos, community spotlights, and more. Delivered monthly to your inbox.

    Subscribe

    Please provide your email address if you'd like to receive our monthly developer newsletter. You can unsubscribe at any time.

    Thank you! You’re subscribed.
    Sorry, there was a problem with your submission, please try again later.
    + + + + + + + +
    + + +
    Next
    \ No newline at end of file diff --git a/tmp/duckduckgo_reqwest.html b/tmp/duckduckgo_reqwest.html new file mode 100644 index 0000000..fc8fdd7 --- /dev/null +++ b/tmp/duckduckgo_reqwest.html @@ -0,0 +1,25 @@ +rust reqwest hyper chunked response streaming backpressure 2024 at DuckDuckGo
    1. Generate answer for rust reqwest hyper chunked response streaming backpressure 2024
    2. Streaming responses support for reqwest for different formats: JSON array stream format JSON Lines (NL/NewLines) format CSV stream format Protobuf len-prefixed stream format Apache Arrow IPC stream format This type of responses are useful when you are reading huge stream of objects from some source (such as database, file, etc) and want to avoid huge memory allocations to store on the server ...
    3. 17 Sep 20240.20 — streaming with backpressure 17 Sep 2024 Version 0.20 of capnproto-rust is now available on crates.io. In this release, the library has new built-in support for streaming. the stream keyword Suppose we have the following interface defined in a capnp schema file:
    4. 6 Jan 2025When working with web applications, it's common to deal with HTTP responses in various formats. Rust, being a systems programming language, provides powerful tools to handle such responses efficiently. This article delves into handling chunked and multipart HTTP responses in Rust with practical examples to help you build robust web applications.
    5. Reqwest can send various things as HTTP bodies -- strings, vectors of bytes, and even streams, using the wrap_stream method. The problem is, the stream has to be 'static, a special lifetime which means "either it's not borrowed, or it's borrowed for the entire length of the program".
    6. 18 Jan 2024I have some working code with hyper 0.14 that looks roughly like this - very simplified code but basically I need the sender end of this channel to be able to data into the body: let (sender, body) =
    7. A Response to a submitted `Request`.Get the full response text given a specific encoding. This method decodes the response body with BOM sniffing and with malformed sequences replaced with the char::REPLACEMENT_CHARACTER. You can provide a default encoding for decoding the raw message, while the charset parameter of Content-Type header is still prioritized. For more information about the ...
    Custom date rangeX
    \ No newline at end of file diff --git a/tmp/duckduckgo_results.html b/tmp/duckduckgo_results.html new file mode 100644 index 0000000..363f69b --- /dev/null +++ b/tmp/duckduckgo_results.html @@ -0,0 +1,25 @@ +rust tokio async streaming chunked responses backpressure best practices 2024 at DuckDuckGo
    1. Generating answer...
    2. I/O loop Backpressure propagation Concurrency 3. Tokio I/O Patterns TCP split stream Split generic AsyncRead+AsyncWrite stream Bidirectional driver for I/O without split Framed I/O Bidirectional driver for framed I/O There are many excellent, straightforward guides for getting started with Async Rust and Tokio.
    3. 8 Aug 2024Conclusion Asynchronous streaming is a powerful technique in Rust programming that enables efficient concurrency and scalability. By leveraging Tokio's async streaming API, you can build high-performance systems that efficiently handle large datasets or real-time data sources. This article has provided a basic example of asynchronous streaming with Tokio, and you can further explore the ...
    4. 6 Oct 2025I just published a blog post about async I/O in Tokio — covering how backpressure, concurrency, and I/O loops interact under the hood. If you've ever wondered why select! might block reads, or how to design ergonomic async streams in Rust, this might resonate. Would love to hear feedback, alternative patterns, or war stories from folks building async systems.
    5. 26 Dec 2024To master concurrency with Tokio and async/await, consider the following best practices: Understand the Async Ecosystem: Familiarize yourself with Rust's asynchronous ecosystem, including crates like futures and async-std, to choose the right tools for your application.
    6. 17 Dec 2025Rust achieves this using Futures and the async/await syntax, enabling tasks to yield control when waiting for external resources and resume efficiently once ready. Combined with powerful runtime libraries like Tokio, Rust can handle thousands of simultaneous operations without the overhead of traditional threads.
    Custom date rangeX
    \ No newline at end of file diff --git a/tmp/github_claude_code.html b/tmp/github_claude_code.html new file mode 100644 index 0000000..140aae7 --- /dev/null +++ b/tmp/github_claude_code.html @@ -0,0 +1,1923 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GitHub - anthropics/claude-code: Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    + Skip to content + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + +
    + + + + + +
    + + + + + + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    + + + + / + + claude-code + + + Public +
    + + +
    + +
    + + +
    +
    + +
    +
    +

    + Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands. +

    + + + + + +
    + +
    + Notifications + You must be signed in to change notification settings + +
    + + + + +
    +
    + +
    + + + + +
    + + + + + +
    + + + + + + +

    anthropics/claude-code

    +
    +
    + +
    +
    + + + + + +

    Folders and files

    NameName
    Last commit message
    Last commit date

    Latest commit

    4f18698 · Jan 10, 2026

    History

    426 Commits
    Nov 26, 2025
    Jan 7, 2026
    Aug 28, 2025
    Dec 3, 2025
    Feb 23, 2025
    Aug 16, 2025
    Jul 3, 2025
    Jan 9, 2026
    Jan 8, 2026
    Mar 11, 2025
    Nov 2, 2025
    Jan 10, 2026
    May 23, 2025
    Jan 7, 2026
    Mar 11, 2025
    Sep 30, 2025

    Repository files navigation

    Claude Code

    +

    npm

    +

    Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows -- all through natural language commands. Use it in your terminal, IDE, or tag @claude on Github.

    +

    Learn more in the official documentation.

    +

    +

    +

    Get started

    +
      +
    1. Install Claude Code:
    2. +
    +

    MacOS/Linux:

    +
    curl -fsSL https://claude.ai/install.sh | bash
    + + + + +
    +

    Homebrew (MacOS):

    +
    brew install --cask claude-code
    + + + + +
    +

    Windows:

    +
    irm https://claude.ai/install.ps1 | iex
    + + + + +
    +

    NPM:

    +
    npm install -g @anthropic-ai/claude-code
    + + + + +
    +

    NOTE: If installing with NPM, you also need to install Node.js 18+

    +
      +
    1. Navigate to your project directory and run claude.
    2. +
    +

    Plugins

    +

    This repository includes several Claude Code plugins that extend functionality with custom commands and agents. See the plugins directory for detailed documentation on available plugins.

    +

    Reporting Bugs

    +

    We welcome your feedback. Use the /bug command to report issues directly within Claude Code, or file a GitHub issue.

    +

    Connect on Discord

    +

    Join the Claude Developers Discord to connect with other developers using Claude Code. Get help, share feedback, and discuss your projects with the community.

    +

    Data collection, usage, and retention

    +

    When you use Claude Code, we collect feedback, which includes usage data (such as code acceptance or rejections), associated conversation data, and user feedback submitted via the /bug command.

    +

    How we use your data

    +

    See our data usage policies.

    +

    Privacy safeguards

    +

    We have implemented several safeguards to protect your data, including limited retention periods for sensitive information, restricted access to user session data, and clear policies against using feedback for model training.

    +

    For full details, please review our Commercial Terms of Service and Privacy Policy.

    +
    +
    + + + +
    +
    + +
    +
    +
    +
    +

    About

    + +

    + Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands. +

    + + + +

    Resources

    + + + + + + + +

    Security policy

    + + + + + + + + + + + +

    Stars

    + + +

    Watchers

    + + +

    Forks

    + + + + +
    + +
    +
    + + + + + + + + +
    +
    +

    + Contributors + 48

    + + + + + + + + + +
    +
    + + + + + +
    +
    + +
    + +
    + + +
    + +
    + + +
    +
    + +
    + +
    +

    Footer

    + + + + +
    +
    + + + + + © 2026 GitHub, Inc. + +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + \ No newline at end of file diff --git a/tmp/introl_guide.html b/tmp/introl_guide.html new file mode 100644 index 0000000..e5c0430 --- /dev/null +++ b/tmp/introl_guide.html @@ -0,0 +1,4964 @@ + + + + + + + Claude Code CLI: The Definitive Technical Reference | Introl Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Claude Code CLI: The Definitive Technical Reference

    + +

    Complete Claude Code CLI guide: installation, configuration, subagents, MCP integrations, hooks, skills, remote execution, IDE integration, and enterprise deployment patterns.

    + + + +
    + + + + + +
    + + + Claude Code CLI: The Definitive Technical Reference + +
    + + + + +
    +

    Claude Code CLI: The Definitive Technical Reference

    +

    Updated December 12, 2025

    +

    December 2025 Update: Claude Code now powers enterprise engineering workflows with agentic multi-file editing, MCP protocol integration with 300+ external services, specialized subagents for complex tasks, and hooks system for CI/CD automation. Permission system enables fine-grained security controls. Model switching between Haiku (fast/cheap) and Opus (powerful) optimizes cost-performance tradeoffs.

    +

    I've spent months pushing Claude Code to its limits across production codebases, CI/CD pipelines, and enterprise deployments. This guide distills that experience into the comprehensive reference I wish existed when I started. It covers everything from first installation to advanced patterns that most users never discover.

    +

    Claude Code isn't a chat interface that happens to know about programming. It's an agentic system that reads your codebase, executes commands, modifies files, manages git workflows, connects to external services, and delegates complex tasks to specialized subagents—all through a command-line interface that integrates into how developers actually work.

    +

    The difference between using Claude Code casually and using it effectively is understanding its architecture: the configuration hierarchy that controls behavior, the permission system that gates operations, the hook system that enables deterministic automation, the MCP protocol that extends capabilities, and the subagent system that handles complex multi-step tasks. Master these systems and Claude Code becomes a force multiplier. Miss them and you're leaving most of the value on the table.

    +

    This guide assumes you're comfortable with command-line tools and want the complete picture. Every feature is documented with actual syntax, real configuration examples, and the edge cases that trip up experienced users. Whether you're setting up your first project or deploying across an enterprise engineering organization, the information is here.

    +
    +

    How Claude Code Works: The Mental Model

    +

    Before diving into features, understand how Claude Code's architecture shapes everything you do with it. The system operates in three layers:

    +
    ┌─────────────────────────────────────────────────────────┐
    +│                    CLAUDE CODE LAYERS                    │
    +├─────────────────────────────────────────────────────────┤
    +│  EXTENSION LAYER                                         │
    +│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐    │
    +│  │   MCP   │  │  Hooks  │  │ Skills  │  │ Plugins │    │
    +│  └─────────┘  └─────────┘  └─────────┘  └─────────┘    │
    +│  External tools, deterministic automation, domain       │
    +│  expertise, packaged extensions                          │
    +├─────────────────────────────────────────────────────────┤
    +│  DELEGATION LAYER                                        │
    +│  ┌─────────────────────────────────────────────────┐    │
    +│  │              Subagents (up to 10 parallel)       │    │
    +│  │   Explore | Plan | General-purpose | Custom      │    │
    +│  └─────────────────────────────────────────────────┘    │
    +│  Isolated contexts for focused work, returns summaries  │
    +├─────────────────────────────────────────────────────────┤
    +│  CORE LAYER                                              │
    +│  ┌─────────────────────────────────────────────────┐    │
    +│  │         Main Conversation Context                │    │
    +│  │   Tools: Read, Edit, Bash, Glob, Grep, etc.     │    │
    +│  └─────────────────────────────────────────────────┘    │
    +│  Your primary interaction; limited context; costs money │
    +└─────────────────────────────────────────────────────────┘
    +
    + +

    Core Layer: Your main conversation. Every message, file read, and tool output consumes context from a shared 200K token window (1M with premium). When context fills, Claude loses track of earlier decisions and quality degrades. This layer costs money per token.

    +

    Delegation Layer: Subagents spawn with clean contexts, do focused work, and return summaries. The exploration results don't bloat your main conversation—only the conclusions return. Use Haiku subagents for exploration (cheap, fast) and Sonnet for implementation.

    +

    Extension Layer: MCP connects external services (databases, GitHub, Sentry). Hooks guarantee execution of shell commands regardless of model behavior. Skills encode domain expertise that Claude applies automatically. Plugins package all of these for distribution.

    +

    The key insight: Most users work entirely in the Core Layer, watching context bloat and costs climb. Power users push exploration and specialized work to the Delegation Layer, keep the Extension Layer configured for their workflow, and use the Core Layer only for orchestration and final decisions.

    +
    +

    Table of Contents

    +
      +
    1. Installation and Authentication
    2. +
    3. Core Interaction Modes
    4. +
    5. Configuration System Deep Dive
    6. +
    7. Model Selection and Switching
    8. +
    9. Permission System and Security
    10. +
    11. Hooks System
    12. +
    13. MCP (Model Context Protocol)
    14. +
    15. Subagents and Task Delegation
    16. +
    17. Extended Thinking Mode
    18. +
    19. Output Styles
    20. +
    21. Slash Commands
    22. +
    23. Skills
    24. +
    25. Plugin System
    26. +
    27. Memory and Context Management
    28. +
    29. Image and Multimodal Input
    30. +
    31. Git Integration and Workflows
    32. +
    33. IDE Integration
    34. +
    35. Advanced Usage Patterns
    36. +
    37. Claude Code Remote
    38. +
    39. Background Agents
    40. +
    41. Cost Management and Billing
    42. +
    43. Performance Optimization
    44. +
    45. Troubleshooting and Debugging
    46. +
    47. Enterprise Deployment
    48. +
    49. Keyboard Shortcuts Reference
    50. +
    51. Best Practices
    52. +
    +
    +

    Installation and Authentication

    +

    System Requirements

    +

    Claude Code runs on macOS 10.15+, Ubuntu 20.04+/Debian 10+, and Windows 10+ through WSL or Git Bash. The system requires 4 GB RAM minimum and an active internet connection. Shell compatibility works best with Bash, Zsh, or Fish.

    +

    For Windows, both WSL 1 and WSL 2 work. Git Bash also works if you prefer native Windows. Alpine Linux and other musl-based systems require additional packages:

    +
    apk add libgcc libstdc++ ripgrep
    +export USE_BUILTIN_RIPGREP=0
    +
    + +

    Installation Methods

    +

    Native installation (recommended)

    +

    The native binary provides the cleanest experience with no Node.js dependency:

    +
    # macOS and Linux
    +curl -fsSL https://claude.ai/install.sh | bash
    +
    +# Homebrew alternative
    +brew install --cask claude-code
    +
    +# Windows PowerShell
    +irm https://claude.ai/install.ps1 | iex
    +
    +# Windows CMD
    +curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
    +
    + +

    For version-specific installation:

    +
    # Install specific version
    +curl -fsSL https://claude.ai/install.sh | bash -s 1.0.58
    +
    +# Install latest explicitly
    +curl -fsSL https://claude.ai/install.sh | bash -s latest
    +
    +# Windows PowerShell - specific version
    +& ([scriptblock]::Create((irm https://claude.ai/install.ps1))) 1.0.58
    +
    + +

    NPM installation

    +

    For environments where npm is preferred:

    +
    npm install -g @anthropic-ai/claude-code
    +
    + +

    Never use sudo with npm installation—it creates permission issues that complicate everything downstream.

    +

    Migration from existing installation

    +

    If you have an older npm-based installation, migrate to the native binary:

    +
    claude install
    +
    + +

    Authentication Options

    +

    Claude Code supports three authentication paths, each with different tradeoffs:

    +

    Claude Console (API billing)

    +

    Connect to Anthropic's API directly through console.anthropic.com. Create an account, set up billing, and authenticate through the CLI. This provides usage-based billing with full API access. A dedicated "Claude Code" workspace is created automatically—you cannot create API keys for this workspace, but you can monitor usage.

    +

    Claude Pro or Max subscription

    +

    Use your claude.ai account credentials. The subscription covers both the web interface and CLI usage under a single monthly plan. This simplifies billing for individual users who want predictable costs.

    +

    Enterprise platforms

    +

    AWS Bedrock, Google Vertex AI, and Microsoft Foundry each provide enterprise-grade access with existing cloud billing relationships:

    +
    # AWS Bedrock
    +export CLAUDE_CODE_USE_BEDROCK=1
    +export AWS_REGION=us-east-1
    +export AWS_PROFILE=your-profile
    +
    +# Google Vertex AI
    +export CLAUDE_CODE_USE_VERTEX=1
    +export CLOUD_ML_REGION=us-east5
    +export ANTHROPIC_VERTEX_PROJECT_ID=your-project
    +
    +# Microsoft Foundry
    +export CLAUDE_CODE_USE_FOUNDRY=1
    +export ANTHROPIC_FOUNDRY_RESOURCE=your-resource-name
    +# Optional: API key auth (otherwise uses Entra ID)
    +export ANTHROPIC_FOUNDRY_API_KEY=your-key
    +
    + +

    For enterprise deployments behind proxies or through LLM gateways:

    +
    # Corporate proxy
    +export HTTPS_PROXY='https://proxy.example.com:8080'
    +
    +# LLM gateway (skip native auth)
    +export CLAUDE_CODE_USE_BEDROCK=1
    +export ANTHROPIC_BEDROCK_BASE_URL='https://your-gateway.com/bedrock'
    +export CLAUDE_CODE_SKIP_BEDROCK_AUTH=1
    +
    + +

    Verification

    +
    claude doctor
    +
    + +

    This reports installation type, version, system configuration, and any detected issues.

    +

    Updates

    +

    Claude Code auto-updates by default, checking at startup and periodically during sessions. Updates download in the background and apply on next launch.

    +

    Disable auto-updates:

    +
    export DISABLE_AUTOUPDATER=1
    +
    + +

    Or in settings.json:

    +
    {
    +  "env": {
    +    "DISABLE_AUTOUPDATER": "1"
    +  }
    +}
    +
    + +

    Manual update:

    +
    claude update
    +
    + +

    Uninstallation

    +

    Native installation (macOS/Linux/WSL):

    +
    rm -f ~/.local/bin/claude
    +rm -rf ~/.claude-code
    +
    + +

    Native installation (Windows PowerShell):

    +
    Remove-Item -Path "$env:LOCALAPPDATA\Programs\claude-code" -Recurse -Force
    +Remove-Item -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\claude.exe" -Force
    +
    + +

    Clean configuration (removes all settings):

    +
    rm -rf ~/.claude
    +rm ~/.claude.json
    +rm -rf .claude
    +rm -f .mcp.json
    +
    + +
    +

    Core Interaction Modes

    +

    Interactive REPL

    +

    Launch Claude Code without arguments to enter the interactive read-eval-print loop:

    +
    cd your-project
    +claude
    +
    + +

    The REPL maintains conversation context across turns. Type queries directly, receive responses, and continue until you exit with /exit or Ctrl+D.

    +

    Start with an initial prompt to focus the session:

    +
    claude "explain the authentication flow in this project"
    +
    + +

    Expert tip: The REPL persists state across compaction events. When context grows too large, Claude automatically summarizes older conversation while preserving key decisions and code snippets. You can trigger this manually with /compact or add custom instructions for what to preserve.

    +

    Non-Interactive Mode

    +

    Print mode (-p) executes a single query and exits:

    +
    # Direct query
    +claude -p "list all TODO comments in this project"
    +
    +# Process piped input
    +cat error.log | claude -p "identify the root cause of these failures"
    +
    +# Chain with other tools
    +claude -p "generate a README" > README.md
    +
    + +

    For structured output suitable for parsing in scripts:

    +
    claude -p "count lines by file type" --output-format json
    +
    + +

    The JSON output includes everything you need for automation:

    +
    {
    +  "type": "result",
    +  "subtype": "success",
    +  "total_cost_usd": 0.0034,
    +  "is_error": false,
    +  "duration_ms": 2847,
    +  "duration_api_ms": 1923,
    +  "num_turns": 4,
    +  "result": "Response text here...",
    +  "session_id": "abc-123-def"
    +}
    +
    + +

    For real-time processing of streaming output:

    +
    claude -p "build the application" --output-format stream-json | while read line; do
    +  echo "$line" | jq -r '.result // empty'
    +done
    +
    + +

    Session Management

    +

    Sessions persist conversation history for continuation. This is essential for complex multi-session work:

    +
    # Continue most recent session
    +claude -c
    +
    +# Continue with additional prompt
    +claude -c -p "now add error handling"
    +
    +# Resume specific session by ID
    +claude -r "abc123" "implement the remaining tests"
    +
    +# Fork a session for parallel exploration
    +claude -r "base-session" --fork-session "try a different approach"
    +
    + +

    Create reproducible sessions with explicit IDs:

    +
    claude --session-id "feature-auth-$(date +%s)"
    +
    + +

    Expert tip: Use session IDs that encode context: feature-${branch}-${timestamp} or bug-JIRA-123. When you come back days later, the ID tells you what the session was about. View available sessions within the REPL using /resume.

    +

    Sessions are stored as JSONL transcripts. Agent execution gets assigned unique agentId values with transcripts stored as agent-{agentId}.jsonl. Resume preserves full context from previous conversations.

    +
    +

    Configuration System Deep Dive

    +

    Claude Code uses a layered configuration system. Understanding the hierarchy is essential because higher levels override lower ones, and enterprise settings cannot be bypassed at all.

    +

    Configuration Hierarchy

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LevelLocationScopeCan Override
    Enterprise/etc/claude-code/managed-settings.json (Linux)All usersNo
    /Library/Application Support/ClaudeCode/managed-settings.json (macOS)
    C:\Program Files\ClaudeCode\managed-settings.json (Windows)
    CLI flagsCommand-line argumentsCurrent sessionYes
    Local project.claude/settings.local.jsonPersonal, current projectYes
    Shared project.claude/settings.jsonTeam via gitYes
    User~/.claude/settings.jsonAll your projectsYes
    State~/.claude.jsonRuntime state, OAuth, MCPN/A
    +

    Expert tip: Use .claude/settings.local.json for personal preferences in shared projects—it should be in .gitignore. Use .claude/settings.json for team-wide configuration that gets checked into version control.

    +

    Complete settings.json Reference

    +

    A comprehensive configuration demonstrating all major options:

    +
    {
    +  "$schema": "https://json.schemastore.org/claude-code-settings.json",
    +  "model": "claude-sonnet-4-5-20250929",
    +  "permissions": {
    +    "allow": [
    +      "Read",
    +      "Glob",
    +      "Grep",
    +      "Bash(npm run:*)",
    +      "Bash(git:*)",
    +      "Bash(make:*)",
    +      "Edit(src/**)",
    +      "Write(src/**)",
    +      "mcp__github"
    +    ],
    +    "deny": [
    +      "Read(.env*)",
    +      "Read(secrets/**)",
    +      "Bash(rm -rf:*)",
    +      "Bash(sudo:*)",
    +      "Edit(package-lock.json)",
    +      "Edit(.git/**)"
    +    ],
    +    "ask": [
    +      "WebFetch",
    +      "Bash(curl:*)",
    +      "Bash(docker:*)"
    +    ],
    +    "additionalDirectories": [
    +      "../shared-lib",
    +      "../docs"
    +    ],
    +    "defaultMode": "acceptEdits"
    +  },
    +  "env": {
    +    "NODE_ENV": "development",
    +    "DEBUG": "app:*"
    +  },
    +  "hooks": {
    +    "PostToolUse": [
    +      {
    +        "matcher": "Edit|Write",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "npx prettier --write \"$FILE_PATH\""
    +          }
    +        ]
    +      }
    +    ]
    +  },
    +  "sandbox": {
    +    "enabled": false,
    +    "autoAllowBashIfSandboxed": true,
    +    "excludedCommands": ["git", "docker"]
    +  },
    +  "statusLine": {
    +    "type": "command",
    +    "command": "~/.claude/statusline.sh"
    +  },
    +  "includeCoAuthoredBy": true,
    +  "cleanupPeriodDays": 30,
    +  "outputStyle": "Explanatory"
    +}
    +
    + +

    Environment Variables Reference

    +

    Authentication and API:

    +
    ANTHROPIC_API_KEY=sk-ant-...                    # Direct API authentication
    +ANTHROPIC_AUTH_TOKEN=token                      # Custom authorization header
    +ANTHROPIC_CUSTOM_HEADERS="X-Key: val"           # Additional request headers
    +
    + +

    Model configuration:

    +
    ANTHROPIC_MODEL=claude-opus-4-5                 # Override default model
    +ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4-5-20251101
    +ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-4-5-20250929-v1:0
    +ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4-5-20251001
    +CLAUDE_CODE_SUBAGENT_MODEL=sonnet               # Model for subagents
    +MAX_THINKING_TOKENS=10000                       # Enable extended thinking
    +CLAUDE_CODE_MAX_OUTPUT_TOKENS=4000              # Limit output length
    +
    + +

    Cloud provider configuration:

    +
    CLAUDE_CODE_USE_BEDROCK=1                       # Use AWS Bedrock
    +CLAUDE_CODE_USE_VERTEX=1                        # Use Google Vertex AI
    +CLAUDE_CODE_USE_FOUNDRY=1                       # Use Microsoft Foundry
    +ANTHROPIC_BEDROCK_BASE_URL=https://...          # Custom Bedrock endpoint
    +CLAUDE_CODE_SKIP_BEDROCK_AUTH=1                 # Skip Bedrock auth (for gateways)
    +CLAUDE_CODE_SKIP_VERTEX_AUTH=1                  # Skip Vertex auth
    +AWS_BEARER_TOKEN_BEDROCK=token                  # Bedrock bearer token
    +VERTEX_REGION_CLAUDE_3_7_SONNET=us-west1        # Override Vertex region
    +
    + +

    Behavior control:

    +
    DISABLE_AUTOUPDATER=1                           # Prevent automatic updates
    +DISABLE_TELEMETRY=1                             # Opt out of usage telemetry
    +DISABLE_ERROR_REPORTING=1                       # Disable Sentry
    +DISABLE_BUG_COMMAND=1                           # Disable /bug command
    +DISABLE_COST_WARNINGS=1                         # Hide cost warnings
    +DISABLE_PROMPT_CACHING=1                        # Disable prompt caching globally
    +DISABLE_PROMPT_CACHING_SONNET=1                 # Disable for Sonnet only
    +DISABLE_PROMPT_CACHING_OPUS=1                   # Disable for Opus only
    +DISABLE_NON_ESSENTIAL_MODEL_CALLS=1             # Skip non-critical API calls
    +
    + +

    Tool configuration:

    +
    BASH_DEFAULT_TIMEOUT_MS=30000                   # Bash command timeout (30s)
    +BASH_MAX_TIMEOUT_MS=600000                      # Maximum bash timeout (10min)
    +BASH_MAX_OUTPUT_LENGTH=50000                    # Bash output limit
    +CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1     # Reset CWD after each bash
    +MCP_TIMEOUT=5000                                # MCP server startup timeout
    +MCP_TOOL_TIMEOUT=30000                          # MCP tool execution timeout
    +MAX_MCP_OUTPUT_TOKENS=25000                     # MCP output limit
    +SLASH_COMMAND_TOOL_CHAR_BUDGET=15000            # Slash command context limit
    +
    + +

    Network and proxy:

    +
    HTTP_PROXY=http://proxy:8080                    # HTTP proxy
    +HTTPS_PROXY=https://proxy:8080                  # HTTPS proxy
    +NO_PROXY=localhost,example.com                  # Bypass proxy for domains
    +CLAUDE_CODE_CLIENT_CERT=/path/to/cert           # mTLS certificate
    +CLAUDE_CODE_CLIENT_KEY=/path/to/key             # mTLS private key
    +CLAUDE_CODE_CLIENT_KEY_PASSPHRASE=pass          # mTLS passphrase
    +
    + +

    UI and terminal:

    +
    CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1            # Don't update terminal title
    +CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL=1             # Skip IDE extension install
    +CLAUDE_CODE_SHELL=/bin/zsh                      # Override shell detection
    +USE_BUILTIN_RIPGREP=1                           # Use included ripgrep (default)
    +CLAUDE_CONFIG_DIR=~/.myconfig                   # Custom config directory
    +
    + +

    Debugging:

    +
    ANTHROPIC_LOG=debug                             # Enable API request logging
    +
    + +
    +

    Model Selection and Switching

    +

    Choosing the right model for each task significantly impacts both cost and quality. Claude Code provides flexible model switching at multiple levels.

    +

    Available Models

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AliasModelBest ForInput/1MOutput/1M
    sonnetClaude Sonnet 4.5Daily coding, balanced performance$3.00$15.00
    opusClaude Opus 4.5Complex reasoning, architecture$5.00$25.00
    haikuClaude Haiku 4.5Simple tasks, fast operations$1.00$5.00
    defaultAccount-dependentGeneral purposeVariesVaries
    sonnet[1m]Sonnet with 1M contextLarge codebases$6.00$22.50
    opusplanOpus (plan) + Sonnet (execute)Complex refactoringHybridHybrid
    +

    Why these price differences matter: A typical coding session consumes 50K-200K input tokens and 10K-50K output tokens. With Haiku, that's $0.10-$0.45 per session. With Opus, the same session costs $0.50-$2.25—5x more. Reserve Opus for genuinely hard problems.1

    +

    When to Use Each Model

    +

    Haiku: Use for subagents doing exploration, simple file searches, quick questions. It's 10-20x cheaper than Opus and responds faster. Perfect for background tasks where you don't need deep reasoning.

    +

    Sonnet: The workhorse for daily development. Handles most coding tasks well: implementing features, fixing bugs, writing tests, code review. Use this as your default.

    +

    Opus: Reserve for genuinely complex reasoning: architectural decisions, tricky debugging, understanding complex systems, security analysis. The quality difference is real for hard problems, but so is the cost.

    +

    Opusplan: A hybrid mode that uses Opus for planning (where reasoning quality matters most) and Sonnet for execution (where speed matters). Excellent for complex refactoring where you want the best plan but don't need Opus-level reasoning for each individual edit.

    +

    Switching Models

    +

    During session:

    +
    > /model opus
    +> /model sonnet
    +> /model haiku
    +
    + +

    At startup:

    +
    claude --model opus
    +
    + +

    Via environment:

    +
    export ANTHROPIC_MODEL=opus
    +
    + +

    In settings.json:

    +
    {
    +  "model": "claude-sonnet-4-5-20250929"
    +}
    +
    + +

    For subagents specifically:

    +
    export CLAUDE_CODE_SUBAGENT_MODEL=haiku
    +
    + +

    Extended Context

    +

    For large codebases or long sessions, enable 1M token context:

    +
    claude --model sonnet[1m]
    +
    + +

    Or within a session:

    +
    > /model anthropic.claude-sonnet-4-5-20250929-v1:0[1m]
    +
    + +

    Extended context costs more per token. Use it when you actually need it, not as a default.

    +

    Checking Current Model

    +
    > /status
    +
    + +

    This shows current model, account info, applied settings, and other session state.

    +
    +

    Decision Frameworks

    +

    Knowing features exists isn't enough—you need to know when to use each. These decision trees transform knowledge into action.

    +

    Which Model Should I Use?

    +
    START → Is the task simple? (file search, quick question, formatting)
    +         │
    +         ├── YES → Use Haiku
    +         │         Cost: ~$0.03/task
    +         │         Speed: Fastest
    +         │
    +         └── NO → Does it require deep reasoning?
    +                  (architecture, complex debugging, security analysis)
    +                  │
    +                  ├── YES → Use Opus
    +                  │         Cost: ~$2.00/task
    +                  │         Quality: Highest
    +                  │
    +                  └── NO → Use Sonnet (default)
    +                           Cost: ~$0.75/task
    +                           Balance: Best overall
    +
    + +

    Rule of thumb: Start with Sonnet. Drop to Haiku for subagents. Escalate to Opus only when Sonnet's answer feels shallow.

    +

    Command vs Skill vs Subagent?

    +
    Do you want explicit control over when it runs?
    +│
    +├── YES → Use Slash Command
    +│         Example: /deploy, /test, /security-review
    +│         You invoke it. You control timing.
    +│
    +└── NO → Should the expertise apply automatically based on context?
    +         │
    +         ├── YES → Use Skill
    +         │         Example: Security patterns, domain rules, code standards
    +         │         Claude recognizes context and applies expertise.
    +         │
    +         └── NO → Does the work need isolated context?
    +                  │
    +                  ├── YES → Use Subagent
    +                  │         Example: Deep exploration, parallel analysis
    +                  │         Prevents context bloat in main conversation.
    +                  │
    +                  └── NO → Just prompt directly
    +                           Not everything needs abstraction.
    +
    + +

    Hook vs Prompt?

    +
    Must the action ALWAYS happen, regardless of Claude's judgment?
    +│
    +├── YES → Use Hook (deterministic)
    +│         Examples:
    +│         - Format code after every edit
    +│         - Log all bash commands
    +│         - Block access to .env files
    +│         Claude cannot skip, forget, or decide otherwise.
    +│
    +└── NO → Use Prompt (probabilistic)
    +         Examples:
    +         - "Consider adding tests"
    +         - "Think about edge cases"
    +         - "Review for security if relevant"
    +         Claude decides based on context.
    +
    + +

    When to Use Extended Thinking?

    +
    Is this a genuinely hard problem?
    +│
    +├── Architectural decision with many tradeoffs → YES, use thinking
    +├── Complex debugging with unclear root cause → YES, use thinking
    +├── Security analysis requiring careful reasoning → YES, use thinking
    +├── Understanding unfamiliar codebase → YES, use thinking
    +│
    +├── Routine bug fix → NO, skip thinking
    +├── Simple refactoring → NO, skip thinking
    +├── Code formatting → NO, skip thinking
    +└── Quick questions → NO, skip thinking
    +
    + +

    Toggle with Tab during session. Higher thinking budgets cost more—start with minimum and increase only if responses feel rushed.

    +
    +

    Permission System and Security

    +

    Claude Code's permission system provides fine-grained control over what operations can execute. Understanding it is essential for both security and workflow efficiency.

    +

    Permission Tiers

    +

    Read-only tools (auto-approved): +- Read - Read file contents +- Glob - Find files by pattern +- Grep - Search file contents +- WebSearch - Search the web

    +

    Modification tools (require approval): +- Edit - Modify existing files +- Write - Create new files +- Bash - Execute shell commands +- WebFetch - Fetch URL contents +- NotebookEdit - Modify Jupyter notebooks

    +

    The first time a modification tool runs, Claude Code prompts for approval. Approvals persist for the session unless explicitly configured otherwise.

    +

    Permission Modes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ModeBehaviorUse Case
    defaultPrompt on first use of each toolNormal development
    acceptEditsAuto-approve file edits, prompt for bashTrusted projects
    planNo execution or editing allowedAnalysis only
    bypassPermissionsSkip all promptsCI/CD automation
    +

    Set mode via CLI:

    +
    claude --permission-mode acceptEdits
    +
    + +

    Toggle during session:

    +
    Shift+Tab  # Cycles through modes
    +
    + +

    In settings.json:

    +
    {
    +  "permissions": {
    +    "defaultMode": "acceptEdits"
    +  }
    +}
    +
    + +

    Permission Rules Syntax

    +

    Fine-grained rules control specific operations. Rules are evaluated in order: first match wins.

    +

    Bash command patterns:

    +
    {
    +  "allow": [
    +    "Bash(npm run build)",
    +    "Bash(npm run test:*)",
    +    "Bash(git commit:*)",
    +    "Bash(make:*)"
    +  ],
    +  "deny": [
    +    "Bash(rm -rf:*)",
    +    "Bash(sudo:*)",
    +    "Bash(curl|wget:*)"
    +  ]
    +}
    +
    + +

    The asterisk provides prefix matching: Bash(npm run test:*) allows npm run test, npm run test:unit, and npm run test:integration.

    +

    Important limitation: Bash patterns match prefixes only, not regex. A pattern like Bash(curl http:*) won't match curl -X GET http://... because the options come before the URL. For robust blocking, deny the command entirely: Bash(curl:*).

    +

    File operation patterns:

    +
    {
    +  "allow": [
    +    "Edit(src/**)",
    +    "Write(src/**)",
    +    "Read(docs/**)"
    +  ],
    +  "deny": [
    +    "Read(.env*)",
    +    "Read(secrets/**)",
    +    "Edit(.git/**)",
    +    "Edit(node_modules/**)"
    +  ]
    +}
    +
    + +

    Path syntax: +- Relative paths: Edit(src/**) - relative to working directory +- Absolute from settings file: Edit(/build/**) - relative to settings file location +- True absolute: Edit(//tmp/**) - starts with // +- Home directory: Read(~/.zshrc)

    +

    MCP tool patterns:

    +
    {
    +  "allow": [
    +    "mcp__github",
    +    "mcp__database__query"
    +  ],
    +  "deny": [
    +    "mcp__dangerous_server"
    +  ]
    +}
    +
    + +

    WebFetch patterns:

    +
    {
    +  "allow": [
    +    "WebFetch(domain:github.com)",
    +    "WebFetch(domain:api.example.com)"
    +  ]
    +}
    +
    + +

    Additional Directories

    +

    Extend Claude's access beyond the current project:

    +
    {
    +  "permissions": {
    +    "additionalDirectories": [
    +      "../shared-lib",
    +      "../docs",
    +      "~/reference-projects/design-system"
    +    ]
    +  }
    +}
    +
    + +

    This is essential for monorepos or when Claude needs to reference code in sibling directories.

    +

    Sandbox Mode

    +

    Enable filesystem and network isolation:

    +
    > /sandbox
    +
    + +

    Or configure in settings:

    +
    {
    +  "sandbox": {
    +    "enabled": true,
    +    "autoAllowBashIfSandboxed": true,
    +    "excludedCommands": ["git", "docker"],
    +    "network": {
    +      "allowUnixSockets": ["~/.ssh/agent-socket"],
    +      "allowLocalBinding": true
    +    }
    +  }
    +}
    +
    + +

    When sandboxed: +- Filesystem access restricted to project directory +- Network access controlled +- Certain commands excluded from sandbox restrictions +- Bash commands auto-allowed if autoAllowBashIfSandboxed is true

    +

    Expert tip: Sandbox mode is excellent for running Claude on untrusted codebases. Enable it when exploring unfamiliar projects or when you want an extra layer of protection.

    +
    +

    Hooks System

    +

    Hooks execute deterministic shell commands at specific points in Claude Code's workflow. Unlike prompting Claude to perform actions, hooks guarantee execution regardless of model behavior. They're essential for enforcing team standards and automating repetitive tasks.

    +

    Why hooks instead of prompts: Telling Claude "always run Prettier after editing files" works sometimes. But Claude might forget, prioritize speed, or decide the change is "too small." Hooks guarantee execution—every Edit or Write triggers your formatter, every time, no exceptions. For compliance, security, and team standards, deterministic beats probabilistic.2

    +

    Available Events

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EventTimingCan BlockPurpose
    PreToolUseBefore tool executesYesValidate, log, or block operations
    PostToolUseAfter tool completesNoFormat output, run linters, trigger builds
    UserPromptSubmitUser sends promptYesAdd context, validate input, inject data
    NotificationAlert triggeredNoCustom notification handling
    StopClaude finishes responseNoCleanup, logging, metrics
    SubagentStopSubagent completesNoTask tracking
    SessionStartSession beginsYesEnvironment setup, validation
    SessionEndSession closesNoCleanup, final logging
    PreCompactBefore context compactionNoValidation, logging
    PermissionRequestPermission dialog shownYesCustom approval logic
    +

    Hook Configuration

    +

    Define hooks in settings.json or a dedicated hooks.json:

    +
    {
    +  "hooks": {
    +    "PostToolUse": [
    +      {
    +        "matcher": "Edit|Write",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "npx prettier --write \"$FILE_PATH\""
    +          }
    +        ]
    +      }
    +    ],
    +    "PreToolUse": [
    +      {
    +        "matcher": "Bash",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": ".claude/hooks/validate-bash.sh"
    +          }
    +        ]
    +      }
    +    ],
    +    "UserPromptSubmit": [
    +      {
    +        "matcher": "",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": ".claude/hooks/inject-context.sh"
    +          }
    +        ]
    +      }
    +    ]
    +  }
    +}
    +
    + +

    Matchers

    +

    The matcher field determines which tools trigger a hook:

    +
    {"matcher": "*"}              // Match all tools
    +{"matcher": "Bash"}           // Match Bash only
    +{"matcher": "Edit|Write"}     // Match Edit or Write
    +{"matcher": "mcp__github"}    // Match MCP server tools
    +{"matcher": ""}               // Match for events without tools (like UserPromptSubmit)
    +
    + +

    Hook Input/Output Protocol

    +

    Hooks receive JSON on stdin:

    +
    {
    +  "tool_name": "Bash",
    +  "tool_input": {
    +    "command": "npm test",
    +    "description": "Run test suite"
    +  },
    +  "session_id": "abc-123"
    +}
    +
    + +

    Exit codes control behavior: +- 0: Success—operation proceeds. Stdout shown in verbose mode (Ctrl+O). For UserPromptSubmit and SessionStart, stdout is added to context. +- 2: Blocking error—operation stops. Stderr becomes the error message fed back to Claude. +- 1, 3, etc.: Non-blocking error—operation continues. Stderr shown as warning in verbose mode.

    +

    For advanced control, hooks can output JSON:

    +
    {
    +  "decision": "allow",
    +  "message": "Command validated and modified",
    +  "modifications": {
    +    "tool_input": {
    +      "command": "npm test -- --coverage"
    +    }
    +  }
    +}
    +
    + +

    Practical Hook Examples

    +

    Auto-format TypeScript files after editing:

    +
    {
    +  "hooks": {
    +    "PostToolUse": [
    +      {
    +        "matcher": "Edit|Write",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "bash -c '[[ \"$FILE_PATH\" == *.ts ]] && npx prettier --write \"$FILE_PATH\" || true'"
    +          }
    +        ]
    +      }
    +    ]
    +  }
    +}
    +
    + +

    Log all bash commands:

    +
    {
    +  "hooks": {
    +    "PreToolUse": [
    +      {
    +        "matcher": "Bash",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "jq -r '.tool_input.command' >> ~/.claude/bash-history.log"
    +          }
    +        ]
    +      }
    +    ]
    +  }
    +}
    +
    + +

    Block access to sensitive files:

    +
    #!/bin/bash
    +# .claude/hooks/protect-files.sh
    +data=$(cat)
    +path=$(echo "$data" | jq -r '.tool_input.file_path // empty')
    +
    +if [[ "$path" == *".env"* ]] || [[ "$path" == *"secrets/"* ]] || [[ "$path" == *".pem"* ]]; then
    +  echo "Blocked: Cannot access sensitive file $path" >&2
    +  exit 1
    +fi
    +exit 0
    +
    + +

    Run tests after code changes:

    +
    {
    +  "hooks": {
    +    "PostToolUse": [
    +      {
    +        "matcher": "Edit",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "bash -c '[[ \"$FILE_PATH\" == *.test.ts ]] || npm run test:affected'"
    +          }
    +        ]
    +      }
    +    ]
    +  }
    +}
    +
    + +

    Custom notification system:

    +
    {
    +  "hooks": {
    +    "Notification": [
    +      {
    +        "matcher": "",
    +        "hooks": [
    +          {
    +            "type": "command",
    +            "command": "notify-send 'Claude Code' 'Waiting for your input'"
    +          }
    +        ]
    +      }
    +    ]
    +  }
    +}
    +
    + +

    Inject dynamic context into prompts:

    +
    #!/bin/bash
    +# .claude/hooks/inject-context.sh
    +# Add current git branch and recent commits to every prompt
    +
    +branch=$(git branch --show-current 2>/dev/null)
    +commits=$(git log --oneline -3 2>/dev/null | tr '\n' ' ')
    +
    +if [ -n "$branch" ]; then
    +  echo "[Context: Branch '$branch', Recent: $commits]"
    +fi
    +exit 0
    +
    + +

    Hook Debugging

    +

    Enable debug mode to troubleshoot hooks:

    +
    claude --debug
    +
    + +

    This logs: +- Hook execution times +- Input/output data +- Error messages and stack traces +- Decision results (allow/reject/ask)

    +
    +

    MCP (Model Context Protocol)

    +

    MCP extends Claude Code with access to external tools, databases, APIs, and services through a standardized protocol. The ecosystem has grown from 100,000 total downloads in November 2024 to over 8 million by April 2025—80x growth in five months.3 Over 300 integrations exist, from GitHub and Slack to PostgreSQL and custom internal systems. Understanding MCP is essential for integrating Claude into your existing toolchain.

    +

    Why MCP matters for developers: Without MCP, Claude Code can only read files and run bash commands. With MCP, Claude can query your production database, create Jira tickets, review GitHub PRs, check Sentry errors, and interact with any API your team uses—all from natural language requests. The protocol standardizes how AI tools connect to external services, preventing vendor lock-in.

    +

    Interactive MCP Setup Wizard

    +

    Run claude mcp add without arguments to launch a step-by-step interface for adding MCP servers. The wizard walks through transport type selection, authentication, and configuration.4

    +

    Transport Types

    +

    HTTP (recommended for remote servers):

    +
    claude mcp add --transport http github https://api.githubcopilot.com/mcp/
    +
    +# With authentication
    +claude mcp add --transport http api https://api.example.com/mcp \
    +  --header "Authorization: Bearer $API_TOKEN"
    +
    + +

    SSE (deprecated but functional):

    +
    claude mcp add --transport sse asana https://mcp.asana.com/sse \
    +  --header "X-API-Key: your-key"
    +
    + +

    Stdio (local servers):

    +
    # PostgreSQL
    +claude mcp add --transport stdio postgres \
    +  --env "DATABASE_URL=postgresql://user:pass@localhost/db" \
    +  -- npx -y @anthropic-ai/mcp-server-postgres
    +
    +# Custom server
    +claude mcp add --transport stdio custom -- python /path/to/server.py --port 8000
    +
    + +

    Windows requires a cmd wrapper for stdio:

    +
    claude mcp add --transport stdio my-server -- cmd /c npx -y @some/package
    +
    + +

    Scope Management

    +

    MCP servers exist at three scopes with clear precedence (local overrides project overrides user):

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ScopeStorageVisibilityUse Case
    Local~/.claude.json (project path)Just you, this projectPersonal API keys
    Project.mcp.jsonEntire team via gitShared integrations
    User~/.claude.json (root)You, all projectsPersonal tools
    +

    Specify scope during installation:

    +
    claude mcp add --scope project --transport http github https://...
    +claude mcp add --scope user --transport stdio personal-tool -- ./my-tool
    +
    + +

    Configuration File Format

    +

    The .mcp.json file defines project-level servers:

    +
    {
    +  "mcpServers": {
    +    "github": {
    +      "type": "http",
    +      "url": "https://api.githubcopilot.com/mcp/"
    +    },
    +    "database": {
    +      "type": "stdio",
    +      "command": "npx",
    +      "args": ["-y", "@anthropic-ai/mcp-server-postgres"],
    +      "env": {
    +        "DATABASE_URL": "${DATABASE_URL}"
    +      }
    +    },
    +    "sentry": {
    +      "type": "http",
    +      "url": "https://mcp.sentry.dev/mcp",
    +      "headers": {
    +        "Authorization": "Bearer ${SENTRY_API_KEY}"
    +      }
    +    },
    +    "internal-api": {
    +      "type": "http",
    +      "url": "${API_BASE_URL:-https://api.example.com}/mcp",
    +      "headers": {
    +        "X-API-Key": "${INTERNAL_API_KEY}"
    +      }
    +    }
    +  }
    +}
    +
    + +

    Environment variables expand using ${VAR} syntax with optional defaults: ${VAR:-default}.

    +

    MCP Management Commands

    +
    claude mcp list                      # View all configured servers
    +claude mcp get github                # Get specific server details
    +claude mcp remove github             # Remove a server
    +claude mcp reset-project-choices     # Reset project-scoped approvals
    +claude mcp add-from-claude-desktop   # Import from Claude Desktop
    +claude mcp add-json weather '{"type":"http","url":"..."}'  # Add from JSON
    +
    +# Within Claude Code REPL
    +> /mcp                               # Interactive MCP management
    +
    + +

    OAuth Authentication

    +

    For servers requiring OAuth:

    +
    > /mcp
    +# Follow browser-based OAuth flow
    +# Tokens stored securely and auto-refreshed
    +# Use "Clear authentication" to revoke access
    +
    + +

    Using MCP Resources and Prompts

    +

    Reference resources:

    +
    @github:issue://123
    +@postgres:schema://users
    +@docs:file://api/authentication
    +
    + +

    MCP prompts as slash commands:

    +
    /mcp__github__list_prs
    +/mcp__github__pr_review 456
    +/mcp__jira__create_issue "Bug title" high
    +
    + +

    Output Limits

    +

    MCP output is limited to prevent context overflow: +- Warning threshold: 10,000 tokens +- Default maximum: 25,000 tokens

    +

    Increase if needed:

    +
    export MAX_MCP_OUTPUT_TOKENS=50000
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ServerPurposeKey Capabilities
    GitHubRepository managementPRs, issues, CI/CD, code review
    PostgreSQLDatabase accessQuery, schema inspection, data analysis
    SentryError monitoringError lookup, stack traces, deployment correlation
    LinearProject managementIssues, projects, sprints
    Jira/AtlassianEnterprise PMTickets, boards, workflows
    PlaywrightWeb automationE2E testing, accessibility trees
    StripePaymentsTransaction lookup, customer data
    CloudflareInfrastructureDNS, workers, analytics
    SupabaseBackend-as-serviceDatabase, auth, storage
    +

    Practical MCP Patterns

    +

    GitHub workflow:

    +
    > Review PR #456
    +> List all open issues assigned to me
    +> Create a bug issue for the authentication failure we found
    +
    + +

    Database queries:

    +
    > What's our total revenue this quarter?
    +> Show the schema for the users table
    +> Find customers with no purchases in 90 days
    +
    + +

    Error monitoring:

    +
    > What errors occurred in production today?
    +> Show the stack trace for error ABC123
    +> Which deployment introduced these errors?
    +
    + +

    Enterprise MCP Configuration

    +

    System administrators can enforce MCP policies via managed-mcp.json:

    +
    {
    +  "allowedMcpServers": [
    +    { "serverName": "github" },
    +    { "serverName": "sentry" },
    +    { "serverCommand": ["npx", "-y", "@approved/server"] }
    +  ],
    +  "deniedMcpServers": [
    +    { "serverName": "dangerous-server" }
    +  ]
    +}
    +
    + +

    Location: +- macOS: /Library/Application Support/ClaudeCode/managed-mcp.json +- Linux: /etc/claude-code/managed-mcp.json +- Windows: C:\ProgramData\ClaudeCode\managed-mcp.json

    +

    Denylist takes absolute precedence. Commands must match exactly including argument order.

    +
    +

    Subagents and Task Delegation

    +

    Subagents are specialized Claude instances that handle complex tasks independently. They're one of the most powerful features in Claude Code and one of the least understood. Mastering subagents dramatically expands what you can accomplish.

    +

    Why subagents exist: Claude Code's main conversation has a single context window. Everything you discuss, every file Claude reads, every tool output—all consume that context. In long sessions, context fills up, Claude loses track of earlier decisions, and performance degrades. Subagents solve this by isolating work: exploration results don't bloat your main conversation, only the summary returns. Claude can also run up to 10 subagents in parallel, enabling concurrent work that would be impossible sequentially.5

    +

    How Subagents Work

    +

    When Claude encounters a task that benefits from focused attention—deep exploration, multi-step analysis, specialized work—it can spawn a subagent. The subagent:

    +
      +
    1. Starts with a clean context (no pollution from main conversation)
    2. +
    3. Has access to specified tools
    4. +
    5. Operates with a specific model (often cheaper/faster)
    6. +
    7. Returns results to the main conversation
    8. +
    +

    This architecture prevents context overflow while enabling complex workflows.

    +

    Built-In Subagent Types

    +

    Explore (fast, read-only): +- Model: Haiku (ultra-fast) +- Mode: Strictly read-only +- Tools: Glob, Grep, Read, and safe bash commands (ls, git status, git log, git diff, find, cat, head, tail) +- Thoroughness levels: Quick, Medium, Very thorough +- Use for: Codebase exploration, finding files, understanding structure

    +

    General-purpose: +- Model: Sonnet +- Mode: Full read/write +- Tools: All available tools +- Use for: Complex research + modification tasks

    +

    Plan: +- Model: Sonnet (or Opus with opusplan) +- Mode: Read-only +- Tools: Read, Glob, Grep, Bash +- Use for: Planning complex implementations before execution

    +

    Triggering Subagents

    +

    Claude automatically delegates to subagents based on task type. You can also explicitly request them:

    +
    > Use the explore agent to find all authentication-related files
    +
    +> Have a subagent analyze the database schema thoroughly
    +
    +> Spawn an agent to research how error handling works in this codebase
    +
    + +

    Expert tip: For complex tasks, explicitly request subagent delegation. "Use an explore agent to find..." prevents context bloat in your main conversation.

    +

    Creating Custom Subagents

    +

    Define subagents in .claude/agents/ (project) or ~/.claude/agents/ (personal):

    +
    ---
    +name: security-reviewer
    +description: Expert security code reviewer. Use PROACTIVELY after any code changes to authentication, authorization, or data handling.
    +tools: Read, Grep, Glob, Bash
    +model: opus
    +permissionMode: plan
    +---
    +
    +You are a senior security engineer reviewing code for vulnerabilities.
    +
    +When invoked:
    +1. Identify the files that were recently changed
    +2. Analyze for OWASP Top 10 vulnerabilities
    +3. Check for secrets, hardcoded credentials, SQL injection
    +4. Report findings with severity levels and remediation steps
    +
    +Focus on actionable security findings, not style issues.
    +
    + +

    Configuration fields:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldRequiredOptionsPurpose
    nameYesLowercase + hyphensUnique identifier
    descriptionYesNatural languageWhen to invoke (include "PROACTIVELY" to encourage auto-delegation)
    toolsNoComma-separatedInherits all tools if omitted
    modelNosonnet, opus, haiku, inheritDefaults to sonnet
    permissionModeNodefault, acceptEdits, bypassPermissions, plan, ignorePermission handling
    skillsNoComma-separatedAuto-load skills when subagent starts
    +

    Managing Subagents

    +
    > /agents                    # Interactive management
    +> /agents create             # Create new subagent
    +> /agents edit               # Modify existing
    +> /agents delete             # Remove subagent
    +> /agents list               # View all
    +
    + +

    Running Agents in Background

    +

    For long-running tasks:

    +
    > Run a thorough security review in the background
    +
    +> /agents  # Check status of running agents
    +
    + +

    Retrieve results later with the agent ID.

    +

    Advanced Patterns

    +

    Chained subagents:

    +
    > First use the code-analyzer subagent to find performance issues, then use the optimizer subagent to fix them
    +
    + +

    Parallel exploration:

    +
    > Have three explore agents search in parallel:
    +> 1. Authentication code
    +> 2. Database models
    +> 3. API routes
    +
    + +

    Resumable agents: +Agents can be resumed with their ID to continue previous work:

    +
    > Resume agent abc123 and continue the analysis
    +
    + +
    +

    Extended Thinking Mode

    +

    Extended thinking gives Claude more time to reason through complex problems before responding. It's particularly valuable for architectural decisions, debugging tricky issues, and tasks requiring careful analysis.

    +

    Supported Models

    +
      +
    • Claude Opus 4.5
    • +
    • Claude Sonnet 4.5
    • +
    • Claude Haiku 4.5
    • +
    +

    Enabling Extended Thinking

    +

    Quick toggle during session:

    +
    Press Tab to toggle thinking on/off
    +
    + +

    Via prompts:

    +
    > think deeply about the architecture for this feature
    +> think hard about what's causing this bug
    +
    + +

    Environment variable (permanent):

    +
    export MAX_THINKING_TOKENS=10000
    +claude
    +
    + +

    Thinking Token Budgets

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    BudgetUse Case
    1,024 (minimum)Simple reasoning tasks
    4,000-8,000Most complex coding tasks
    16,000+Very complex architecture, deep debugging
    32,000+Exhaustive analysis (consider batch processing)
    +

    Expert tip: Start with the minimum budget and increase only if Claude's responses seem rushed. Higher budgets cost more and aren't always better—they can lead to overthinking simple problems.

    +

    How It Works

    +

    When thinking is enabled, Claude's response includes internal reasoning that's not shown in the output but influences the answer. The thinking is encrypted and returned in a signature field for verification.

    +

    In multi-turn conversations with tool use, thinking blocks must be passed back to the API to preserve reasoning continuity. Claude Code handles this automatically.

    +

    When to Use Extended Thinking

    +

    Enable for: +- Architectural decisions +- Complex debugging +- Security analysis +- Performance optimization +- Understanding unfamiliar codebases

    +

    Skip for: +- Simple file edits +- Routine refactoring +- Quick questions +- Code formatting

    +

    Cache Behavior

    +

    System prompt caching is preserved when thinking parameters change. Message caching is invalidated when thinking budget or enabled status changes between turns.

    +
    +

    Output Styles

    +

    Output styles customize how Claude presents information—useful for learning, documentation, or specific team preferences.6

    +

    Built-In Styles

    + + + + + + + + + + + + + + + + + + + + + +
    StylePurpose
    ExplanatoryDetailed explanations with reasoning
    LearningEducational format with concepts explained
    ConciseMinimal output, just essentials
    +

    Setting Output Style

    +
    > /output-style Explanatory
    +> /output-style Learning
    +
    + +

    Or via settings:

    +
    {
    +  "outputStyle": "Explanatory"
    +}
    +
    + +

    Custom Output Styles

    +

    Create in .claude/styles/:

    +
    # my-style
    +
    +## Instructions
    +- Always explain the WHY behind each decision
    +- Include relevant documentation links
    +- Format code examples with comments
    +- End with a "What to do next" section
    +
    +## Format
    +Use markdown headers for organization.
    +Keep explanations under 200 words per section.
    +
    + +

    Invoke with /output-style my-style.

    +
    +

    Slash Commands

    +

    Slash commands provide quick access to Claude Code features and enable custom workflows. They're faster than typing out full prompts for common operations.

    +

    Built-In Command Reference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CommandPurposeNotes
    /initInitialize project with CLAUDE.mdCreates memory file with project structure
    /memoryEdit memory filesOpens CLAUDE.md editor
    /contextView context window usageShows visual breakdown
    /compactCondense conversation historyAdd focus: /compact focus on tests
    /costDisplay token usage and costSession breakdown
    /statsUsage statisticsFavorite model, usage graph, streak
    /permissionsManage permission settingsInteractive interface
    /mcpConfigure MCP serversAlso /mcp enable, /mcp disable
    /hooksView hook configurationDebug hooks
    /configOpen settings interfaceFull configuration
    /resumeResume named session/resume <n> or /resume session-name
    /renameName current session/rename feature-auth
    /forkBranch conversationExplore alternatives without losing context
    /clearClear conversation historyFresh start
    /vimEnable vim editing modeModal editing
    /ideConnect to IDEVS Code/JetBrains integration
    /sandboxEnable sandbox modeIsolation
    /statusView session statusModel, settings, etc.
    /statuslineCustomize status lineConfigure display
    /modelChange AI model/model opus
    /output-styleSet output styleExplanatory, Learning, custom
    /agentsManage subagentsCreate, edit, delete
    /bashesList background tasksLong-running commands
    /tasksList background agentsMonitor async tasks
    /exportExport conversationSave transcript
    /add-dirAdd working directoriesExpand access
    /terminal-setupConfigure terminalShift+Enter setup
    /doctorCheck installationHealth check
    /bugReport bugsFile issue with Anthropic
    /release-notesView release notesCheck what's new
    /rewindReturn to checkpointUndo changes (or Esc×2)
    +

    Custom Command Creation

    +

    Create reusable commands in .claude/commands/ (project) or ~/.claude/commands/ (personal):

    +
    ---
    +description: Security-focused code review
    +allowed-tools: Read, Grep, Glob
    +model: claude-sonnet-4-5
    +---
    +
    +Review this code for security vulnerabilities:
    +
    +1. Injection attacks (SQL, command, XSS)
    +2. Authentication and authorization flaws
    +3. Sensitive data exposure
    +4. Insecure dependencies
    +
    +Focus on actionable findings with specific line references.
    +
    + +

    Save as .claude/commands/security-review.md, invoke with /security-review.

    +

    Command Frontmatter Options

    +
    ---
    +description: Brief description for /help
    +allowed-tools: Read, Edit, Bash(npm:*)
    +model: opus
    +argument-hint: [arg1] [arg2]
    +disable-model-invocation: false
    +---
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    OptionPurpose
    descriptionHelp text and auto-delegation matching
    allowed-toolsRestrict available tools
    modelOverride model for this command
    argument-hintDocument expected arguments
    disable-model-invocationPrevent SlashCommand tool usage
    +

    Argument Interpolation

    +

    All arguments as single string:

    +
    ---
    +description: Fix GitHub issue
    +argument-hint: [issue-number]
    +---
    +
    +Fix GitHub issue #$ARGUMENTS following our coding standards.
    +
    + +

    Usage: /fix-issue 123

    +

    Numbered arguments:

    +
    ---
    +description: Create component
    +argument-hint: [name] [type]
    +---
    +
    +Create a new $2 component named $1 in src/components/.
    +
    + +

    Usage: /create-component Button functional

    +

    Inline Bash Execution

    +

    Execute bash commands within command prompts:

    +
    ---
    +description: Git status summary
    +allowed-tools: Bash(git:*)
    +---
    +
    +Current branch: !`git branch --show-current`
    +Recent commits: !`git log --oneline -5`
    +Changed files: !`git status --short`
    +
    +Summarize the current state of this repository.
    +
    + +

    File References

    +

    Include file contents in commands:

    +
    ---
    +description: Compare implementations
    +---
    +
    +Compare these files:
    +@src/v1/handler.ts
    +@src/v2/handler.ts
    +
    +Which implementation is more maintainable?
    +
    + +

    Command Namespacing

    +

    Organize commands in subdirectories:

    +
    .claude/commands/
    +├── backend/
    +│   ├── test.md
    +│   └── deploy.md
    +├── frontend/
    +│   ├── test.md
    +│   └── build.md
    +└── review.md
    +
    + +

    Commands with the same name show their namespace in help: /test (project:backend) vs /test (project:frontend).

    +
    +

    Skills

    +

    Skills represent a fundamentally different approach to extending Claude Code. Unlike slash commands that you invoke explicitly, skills are model-invoked—Claude automatically discovers and uses them based on context. You embed domain expertise into a skill, and Claude draws on that expertise whenever the situation calls for it, without you needing to remember to ask.

    +

    Why skills change everything: Consider domain expertise—the payment processing rules, the compliance requirements, the architectural patterns your team has refined over years. Without skills, you either re-explain this context every session or hope Claude infers it from code comments. With skills, you encode it once. Claude reads the skill definition and applies that expertise automatically whenever relevant. Your junior developers get senior-level guidance without asking. Your security patterns get enforced without remembering to invoke them.

    +

    This distinction matters. A slash command is a shortcut you remember to use. A skill is knowledge Claude always has available. When you create a security review skill with your team's specific vulnerability patterns and compliance requirements, Claude applies that expertise whenever it encounters relevant code—during PR reviews, refactoring, or any task where security matters. You don't invoke /security-review; Claude recognizes the context and applies the skill automatically.

    +

    Skills vs Commands vs Subagents

    +

    Understanding when to use each extension mechanism prevents duplication and maximizes effectiveness:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AspectSlash CommandsSkillsSubagents
    InvocationUser-invoked (/command)Model-invoked (automatic)Explicit or auto-delegated
    TriggerYou remember to use itClaude recognizes contextTask requires delegation
    StructureSingle markdown fileDirectory with resourcesMarkdown with frontmatter
    ContextMain conversationMain conversationSeparate context window
    ComplexitySimple promptsMulti-file capabilitiesFull agent personality
    Best forExplicit actionsDomain expertiseComplex task delegation
    +

    Use slash commands when you want explicit control: /deploy, /test, /review PR 456. You decide when to run them.

    +

    Use skills when expertise should be automatically available: security patterns, code style enforcement, domain-specific knowledge. Claude decides when to apply them.

    +

    Use subagents when tasks need isolation: background exploration, parallel analysis, specialized reasoning that shouldn't pollute your main conversation.

    +

    Skill Structure and Location

    +

    Skills live in dedicated directories containing a required SKILL.md file plus optional supporting resources:

    +

    Personal skills (available across all your projects):

    +
    ~/.claude/skills/
    +├── code-reviewer/
    +│   ├── SKILL.md
    +│   ├── SECURITY_PATTERNS.md
    +│   └── PERFORMANCE_CHECKLIST.md
    +├── sql-analyst/
    +│   ├── SKILL.md
    +│   └── QUERY_PATTERNS.md
    +└── api-designer/
    +    └── SKILL.md
    +
    + +

    Project skills (shared with team via git):

    +
    .claude/skills/
    +├── domain-expert/
    +│   ├── SKILL.md
    +│   ├── BUSINESS_RULES.md
    +│   └── DATA_MODELS.md
    +└── deployment/
    +    ├── SKILL.md
    +    └── RUNBOOKS.md
    +
    + +

    Project skills commit to version control. When teammates pull, they get your skills automatically—no installation, no configuration. This is how you standardize expertise across a team.

    +

    SKILL.md Format

    +

    Every skill requires a SKILL.md file with YAML frontmatter:

    +
    ---
    +name: code-reviewer
    +description: Review code for security vulnerabilities, performance issues, and best practice violations. Use when examining code changes, reviewing PRs, analyzing code quality, or when asked to review or audit code.
    +allowed-tools: Read, Grep, Glob
    +---
    +
    +# Code Review Expertise
    +
    +## Security Analysis
    +
    +When reviewing code, check for:
    +
    +### Input Validation
    +- All user input sanitized before use
    +- Parameterized queries for database operations
    +- Output encoding for rendered content
    +
    +### Authentication & Authorization
    +- Session tokens properly validated
    +- Permission checks before sensitive operations
    +- No hardcoded credentials or API keys
    +
    +### Data Exposure
    +- Sensitive data not logged
    +- PII properly masked in error messages
    +- API responses don't leak internal details
    +
    +## Performance Patterns
    +
    +### Database
    +- N+1 query detection
    +- Missing indexes on filtered columns
    +- Unbounded result sets
    +
    +### Memory
    +- Large object lifecycle management
    +- Stream processing for big files
    +- Connection pool exhaustion risks
    +
    +## Review Output Format
    +
    +For each finding:
    +- **File**: path/to/file.ts:123
    +- **Severity**: Critical | High | Medium | Low
    +- **Category**: Security | Performance | Maintainability
    +- **Issue**: Clear description of the problem
    +- **Recommendation**: Specific fix with code example
    +- **Rationale**: Why this matters
    +
    +See [SECURITY_PATTERNS.md](SECURITY_PATTERNS.md) for detailed vulnerability patterns.
    +See [PERFORMANCE_CHECKLIST.md](PERFORMANCE_CHECKLIST.md) for optimization guidelines.
    +
    + +

    Frontmatter Reference

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldRequiredConstraintsPurpose
    nameYesLowercase, numbers, hyphens; max 64 charsUnique identifier
    descriptionYesMax 1024 charsDiscovery trigger—Claude uses this to decide when to apply the skill
    allowed-toolsNoComma-separated tool namesRestrict Claude's capabilities when using this skill
    +

    The description field is critical. Claude discovers skills by matching your requests against skill descriptions. A vague description means Claude won't recognize when to use the skill. A specific description with clear trigger conditions means reliable activation.

    +

    Poor description:

    +
    description: Helps with code
    +
    + +

    Effective description:

    +
    description: Review code for security vulnerabilities, performance issues, and best practice violations. Use when examining code changes, reviewing PRs, analyzing code quality, or when asked to review, audit, or check code.
    +
    + +

    The effective description includes: +- What the skill does (review code for specific issues) +- When to use it (examining changes, PRs, quality analysis) +- Trigger phrases (review, audit, check)

    +

    Tool Restrictions

    +

    The allowed-tools field limits what Claude can do when a skill is active. This is essential for skills that should be read-only or limited in scope:

    +
    ---
    +name: security-auditor
    +description: Audit code for security vulnerabilities without making changes
    +allowed-tools: Read, Grep, Glob
    +---
    +
    + +

    With this configuration, Claude can analyze code but cannot edit files, run bash commands, or make modifications. The skill enforces read-only behavior.

    +

    Common restriction patterns:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PatternToolsUse Case
    Read-only analysisRead, Grep, GlobSecurity audits, code review
    Safe explorationRead, Grep, Glob, Bash(git log:*), Bash(git diff:*)Historical analysis
    DocumentationRead, Grep, Glob, WriteGenerate docs without editing source
    Full access(omit field)Skill inherits all available tools
    +

    Supporting Files

    +

    Skills can include multiple files. Claude reads the main SKILL.md on activation, then accesses supporting files as needed—progressive disclosure that manages context efficiently.

    +

    Structure pattern:

    +
    my-skill/
    +├── SKILL.md           # Required: overview + quick reference
    +├── DETAILED_GUIDE.md  # Deep documentation
    +├── EXAMPLES.md        # Concrete examples
    +├── PATTERNS.md        # Reference patterns
    +├── templates/         # Reusable templates
    +│   └── component.tsx
    +└── scripts/           # Helper utilities
    +    └── validate.py
    +
    + +

    Reference supporting files from SKILL.md:

    +
    For detailed security patterns, see [SECURITY_PATTERNS.md](SECURITY_PATTERNS.md).
    +
    +Use this template for new components:
    +@templates/component.tsx
    +
    +Validate configurations with:
    +```bash
    +python scripts/validate.py config.json
    +
    + +
    **Expert tip:** Put essential information in SKILL.md directly. Reserve supporting files for deep reference material. Claude reads SKILL.md immediately but only accesses supporting files when needed. If critical information is buried in a supporting file, Claude might not find it.
    +
    +### Complete Example: Domain Expert Skill
    +
    +Here's a production-quality skill for a fintech application:
    +
    +**Directory structure:**
    +
    + +

    .claude/skills/payments-domain/ +├── SKILL.md +├── BUSINESS_RULES.md +├── COMPLIANCE.md +└── DATA_MODELS.md

    +
    **SKILL.md:**
    +```markdown
    +---
    +name: payments-domain
    +description: Expert knowledge of payment processing domain including transaction flows, compliance requirements, and business rules. Use when working with payment code, transaction handling, refunds, disputes, or financial calculations.
    +---
    +
    +# Payments Domain Expertise
    +
    +## Core Concepts
    +
    +### Transaction States
    +
    + +

    PENDING → AUTHORIZED → CAPTURED → SETTLED + ↘ VOIDED + AUTHORIZED → DECLINED +CAPTURED → REFUNDED (partial or full) +SETTLED → CHARGEBACK → REPRESENTED

    +
    ### Money Handling Rules
    +- ALL monetary values stored as integers (cents, not dollars)
    +- Currency always explicitly tracked (never assume USD)
    +- Rounding: HALF_EVEN for calculations, HALF_UP for display
    +- Never use floating point for money
    +
    +### Idempotency Requirements
    +Every payment operation MUST be idempotent:
    +```typescript
    +// Required pattern
    +async function processPayment(idempotencyKey: string, amount: number) {
    +  const existing = await findByIdempotencyKey(idempotencyKey);
    +  if (existing) return existing; // Return cached result
    +
    +  const result = await executePayment(amount);
    +  await storeWithIdempotencyKey(idempotencyKey, result);
    +  return result;
    +}
    +
    + +

    Quick Reference

    +

    Fee Calculations

    +
      +
    • Interchange: 1.5% + $0.10 (debit), 2.1% + $0.10 (credit)
    • +
    • Platform fee: 2.9% + $0.30 (standard), 2.2% + $0.30 (enterprise)
    • +
    • International: +1% cross-border fee
    • +
    • Currency conversion: mid-market rate + 1%
    • +
    +

    Compliance Thresholds

    +
      +
    • $3,000: Enhanced due diligence trigger
    • +
    • $10,000: CTR filing required
    • +
    • $25,000: Additional verification required
    • +
    +

    Refund Windows

    +
      +
    • Full refund: 120 days from capture
    • +
    • Partial refund: 180 days from capture
    • +
    • Chargeback window: 120 days (Visa), 180 days (Mastercard)
    • +
    +

    Key Files

    +
      +
    • src/payments/processor.ts - Core payment logic
    • +
    • src/payments/refunds.ts - Refund handling
    • +
    • src/compliance/aml.ts - AML checks
    • +
    • src/models/transaction.ts - Transaction model
    • +
    +

    See BUSINESS_RULES.md for detailed business logic. +See COMPLIANCE.md for regulatory requirements. +See DATA_MODELS.md for schema documentation.

    +
    With this skill in place, Claude automatically applies payments domain expertise when you work on transaction code, ask about refund logic, or debug payment flows. You don't invoke anything—the expertise is just there.
    +
    +### Creating Effective Skills
    +
    +**Start with the description.** Write the description first, then build the skill content to match. The description determines when Claude uses the skill, so get it right:
    +
    +1. State what the skill provides
    +2. List specific trigger conditions
    +3. Include relevant keywords and phrases
    +
    +**Keep skills focused.** One skill should cover one domain or capability:
    +
    +| Good (focused) | Bad (too broad) |
    +|----------------|-----------------|
    +| `security-auditor` | `code-helper` |
    +| `react-patterns` | `frontend-stuff` |
    +| `postgres-optimization` | `database-expert` |
    +| `api-documentation` | `docs-generator` |
    +
    +If a skill tries to cover too much, its description becomes vague, and Claude won't reliably recognize when to use it.
    +
    +**Use progressive disclosure.** Put the most important information in SKILL.md directly. Reference supporting files for depth:
    +
    +```markdown
    +## Quick Reference
    +[Essential patterns here - Claude sees this immediately]
    +
    +## Deep Dive
    +For comprehensive coverage, see [DETAILED_GUIDE.md](DETAILED_GUIDE.md).
    +
    + +

    Include concrete examples. Abstract descriptions are less useful than concrete patterns:

    +
    ## Input Validation
    +
    +### Pattern
    +```typescript
    +// Good: Explicit validation with typed errors
    +const validated = PaymentSchema.safeParse(input);
    +if (!validated.success) {
    +  throw new ValidationError(validated.error.issues);
    +}
    +
    +// Bad: Implicit coercion
    +const amount = Number(input.amount); // Silent NaN on invalid input
    +
    + +
    **Test with realistic requests.** After creating a skill, test whether Claude activates it:
    +
    + +
    +

    Review this payment processing code for issues

    +
    +

    Should activate payments-domain skill

    +
    +

    How should I handle refunds?

    +
    +

    Should activate payments-domain skill

    +
    +

    What's the weather like?

    +
    +

    Should NOT activate payments-domain skill

    +
    If Claude doesn't activate the skill when expected, revise the description to include the trigger phrases you're using.
    +
    +### Team Sharing Strategies
    +
    +**Git-based sharing (recommended for project skills):**
    +```bash
    +# Add skill to project
    +mkdir -p .claude/skills/team-standard
    +# Create SKILL.md and supporting files
    +
    +# Commit
    +git add .claude/skills/
    +git commit -m "Add team coding standards skill"
    +git push
    +
    +# Teammates get it automatically
    +git pull
    +claude  # Skill now available
    +
    + +

    Cross-project sharing via symlinks:

    +
    # Create canonical skill location
    +mkdir -p ~/shared-skills/security-reviewer
    +# Create SKILL.md
    +
    +# Symlink into projects
    +ln -s ~/shared-skills/security-reviewer ~/.claude/skills/security-reviewer
    +# Now available in all your projects
    +
    + +

    Plugin distribution: +For broader distribution, package skills into plugins:

    +
    my-plugin/
    +├── .claude-plugin/
    +│   └── plugin.json
    +└── skills/
    +    └── my-skill/
    +        └── SKILL.md
    +
    + +

    Skills bundled in plugins become available when users install the plugin.

    +

    Debugging Skills

    +

    Skill not activating:

    +
      +
    1. +

      Check the description matches your request: + yaml + # If you're saying "check this code" but description says "review" + description: Review OR check code for issues...

      +
    2. +
    3. +

      Verify file location: + ```bash + # Personal + ls ~/.claude/skills/my-skill/SKILL.md

      +
    4. +
    +

    # Project + ls .claude/skills/my-skill/SKILL.md + ```

    +
      +
    1. Validate YAML frontmatter:
    2. +
    3. First line must be exactly ---
    4. +
    5. Closing --- before markdown content
    6. +
    7. No tabs in YAML (use spaces)
    8. +
    9. +

      Name field is lowercase with hyphens only

      +
    10. +
    11. +

      Run in debug mode: + bash + claude --debug + # Watch for skill loading messages

      +
    12. +
    +

    Skill activating unexpectedly:

    +

    Narrow the description. If your skill activates when it shouldn't, the description is too broad:

    +
    # Too broad - activates on any "code" mention
    +description: Help with code
    +
    +# Specific - activates only for security contexts
    +description: Audit code for security vulnerabilities including injection attacks, authentication flaws, and data exposure. Use when specifically asked about security, vulnerabilities, or when reviewing code for security issues.
    +
    + +

    Supporting files not found:

    +
      +
    • Use relative paths from SKILL.md location
    • +
    • Forward slashes only (even on Windows)
    • +
    • Check file actually exists: ls .claude/skills/my-skill/REFERENCED.md
    • +
    +

    When to Create a Skill

    +

    Create a skill when: +- Domain expertise should be automatically available +- Multiple team members need the same knowledge +- You're repeatedly explaining the same patterns or rules +- Context should be injected without explicit invocation +- Knowledge spans multiple files and needs organization

    +

    Don't create a skill when: +- You want explicit control over invocation (use slash command) +- The task needs separate context (use subagent) +- It's a one-off prompt (just type it) +- The "skill" is really just a single template (use slash command)

    +

    Expert tip: If you find yourself repeatedly typing /security-review before working on auth code, convert it to a skill. The expertise should be ambient, not explicitly invoked. If you want explicit invocation, keep it as a command.

    +
    +

    Plugin System

    +

    Plugins package Claude Code extensions for distribution. A plugin can include custom commands, subagents, skills, hooks, and MCP servers.

    +

    Plugin Structure

    +
    my-plugin/
    +├── .claude-plugin/
    +│   └── plugin.json              # Required: metadata
    +├── commands/                     # Slash commands
    +│   └── hello.md
    +├── agents/                       # Subagents
    +│   └── helper.md
    +├── skills/                       # Skills
    +│   └── my-skill/
    +│       └── SKILL.md
    +├── hooks/                        # Event handlers
    +│   └── hooks.json
    +└── .mcp.json                     # MCP servers
    +
    + +

    Plugin Manifest

    +

    Minimal plugin.json:

    +
    {
    +  "name": "my-plugin",
    +  "description": "What this plugin does",
    +  "version": "1.0.0",
    +  "author": {
    +    "name": "Your Name"
    +  }
    +}
    +
    + +

    Plugin Management

    +
    > /plugin                              # Interactive interface
    +> /plugin install name@marketplace     # Install
    +> /plugin enable name@marketplace      # Enable
    +> /plugin disable name@marketplace     # Disable
    +> /plugin uninstall name@marketplace   # Remove
    +> /plugin marketplace add ./local      # Add local marketplace
    +> /plugin marketplace list             # View marketplaces
    +
    + +

    Local Development

    +

    Create a local marketplace for testing:

    +
    mkdir dev-marketplace && cd dev-marketplace
    +mkdir my-plugin
    +# Create plugin structure
    +
    +cd ..
    +claude
    +> /plugin marketplace add ./dev-marketplace
    +> /plugin install my-plugin@dev-marketplace
    +
    + +

    Plugin Components

    +
      +
    • Commands: Available as slash commands (/plugin-command)
    • +
    • Agents: Appear in /agents list
    • +
    • Skills: Auto-load based on skill config
    • +
    • Hooks: Merged with user/project hooks, run in parallel
    • +
    • MCP Servers: Auto-start when plugin enabled
    • +
    +
    +

    Memory and Context Management

    +

    Claude Code's memory system enables persistent context across sessions. Effective memory management is the difference between Claude understanding your project deeply and treating every session as a fresh start.

    +

    CLAUDE.md Hierarchy

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LocationScopeSharedUse Case
    /Library/Application Support/ClaudeCode/CLAUDE.md (macOS)EnterpriseAll usersCompany standards
    ./CLAUDE.md or ./.claude/CLAUDE.mdProjectVia gitTeam context
    ~/.claude/CLAUDE.mdUserAll projectsPersonal preferences
    ./CLAUDE.local.mdProject-localNeverPersonal project notes
    +

    Effective CLAUDE.md Structure

    +
    # Project Context
    +
    +## Architecture
    +- Monorepo with packages in /packages
    +- React frontend in /packages/ui
    +- Node.js API in /packages/api
    +- Shared types in /packages/types
    +- PostgreSQL database via Prisma
    +
    +## Code Standards
    +- TypeScript strict mode everywhere
    +- ESLint + Prettier enforced (pre-commit hooks)
    +- No default exports
    +- JSDoc on all public APIs
    +- Tests required for all new code
    +
    +## Commands
    +- `npm test` - Run all tests
    +- `npm run test:watch` - Watch mode
    +- `npm run lint` - Check linting
    +- `npm run lint:fix` - Auto-fix lint issues
    +- `npm run build` - Production build
    +- `npm run dev` - Start dev servers
    +- `npm run db:migrate` - Run migrations
    +- `npm run db:seed` - Seed database
    +
    +## Patterns
    +
    +### API Endpoints
    +Create in packages/api/src/routes/
    +Use Zod for request/response validation
    +All endpoints need OpenAPI documentation
    +
    +### React Components
    +Create in packages/ui/src/components/
    +Use React Query for server state
    +Prefer composition over inheritance
    +
    +### Database
    +Prisma schema in packages/api/prisma/
    +Always create migration for schema changes
    +Use transactions for multi-table operations
    +
    +## Important Notes
    +- NEVER commit .env files
    +- API runs on :3000, UI on :3001
    +- Local DB: postgres://localhost:5432/myapp
    +- Feature flags in packages/api/src/flags.ts
    +
    +## Recent Decisions
    +- 2025-12-01: Migrated to React Query v5
    +- 2025-11-15: Adopted Zod for all validation
    +- 2025-11-01: Moved to ESM modules
    +
    +# Summary Instructions
    +When using compact, focus on:
    +- Recent code changes
    +- Test results
    +- Architecture decisions made this session
    +
    + +

    File Imports

    +

    Reference other files within CLAUDE.md:

    +
    See @README.md for project overview
    +Coding standards: @docs/STYLE_GUIDE.md
    +API documentation: @docs/API.md
    +Personal preferences: @~/.claude/preferences.md
    +
    + +

    Import syntax: +- Relative: @docs/file.md +- Absolute from project: @/absolute/path.md +- Home directory: @~/.claude/file.md +- Maximum depth: 5 levels of imports

    +

    Memory Rules Directory

    +

    For more organized memory, use .claude/rules/ to store categorized rule files:7

    +
    .claude/rules/
    +├── testing.md          # Testing conventions
    +├── security.md         # Security requirements
    +├── api-patterns.md     # API design patterns
    +└── deployments.md      # Deployment procedures
    +
    + +

    Rules load automatically and provide structured context without cluttering CLAUDE.md.

    +

    Quick Memory Addition

    +

    Use the # prefix to add notes during a session:

    +
    # Always run tests before committing
    +# The payment module is especially fragile
    +# Use the new logger from packages/api/src/logger.ts
    +
    + +

    You'll be prompted to select which memory file to store the note in.

    +

    Context Management Commands

    +

    View context usage:

    +
    > /context
    +
    + +

    Shows a visual grid of context allocation across system prompt, conversation, tools, and file contents.

    +

    Compact conversation:

    +
    > /compact
    +> /compact focus on the authentication changes
    +> /compact preserve test output and error messages
    +
    + +

    Intelligently summarizes older conversation while preserving key information.

    +

    Custom compaction instructions (in CLAUDE.md):

    +
    # Summary Instructions
    +When using compact, focus on:
    +- Test output and failures
    +- Code changes made this session
    +- Architecture decisions
    +
    + +

    Extended thinking for context:

    +
    export MAX_THINKING_TOKENS=10000
    +
    + +

    More thinking tokens means more reasoning capacity but higher costs.

    +

    Context Optimization Strategies

    +
      +
    1. Use specific file references instead of asking Claude to search
    2. +
    3. Clear unrelated conversations with /clear between tasks
    4. +
    5. Compact proactively during long sessions
    6. +
    7. Use subagents to isolate exploratory work
    8. +
    9. Break complex tasks into focused interactions
    10. +
    11. Resume sessions for ongoing work rather than re-explaining
    12. +
    +
    +

    Image and Multimodal Input

    +

    Claude Code can analyze images—screenshots, diagrams, mockups, error messages, database schemas.

    +

    Input Methods

    +
      +
    1. Drag and drop: Drag image files into the Claude Code window
    2. +
    3. Paste: Ctrl+V (not Cmd+V on Mac) to paste from clipboard
    4. +
    5. Path reference: "Analyze this image: /path/to/screenshot.png"
    6. +
    +

    Use Cases

    +
      +
    • Debug UI issues: "Here's a screenshot of the bug, what's causing it?"
    • +
    • Implement designs: "Build this component based on the mockup"
    • +
    • Analyze diagrams: "Explain this architecture diagram"
    • +
    • Database schemas: "Create Prisma models matching this ERD"
    • +
    • Error analysis: "What does this error screenshot mean?"
    • +
    +

    Expert tip: When implementing from mockups, include multiple screenshots showing different states (default, hover, loading, error). The more visual context, the better the implementation.

    +
    +

    Git Integration and Workflows

    +

    Claude Code has deep git integration with built-in safety protocols.

    +

    Safety Protocols

    +
      +
    • Respects .gitignore automatically
    • +
    • Won't modify branches without permission
    • +
    • Shows diffs before commits
    • +
    • Follows project's commit conventions
    • +
    • Never force pushes without explicit request
    • +
    • Checks authorship before amending commits
    • +
    +

    Common Workflows

    +

    Create commits:

    +
    > commit these changes
    +> create a commit with a meaningful message
    +
    + +

    Claude will: +1. Run git status and git diff +2. Analyze changes +3. Generate a conventional commit message +4. Wait for approval before committing

    +

    Create pull requests:

    +
    > create a PR for this feature
    +> summarize the changes and create a PR
    +
    + +

    Review code:

    +
    > review the changes in this PR
    +> what could go wrong with these changes?
    +
    + +

    GitHub Actions Integration

    +

    Automate Claude in CI/CD with the official action:

    +

    Quick setup:

    +
    > /install-github-app
    +
    + +

    Manual workflow file:

    +
    name: Claude Code Review
    +on:
    +  pull_request:
    +    types: [opened, synchronize]
    +  issue_comment:
    +    types: [created]
    +
    +jobs:
    +  claude-review:
    +    runs-on: ubuntu-latest
    +    steps:
    +      - uses: anthropics/claude-code-action@v1
    +        with:
    +          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
    +          prompt: "Review this PR for bugs, security issues, and performance problems"
    +          claude_args: "--max-turns 5"
    +
    + +

    For Bedrock (with OIDC):

    +
    - name: Configure AWS
    +  uses: aws-actions/configure-aws-credentials@v4
    +  with:
    +    role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
    +    aws-region: us-west-2
    +
    +- uses: anthropics/claude-code-action@v1
    +  with:
    +    use_bedrock: "true"
    +    claude_args: '--model us.anthropic.claude-sonnet-4-5-20250929-v1:0'
    +
    + +
    +

    IDE Integration

    +

    VS Code Extension

    +

    Requirements: VS Code 1.98.0+

    +

    Installation: Search "Claude Code" in Extensions marketplace

    +

    Features: +- Sidebar panel (Spark icon) +- Plan mode with diff preview +- Auto-accept edits toggle +- Extended thinking toggle +- File attachment and image pasting +- Conversation history +- Multiple simultaneous sessions

    +

    Third-party provider configuration (in .claude/settings.json):

    +
    {
    +  "env": {
    +    "CLAUDE_CODE_USE_BEDROCK": "1",
    +    "AWS_REGION": "us-east-1",
    +    "AWS_PROFILE": "your-profile"
    +  }
    +}
    +
    + +

    JetBrains Plugin

    +

    Supported: IntelliJ IDEA, PyCharm, WebStorm, GoLand, PhpStorm, DataGrip

    +

    Installation: Settings → Plugins → Search "Claude Code" → Install → Restart

    +

    Key shortcuts: +- Cmd+Esc (Mac) / Ctrl+Esc (Windows): Quick launch +- Cmd+Option+K (Mac) / Alt+Ctrl+K (Windows): Add file reference

    +

    Features: +- Diff viewing in IDE diff viewer +- Selection context auto-sharing +- Diagnostic integration +- Multiple sessions

    +

    WSL2 configuration: +Set Claude command to:

    +
    wsl -d Ubuntu -- bash -lic "claude"
    +
    + +

    Terminal Integration

    +

    Connect an external terminal to your IDE:

    +
    > /ide
    +
    + +

    Claude Code auto-detects VS Code, Cursor, Windsurf, and JetBrains IDEs.

    +

    Slack Integration (December 2025)

    +

    Claude Code now integrates directly with Slack, enabling developers to delegate coding tasks from chat threads.8

    +

    How it works: +1. Mention @Claude in a Slack channel or thread +2. Claude reviews the message to determine if it's a coding task +3. A Claude Code session automatically starts on Anthropic infrastructure +4. Claude gathers context from recent channel/thread messages +5. Progress updates post back to your Slack thread +6. Links to review changes and open PRs provided on completion

    +

    Use cases: +- Bug investigation from bug reports posted in Slack +- Quick code reviews based on team feedback +- Small feature implementations from feature requests

    +

    Requirements: +- Claude app installed via Slack App Marketplace +- Paid Slack plan +- Access to Claude Code on the web

    +

    Privacy: Claude respects Slack's existing permission structure. It cannot access conversations or repositories you aren't authorized to see. Conversations are not used for model training.

    +
    +

    Advanced Usage Patterns

    +

    Headless and CI Mode

    +

    Run Claude Code in scripts and CI pipelines:

    +
    #!/bin/bash
    +# Automated code review
    +
    +result=$(claude -p "Review this code for quality issues" \
    +  --output-format json \
    +  --allowedTools "Read,Grep,Glob" \
    +  --permission-mode plan \
    +  --disable-slash-commands \
    +  --max-turns 5)
    +
    +if echo "$result" | jq -e '.result | test("critical|high severity")' > /dev/null; then
    +  echo "Issues found:"
    +  echo "$result" | jq -r '.result'
    +  exit 1
    +fi
    +
    +echo "Review passed"
    +exit 0
    +
    + +

    Piping and Chaining

    +
    # Analyze logs
    +cat production.log | claude -p "summarize errors" > error-summary.md
    +
    +# Process multiple files
    +find . -name "*.ts" -exec cat {} \; | claude -p "find security issues"
    +
    +# Chain with jq
    +claude -p "generate config" --output-format json | jq -r '.result' > config.json
    +
    + +

    Background Tasks

    +

    Run long operations without blocking:

    +
    > start the build in the background
    +
    + +

    Or press Ctrl+B during command execution.

    +

    Manage background tasks:

    +
    > /bashes                    # List running tasks
    +> get output from task xyz   # Retrieve output
    +
    + +

    Parallel Sessions with Git Worktrees

    +
    # Create worktrees for parallel work
    +git worktree add ../project-feature-a -b feature-a
    +git worktree add ../project-bugfix bugfix-123
    +
    +# Run Claude in each
    +cd ../project-feature-a && claude --session-id "feature-a"
    +cd ../project-bugfix && claude --session-id "bugfix-123"
    +
    + +

    Each worktree is an independent project directory with its own session.

    +

    JSON Output Parsing

    +
    result=$(claude -p "analyze this code" --output-format json)
    +
    +# Extract fields
    +echo "Result: $(echo $result | jq -r '.result')"
    +echo "Cost: $(echo $result | jq -r '.total_cost_usd')"
    +echo "Session: $(echo $result | jq -r '.session_id')"
    +echo "Duration: $(echo $result | jq -r '.duration_ms')ms"
    +
    + +

    Programmatic Session Management

    +
    # Named sessions for tracking
    +claude --session-id "feature-$(git branch --show-current)-$(date +%s)"
    +
    +# Continue previous work
    +claude -c "continue implementing the tests"
    +
    +# Fork for parallel exploration
    +claude -r "main-session" --fork-session "try alternative approach"
    +
    + +
    +

    Claude Code Remote

    +

    Claude Code Remote bridges the gap between web and terminal, letting you start tasks in the cloud and continue them locally—or vice versa. This feature transforms how you work across devices.

    +

    The Core Concept

    +

    The web interface at claude.ai/code runs Claude Code in the cloud. Tasks execute in the background while you're away from your terminal. When you're ready to continue, teleport the session to your local machine and pick up exactly where Claude left off.

    +

    This enables workflows that weren't possible before: +- Start a complex refactoring task from your phone, let it run while you commute, then finish on your workstation +- Queue up multiple tasks on the web interface, review results when you return to your desk +- Hand off long-running operations to the cloud when you need to close your laptop

    +

    The & Prefix

    +

    Send a task to run on Claude Code web in the background:

    +
    & Build a comprehensive REST API for user management with authentication, CRUD operations, and proper error handling
    +
    + +

    The & prefix dispatches your prompt to the cloud. Claude works on it asynchronously—you can close your terminal, switch devices, or continue with other work. The web interface at claude.ai/code shows your running and completed sessions.

    +

    The --teleport Flag

    +

    Pull a cloud session into your local terminal:

    +
    claude --teleport session_abc123
    +
    + +

    This retrieves the session state from the web and resumes it locally. You get the full conversation history, any files Claude modified, and can continue the interaction as if you'd been there the whole time.

    +

    The session ID appears in the web interface. Click on any session to see its ID and current status.

    +

    Requirements

    +

    Claude Code Remote requires a Claude Max subscription. The web interface runs on Anthropic's infrastructure, executing the same Claude Code capabilities you have locally—file operations, bash commands, MCP integrations—but in a managed cloud environment.

    +

    Practical Workflow

    +

    Morning commute:

    +
    & Review all PRs assigned to me and prepare summaries with recommendations
    +
    + +

    At your desk:

    +
    # Check what completed
    +# Visit claude.ai/code to see session list
    +
    +# Pull the session locally to review and act on recommendations
    +claude --teleport pr-review-session-xyz
    +
    + +

    Before leaving work:

    +
    & Run the full test suite, fix any failures, and prepare a summary of what was changed
    +
    + +

    Next morning:

    +
    claude --teleport test-fixes-session-abc
    +# Review what Claude did overnight, make final adjustments
    +
    + +

    Current Status

    +

    Claude Code Remote is currently in research preview. Expect the feature to evolve as Anthropic gathers feedback. The core workflow—cloud execution with local teleportation—represents where agentic coding is headed: AI that works for you around the clock, not just when you're at your keyboard.

    +
    +

    Background Agents (December 2025)

    +

    Background agents run while you continue working—no waiting for long-running tasks to complete.9

    +

    How Background Agents Work

    +

    Instead of blocking your terminal while Claude runs a complex task, background agents: +1. Execute independently in a separate process +2. Continue working even if you close your terminal +3. Report results when complete via notification +4. Can be monitored and managed while running

    +

    Starting a Background Agent

    +

    Using Ctrl+B: +While Claude is working, press Ctrl+B to send the current task to the background. Your terminal becomes available immediately.

    +

    Using the & prefix:

    +
    & Run all tests and fix any failures
    +& Refactor the authentication module to use JWT
    +& Generate comprehensive API documentation
    +
    + +

    The & prefix dispatches to Claude Code Remote (cloud execution). For local background execution, use Ctrl+B on an already-running task.

    +

    Monitoring Background Tasks

    +
    > /tasks                    # List all running tasks
    +> /task status abc123       # Check specific task
    +> /task cancel abc123       # Stop a task
    +> /task output abc123       # View task output so far
    +
    + +

    Parallel Background Workflows

    +

    Run multiple agents simultaneously:

    +
    & Fix all failing tests in src/
    +& Update documentation for the API module
    +& Run security scan on the codebase
    +
    + +

    Each runs independently. Monitor progress with /tasks and pull results as they complete.

    +
    +

    Cost Management and Billing

    +

    Understanding and controlling costs is essential for sustainable Claude Code usage.

    +

    Viewing Costs

    +
    > /cost
    +
    + +

    Output:

    +
    Total cost:            $0.55
    +Total duration (API):  6m 19.7s
    +Total duration (wall): 6h 33m 10.2s
    +Total code changes:    247 lines added, 89 lines removed
    +
    + +

    Cost Factors

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FactorImpactOptimization
    Model choiceOpus >> Sonnet >> HaikuUse Haiku for simple tasks
    Input tokensMore context = more costKeep CLAUDE.md focused
    Output tokensLonger responses cost moreSet MAX_OUTPUT_TOKENS
    Thinking tokensExtended thinking adds costUse only when needed
    Prompt cachingReduces repeated input costsKeep enabled (default)
    +

    Real-World Cost Examples

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TaskModelInputOutputCost
    Quick file searchHaiku20K2K$0.03
    Bug fix with testsSonnet100K30K$0.75
    Architecture reviewOpus150K50K$2.00
    Full-day session (Sonnet)Sonnet500K150K$3.75
    Full-day session (mixed)Haiku+Sonnet500K150K~$2.00
    +

    Cost-saving insight: Using Haiku for exploration subagents and Sonnet for implementation typically reduces costs 40-50% compared to using Sonnet for everything.

    +

    Team Cost Management

    +

    Recommended TPM/RPM by team size:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Team SizeTPM per UserRPM per User
    1-5200k-300k5-7
    5-20100k-150k2.5-3.5
    20-5050k-75k1.25-1.75
    50-10025k-35k0.62-0.87
    100+10k-20k0.25-0.5
    +

    Hidden Tool Fees

    +

    Beyond per-token pricing, some tools incur separate charges:10

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ToolFeeNotes
    Code execution$0.05/session-hourBilled separately from tokens
    Web search$10/1,000 searchesToken costs still apply
    Bash tool+245 input tokens/callOverhead per invocation
    Text editor+~700 input tokens/callTypical overhead
    +

    These add up in agent loops. A 100-iteration debug cycle with Bash costs ~24,500 extra input tokens in overhead alone.

    +

    Cost-Saving Strategies

    +
      +
    1. Use Haiku for subagents: Most exploration doesn't need Sonnet
    2. +
    3. Enable prompt caching: Default, but verify it's not disabled
    4. +
    5. Set max turns: claude --max-turns 5 prevents runaway conversations
    6. +
    7. Use plan mode for exploration: No execution = no accidental expensive operations
    8. +
    9. Compact proactively: Smaller context = fewer tokens
    10. +
    11. Limit output: export CLAUDE_CODE_MAX_OUTPUT_TOKENS=2000
    12. +
    13. Batch API for non-urgent work: 50% off both input and output tokens
    14. +
    +

    Monitoring Usage

    +
      +
    • Claude Console: console.anthropic.com (requires Admin or Billing role)
    • +
    • Workspace limits: Set spending limits per workspace
    • +
    • Bedrock/Vertex: Use native cloud cost monitoring
    • +
    • LiteLLM: For detailed per-user tracking with third-party providers
    • +
    +

    Background Token Usage

    +

    Some operations consume tokens in the background: +- Conversation summarization for /resume +- /cost and /status commands +- Auto-compaction

    +

    Typically under $0.04 per session.

    +
    +

    Performance Optimization

    +

    Reducing Latency

    +

    Model selection: +- Haiku: Fastest responses, lowest cost +- Sonnet: Good balance +- Opus: Best quality, highest latency

    +

    Streaming: +All responses stream by default—you see output as it's generated.

    +

    Prompt caching: +Enabled by default. Reduces latency for repeated context (system prompts, tool definitions).

    +

    Caching Strategies

    +

    System prompts and tool definitions are cached automatically: +- Cache duration: 5 minutes (ephemeral) +- Cache hit: Reduced input tokens and faster response

    +

    Thinking blocks from previous turns are cached in multi-turn conversations.

    +

    Disable caching per model if needed:

    +
    export DISABLE_PROMPT_CACHING_SONNET=1
    +export DISABLE_PROMPT_CACHING_OPUS=1
    +export DISABLE_PROMPT_CACHING_HAIKU=1
    +
    + +

    Parallel Operations

    +

    Subagent parallelization: +Multiple subagents can run simultaneously. Each operates independently without polluting main context.

    +

    Background bash: +Long-running commands don't block the conversation:

    +
    > run the full test suite in the background
    +
    + +

    Git worktrees: +Enable true parallel sessions on separate branches.

    +

    Memory Optimization

    +
      +
    • Specific file references: @src/auth.ts instead of "find the auth file"
    • +
    • Targeted searches: "search in src/api" not "search everywhere"
    • +
    • Fresh sessions: /clear between unrelated tasks
    • +
    • Custom compaction: Add instructions to CLAUDE.md for what to preserve
    • +
    +
    +

    Troubleshooting and Debugging

    +

    Installation Issues

    +

    WSL path problems:

    +
    npm config set os linux
    +npm install -g @anthropic-ai/claude-code --force --no-os-check
    +which npm  # Should start with /usr not /mnt/c
    +
    + +

    Node version conflicts (nvm): +Add to ~/.bashrc or ~/.zshrc:

    +
    export NVM_DIR="$HOME/.nvm"
    +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
    +
    + +

    Permission errors: +Use native installation instead of npm:

    +
    curl -fsSL https://claude.ai/install.sh | bash
    +
    + +

    Authentication Issues

    +
    # Complete reset
    +/logout
    +rm -rf ~/.config/claude-code/auth.json
    +claude  # Fresh login
    +
    + +

    Performance Issues

    +

    High CPU/memory: +- Use /compact to reduce context +- Restart between major tasks +- Add large directories to .gitignore +- Run claude doctor

    +

    Slow search: +Install system ripgrep:

    +
    # macOS
    +brew install ripgrep
    +
    +# Windows
    +winget install BurntSushi.ripgrep.MSVC
    +
    +# Linux
    +sudo apt install ripgrep
    +
    + +

    Then:

    +
    export USE_BUILTIN_RIPGREP=0
    +
    + +

    Slow on WSL: +- Move project to Linux filesystem (not /mnt/c/) +- Use specific directory filters in searches

    +

    IDE Integration Issues

    +

    JetBrains not detected (WSL2):

    +

    Option 1 - Windows Firewall:

    +
    wsl hostname -I  # Get WSL IP
    +New-NetFirewallRule -DisplayName "Allow WSL2" -Direction Inbound -Protocol TCP -Action Allow -RemoteAddress 172.21.0.0/16
    +
    + +

    Option 2 - Mirrored networking (add to ~/.wslconfig):

    +
    [wsl2]
    +networkingMode=mirrored
    +
    + +

    Then: wsl --shutdown

    +

    Escape key not working in JetBrains: +Settings → Tools → Terminal → Uncheck "Move focus to the editor with Escape"

    +

    Debug Mode

    +
    claude --debug                    # Full debug output
    +ANTHROPIC_LOG=debug claude       # API request logging
    +claude doctor                    # Health check
    +
    + +

    Configuration Reset

    +
    # Reset user settings
    +rm ~/.claude.json
    +rm -rf ~/.claude/
    +
    +# Reset project settings
    +rm -rf .claude/
    +rm .mcp.json
    +
    + +

    Common Error Messages

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ErrorCauseSolution
    "Rate limit exceeded"Too many requestsWait or reduce frequency
    "Context length exceeded"Conversation too longUse /compact or /clear
    "Authentication failed"Invalid or expired tokenRun /login
    "Tool not permitted"Permission deniedCheck settings.json permissions
    "MCP server failed to start"Server misconfiguredCheck claude mcp get <name>
    +
    +

    Enterprise Deployment

    +

    Cloud Provider Comparison

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FeatureAnthropic DirectAWS BedrockGoogle VertexMicrosoft Foundry
    AuthAPI keyIAM/API keyGCP credentialsEntra ID/API key
    Cost trackingConsoleAWS Cost ExplorerGCP BillingAzure Cost Mgmt
    Audit loggingLimitedCloudTrailCloud Audit LogsAzure Monitor
    SSONoIAMIAMEntra ID
    +

    Managed Settings Deployment

    +

    Deploy organization-wide policies via managed-settings.json:

    +

    Location: +- macOS: /Library/Application Support/ClaudeCode/managed-settings.json +- Linux: /etc/claude-code/managed-settings.json +- Windows: C:\Program Files\ClaudeCode\managed-settings.json

    +

    Example policy:

    +
    {
    +  "permissions": {
    +    "allow": [
    +      "Read",
    +      "Glob",
    +      "Grep",
    +      "Bash(npm run:*)",
    +      "Bash(git:*)"
    +    ],
    +    "deny": [
    +      "Bash(rm -rf:*)",
    +      "Bash(curl:*)",
    +      "Read(.env*)",
    +      "WebFetch"
    +    ],
    +    "defaultMode": "default"
    +  },
    +  "model": "claude-sonnet-4-5-20250929",
    +  "disableBypassPermissionsMode": "disable"
    +}
    +
    + +

    Users cannot override managed settings.

    +

    Enterprise CLAUDE.md

    +

    Deploy organization-wide context:

    +

    Location: +- macOS: /Library/Application Support/ClaudeCode/CLAUDE.md +- Linux: /etc/claude-code/CLAUDE.md

    +

    Content:

    +
    # Company Standards
    +
    +## Security Requirements
    +- Never commit secrets or credentials
    +- All external API calls require security review
    +- Use parameterized queries for all database access
    +
    +## Code Standards
    +- Follow company style guide at @docs/STYLE.md
    +- All PRs require two approvals
    +- Test coverage minimum: 80%
    +
    +## Approved Tools
    +- npm, yarn, pnpm for package management
    +- Jest for testing
    +- ESLint + Prettier for formatting
    +
    + +

    Rollout Strategy

    +
      +
    1. Start with documentation: Get CLAUDE.md right before deploying
    2. +
    3. Pilot group: Begin with 5-10 developers
    4. +
    5. Q&A phase: Let pilots use Claude for code exploration
    6. +
    7. Guided development: Progress to small bug fixes
    8. +
    9. Full deployment: Roll out with managed settings
    10. +
    11. Monitor costs: Track per-team usage
    12. +
    +

    Audit and Compliance

    +
      +
    • Session transcripts stored locally by default
    • +
    • Use cloud provider logging for enterprise audit
    • +
    • Consider LiteLLM for detailed usage tracking
    • +
    • Managed settings enforce compliance policies
    • +
    +
    +

    Keyboard Shortcuts Reference

    +

    General Controls

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ShortcutAction
    Ctrl+CCancel current operation
    Ctrl+DExit session (EOF)
    Ctrl+LClear screen (keeps history)
    Ctrl+OToggle verbose output
    Ctrl+RSearch command history
    Ctrl+VPaste image from clipboard
    Ctrl+BBackground current operation
    Esc EscRewind last change
    TabAccept prompt suggestion / Toggle extended thinking
    Shift+TabCycle permission modes
    Alt+P / Option+PSwitch models while typing prompt
    Up/DownNavigate command history
    ?Show shortcuts
    +

    Prompt suggestions (Dec 2025): Claude now suggests prompts to speed up your workflow. Press Tab to accept a suggestion or Enter to submit your own prompt.11

    +

    Multiline Input

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    MethodKeys
    Escape newline\ then Enter
    macOSOption+Enter
    After setupShift+Enter (run /terminal-setup)
    Control characterCtrl+J
    +

    Quick Prefixes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PrefixActionExample
    #Add to memory# Always use TypeScript
    /Slash command/review
    !Direct bash! git status
    @File reference@src/index.ts
    &Send to cloud& Build the API
    +

    Vim Mode

    +

    Enable with /vim:

    +

    Normal mode: +- h/j/k/l - Navigation +- w/e/b - Word movement +- 0/$ - Line start/end +- gg/G - Buffer start/end +- dd - Delete line +- cc/C - Change line/to end +- dw/de/db - Delete word variations +- x - Delete character +- . - Repeat last edit

    +

    Insert mode: +- i/I - Insert before/at line start +- a/A - Insert after/at line end +- o/O - Open line below/above +- Esc - Return to normal mode

    +
    +

    Best Practices

    +

    Session Strategy

    +

    Use descriptive session IDs:

    +
    claude --session-id "feature-$(git branch --show-current)-$(date +%s)"
    +claude --session-id "bug-JIRA-456"
    +claude --session-id "spike-new-architecture"
    +
    + +

    Resume sessions for ongoing work rather than re-explaining context.

    +

    CLAUDE.md Design

    +

    Keep it scannable. Claude reads this every session—dense prose wastes context.

    +

    Focus on the non-obvious. Document project-specific patterns, unusual conventions, decisions. Skip what Claude can infer from code.

    +

    Update continuously. Add notes during development with #. Review and consolidate weekly.

    +

    Include command reference. The commands you run constantly should be documented.

    +

    Custom Commands

    +

    Create commands for repetitive workflows:

    +
    ---
    +description: Start new feature
    +allowed-tools: Bash(git:*), Read, Edit
    +---
    +
    +1. Create branch: !`git checkout -b feature/$ARGUMENTS`
    +2. Pull latest main
    +3. Set up boilerplate
    +4. Begin implementation
    +
    + +

    Effective Prompting

    +

    Be specific:

    +
    # Good
    +"Add email validation to LoginForm in src/components/LoginForm.tsx"
    +
    +# Too vague
    +"Improve the login"
    +
    + +

    Reference files directly:

    +
    "Review @src/auth/middleware.ts for security issues"
    +
    + +

    Provide constraints:

    +
    "Refactor using the same pattern as @src/repositories/UserRepository.ts"
    +
    + +

    Use subagents for exploration:

    +
    "Have an explore agent find all places where we handle errors"
    +
    + +

    Cost Control

    +
      +
    • Use /cost regularly
    • +
    • Use Haiku for simple tasks and subagents
    • +
    • Set MAX_THINKING_TOKENS only when needed
    • +
    • Use --max-turns for automated scripts
    • +
    • Compact proactively in long sessions
    • +
    +

    Security

    +
      +
    • Configure .claude/settings.json deny rules for sensitive files
    • +
    • Use sandbox mode for untrusted projects
    • +
    • Never allow Bash(rm -rf:*) or Bash(sudo:*)
    • +
    • Use hooks to block access to secrets
    • +
    • Deploy managed settings for enterprise
    • +
    +
    +

    Enterprise teams deploying Claude Code at scale benefit from standardized configuration, managed policies, and integrated tooling. Teams at Introl help organizations implement AI development infrastructure across distributed engineering teams, from initial architecture through production deployment.

    +
    +

    Common Anti-patterns

    +

    Learning what NOT to do often provides more value than best practices. These patterns consistently cause problems:

    +

    Cost Anti-patterns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Anti-patternProblemSolution
    Using Opus for everything5x cost, often unnecessaryDefault Sonnet, Opus only for architecture
    Never checking /costSurprise billsCheck cost after major tasks
    Extended thinking on simple tasksWasted tokensToggle off (Tab) for routine work
    Running explore in main contextContext bloatUse Explore subagent instead
    +

    Context Anti-patterns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Anti-patternProblemSolution
    Ignoring context until it bloatsDegraded reasoning, forgotten decisions/compact proactively at 50% capacity
    Reading entire files when you need sectionsWastes context on irrelevant codeReference specific line ranges
    Never using subagentsEverything fills main contextDelegate exploration and analysis
    Giant CLAUDE.md filesContext waste every sessionKeep it under 500 lines, use imports
    +

    Workflow Anti-patterns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Anti-patternProblemSolution
    Creating overlapping skills and commandsConfusion, unpredictable behaviorOne mechanism per purpose
    Prompts for guaranteed actionsClaude may skip or forgetUse hooks for must-run actions
    No hooks for formattingInconsistent code styleHook every Edit/Write for formatter
    Allowing all bash by defaultSecurity riskExplicit allowlist for safe commands
    +

    Configuration Anti-patterns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Anti-patternProblemSolution
    All config in user settingsNothing shared with teamProject settings for team standards
    Committing personal preferencesOverrides teammatesUse settings.local.json for personal
    No deny rulesClaude can touch sensitive filesDeny .env, credentials, secrets
    Ignoring managed settingsEnterprise policies bypassedManaged settings for compliance
    +

    Prompt Anti-patterns

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Anti-patternProblemSolution
    "Make it better"Vague, poor resultsSpecify exactly what "better" means
    Not referencing filesClaude guesses pathsUse @path/to/file.ts syntax
    Ignoring Claude's questionsWorks on wrong assumptionsAnswer before proceeding
    Providing full docs when snippet sufficesContext wasteExtract relevant sections
    +
    +

    Workflow Recipes

    +

    End-to-end patterns for common scenarios.

    +

    Recipe 1: Starting a New Project

    +
    # 1. Initialize
    +cd my-project
    +claude
    +
    +# 2. Let Claude understand the codebase
    +> "Explore this codebase and summarize the architecture"
    +
    +# 3. Set up project configuration
    +> /init
    +
    +# 4. Create CLAUDE.md with learned patterns
    +> "Create CLAUDE.md documenting the patterns you observed"
    +
    +# 5. Add team commands
    +> "Create a /test command that runs our test suite"
    +> "Create a /deploy command for staging deployment"
    +
    + +

    Recipe 2: Daily Development Flow

    +
    # 1. Continue yesterday's session
    +claude -c
    +
    +# 2. Quick context recap
    +> "What did we work on yesterday?"
    +
    +# 3. Check current state
    +> /status
    +
    +# 4. Work on feature (Sonnet handles most tasks)
    +> "Implement the user profile endpoint"
    +
    +# 5. Proactive context management
    +> /compact  # Before context exceeds 50%
    +
    +# 6. Check spending
    +> /cost
    +
    +# 7. End session cleanly
    +> "Summarize what we accomplished today"
    +
    + +

    Recipe 3: Complex Refactoring

    +
    # 1. Use Opus for planning, Sonnet for execution
    +> /model opusplan
    +
    +# 2. Plan the refactoring
    +> "Plan refactoring our authentication from sessions to JWT"
    +
    +# 3. Review the plan
    +# (Claude presents approach, you approve or modify)
    +
    +# 4. Execute with Sonnet
    +> "Execute the plan"
    +
    +# 5. Verify nothing broke
    +> "Have an explore agent verify all auth-related tests pass"
    +
    +# 6. Review the diff
    +> !git diff
    +
    + +

    Recipe 4: PR Review Automation

    +
    # In CI/CD (GitHub Actions, etc.)
    +claude -p "Review this PR for:" \
    +  --input-file pr_diff.txt \
    +  --output-format json \
    +  --permission-mode plan \
    +  --max-turns 5 << EOF
    +- Security vulnerabilities
    +- Performance issues
    +- Code style violations
    +- Missing test coverage
    +Provide findings in JSON format.
    +EOF
    +
    + +

    Recipe 5: Debugging Production Issues

    +
    # 1. Configure Sentry MCP for error access
    +claude --add-mcp sentry
    +
    +# 2. Get error context
    +> "Fetch the last 10 errors from Sentry for the auth service"
    +
    +# 3. Deep dive with thinking
    +> Tab  # Enable extended thinking
    +> "Analyze these errors and identify the root cause"
    +
    +# 4. Fix and verify
    +> "Implement a fix and add a regression test"
    +> !npm test
    +
    + +
    +

    Migration Guide

    +

    Coming from other AI coding tools? Here's how concepts map.

    +

    From GitHub Copilot

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Copilot ConceptClaude Code Equivalent
    Tab completionNot a focus—Claude Code does agentic editing
    Chat panel suggestionsREPL conversation with tool execution
    Inline suggestionsUse @file references + Edit tool
    No file creationCreates, edits, deletes files directly
    No terminal accessFull bash execution (with permissions)
    Limited context200K-1M token window
    IDE-onlyTerminal + IDE extensions
    +

    What you gain: True agentic capability—Claude Code reads your codebase, runs tests, creates PRs, and delegates to subagents. Not just suggestions.

    +

    From Cursor

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cursor ConceptClaude Code Equivalent
    ComposerSession with full tool access
    ChatREPL with subagent delegation
    Codebase indexingReal-time file access (Glob, Grep, Read)
    Tab autocompleteNot primary focus
    IDE-integratedTerminal-native + IDE extensions
    No MCP300+ MCP integrations
    Cursor rulesCLAUDE.md + Skills
    +

    What you gain: MCP integrations (databases, GitHub, Sentry), subagent delegation, hooks for automation, and terminal-native workflow.

    +

    From ChatGPT / Claude Web

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Web InterfaceClaude Code
    Copy-paste codeDirect file access
    Manual file creationWrites files directly
    No executionFull bash, git, npm, etc.
    Context resetsSession continuity (-c flag)
    No codebase awarenessGlob, Grep, Read tools
    No automationHooks, CI/CD integration
    +

    What you gain: Everything. Web interfaces require copy-paste workflows; Claude Code operates directly on your codebase.

    +

    Key Mindset Shifts

    +
      +
    1. Stop copying code. Claude Code writes to files directly.
    2. +
    3. Stop context-switching. MCP brings external tools into the session.
    4. +
    5. Delegate aggressively. Subagents handle exploration without bloating your context.
    6. +
    7. Automate with hooks. Formatting, linting, logging happen automatically.
    8. +
    9. Think in sessions. Continue work with -c, not fresh conversations.
    10. +
    +
    +

    Key Takeaways

    +

    For developers: +- Haiku costs 10-20x less than Opus—use for subagents and simple tasks +- Use /compact proactively during long sessions to manage context +- Session IDs encoding context (feature-${branch}-${timestamp}) help navigate back to previous work +- Prefix common prompts with # to add to persistent memory without extra typing

    +

    For DevOps and platform teams: +- Headless mode (-p flag) enables CI/CD integration with JSON output for parsing +- Hooks guarantee execution regardless of model behavior—use for linting, formatting, security checks +- MCP extends capabilities to databases, GitHub, Sentry, and 300+ integrations +- Background tasks (& prefix) run on Claude Code Remote for asynchronous execution

    +

    For security teams: +- Permission rules evaluated first-match-wins—structure allow/deny lists carefully +- Sandbox mode isolates filesystem and network for untrusted codebases +- Bash patterns match prefixes only—Bash(curl:*) blocks all curl, not just specific URLs +- Enterprise managed settings cannot be overridden by users

    +

    For team leads: +- Skills auto-activate based on context—embed domain expertise without explicit invocation +- Project skills commit to git—teammates get standardized expertise automatically +- Cost tracking via /cost shows session breakdown; budget 10k-300k TPM per user based on team size +- Custom commands in .claude/commands/ create reusable workflows

    +

    For enterprise architects: +- Managed settings deploy organization-wide policies via /etc/claude-code/managed-settings.json +- AWS Bedrock, Google Vertex AI, and Microsoft Foundry integrate with existing cloud billing +- Extended thinking (Tab to toggle) improves complex reasoning at higher cost +- Start pilot with 5-10 developers before full rollout

    +
    +

    Quick Reference Card

    +

    Print this. Tape it to your monitor.

    +
    ╔═══════════════════════════════════════════════════════════════╗
    +║                    CLAUDE CODE QUICK REFERENCE                 ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  MODELS                                                        ║
    +║    haiku     $1/$5/M     Exploration, simple tasks            ║
    +║    sonnet    $3/$15/M    Daily coding (default)               ║
    +║    opus      $5/$25/M    Architecture, hard problems          ║
    +║    sonnet[1m] $6/$22.50/M Large codebases (1M context)        ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  ESSENTIAL COMMANDS                                            ║
    +║    /compact        Reduce context (do at 50% capacity)        ║
    +║    /cost           Check session spending                     ║
    +║    /model opus     Switch to Opus                             ║
    +║    /status         Show current state                         ║
    +║    /init           Set up project config                      ║
    +║    /mcp            Configure integrations                     ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  KEYBOARD SHORTCUTS                                            ║
    +║    Tab             Toggle extended thinking                   ║
    +║    Shift+Tab       Cycle permission modes                     ║
    +║    Ctrl+C          Interrupt current operation                ║
    +║    Esc → Esc       Rewind last change                         ║
    +║    Ctrl+L          Clear screen                               ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  PREFIXES                                                      ║
    +║    #message        Add to persistent memory                   ║
    +║    @path/file      Reference file in prompt                   ║
    +║    !command        Execute bash directly                      ║
    +║    &task           Send to cloud (async)                      ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  CONFIG FILE HIERARCHY (first found wins)                      ║
    +║    .claude/settings.local.json    Personal (gitignored)       ║
    +║    .claude/settings.json          Project (shared)            ║
    +║    ~/.claude/settings.json        User global                 ║
    +║    /etc/.../managed-settings.json Enterprise (locked)         ║
    +║    CLAUDE.md                      Project context             ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  DAILY WORKFLOW                                                ║
    +║    1. claude -c              Continue session                 ║
    +║    2. Work on features       Use Sonnet                       ║
    +║    3. /compact               Before context bloats            ║
    +║    4. /cost                  Check spending                   ║
    +║    5. Summarize              Clean exit                       ║
    +╠═══════════════════════════════════════════════════════════════╣
    +║  DECISION RULES                                                ║
    +║    Simple task?        → Haiku                                ║
    +║    Hard reasoning?     → Opus                                 ║
    +║    Everything else?    → Sonnet                               ║
    +║    Must always run?    → Hook (not prompt)                    ║
    +║    Auto-apply wisdom?  → Skill (not command)                  ║
    +║    Needs isolation?    → Subagent                             ║
    +╚═══════════════════════════════════════════════════════════════╝
    +
    + +
    +

    Changelog

    +

    This reference is a living document. Updates are applied as Claude Code evolves.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    DateChangeSource
    2025-12-12Added: Background Agents section, Output Styles section, hidden tool fees, /stats, /fork, /rename, /statusline, /tasks commands, .claude/rules/ memory directory, Batch API tip10976
    2025-12-12Added: Slack integration, prompt suggestions, Alt+P model switching, /release-notes command, /rewind command, interactive MCP setup wizard1184
    2025-12-12Initial 10.0 version: Architecture mental model, decision frameworks, anti-patterns, workflow recipes, migration guide, quick reference card
    +

    Run /update-cc-guide to scan for and apply the latest Claude Code updates.

    +
    +

    References

    +
    +

    For enterprise AI development infrastructure and Claude Code deployment support, contact Introl.

    +
    +
    +
      +
    1. +

      Anthropic Pricing. "Claude API Pricing." December 2025. 

      +
    2. +
    3. +

      Anthropic. "Hooks Guide." December 2025. 

      +
    4. +
    5. +

      MCPcat. "MCP Server Downloads Growth Statistics." December 2025. 

      +
    6. +
    7. +

      Anthropic. "Interactive MCP Setup." December 2025. 

      +
    8. +
    9. +

      Claude Code Subagents. "Subagents Documentation." December 2025. 

      +
    10. +
    11. +

      GitHub. "Output Styles Release." December 2025. 

      +
    12. +
    13. +

      Claude Code Docs. "Memory Rules Directory." December 2025. 

      +
    14. +
    15. +

      Anthropic. "Claude Slack Integration." December 2025. 

      +
    16. +
    17. +

      Anthropic. "Background Agents." December 2025. 

      +
    18. +
    19. +

      Northflank. "Claude Code Hidden Tool Fees." December 2025. 

      +
    20. +
    21. +

      Anthropic. "Claude Code Announcement." December 2025. 

      +
    22. +
    23. +

      Anthropic. "Claude Code Documentation." December 2025. 

      +
    24. +
    25. +

      Anthropic. "CLI Reference." December 2025. 

      +
    26. +
    27. +

      Anthropic. "Settings Documentation." December 2025. 

      +
    28. +
    29. +

      Anthropic. "MCP Documentation." December 2025. 

      +
    30. +
    31. +

      Anthropic. "Claude Code Best Practices." December 2025. 

      +
    32. +
    33. +

      Anthropic. "Remote MCP Support." December 2025. 

      +
    34. +
    35. +

      Anthropic. "Building Agents with Claude Agent SDK." December 2025. 

      +
    36. +
    37. +

      GitHub. "Claude Code GitHub Action." December 2025. 

      +
    38. +
    +
    +
    + + + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + \ No newline at end of file diff --git a/tmp/npm_claude_code.html b/tmp/npm_claude_code.html new file mode 100644 index 0000000..4bbd570 --- /dev/null +++ b/tmp/npm_claude_code.html @@ -0,0 +1,41 @@ + + + + @anthropic-ai/claude-code - npm + + + + + + + +
    ⚠️

    @anthropic-ai/claude-code

    2.1.3 • Public • Published

    Claude Code

    +

    npm

    +

    Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows -- all through natural language commands. Use it in your terminal, IDE, or tag @claude on Github.

    +

    Learn more in the official documentation.

    +

    +

    Get started

    +
      +
    1. Install Claude Code:
    2. +
    +
    npm install -g @anthropic-ai/claude-code
    +
      +
    1. Navigate to your project directory and run claude.
    2. +
    +

    Reporting Bugs

    +

    We welcome your feedback. Use the /bug command to report issues directly within Claude Code, or file a GitHub issue.

    +

    Connect on Discord

    +

    Join the Claude Developers Discord to connect with other developers using Claude Code. Get help, share feedback, and discuss your projects with the community.

    +

    Data collection, usage, and retention

    +

    When you use Claude Code, we collect feedback, which includes usage data (such as code acceptance or rejections), associated conversation data, and user feedback submitted via the /bug command.

    +

    How we use your data

    +

    See our data usage policies.

    +

    Privacy safeguards

    +

    We have implemented several safeguards to protect your data, including limited retention periods for sensitive information and restricted access to user session data.

    +

    For full details, please review our Commercial Terms of Service and Privacy Policy.

    +

    Readme

    Keywords

    none
    + + + + +
    Viewing @anthropic-ai/claude-code version 2.1.3
    \ No newline at end of file diff --git a/tmp/poespas_streaming.html b/tmp/poespas_streaming.html new file mode 100644 index 0000000..07bd923 --- /dev/null +++ b/tmp/poespas_streaming.html @@ -0,0 +1,129 @@ + + + Asynchronous Streaming in Rust with Tokio: A Deep Dive into Efficient Concurrency | Poespas Blog + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    Asynchronous Streaming in Rust with Tokio: A Deep Dive into Efficient Concurrency

    + +

    Introduction

    +

    Rust has emerged as a popular choice for building high-performance, concurrent systems due to its ownership model, memory safety features, and native support for concurrency. When it comes to handling large datasets or streaming data from various sources, asynchronous programming becomes essential. In this article, we’ll delve into the world of asynchronous streaming in Rust using the Tokio framework.

    +

    What is Asynchronous Streaming?

    +

    Asynchronous streaming allows your program to process a stream of data without blocking on individual elements. This approach is particularly useful when dealing with large datasets or real-time data sources. By using asynchronous programming, you can efficiently handle multiple streams concurrently, improving overall system performance and responsiveness.

    +

    Tokio’s Async Streaming API

    +

    Tokio provides a robust async streaming API that makes it easy to implement efficient concurrency in your Rust applications. The tokio::sync::mpsc (multi-producer, single-consumer) channel is a key component of this API, enabling you to send and receive data asynchronously.

    +

    Code Example: Basic Asynchronous Streaming with Tokio

    +
    use tokio::sync::mpsc;
    +use tokio::time::{interval, Interval};
    +async fn producer(mut sender: mpsc::Sender<i32>, interval: Interval) {
    +    for i in 0..10 {
    +        sender.send(i).await;
    +        interval.sleep().await;
    +    }
    +}
    +#[tokio::main]
    +async fn main() -> Result<(), Box<dyn std::error::Error>> {
    +    let (sender, receiver) = mpsc::channel(32);
    +    let producer_handle = tokio::spawn(producer(sender, interval()));
    +    while let Some(i) = receiver.recv().await {
    +        println!("Received: {}", i);
    +    }
    +    producer_handle.await?;
    +    Ok(())
    +}
    +
    +

    In this example, we create a Tokio async channel and spawn a producer task that sends numbers from 0 to 9 using the sender channel. The main task receives these numbers using the receiver channel.

    +

    Conclusion

    +

    Asynchronous streaming is a powerful technique in Rust programming that enables efficient concurrency and scalability. By leveraging Tokio’s async streaming API, you can build high-performance systems that efficiently handle large datasets or real-time data sources. This article has provided a basic example of asynchronous streaming with Tokio, and you can further explore the possibilities by experimenting with different use cases and configurations.

    +
    + + +
    + + + + + + + \ No newline at end of file diff --git a/tmp/rust_homepage.html b/tmp/rust_homepage.html new file mode 100644 index 0000000..9b5cffe --- /dev/null +++ b/tmp/rust_homepage.html @@ -0,0 +1,380 @@ + + + + Rust Programming Language + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +

    Rust

    +

    + A language empowering everyone
    to build reliable and efficient software. +

    +
    + +
    +
    + +
    +
    +
    +

    + Why Rust? +

    +
    +
    +
    +
    +

    Performance

    +

    + Rust is blazingly fast and memory-efficient: with no runtime or +garbage collector, it can power performance-critical services, run on +embedded devices, and easily integrate with other languages. +

    +
    +
    +

    Reliability

    +

    + Rust’s rich type system and ownership model guarantee memory-safety +and thread-safety — enabling you to eliminate many classes of +bugs at compile-time. +

    +
    +
    +

    Productivity

    +

    + Rust has great documentation, a friendly compiler with useful error +messages, and top-notch tooling — an integrated package manager +and build tool, smart multi-editor support with auto-completion and +type inspections, an auto-formatter, and more. +

    +
    + +
    +
    +
    +
    +
    +
    +

    + Build it in Rust +

    +
    +
    + +
    +

    + In 2018, the Rust community decided to improve the programming experience +for a few distinct domains (see the 2018 +roadmap). For these, you can find many high-quality crates and some +awesome guides on how to get started. +

    +
    + +
    +
    +
    + terminal +
    +
    +

    + Command Line +

    +

    + Whip up a CLI tool quickly with Rust’s robust ecosystem. +Rust helps you maintain your app with confidence and distribute it with ease. +

    + Building Tools +
    +
    + +
    +
    + gear with puzzle piece elements +
    +
    +

    + WebAssembly +

    +

    + Use Rust to supercharge your JavaScript, one module at a time. +Publish to npm, bundle with webpack, and you’re off to the races. +

    + Writing Web Apps +
    +
    + +
    +
    + a cloud with nodes +
    +
    +

    + Networking +

    +

    + Predictable performance. Tiny resource footprint. Rock-solid reliability. +Rust is great for network services. +

    + Working On Servers +
    +
    + +
    +
    + an embedded device chip +
    +
    +

    + Embedded +

    +

    + Targeting low-resource devices? +Need low-level control without giving up high-level conveniences? +Rust has you covered. +

    + Starting With Embedded +
    +
    +
    +
    +
    +
    +
    +
    +

    Rust in production

    +
    +
    +
    +

    + Hundreds of companies around the world are using Rust in production +today for fast, low-resource, cross-platform solutions. From startups to large +corporations, from embedded devices to scalable web services, Rust is a great fit. +

    +
    +
    +
    +
    +
    +
    +

    Get involved

    +
    +
    +
    +
    +

    Read Rust

    +

    We love documentation! Take a look at the books available online, as well as key blog posts and user guides.

    + Read the book +
    +
    +

    Watch Rust

    +

    The Rust community has a dedicated YouTube channel collecting a huge range of presentations and +tutorials.

    + Watch the Videos +
    +
    +
    +

    Contribute code

    +

    + Rust is truly a community effort, and we welcome contribution from hobbyists and production users, from +newcomers and seasoned professionals. Come help us make the Rust experience even better! +

    + + Read Contribution Guide + +
    +
    +
    +
    +
    +
    +

    Thanks

    +
    +
    +
    +

    + Rust would not exist without the generous contributions of time, work, and resources from individuals and companies. We are very grateful for the support! +

    +
    +
    +
    +

    Individuals

    +

    Rust is a community project and is very thankful for the many community contributions it receives.

    + See individual contributors +
    +
    +

    Corporate sponsors

    +

    The Rust project receives support from companies through the Rust Foundation.

    + See Foundation members +
    +
    +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/tmp/rust_release.html b/tmp/rust_release.html new file mode 100644 index 0000000..9bb63e5 --- /dev/null +++ b/tmp/rust_release.html @@ -0,0 +1,231 @@ + + + Announcing Rust 1.92.0 | Rust Blog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +

    Announcing Rust 1.92.0

    +
    +
    + +
    Dec. 11, 2025 · The Rust Release Team + +
    + +
    +

    The Rust team is happy to announce a new version of Rust, 1.92.0. Rust is a programming language empowering everyone to build reliable and efficient software.

    +

    If you have a previous version of Rust installed via rustup, you can get 1.92.0 with:

    +
    $ rustup update stable
    +
    +

    If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.92.0.

    +

    If you'd like to help us out by testing future releases, you might consider updating locally to use the beta channel (rustup default beta) or the nightly channel (rustup default nightly). Please report any bugs you might come across!

    +

    +What's in 1.92.0 stable

    +

    +Deny-by-default never type lints

    +

    The language and compiler teams continue to work on stabilization of the never type. In this release the never_type_fallback_flowing_into_unsafe and dependency_on_unit_never_type_fallback future compatibility lints were made deny-by-default, meaning they will cause a compilation error when detected.

    +

    It's worth noting that while this can result in compilation errors, it is still a lint; these lints can all be #[allow]ed. These lints also will only fire when building the affected crates directly, not when they are built as dependencies (though a warning will be reported by Cargo in such cases).

    +

    These lints detect code which is likely to be broken by the never type stabilization. It is highly advised to fix them if they are reported in your crate graph.

    +

    We believe there to be approximately 500 crates affected by this lint. Despite that, we believe this to be acceptable, as lints are not a breaking change and it will allow for stabilizing the never type in the future. For more in-depth justification, see the Language Team's assessment.

    +

    +unused_must_use no longer warns about Result<(), UninhabitedType>

    +

    Rust's unused_must_use lint warns when ignoring the return value of a function, if the function or its return type is annotated with #[must_use]. For instance, this warns if ignoring a return type of Result, to remind you to use ?, or something like .expect("...").

    +

    However, some functions return Result, but the error type they use is not actually "inhabited", meaning you cannot construct any values of that type (e.g. the ! or Infallible types).

    +

    The unused_must_use lint now no longer warns on Result<(), UninhabitedType>, or on ControlFlow<UninhabitedType, ()>. For instance, it will not warn on Result<(), Infallible>. This avoids having to check for an error that can never happen.

    +
    use core::convert::Infallible;
    +fn can_never_fail() -> Result<(), Infallible> {
    +    // ...
    +    Ok(())
    +}
    +
    +fn main() {
    +    can_never_fail();
    +}
    +
    +

    This is particularly useful with the common pattern of a trait with an associated error type, where the error type may sometimes be infallible:

    +
    trait UsesAssocErrorType {
    +    type Error;
    +    fn method(&self) -> Result<(), Self::Error>;
    +}
    +
    +struct CannotFail;
    +impl UsesAssocErrorType for CannotFail {
    +    type Error = core::convert::Infallible;
    +    fn method(&self) -> Result<(), Self::Error> {
    +        Ok(())
    +    }
    +}
    +
    +struct CanFail;
    +impl UsesAssocErrorType for CanFail {
    +    type Error = std::io::Error;
    +    fn method(&self) -> Result<(), Self::Error> {
    +        Err(std::io::Error::other("something went wrong"))
    +    }
    +}
    +
    +fn main() {
    +    CannotFail.method(); // No warning
    +    CanFail.method(); // Warning: unused `Result` that must be used
    +}
    +
    +

    +Emit unwind tables even when -Cpanic=abort is enabled on linux

    +

    Backtraces with -Cpanic=abort previously worked in Rust 1.22 but were broken in Rust 1.23, as we stopped emitting unwind tables with -Cpanic=abort. In Rust 1.45 a workaround in the form of -Cforce-unwind-tables=yes was stabilized.

    +

    In Rust 1.92 unwind tables will be emitted by default even when -Cpanic=abort is specified, allowing for backtraces to work properly. If unwind tables are not desired then users should use -Cforce-unwind-tables=no to explicitly disable them being emitted.

    +

    +Validate input to #[macro_export]

    +

    Over the past few releases, many changes were made to the way built-in attributes are processed in the compiler. This should greatly improve the error messages and warnings Rust gives for built-in attributes and especially make these diagnostics more consistent among all of the over 100 built-in attributes.

    +

    To give a small example, in this release specifically, Rust became stricter in checking what arguments are allowed to macro_export by upgrading that check to a "deny-by-default lint" that will be reported in dependencies.

    +

    +Stabilized APIs

    + +

    These previously stable APIs are now stable in const contexts:

    + +

    +Other changes

    +

    Check out everything that changed in Rust, Cargo, and Clippy.

    +

    +Contributors to 1.92.0

    +

    Many people came together to create Rust 1.92.0. We couldn't have done it without all of you. Thanks!

    + +
    +
    +
    + + + + \ No newline at end of file diff --git a/tmp/search_results.html b/tmp/search_results.html new file mode 100644 index 0000000..0af0be6 --- /dev/null +++ b/tmp/search_results.html @@ -0,0 +1,25 @@ +Claude Code Anthropic CLI agent features capabilities 2025 at DuckDuckGo
    1. Reading search results...
    2. 2 days agoAnthropic has released Claude Code v2.1.0, a notable update to its "vibe coding" development environment for autonomously building software, spinning up AI agents, and completing a wide range of ...
    3. 24 Nov 2025That's exactly why Anthropic introduced Agent Skills — modular, customizable, and sharable capabilities that extend what Claude can do inside Claude Code. In this guide, we'll break down what Agent Skills are, how they work, and how you can create your own to supercharge your development environment.
    4. 21 Apr 2025Anthropic has released a detailed best-practice guide for using Claude Code, a command-line interface designed for agentic software development workflows. Rather than offering a prescriptive agent framework, Claude Code provides a low-level, developer-centric interface to integrate the Claude language model into day-to-day programming tasks. The guide draws from practical experience within ...
    5. 18 Apr 2025Claude Code: Best practices for agentic coding Published Apr 18, 2025 Claude Code is a command line tool for agentic coding. This post covers tips and tricks that have proven effective for using Claude Code across various codebases, languages, and environments. We recently released Claude Code, a command line tool for agentic coding.
    6. See also: Claude Claude Code is an AI -powered command-line tool for agentic coding developed by Anthropic. First released as a beta research preview alongside Claude 3.7 Sonnet on February 24, 2025, and made generally available on May 22, 2025, Claude Code enables developers to delegate coding tasks to Claude directly from their terminal. [1] [2] On September 29, 2025, Anthropic released ...
    7. 15 Nov 2025What's in This Roundup? Anthropic Engineering has been busy shipping major improvements across the Claude platform. This roundup covers four key updates from September to November 2025: MCP code execution patterns, Claude Code security enhancements, Agent Skills framework, and the Agent SDK.
    8. 1 day agoAnthropic has launched Claude Code v2.1.0, a major update to its AI-powered coding assistant featuring 1,096 commits. The release introduces asynchronous sub-agents for parallel task execution, session teleportation between terminal and browser, and hot reload capabilities. Developers gain fine-grained control over AI agent creation with improved lifecycle management, tool permissions, and ...
    9. 25 Dec 2025This document provides a comprehensive overview of Claude Code, an agentic coding assistant that operates through natural language in terminals, IDEs, and GitHub. It introduces the system's architecture, deployment options, core capabilities including LSP integration, MCP protocol support, multi-model execution, and extensibility features.
    Custom date rangeX
    \ No newline at end of file diff --git a/tmp/tokio_channels.html b/tmp/tokio_channels.html new file mode 100644 index 0000000..da1d241 --- /dev/null +++ b/tmp/tokio_channels.html @@ -0,0 +1,335 @@ +Channels | Tokio - An asynchronous Rust runtime

    Channels

    Now that we have learned a bit about concurrency with Tokio, let's apply this on +the client side. Put the server code we wrote before into an explicit binary +file:

    +
    $ mkdir src/bin
    +$ mv src/main.rs src/bin/server.rs
    +
    +

    and create a new binary file that will contain the client code:

    +
    $ touch src/bin/client.rs
    +
    +

    In this file you will write this page's code. Whenever you want to run it, +you will have to launch the server first in a separate terminal window:

    +
    $ cargo run --bin server
    +
    +

    And then the client, separately:

    +
    $ cargo run --bin client
    +
    +

    That being said, let's code!

    +

    Say we want to run two concurrent Redis commands. We can spawn +one task per command. Then the two commands would happen concurrently.

    +

    At first, we might try something like:

    +
    use mini_redis::client;
    +
    +#[tokio::main]
    +async fn main() {
    +    // Establish a connection to the server
    +    let mut client = client::connect("127.0.0.1:6379").await.unwrap();
    +
    +    // Spawn two tasks, one gets a key, the other sets a key
    +    let t1 = tokio::spawn(async {
    +        let res = client.get("foo").await;
    +    });
    +
    +    let t2 = tokio::spawn(async {
    +        client.set("foo", "bar".into()).await;
    +    });
    +
    +    t1.await.unwrap();
    +    t2.await.unwrap();
    +}
    +
    +

    This does not compile because both tasks need to access the client somehow. +As Client does not implement Copy, it will not compile without some code to +facilitate this sharing. Additionally, Client::set takes &mut self, which +means that exclusive access is required to call it. We could open a connection +per task, but that is not ideal. We cannot use std::sync::Mutex as .await +would need to be called with the lock held. We could use tokio::sync::Mutex, +but that would only allow a single in-flight request. If the client implements +pipelining (in short, sending many commands without waiting for each prior +command's response), an async mutex results in underutilizing +the connection.

    +

    Message passing

    +

    The answer is to use message passing. The pattern involves spawning a dedicated +task to manage the client resource. Any task that wishes to issue a request +sends a message to the client task. The client task issues the request on +behalf of the sender, and the response is sent back to the sender.

    +

    Using this strategy, a single connection is established. The task managing the +client is able to get exclusive access in order to call get and set. +Additionally, the channel works as a buffer. Operations may be sent to the +client task while the client task is busy. Once the client task is +available to process new requests, it pulls the next request from the channel. +This can result in better throughput, and be extended to support connection +pooling.

    +

    Tokio's channel primitives

    +

    Tokio provides a number of channels, each serving a different purpose.

    +
      +
    • mpsc: multi-producer, single-consumer channel. Many values can be sent.
    • +
    • oneshot: single-producer, single consumer channel. A single value can be sent.
    • +
    • broadcast: multi-producer, multi-consumer. Many values can be sent. Each +receiver sees every value.
    • +
    • watch: multi-producer, multi-consumer. Many values can be sent, but no +history is kept. Receivers only see the most recent value.
    • +
    +

    If you need a multi-producer multi-consumer channel where only one consumer sees +each message, you can use the async-channel crate. There are also channels +for use outside of asynchronous Rust, such as std::sync::mpsc and +crossbeam::channel. These channels wait for messages by blocking the +thread, which is not allowed in asynchronous code.

    +

    In this section, we will use mpsc and oneshot. The other types of message +passing channels are explored in later sections. The full code from this section +is found here.

    +

    Define the message type

    +

    In most cases, when using message passing, the task receiving the messages +responds to more than one command. In our case, the task will respond to GET and +SET commands. To model this, we first define a Command enum and include a +variant for each command type.

    +
    use bytes::Bytes;
    +
    +#[derive(Debug)]
    +enum Command {
    +    Get {
    +        key: String,
    +    },
    +    Set {
    +        key: String,
    +        val: Bytes,
    +    }
    +}
    +
    +

    Create the channel

    +

    In the main function, an mpsc channel is created.

    +
    use tokio::sync::mpsc;
    +
    +#[tokio::main]
    +async fn main() {
    +    // Create a new channel with a capacity of at most 32.
    +    let (tx, mut rx) = mpsc::channel(32);
    +
    +    // ... Rest comes here
    +}
    +
    +

    The mpsc channel is used to send commands to the task managing the redis +connection. The multi-producer capability allows messages to be sent from many +tasks. Creating the channel returns two values, a sender and a receiver. The two +handles are used separately. They may be moved to different tasks.

    +

    The channel is created with a capacity of 32. If messages are sent faster than +they are received, the channel will store them. Once the 32 messages are stored +in the channel, calling send(...).await will go to sleep until a message has +been removed by the receiver.

    +

    Sending from multiple tasks is done by cloning the Sender. For example:

    +
    use tokio::sync::mpsc;
    +
    +#[tokio::main]
    +async fn main() {
    +    let (tx, mut rx) = mpsc::channel(32);
    +    let tx2 = tx.clone();
    +
    +    tokio::spawn(async move {
    +        tx.send("sending from first handle").await.unwrap();
    +    });
    +
    +    tokio::spawn(async move {
    +        tx2.send("sending from second handle").await.unwrap();
    +    });
    +
    +    while let Some(message) = rx.recv().await {
    +        println!("GOT = {}", message);
    +    }
    +}
    +
    +

    Both messages are sent to the single Receiver handle. It is not possible to +clone the receiver of an mpsc channel.

    +

    When every Sender has gone out of scope or has otherwise been dropped, it is +no longer possible to send more messages into the channel. At this point, the +recv call on the Receiver will return None, which means that all senders +are gone and the channel is closed.

    +

    In our case of a task that manages the Redis connection, it knows that it +can close the Redis connection once the channel is closed, as the connection +will not be used again.

    +

    Spawn manager task

    +

    Next, spawn a task that processes messages from the channel. First, a client +connection is established to Redis. Then, received commands are issued via the +Redis connection.

    +
    use mini_redis::client;
    +// The `move` keyword is used to **move** ownership of `rx` into the task.
    +let manager = tokio::spawn(async move {
    +    // Establish a connection to the server
    +    let mut client = client::connect("127.0.0.1:6379").await.unwrap();
    +
    +    // Start receiving messages
    +    while let Some(cmd) = rx.recv().await {
    +        use Command::*;
    +
    +        match cmd {
    +            Get { key } => {
    +                client.get(&key).await;
    +            }
    +            Set { key, val } => {
    +                client.set(&key, val).await;
    +            }
    +        }
    +    }
    +});
    +
    +

    Now, update the two tasks to send commands over the channel instead of issuing +them directly on the Redis connection.

    +
    // The `Sender` handles are moved into the tasks. As there are two
    +// tasks, we need a second `Sender`.
    +let tx2 = tx.clone();
    +
    +// Spawn two tasks, one gets a key, the other sets a key
    +let t1 = tokio::spawn(async move {
    +    let cmd = Command::Get {
    +        key: "foo".to_string(),
    +    };
    +
    +    tx.send(cmd).await.unwrap();
    +});
    +
    +let t2 = tokio::spawn(async move {
    +    let cmd = Command::Set {
    +        key: "foo".to_string(),
    +        val: "bar".into(),
    +    };
    +
    +    tx2.send(cmd).await.unwrap();
    +});
    +
    +

    At the bottom of the main function, we .await the join handles to ensure the +commands fully complete before the process exits.

    +
    t1.await.unwrap();
    +t2.await.unwrap();
    +manager.await.unwrap();
    +
    +

    Receive responses

    +

    The final step is to receive the response back from the manager task. The GET +command needs to get the value and the SET command needs to know if the +operation completed successfully.

    +

    To pass the response, a oneshot channel is used. The oneshot channel is a +single-producer, single-consumer channel optimized for sending a single value. +In our case, the single value is the response.

    +

    Similar to mpsc, oneshot::channel() returns a sender and receiver handle.

    +
    use tokio::sync::oneshot;
    +
    +let (tx, rx) = oneshot::channel();
    +
    +

    Unlike mpsc, no capacity is specified as the capacity is always one. +Additionally, neither handle can be cloned.

    +

    To receive responses from the manager task, before sending a command, a oneshot +channel is created. The Sender half of the channel is included in the command +to the manager task. The receive half is used to receive the response.

    +

    First, update Command to include the Sender. For convenience, a type alias +is used to reference the Sender.

    +
    use tokio::sync::oneshot;
    +use bytes::Bytes;
    +
    +/// Multiple different commands are multiplexed over a single channel.
    +#[derive(Debug)]
    +enum Command {
    +    Get {
    +        key: String,
    +        resp: Responder<Option<Bytes>>,
    +    },
    +    Set {
    +        key: String,
    +        val: Bytes,
    +        resp: Responder<()>,
    +    },
    +}
    +
    +/// Provided by the requester and used by the manager task to send
    +/// the command response back to the requester.
    +type Responder<T> = oneshot::Sender<mini_redis::Result<T>>;
    +
    +

    Now, update the tasks issuing the commands to include the oneshot::Sender.

    +
    let t1 = tokio::spawn(async move {
    +    let (resp_tx, resp_rx) = oneshot::channel();
    +    let cmd = Command::Get {
    +        key: "foo".to_string(),
    +        resp: resp_tx,
    +    };
    +
    +    // Send the GET request
    +    tx.send(cmd).await.unwrap();
    +
    +    // Await the response
    +    let res = resp_rx.await;
    +    println!("GOT = {:?}", res);
    +});
    +
    +let t2 = tokio::spawn(async move {
    +    let (resp_tx, resp_rx) = oneshot::channel();
    +    let cmd = Command::Set {
    +        key: "foo".to_string(),
    +        val: "bar".into(),
    +        resp: resp_tx,
    +    };
    +
    +    // Send the SET request
    +    tx2.send(cmd).await.unwrap();
    +
    +    // Await the response
    +    let res = resp_rx.await;
    +    println!("GOT = {:?}", res);
    +});
    +
    +

    Finally, update the manager task to send the response over the oneshot channel.

    +
    while let Some(cmd) = rx.recv().await {
    +    match cmd {
    +        Command::Get { key, resp } => {
    +            let res = client.get(&key).await;
    +            // Ignore errors
    +            let _ = resp.send(res);
    +        }
    +        Command::Set { key, val, resp } => {
    +            let res = client.set(&key, val).await;
    +            // Ignore errors
    +            let _ = resp.send(res);
    +        }
    +    }
    +}
    +
    +

    Calling send on oneshot::Sender completes immediately and does not +require an .await. This is because send on a oneshot channel will always +fail or succeed immediately without any form of waiting.

    +

    Sending a value on a oneshot channel returns Err when the receiver half has +dropped. This indicates the receiver is no longer interested in the response. In +our scenario, the receiver cancelling interest is an acceptable event. The Err +returned by resp.send(...) does not need to be handled.

    +

    You can find the entire code here.

    +

    Backpressure and bounded channels

    +

    Whenever concurrency or queuing is introduced, it is important to ensure that the +queing is bounded and the system will gracefully handle the load. Unbounded queues +will eventually fill up all available memory and cause the system to fail in +unpredictable ways.

    +

    Tokio takes care to avoid implicit queuing. A big part of this is the fact that +async operations are lazy. Consider the following:

    +
    loop {
    +    async_op();
    +}
    +
    +

    If the asynchronous operation runs eagerly, the loop will repeatedly queue a new +async_op to run without ensuring the previous operation completed. This +results in implicit unbounded queuing. Callback based systems and eager +future based systems are particularly susceptible to this.

    +

    However, with Tokio and asynchronous Rust, the above snippet will not result +in async_op running at all. This is because .await is never called. If the +snippet is updated to use .await, then the loop waits for the operation to +complete before starting over.

    +
    loop {
    +    // Will not repeat until `async_op` completes
    +    async_op().await;
    +}
    +
    +

    Concurrency and queuing must be explicitly introduced. Ways to do this include:

    +
      +
    • tokio::spawn
    • +
    • select!
    • +
    • join!
    • +
    • mpsc::channel
    • +
    +

    When doing so, take care to ensure the total amount of concurrency is bounded. For +example, when writing a TCP accept loop, ensure that the total number of open +sockets is bounded. When using mpsc::channel, pick a manageable channel +capacity. Specific bound values will be application specific.

    +

    Taking care and picking good bounds is a big part of writing reliable Tokio applications.

    \ No newline at end of file diff --git a/tmp/tokio_stream_docs.html b/tmp/tokio_stream_docs.html new file mode 100644 index 0000000..b4d7a22 --- /dev/null +++ b/tmp/tokio_stream_docs.html @@ -0,0 +1,344 @@ +tokio_stream - Rust + + + +
    +
    + + + + +
    + Settings +
    +
    + Help +
    +

    Crate tokio_stream

    Crate tokio_stream 

    Source +
    + Search +
    +
    + Settings +
    +
    + Help +
    +
    Expand description

    Stream utilities for Tokio.

    +

    A Stream is an asynchronous sequence of values. It can be thought of as +an asynchronous version of the standard library’s Iterator trait.

    +

    This crate provides helpers to work with them. For examples of usage and a more in-depth +description of streams you can also refer to the streams +tutorial on the tokio website.

    +

    §Iterating over a Stream

    +

    Due to similarities with the standard library’s Iterator trait, some new +users may assume that they can use for in syntax to iterate over a +Stream, but this is unfortunately not possible. Instead, you can use a +while let loop as follows:

    + +
    use tokio_stream::{self as stream, StreamExt};
    +
    +let mut stream = stream::iter(vec![0, 1, 2]);
    +
    +while let Some(value) = stream.next().await {
    +    println!("Got {}", value);
    +}

    §Returning a Stream from a function

    +

    A common way to stream values from a function is to pass in the sender +half of a channel and use the receiver as the stream. This requires awaiting +both futures to ensure progress is made. Another alternative is the +async-stream crate, which contains macros that provide a yield keyword +and allow you to return an impl Stream.

    +

    §Conversion to and from AsyncRead/AsyncWrite

    +

    It is often desirable to convert a Stream into an AsyncRead, +especially when dealing with plaintext formats streamed over the network. +The opposite conversion from an AsyncRead into a Stream is also +another commonly required feature. To enable these conversions, +tokio-util provides the StreamReader and ReaderStream +types when the io feature is enabled.

    +

    Re-exports§

    pub use futures_core::Stream;

    Modules§

    adapters
    Adapters for Streams created by methods in StreamExt.
    wrappers
    Wrappers for Tokio types that implement Stream.

    Structs§

    Elapsedtime
    Error returned by Timeout and TimeoutRepeating.
    Empty
    Stream for the empty function.
    Iter
    Stream for the iter function.
    Once
    Stream for the once function.
    Pending
    Stream for the pending function.
    StreamMap
    Combine many streams into one, indexing each source stream with a unique +key.
    StreamNotifyClose
    A Stream that wraps the values in an Option.

    Traits§

    FromStream
    Convert from a Stream.
    StreamExt
    An extension trait for the Stream trait that provides a variety of +convenient combinator functions.

    Functions§

    empty
    Creates a stream that yields nothing.
    iter
    Converts an Iterator into a Stream which is always ready +to yield the next value.
    once
    Creates a stream that emits an element exactly once.
    pending
    Creates a stream that is never ready
    \ No newline at end of file diff --git a/tmp/venturebeat_claude_code.html b/tmp/venturebeat_claude_code.html new file mode 100644 index 0000000..37591f5 --- /dev/null +++ b/tmp/venturebeat_claude_code.html @@ -0,0 +1,304 @@ +Claude Code 2.1.0 arrives with smoother workflows and smarter agents | VentureBeat
    All Posts
    Featured

    Claude Code 2.1.0 arrives with smoother workflows and smarter agents

    Carl Franzen
    Claude Code orange sprite mascot typing in home office while sleepy human guy in bathrobe with coffee looks on approvingly and gives thumbs-up

    Credit: VentureBeat made with Google Gemini 3 Pro Image / Nano Banana Pro

    Anthropic has released Claude Code v2.1.0, a notable update to its "vibe coding" development environment for autonomously building software, spinning up AI agents, and completing a wide range of computer tasks, according to Head of Claude Code Boris Cherny in a post on X last night.

    The release introduces improvements across agent lifecycle control, skill development, session portability, and multilingual output — all bundled in a dense package of 1,096 commits.

    It comes amid a growing wave of praise for Claude Code from software developers and startup founders on X, as they increasingly use the system — powered by Anthropic's Claude model family, including the flagship Opus 4.5 — to push beyond simple completions and into long-running, modular workflows.

    Enterprise Relevance: Agent Lifecycle and Orchestration Improvements

    Claude Code was originally released as a "command line" tool back in February 2025, almost a year ago, alongside Anthropic's then cutting-edge Claude Sonnet 3.7 large language model (LLM). It has been updated various times since then, as Anthropic has also advanced its underlying LLMs.

    The new version, Claude Code 2.1.0 introduces infrastructure-level features aimed at developers deploying structured workflows and reusable skills. These changes reduce the manual scaffolding required to manage agents across sessions, tools, and environments — letting teams spend less time on configuration and more time on building.

    Key additions include:

    • Hooks for agents, skills, and slash commands, enabling scoped PreToolUse, PostToolUse, and Stop logic. This gives developers fine-grained control over state management, tool constraints, and audit logging — reducing unexpected behavior and making agent actions easier to debug and reproduce.

    • Hot reload for skills, so new or updated skills in ~/.claude/skills or .claude/skills become available immediately without restarting sessions. Developers can iterate on skill logic in real time, eliminating the stop-start friction that slows down experimentation.

    • Forked sub-agent context via context: fork in skill frontmatter, allowing skills and slash commands to run in isolated contexts. This prevents unintended side effects and makes it safer to test new logic without polluting the main agent's state.

    • Wildcard tool permissions (e.g., Bash(npm *), Bash(*-h*)) for easier rule configuration and access management. Teams can define broader permission patterns with fewer rules, reducing configuration overhead and the risk of mismatched permissions blocking legitimate workflows.

    • Language-specific output via a language setting, enabling workflows that require output in Japanese, Spanish, or other languages. Global teams and multilingual projects no longer need post-processing workarounds to localize Claude's responses.

    • Session teleportation via /teleport and /remote-env slash commands, which allow claude.ai subscribers to resume and configure remote sessions at claude.ai/code. Developers can seamlessly move work between local terminals and the web interface — ideal for switching devices or sharing sessions with collaborators.

    • Improved terminal UX, including Shift+Enter working out of the box in iTerm2, Kitty, Ghostty, and WezTerm without modifying terminal configs. This removes a common setup frustration and lets developers start working immediately in their preferred terminal.

    • Unified Ctrl+B behavior for backgrounding both agents and shell commands simultaneously. Developers can push long-running tasks to the background with a single keystroke, freeing up the terminal for other work without losing progress.

    • New Vim motions including ; and , to repeat f/F/t/T motions, yank operator (y, yy, Y), paste (p/P), text objects, indent/dedent (>>, <<), and line joining (J). Power users who rely on Vim-style editing can now work faster without switching mental models or reaching for the mouse.

    • MCP list_changed notifications, allowing MCP servers to dynamically update their available tools, prompts, and resources without requiring reconnection. This keeps workflows running smoothly when tool configurations change, avoiding interruptions and manual restarts.

    • Agents continue after permission denial, allowing subagents to try alternative approaches rather than stopping entirely. This makes autonomous workflows more resilient, reducing the need for human intervention when an agent hits a permissions wall.

    Developer Experience Improvements

    Beyond the headline features, this release includes numerous quality-of-life improvements designed to reduce daily friction and help developers stay in flow.

    • /plan command shortcut to enable plan mode directly from the prompt — fewer keystrokes to switch modes means less context-switching and faster iteration on complex tasks.

    • Slash command autocomplete now works when / appears anywhere in input, not just at the beginning. Developers can compose commands more naturally without backtracking to the start of a line.

    • Real-time thinking block display in Ctrl+O transcript mode, giving developers visibility into Claude's reasoning as it happens. This makes it easier to catch misunderstandings early and steer the agent before it goes down the wrong path.

    • respectGitignore support in settings.json for per-project control over @-mention file picker behavior. Teams can keep sensitive or irrelevant files out of suggestions, reducing noise and preventing accidental exposure of ignored content.

    • IS_DEMO environment variable to hide email and organization from the UI, useful for streaming or recording sessions. Developers can share their work publicly without leaking personal or company information.

    • Skills progress indicators showing tool uses as they happen during execution. Developers get real-time feedback on what Claude is doing, reducing uncertainty during long-running operations and making it easier to spot issues mid-flight.

    • Skills visible in slash command menu by default from /skills/ directories (opt-out with user-invocable: false in frontmatter. Custom skills are now more discoverable, helping teams adopt shared workflows without hunting through documentation.

    • Improved permission prompt UX with Tab hint moved to footer, cleaner Yes/No input labels with contextual placeholders. Clearer prompts mean fewer mistakes and faster decisions when approving tool access.

    • Multiple startup performance optimizations and improved terminal rendering performance, especially for text with emoji, ANSI codes, and Unicode characters. Faster startup and smoother rendering reduce waiting time and visual distractions, keeping developers focused on the task at hand.

    The release also addresses numerous bug fixes, including a security fix where sensitive data (OAuth tokens, API keys, passwords) could be exposed in debug logs, fixes for session persistence after transient server errors, and resolution of API context overflow when background tasks produce large output. Together, these fixes improve reliability and reduce the risk of data leaks or lost work.

    Why This Matters: Claude Code Hits a Turning Point with Power Users

    Claude Code 2.1.0 arrives in the midst of a significant shift in developer behavior. Originally built as an internal tool at Anthropic, Claude Code is now gaining real traction among external power users — especially those building autonomous workflows, experimenting with agent tooling, and integrating Claude into terminal-based pipelines.

    According to X discussions in late December 2025 and early January 2026, enthusiasm surged as developers began describing Claude Code as a game-changer for "vibe coding," agent composition, and productivity at scale.

    @JsonBasedman captured the prevailing sentiment: "I don't even see the timeline anymore, it's just 'Holy shit Claude code is so good'..."

    "Claude Code addiction is real," opined Matt Shumer, co-founder and CEO of Hyperwrite/Otherside AI, in another X post.

    Non-developers have embraced the accessibility. @LegallyInnovate, a lawyer, noted: "Trying Claude code for the first time today. I’m a lawyer not a developer. It’s AMAZING. I am blown away and probably not even scratching the surface. "

    Some users are shifting away from popular alternatives — @troychaplin switched from Cursor, calling Claude Code "so much better!" for standalone use.

    Claude Code has even fueled discussion that Anthropic has actually achieved artificial generalized intelligence, AGI, the so-called "holy grail" of artificial systems development — something that outperforms humans at most "economically valuable work," according to the definition offered by Anthropic rival OpenAI.

    @deepfates argued that Claude Code may not be AGI, but that "if Claude Code is good enough to to do that, combine ideas on the computer, then I think it is 'artificial general intellect' at least. And that is good enough to create a new frontier..."

    A clear pattern emerges: users who engage with Claude Code as an orchestration layer — configuring tools, defining reusable components, and layering logic — report transformative results. Those treating it as a standard AI assistant often find its limitations more apparent.

    Claude Code 2.1.0 doesn't try to paper over those divisions — it builds for the advanced tier. Features like agent lifecycle hooks, hot-reloading of skills, wildcard permissioning, and session teleportation reinforce Claude Code's identity as a tool for builders who treat agents not as chatbots, but as programmable infrastructure.

    In total, these updates don't reinvent Claude Code, but they do lower friction for repeat users and unlock more sophisticated workflows. For teams orchestrating multi-step agent logic, Claude Code 2.1.0 makes Claude feel less like a model — and more like a framework.

    Pricing and Availability

    Claude Code is available to Claude Pro ($20/month), Claude Max ($100/month), Claude Team (Premium Seat, $150 per month) with and Claude Enterprise (variable pricing) subscribers.

    The /teleport and /remote-env commands require access to Claude Code's web interface at claude.ai/code. Full installation instructions and documentation are available at code.claude.com/docs/en/setup.

    What's Next?

    With reusable skills, lifecycle hooks, and improved agent control, Claude Code continues evolving from a chat-based coding assistant into a structured environment for programmable, persistent agents.

    As enterprise teams and solo builders increasingly test Claude in real workflows — from internal copilots to complex bash-driven orchestration — version 2.1.0 makes it easier to treat agents as first-class components of a production stack.

    Anthropic appears to be signaling that it views Claude Code not as an experiment, but as infrastructure. And with this release, it's building like it means it.

    More

    MCP

    Why “which API do I call?” is the wrong question in the LLM era

    For decades, we have adapted to software. We learned shell commands, memorized HTTP method names and wired together SDKs. Each interface assumed we would speak its language. In the 1980s, we typed 'grep', 'ssh' and 'ls' into a shell; by the mid-2000s, we were invoking REST endpoints like GET /users; by the 2010s, we imported SDKs (client.orders.list()) so we didn’t have to think about HTTP. But underlying each of those steps was the same premise: Expose capabilities in a structured form so others can invoke them.

    Dhyey Mavani
    Greedy Zuck holding dollars grabbing PC

    Why Meta bought Manus — and what it signals for your enterprise AI agent strategy

    Facebook and Instagram parent company Meta’s agreement to acquire Manus for more than $2 billion — announced last night by both companies and reported in The Wall Street Journal — marks one of the clearest signals yet that large tech platforms are no longer just competing on model quality, but on who controls the execution layer of AI-powered work.

    Carl Franzen
    + + + + + + \ No newline at end of file