Skip to content

Instantly share code, notes, and snippets.

@thimslugga
Last active July 31, 2026 13:34
Show Gist options
  • Select an option

  • Save thimslugga/b8264b165084a2cfbb463be83671a6d5 to your computer and use it in GitHub Desktop.

Select an option

Save thimslugga/b8264b165084a2cfbb463be83671a6d5 to your computer and use it in GitHub Desktop.
AI Notes

AI Notes

Training

LLMs

Anthropic

OpenAI

This is my current setup:

Task Model
Commits, renaming, spacing, tiny UI changes Luna Medium/High or GPT-5.4
Normal bug fix or a clearly scoped feature Luna High
Unclear task that requires exploring several parts of the repo Terra Medium
Complex bug, architecture, auth, payments, migrations Sol Medium
Terra/Sol Medium failed Sol High/Max
Sol Ultra Basically never

Experience:

  • Sol is clearly strong, but it burns tokens ridiculously fast. I only use it when the task is genuinely difficult or a bad implementation could cause serious problems.
  • Terra is good, but it has been using more of my limits than I expected. On some tasks, it feels like it burns noticeably more than GPT-5.5, so I do not think it makes sense as my default model.
  • Luna currently looks like the best option for everyday work. It’s cheaper and seems good enough when the task is clearly explained and reasonably limited.

So my current workflow is:

Luna High → Terra Medium → Sol Medium

Gemini

DeepSeek

IDEs

CLIs

Codex

npm i -g @openai/codex

mkdir -p ~/.agents/skills
mkdir -p ~/.codex/skills

codex

Kiro CLI

curl -fsSL https://cli.kiro.dev/install | bash

Agent Skills

Claude Code:

/plugin marketplace add blader/humanizer
/plugin install humanizer@humanizer
mkdir -p ~/.codex/skills
git clone https://github.com/hardikpandya/stop-slop.git ~/.codex/skills/stop-slop

Skill Hubs

Tools

RAG

Claude Code Cheatsheet

Quick reference for Claude Code CLI — the official Anthropic CLI for Claude.


Table of Contents


Getting Started

# Install
npm install -g @anthropic-ai/claude-code

# Update
claude update

# Authenticate
claude auth login                          # Browser-based login
claude auth login --console                # API key / Console login
claude auth login --sso                    # SSO authentication
claude auth status                         # Check auth (JSON)
claude auth status --text                  # Check auth (human-readable)
claude auth logout                         # Log out

# Start interactive session
claude
claude "explain this project"

# Version
claude --version

CLI Commands

Command Description
claude Start interactive session
claude "prompt" Interactive session with initial prompt
claude -p "prompt" Print mode — respond and exit
claude -c Continue most recent conversation
claude -r <session> Resume session by ID or name
claude update Update to latest version
claude auth login Sign in
claude auth logout Sign out
claude auth status Show auth status
claude agents List configured subagents
claude mcp add <name> Add MCP server
claude mcp remove <name> Remove MCP server
claude mcp list List MCP servers
claude mcp status Show MCP server status
claude mcp reset-project-choices Reset project MCP approvals
claude plugin install <plugin> Install a plugin
claude plugins Manage plugins
claude auto-mode defaults Print auto mode classifier rules
claude auto-mode config Show effective auto mode config
claude remote-control [name] Start Remote Control server

CLI Flags

Essential

Flag Short Description
--print -p Non-interactive print mode
--continue -c Continue most recent conversation
--resume <session> -r Resume session by ID or name
--name <name> -n Name the session
--version -v Show version
--verbose Enable verbose logging
--debug [categories] Debug mode with optional filter

Model & Effort

Flag Description Example
--model <name> Set model (alias or full ID) --model opus
--effort <level> Set effort level --effort high
--fallback-model <name> Fallback when overloaded (print mode) --fallback-model sonnet

Permissions & Tools

Flag Description Example
--permission-mode <mode> Set permission mode --permission-mode plan
--allowedTools <tools> Auto-approve these tools --allowedTools "Bash(git *),Read"
--disallowedTools <tools> Block these tools --disallowedTools "Bash(rm *)"
--tools <tools> Restrict available tools --tools "Bash,Edit,Read"
--dangerously-skip-permissions Skip all permission prompts
--enable-auto-mode Unlock auto permission mode
--permission-prompt-tool <tool> MCP tool for permission prompts

System Prompt

Flag Description
--system-prompt <text> Replace entire system prompt
--system-prompt-file <path> Load system prompt from file
--append-system-prompt <text> Append to default system prompt
--append-system-prompt-file <path> Append file contents to system prompt

Output Format (Print Mode)

Flag Description
--output-format text|json|stream-json Output format
--input-format text|stream-json Input format
--json-schema <schema> Validate JSON output against schema
--include-partial-messages Include streaming partial events
--include-hook-events Include hook lifecycle events
--replay-user-messages Re-emit user messages on stdout

Execution Control (Print Mode)

Flag Description
--max-turns <n> Limit agentic turns
--max-budget-usd <n> Max API spend before stopping
--no-session-persistence Don't persist session

Directories & Settings

Flag Description
--add-dir <path(s)> Add working directories
--settings <path|json> Load settings from file or JSON
--setting-sources <scopes> Scopes to load: user,project,local
--mcp-config <path(s)|json> Load MCP config
--strict-mcp-config Only use --mcp-config servers

Sessions & Worktrees

Flag Description
--session-id <uuid> Use specific session ID
--fork-session Fork instead of reuse when resuming
--worktree [name] / -w Start in isolated git worktree
--tmux [=classic] Create tmux session for worktree

Advanced

Flag Description
--bare Skip auto-discovery (hooks, skills, plugins, MCP, CLAUDE.md)
--init Run initialization hooks then interactive mode
--init-only Run initialization hooks and exit
--maintenance Run maintenance hooks then interactive mode
--ide Auto-connect to IDE
--chrome / --no-chrome Enable/disable Chrome integration
--remote <desc> Create web session on claude.ai
--remote-control [name] Start with Remote Control
--teleport Resume web session in local terminal
--from-pr <number|url> Resume sessions linked to PR
--agents <json> Define subagents dynamically
--agent <name> Use specific agent
--plugin-dir <path(s)> Load plugins from directory
--disable-slash-commands Disable all skills/commands
--betas <headers> Beta headers for API
--debug-file <path> Write debug logs to file
--teammate-mode <mode> Agent team display: auto|in-process|tmux
--channels <servers> MCP servers with channel notifications

Slash Commands (Interactive)

Session & Navigation

Command Description
/help Show help and available commands
/clear Clear conversation history (aliases: /reset, /new)
/compact [instructions] Compact context (optional: with focus instructions)
/context Visualize context usage as colored grid
/resume [session] Resume a previous session (alias: /continue)
/branch [name] Branch conversation at this point (alias: /fork)
/rewind Rewind conversation to a previous point (alias: /checkpoint)
/rename [name] Rename current session
/export [filename] Export conversation as plain text
/copy [N] Copy last (or Nth) assistant response to clipboard
/quit or /exit Exit Claude Code

Configuration

Command Description
/model [name] Show or switch model (use left/right arrows for effort)
/effort [level] Show or set effort level (low|medium|high|max|auto)
/fast Toggle fast mode (same model, faster output)
/permissions View/change permission mode (alias: /allowed-tools)
/config Open settings interface (alias: /settings)
/theme Change color theme (includes colorblind-accessible options)
/color [color] Set prompt bar color (red, blue, green, yellow, purple, etc.)
/cost Show session cost & token usage
/usage Show plan usage limits and rate limit status
/status Show version, model, account, connectivity
/doctor Diagnose and verify installation

Development

Command Description
/commit Create a git commit
/review-pr [number] Review a pull request
/simplify Review changed code for quality, then fix issues
/init Initialize project config (CLAUDE.md, etc.)
/plan [description] Enter plan mode (pass description for immediate start)
/diff Open interactive diff viewer for uncommitted changes
/security-review Analyze pending branch changes for security vulnerabilities
/batch <instruction> Orchestrate large-scale parallel changes (5-30 agents)
/debug [description] Enable debug logging and troubleshoot issues

Tools & Memory

Command Description
/mcp Show MCP server status
/memory View/manage auto-memory and CLAUDE.md
/hooks View hook configurations
/add-dir <path> Add working directory for file access
/chrome Configure Chrome browser integration
/ide Manage IDE integrations and show status

Agents & Plugins

Command Description
/agents Manage agent configurations
/skills List available skills
/plugin Manage Claude Code plugins
/reload-plugins Reload plugins to apply changes
/powerup Discover Claude Code features (interactive lessons)

Task Management

Command Description
/loop <interval> <command> Run command on recurring interval (e.g., /loop 5m /commit)
/schedule Manage scheduled remote agents (cron)
/tasks or /bashes List and manage background tasks

Remote & Web

Command Description
/remote-control Make session available for remote control (alias: /rc)
/teleport Pull a web session into your terminal (alias: /tp)
/ultraplan <prompt> Draft plan in browser, execute remotely
/web-setup Connect GitHub account to Claude Code on web
/remote-env Configure default remote environment
/desktop Continue session in desktop app (alias: /app)
/mobile Show QR code for mobile app (aliases: /ios, /android)

Account & Login

Command Description
/login Sign in
/logout Sign out
/upgrade Upgrade plan
/extra-usage Configure extra usage when rate-limited
/passes Share free week of Claude Code (if eligible)
/privacy-settings View/update privacy settings (Pro/Max only)
/feedback Submit feedback (alias: /bug)
/install-github-app Set up Claude GitHub Actions app
/install-slack-app Install Claude Slack app

Utility

Command Description
/btw <question> Quick side question (not added to conversation)
/listen or /voice Toggle voice dictation / push-to-talk
/terminal-setup Configure terminal keybindings for Shift+Enter
/keybindings Open keybindings configuration file
/insights Generate report analyzing your Claude Code sessions
/stats Visualize daily usage, session history, streaks
/release-notes View changelog in interactive version picker

Custom Skills

Command Description
/claude-api Help with Claude API / Anthropic SDK
Custom /skill-name Run any custom skill from .claude/skills/

Keyboard Shortcuts

Input & Submission

Shortcut Action
Enter Submit message
Shift+Enter or Option+Enter New line (iTerm2, WezTerm, Ghostty, Kitty)
\ + Enter New line (works in all terminals)
Ctrl+J Line feed (multiline)
Tab Accept autocomplete suggestion
Up/Down Arrow Navigate input history
Ctrl+R Reverse search command history
/ at start Slash command / skill autocomplete
! at start Bash mode (run commands directly)
@ File path mention autocomplete

Text Editing

Shortcut Action
Ctrl+A / Ctrl+E Move to start / end of line
Alt+B / Alt+F Move cursor back / forward one word
Ctrl+W Delete word backward
Ctrl+K Delete to end of line
Ctrl+U Delete from cursor to line start
Ctrl+Y Paste deleted text (yank)
Alt+Y (after Ctrl+Y) Cycle paste history
Ctrl+L Clear prompt input
Ctrl+G or Ctrl+X Ctrl+E Open prompt in external text editor

Session & Generation Control

Shortcut Action
Escape Cancel current generation / interrupt
Escape (twice) Rewind / summarize from selected message
Ctrl+C Cancel current action
Ctrl+D Exit (EOF)
Ctrl+B Background running tasks (tmux users: press twice)
Ctrl+X Ctrl+K Kill all background agents (press twice to confirm)

Model & Mode Switching

Shortcut Action
Option+P / Alt+P Switch model
Option+T / Alt+T Toggle extended thinking
Option+O / Alt+O Toggle fast mode
Shift+Tab / Alt+M Cycle permission modes
Ctrl+O Toggle verbose output
Ctrl+T Toggle task list display

Navigation

Shortcut Action
Shift+Up/Down Scroll through output
Mouse scroll Scroll through output
Left/Right arrows Cycle through dialog tabs

Media

Shortcut Action
Ctrl+V / Cmd+V (iTerm2) / Alt+V (Windows) Paste image from clipboard
Hold Space Push-to-talk voice dictation (when enabled)

Permission Prompts

Shortcut Action
y / Enter Approve
n Deny
a Always allow (this session)
e Edit (for some tools)

Vim Mode (enable via /config)

Click to expand Vim shortcuts

Mode Switching

Key Action
Esc Enter NORMAL mode
i / I Insert before cursor / at line start
a / A Insert after cursor / at line end
o / O Open line below / above

Navigation (NORMAL)

Key Action
h/j/k/l Left / down / up / right
w / e / b Next word / end of word / previous word
0 / $ / ^ Line start / end / first non-blank
gg / G Beginning / end of input
f{c} / F{c} Jump to next / previous char
t{c} / T{c} Jump before next / after previous char
; / , Repeat / reverse last f/F/t/T

Editing (NORMAL)

Key Action
x Delete character
dd / D Delete line / to end of line
dw / de / db Delete word / to end / back
cc / C Change line / to end of line
cw / ce / cb Change word / to end / back
yy / Y Yank (copy) line
p / P Paste after / before cursor
>> / << Indent / dedent line
J Join lines
. Repeat last change

Text Objects: iw/aw (word), i"/a" (quotes), i(/a( (parens), i{/a{ (braces), i[/a[ (brackets)

Keybindings are customizable via ~/.claude/keybindings.json or /keybindings


Models & Effort Levels

Available Models

Model Alias ID Notes
Opus 4.6 opus claude-opus-4-6 Most capable, supports max effort
Sonnet 4.6 sonnet claude-sonnet-4-6 Fast and capable
Haiku 4.5 haiku claude-haiku-4-5-20251001 Fastest, lightest

Model Aliases

Alias Behavior
default Reset to recommended model for your account tier
best Most capable available (currently = opus)
opus Latest Opus (4.6)
sonnet Latest Sonnet (4.6)
haiku Fast & efficient
opus[1m] Opus with 1M token context window
sonnet[1m] Sonnet with 1M token context window
opusplan Opus in plan mode, Sonnet in execution mode
# Switch model
claude --model opus
claude --model claude-sonnet-4-6
/model sonnet                          # Interactive
Option+P / Alt+P                       # Keyboard shortcut

Effort Levels

Level Description
low Quick responses, minimal reasoning
medium Balanced (default for auto)
high Comprehensive, more thorough reasoning
max Deepest reasoning (Opus 4.6 only)
auto Dynamically adjusts based on task complexity
claude --effort high
/effort max                            # Interactive

Fast Mode

Toggle with /fast — uses the same model but with faster output generation. Does not switch models.


Permission Modes

Mode Description
default Prompt for each tool use
acceptEdits Auto-approve file edits, prompt for others
plan Read-only — no edits or commands without approval
auto AI classifies safe vs. unsafe actions (Team/Enterprise/API)
dontAsk Deny anything not pre-approved in allowedTools
bypassPermissions Skip all prompts (use with caution)
claude --permission-mode plan
/permissions                           # Interactive — cycle through modes

Print Mode (Non-Interactive)

Print mode (-p) is the programmatic interface. Claude responds and exits.

# Basic
claude -p "What does this project do?"

# With tool permissions
claude -p "Fix the bug in auth.py" --allowedTools "Read,Edit,Bash(npm test)"

# JSON output
claude -p "List all functions" --output-format json | jq '.result'

# Structured output with schema validation
claude -p "Extract function names" \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'

# Streaming JSON
claude -p "Write a function" --output-format stream-json

# Budget & turn limits
claude -p "Refactor this module" --max-turns 5 --max-budget-usd 2.00

# Custom system prompt
claude -p "Review this" --append-system-prompt "Focus on security vulnerabilities"

# Bare mode (fast, no auto-discovery)
claude --bare -p "Summarize" --allowedTools "Read"

Piping & Streaming

# Pipe file contents
cat auth.py | claude -p "Find the bug"

# Pipe command output
git diff | claude -p "Summarize changes"
git log --oneline -20 | claude -p "Summarize recent work"

# Chain with jq
claude -p "List API endpoints" --output-format json | jq '.result'

# Stream tokens in real-time
claude -p "Write a poem" --output-format stream-json | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'

# Multi-step pipeline
git diff HEAD~5 | claude -p \
  --append-system-prompt "You are a code reviewer" \
  --output-format json | jq '.result'

Sessions & Resumption

# Name a session
claude -n "auth-refactor"

# Continue most recent session
claude -c

# Resume by name or ID
claude -r "auth-refactor"
claude -r "abc123-session-id"

# Resume and fork (new session from old context)
claude --resume "auth-refactor" --fork-session

# Capture session ID from print mode
session_id=$(claude -p "Start review" --output-format json | jq -r '.session_id')
claude -p "Continue" --resume "$session_id"

Hooks

Hooks are shell commands that run in response to Claude Code events. Configure in settings.json.

Hook Events

Event Trigger
SessionStart When a session begins
SessionEnd When a session ends
PreToolUse Before a tool executes
PostToolUse After a tool executes
PostToolUseFailure After a tool fails
PermissionRequest When a permission prompt is shown
PermissionDenied When a permission is denied
SubagentStart When a subagent launches
SubagentStop When a subagent finishes
UserPromptSubmit When user submits a prompt
Stop When Claude finishes responding
Notification When Claude sends a notification
FileChanged When a file is modified
ConfigChange When configuration changes

Hook Types

Type Description Key Field
command Run a shell script command: "./script.sh"
http POST JSON to URL url: "http://localhost:8080/hook"
prompt Single-turn LLM call prompt: "Is this safe? $ARGUMENTS"
agent Spawn a subagent prompt: "Verify this action"

Configuration

// .claude/settings.json or ~/.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",                     // Tool name to match (regex supported)
        "script": "./hooks/validate-bash.sh",  // Script to run
        "timeout": 600                         // Timeout in seconds
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "script": "echo 'File modified' >> ./audit.log"
      }
    ],
    "SessionStart": [
      {
        "script": "echo 'Session started at $(date)'"
      }
    ]
  }
}

Hook Behavior

  • PreToolUse: Can block tool execution (exit code 2 = blocking error)
  • PostToolUse: Runs after tool completes; output is shown to Claude
  • SessionStart/End: Run at session lifecycle boundaries
  • Hooks receive JSON on stdin with event details
  • Hook stdout/stderr is captured and fed back to Claude
  • Exit 0: Success, process stdout JSON
  • Exit 2: Blocking error, stderr is feedback
  • Other exit codes: Non-blocking error

MCP Server Configuration

Configuration Locations (Priority Order)

Scope Location Shared?
Managed System-level managed-mcp.json Yes (IT deployed)
Local .claude/settings.local.json No (gitignored)
Project .mcp.json (repo root) Yes (version controlled)
User ~/.claude/mcp.json No (personal)

.mcp.json Format

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["./mcp-server.js"],
      "env": {
        "API_KEY": "${API_KEY}",
        "PROJECT_ROOT": "${PWD}"
      },
      "disabled": false,
      "alwaysAllow": true
    }
  }
}

OAuth MCP Servers

{
  "mcpServers": {
    "slack": {
      "command": "npx",
      "args": ["@slack/mcp-server"],
      "oauth": {
        "clientId": "${SLACK_CLIENT_ID}",
        "clientSecret": "${SLACK_CLIENT_SECRET}",
        "authServerMetadataUrl": "https://slack.com/.well-known/oauth.json"
      }
    }
  }
}

Managed MCP (Enterprise)

OS Path
macOS /Library/Application Support/ClaudeCode/managed-mcp.json
Linux/WSL /etc/claude-code/managed-mcp.json
Windows C:\Program Files\ClaudeCode\managed-mcp.json

When present, takes exclusive control — users cannot add/modify MCP servers.

CLI Commands

claude mcp add my-server
claude mcp remove my-server
claude mcp list
claude mcp status
claude mcp reset-project-choices

# Load from CLI
claude --mcp-config ./mcp.json
claude --strict-mcp-config --mcp-config ./mcp.json    # Only use these servers

Memory System

Claude Code has a persistent file-based memory at ~/.claude/projects/<project>/memory/.

Memory Types

Type Purpose
user User role, preferences, knowledge
feedback Corrections and confirmed approaches
project Ongoing work, goals, decisions
reference Pointers to external resources

Memory File Format

---
name: Memory Title
description: One-line description for relevance matching
type: user|feedback|project|reference
---

Content of the memory...

Index File

MEMORY.md in the memory directory is an index of all memories. Each entry is one line under 150 characters.

Usage

  • Ask Claude to "remember" something and it saves to memory
  • Ask Claude to "forget" something and it removes it
  • Claude reads relevant memories at the start of conversations
  • /memory shows current memories interactively

Settings & Configuration

File Locations

File Scope Shared?
~/.claude/settings.json User (global) No
.claude/settings.json Project Yes (commit)
.claude/settings.local.json Local No (gitignored)

Settings Schema

{
  // Model & effort
  "model": "claude-opus-4-6",
  "effortLevel": "high",

  // Permissions
  "permissions": {
    "allow": [
      "Read",
      "Bash(git *)",
      "Bash(npm test)"
    ],
    "deny": [
      "Bash(rm *)",
      "Bash(sudo *)"
    ]
  },

  // Hooks
  "hooks": {
    "PreToolUse": [{ "matcher": "Bash", "script": "./validate.sh" }],
    "PostToolUse": [{ "matcher": "Edit", "script": "./on-edit.sh" }]
  },

  // Environment variables
  "env": {
    "DEBUG": "1"
  }
}

Permission Rule Patterns

Pattern Matches
Bash All bash commands
Bash(npm run build) Exact command
Bash(npm run *) Prefix with wildcard
Read All file reads
Read(./.env) Specific file
Read(/docs/**) Recursive directory (relative to project root)
Read(//Users/me/*) Absolute path (note double //)
Read(~/.zshrc) Home directory path
Edit All file edits
WebFetch All web fetches
WebFetch(domain:example.com) Specific domain
mcp__server__tool MCP tools
Agent(AgentName) Specific subagent
Skill(name) Specific skill

CLAUDE.md Files

Project instructions loaded automatically:

Scope Location Shared?
Managed policy /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) Yes (org-wide)
Project ./CLAUDE.md or ./.claude/CLAUDE.md Yes (in git)
User ~/.claude/CLAUDE.md No (global personal)
Local ./CLAUDE.local.md No (gitignored)
Subdirectory subdir/CLAUDE.md Yes (loaded when working in that dir)

Features:

  • Imports: See @README for overview and @package.json for commands.
  • Nested: CLAUDE.md in subdirectories auto-load when Claude works there
  • Path-specific rules: .claude/rules/*.md with paths: frontmatter

Environment Variables

Authentication

ANTHROPIC_API_KEY="sk-ant-..."              # API key
ANTHROPIC_AUTH_TOKEN="..."                  # Custom auth header

API Endpoints

ANTHROPIC_BASE_URL="https://..."            # API endpoint override
CLAUDE_CODE_USE_BEDROCK=1                   # Use Amazon Bedrock
CLAUDE_CODE_USE_VERTEX=1                    # Use Google Vertex AI
CLAUDE_CODE_USE_FOUNDRY=1                   # Use Microsoft Foundry

Model

ANTHROPIC_MODEL="claude-opus-4-6"           # Default model
CLAUDE_CODE_MAX_OUTPUT_TOKENS="4096"        # Max output tokens
CLAUDE_CODE_SUBAGENT_MODEL="claude-sonnet-4-6"  # Subagent model

Thinking & Effort

CLAUDE_CODE_EFFORT_LEVEL="high"             # Effort level
CLAUDE_CODE_DISABLE_THINKING=1              # Disable extended thinking

Performance

DISABLE_PROMPT_CACHING=1                    # Disable prompt caching
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE="75"        # Auto-compact trigger %
DISABLE_AUTO_COMPACT=1                      # Disable auto-compaction

Feature Toggles

CLAUDE_CODE_DISABLE_AUTO_MEMORY=1           # Disable auto memory
CLAUDE_CODE_DISABLE_CLAUDE_MDS=1            # Don't load CLAUDE.md files
CLAUDE_CODE_DISABLE_FAST_MODE=1             # Disable fast mode
CLAUDE_CODE_DISABLE_MOUSE=1                 # Disable mouse tracking
CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1        # Disable terminal title updates
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1      # Disable background tasks
CLAUDE_CODE_DISABLE_CRON=1                  # Disable scheduled tasks

Shell

CLAUDE_CODE_SHELL="zsh"                     # Override shell
BASH_DEFAULT_TIMEOUT_MS="120000"            # Default bash timeout (ms)
BASH_MAX_TIMEOUT_MS="600000"                # Max bash timeout (ms)
BASH_MAX_OUTPUT_LENGTH="10000"              # Max bash output chars
CLAUDE_ENV_FILE="/path/to/env.sh"           # Shell env script

Security (mTLS)

CLAUDE_CODE_CLIENT_CERT="/path/to/cert"     # Client certificate
CLAUDE_CODE_CLIENT_KEY="/path/to/key"       # Client private key

Telemetry

DISABLE_TELEMETRY=1                         # Opt out of telemetry
DISABLE_ERROR_REPORTING=1                   # Opt out of Sentry

UI

CLAUDE_CODE_ACCESSIBILITY=1                 # Keep native cursor visible
CLAUDE_CODE_SCROLL_SPEED="5"                # Scroll speed (1-20)
CLAUDE_CODE_NO_FLICKER=1                    # Fullscreen rendering mode
DISABLE_COST_WARNINGS=1                     # Disable cost warnings

Debugging

CLAUDE_CODE_DEBUG_LOGS_DIR="/path/to/logs"  # Debug log directory
CLAUDE_CODE_DEBUG_LOG_LEVEL="debug"         # Log level
CLAUDECODE=1                                # Auto-set in Claude-spawned shells

IDE Integration

VS Code

  • Extension: Claude Code in VS Code marketplace
  • Auto-connects when claude --ide is used
  • Provides inline diff view, file navigation, and terminal integration

JetBrains

  • Plugin available for IntelliJ, WebStorm, PyCharm, etc.
  • Similar integration to VS Code

Configuration

CLAUDE_CODE_AUTO_CONNECT_IDE="true"         # Auto-connect on startup
CLAUDE_CODE_IDE_HOST_OVERRIDE="localhost:5000"  # Override IDE host
CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL=1         # Skip extension auto-install

Usage

claude --ide                                # Auto-connect to running IDE

Agent SDK

Build custom agents programmatically using Claude Code's capabilities.

Python

pip install claude-agent-sdk
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

async def main():
    async for message in query(
        prompt="Fix the bug in auth.py",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Bash"],
            permission_mode="acceptEdits",
            model="claude-opus-4-6",
        )
    ):
        if hasattr(message, 'result'):
            print(message.result)

asyncio.run(main())

TypeScript

npm install @anthropic-ai/claude-agent-sdk
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Fix the bug in auth.py",
  options: {
    allowedTools: ["Read", "Edit", "Bash"],
    permissionMode: "acceptEdits",
    model: "claude-opus-4-6",
  }
})) {
  if ("result" in message) console.log(message.result);
}

Key SDK Features

  • Custom tools — define tools with @tool decorator (Python) or tool() function (TypeScript)
  • Hooks — intercept PreToolUse, PostToolUse events programmatically
  • Subagents — delegate to specialist agents
  • Sessions — capture session_id and resume later
  • Structured output — validate responses against JSON Schema
  • Permission callbacks — custom can_use_tool function for fine-grained control
  • MCP integration — connect MCP servers programmatically
  • Multi-turn — use ClaudeSDKClient for continuous conversations

Plugins & Custom Skills

Custom Skills

Create .claude/skills/<skill-name>/SKILL.md:

---
name: skill-name
description: What it does
disable-model-invocation: true   # Optional: only user can invoke
allowed-tools: Read Grep         # Optional: restrict tools
---

Your instructions here...

Invoke with /skill-name in interactive mode.

Custom Subagents

Create .claude/agents/<name>.md:

---
name: my-agent
description: What this agent does
model: opus
effort: high
tools: Read,Bash
---

System prompt and instructions...

Plugin Structure

my-plugin/
├── .claude-plugin/plugin.json   # Manifest (name, version, author)
├── skills/                      # Skills (SKILL.md files)
├── agents/                      # Custom agents
├── hooks/hooks.json             # Hook definitions
├── .mcp.json                    # MCP servers
├── bin/                         # Executables added to PATH
└── settings.json                # Default settings

Plugin Commands

claude plugin install <plugin>              # Install from marketplace
claude plugin install code-review@official  # Example
/reload-plugins                             # Reload after changes
--plugin-dir ./path                         # Load local plugin for testing

Worktrees

Isolated git worktrees for parallel work without branch switching.

# Start in a worktree
claude -w feature-auth

# With tmux session
claude -w feature-auth --tmux

# Worktree location
# .claude/worktrees/<name>/
  • Each worktree gets its own copy of the repo on a separate branch
  • Changes stay isolated until merged
  • Automatically cleaned up if no changes are made

Useful Recipes

Code Review

# Review a PR
gh pr diff 123 | claude -p "Review this PR for bugs and security issues"

# Review with custom instructions
gh pr diff 123 | claude -p \
  --append-system-prompt "Focus on: SQL injection, XSS, auth bypass" \
  "Review this diff"

Git Workflows

# Commit with Claude
/commit                                    # Interactive

# Summarize recent changes
git log --oneline -20 | claude -p "Summarize recent work"

# Generate release notes
git log v1.0..v2.0 --oneline | claude -p "Write release notes"

CI/CD Integration

# Bare mode for fast, reproducible CI runs
claude --bare -p "Run tests and report failures" \
  --allowedTools "Bash(npm test),Read" \
  --max-turns 5 \
  --max-budget-usd 1.00 \
  --output-format json

Security Audit

claude -p "Audit this codebase for OWASP top 10 vulnerabilities" \
  --allowedTools "Read,Glob,Grep" \
  --effort high

Documentation

claude -p "Generate API documentation for the public functions in src/" \
  --allowedTools "Read,Glob,Grep"

Batch Processing

# Process multiple files
for f in src/*.py; do
  claude --bare -p "Add type hints to $f" \
    --allowedTools "Read,Edit" \
    --output-format json
done

Claude Code Configuration

Overview

  1. .claude/ at the project root (per-repo, team config)
  2. ~/.claude/ in your home directory (global, personal config)

There is also a separate file ~/.claude.json (not a directory) that Claude Code writes to for app state and OAuth tokens. Think of it like .git/ vs .gitconfig: one is a per-project directory, one is global.

Note: There is no .claude-code directory, Claude Code uses .claude/.


Project-level .claude/ (lives in the repo)

This is the folder you commit to git so your team gets the same rules, commands, and permissions. A full-featured layout looks like this:

my-project/
├── CLAUDE.md                    # Instructions loaded every session (project root, not inside .claude/)
├── CLAUDE.local.md              # Your private notes for this project (add to .gitignore)
├── .mcp.json                    # Team-shared MCP server definitions (repo root)
├── .worktreeinclude             # Gitignored files to copy into new git worktrees
├── .claudeignore                # Paths Claude should never read
└── .claude/
    ├── settings.json            # Permissions, hooks, env vars, model defaults
    ├── settings.local.json      # Personal overrides, auto-gitignored
    ├── rules/
    │   ├── testing.md           # Topic-scoped instructions (can be path-gated)
    │   └── security.md
    ├── skills/
    │   └── code-review/
    │       ├── SKILL.md         # Reusable workflow, auto-invoked when relevant
    │       └── reference.md     # Supporting docs the skill reads on demand
    ├── commands/
    │   └── deploy.md            # Single-file slash command (/deploy)
    ├── agents/
    │   └── security-auditor.md  # Subagent with its own prompt and tool allowlist
    ├── agent-memory/
    │   └── security-auditor/    # Persistent memory for that subagent
    ├── output-styles/
    │   └── terse.md             # Custom system-prompt sections
    └── docs/                    # Unofficial but common: reference docs skills read on demand
        └── architecture.md

Loading behavior

A few things worth knowing about loading behavior, because this trips people up:

  • CLAUDE.md sits at the repo root, not inside .claude/. It loads every session. Claude walks from your current working directory up to the root, so nested CLAUDE.md files in subdirectories also apply, with deeper files taking priority.
  • rules/*.md loads automatically too, so keep them short and topical. Heavy reference material belongs in skills/ or docs/ where it only loads when needed. The analogy here is eager vs lazy imports: rules are eager, skills are lazy.
  • settings.local.json gets added to .gitignore automatically when Claude writes to it. Safe place to put personal permission overrides.
  • commands/ and skills/ are converging. A file at .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy. Skills are the newer form and support a folder with extra files plus frontmatter.

Global ~/.claude/ (lives in your home directory)

This is your personal setup, shared across every project on this machine. You do not commit this anywhere.

~/.claude/
├── CLAUDE.md                    # Your global instructions (loaded every session, everywhere)
├── settings.json                # Your global permissions, hooks, model defaults
├── settings.local.json          # Machine-local overrides
├── rules/                       # Global topic-scoped rules
├── skills/                      # Skills available across all projects
│   └── my-personal-skill/
│       └── SKILL.md
├── commands/                    # Personal slash commands
├── agents/                      # Personal subagents
├── agent-memory/                # Persistent memory for personal subagents
├── output-styles/
├── keybindings.json             # Custom keyboard shortcuts
│
│   # Data Claude writes during sessions (not config you author):
├── projects/
│   └── <project-hash>/
│       ├── <session>.jsonl      # Full session transcripts (plaintext, not encrypted)
│       └── memory/              # Auto-memory: Claude's notes to itself across sessions
├── history.jsonl                # Your prompt history across all sessions
├── todos/                       # Task lists per session
├── plans/                       # Plan-mode markdown documents
├── file-history/                # File checkpoints for undo/rollback
├── shell-snapshots/             # Shell environment snapshots (cleared on clean exit)
├── session-env/                 # Per-session environment variables
├── stats-cache.json             # Aggregated usage statistics
└── debug/                       # Debug logs per session

The config files mirror the project layout so muscle memory transfers. The session data directories (projects/, history.jsonl, todos/, file-history/, etc.) are machine-written, not hand-edited. Files in most of them get cleaned up automatically once older than cleanupPeriodDays (default 30).

Security note: Transcripts in projects/<project>/<session>.jsonl are plaintext. If a tool reads a .env or a command prints a credential, that value lands on disk. Lower cleanupPeriodDays in settings.json or set CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 to reduce exposure.

You can also redirect everything with the CLAUDE_CONFIG_DIR environment variable. Every ~/.claude/ path above will live under that directory instead. Useful if you want XDG-style placement under ~/.config/claude/.


Minimal starter examples

A bare-bones CLAUDE.md

# Project Name

Short description of what this project does and who uses it.

## Stack

- Language: Python 3.12
- Framework: Flask
- Database: SQLite (dev), PostgreSQL (prod)

## Conventions

- Prefer standard library over third-party deps
- Use pytest for tests, files in tests/ mirror src/
- No heavy frameworks; keep it simple

## Commands

- `make dev` - start dev server on :5000
- `make test` - run pytest
- `make lint` - ruff check

A minimal .claude/settings.json

With the $schema line for editor autocomplete:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(make *)",
      "Bash(pytest *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Read(**)",
      "Edit(src/**)",
      "Edit(tests/**)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(curl * | sh)",
      "Read(.env)",
      "Read(**/*secret*)"
    ]
  },
  "model": "claude-opus-4-7"
}

Anything not in allow or deny will prompt you for confirmation, which is the intentional middle ground.

A simple slash command

At .claude/commands/review.md:

---
description: Review the current branch diff before merging
---

## Changes

!`git diff --name-only main...HEAD`

## Full diff

!`git diff main...HEAD`

Review for code quality, security issues, missing tests, and performance.
Give specific feedback per file.

That becomes /review in your session, with the actual git diff injected via the !`backtick` shell-execution syntax.


Quick verification commands

Once you are in a session, you can see what actually loaded:

Command Description
/context Token usage across system prompt, memory, skills, MCP tools
/memory Which CLAUDE.md and rules files are loaded
/skills Available skills from project, user, and plugin sources
/permissions Current allow/deny rules
/mcp Connected MCP servers
/hooks Active hook configurations
/agents Configured subagents
/doctor Installation and configuration diagnostics

Start with /context when something feels off, then drill into the specific subsystem.


What to commit and what to ignore

Add these to .gitignore at the project level:

.claude/settings.local.json
CLAUDE.local.md

Commit everything else in .claude/. That way your team gets consistent rules, permissions, skills, and commands, while personal overrides stay on your machine.


Official reference: https://code.claude.com/docs/en/claude-directory

Claude Code Plugins

A Claude Code plugin is a directory with a manifest at .claude-plugin/plugin.json, plus whatever components it ships. A typical structure might look like this:

my-plugin/
├── .claude-plugin/
│   └── plugin.json
├── skills/
├── agents/
├── hooks/
└── .mcp.json

Claude Code can load plugins from local paths or install them from a marketplace. Once installed, the components become part of the session surface. Skills show up as slash invocations. Agents show up in /agents. MCP servers register tools. Hooks and monitors run when their matchers fire.

Agent Skills

What is a Claude Code skill? A reusable instruction pack with a name, a description, and a set of conditions for when it should be applied. The main agent loads relevant skills automatically based on context.

Where do skills live? In ~/.claude/skills/<name>/ for user scope or .claude/skills/<name>/ inside a project for project scope.

How is a skill different from an MCP server? A skill is instructions. An MCP server is tools. A skill tells the agent what to do. An MCP server gives it new things it can do.

How is a skill different from a subagent? A skill modifies how the main agent behaves. A subagent is a separate agent the main one delegates to. Skills are inline guidance. Subagents are spawned workers.

What bundled skills are worth knowing? /batch for parallel work in worktrees, /simplify for restructuring complex prompts, /debug for troubleshooting, /loop for repeated prompts, and /claude-api for API-focused work.

Bundled skills worth knowing

Claude Code ships several bundled skills. The ones that pay off immediately: /batch

Spawns parallel work across multiple git worktrees. Hand it a list of tasks (“apply this refactor to these five packages”) and it creates worktrees, runs the work in parallel, and collects the results. /simplify

Useful when the task or prompt has become too sprawling. It helps Claude reduce a messy ask into a smaller, clearer execution plan. /debug

Focused on troubleshooting loops, reproductions, and narrowing root cause. It is the first bundled skill I would reach for when a session is stuck in “something is broken” mode. /loop

Runs a prompt on repeat while the session stays open. Good for lightweight monitoring or repeated checks without building a separate automation system. /claude-api

Useful when the task is specifically about Anthropic’s API surface rather than general code work.

One thing to be careful about: /commit is a very common custom skill pattern, but it is not one of the bundled skills Claude Code documents today.

What a skill actually is

The mental model is simple. A skill is a folder with a SKILL.md (instructions and triggering conditions) plus optional supporting files (templates, examples, helper scripts).

When Claude Code starts a session, it reads the skill descriptions from your skills directories. As the session progresses, the model decides whether the current task matches a skill’s description. If it matches, the skill’s instructions get loaded and applied.

This is different from a system prompt that runs every session. It is closer to a library: the agent has a shelf of skills, and pulls down the one it needs when it needs it.

When to write a skill

Skills pay off in three patterns.

Repeatable workflows that span many sessions

If you find yourself writing the same instructions to Claude Code at the start of every relevant session (“write tests in this style, use Vitest, prefer integration tests over unit tests”), that is a skill. Write it once, save it, and the agent picks it up automatically next time.

Project-specific conventions

Every codebase has unwritten rules. Naming, error handling, where to put new files, which patterns to copy from. A project skill captures those rules in one place, and any agent working in the repo gets them for free.

Domain expertise

If a session needs to know how to use a specific framework, library, or internal API, package that knowledge into a skill. The skill description triggers it when relevant. The instructions teach the agent the API once, and the agent uses it correctly from then on.

Skill vs MCP server vs subagent

These three layers of Claude Code’s platform get conflated. They are not the same.

Layer What it adds Example MCP server New tools the agent can call ”GitHub MCP server lets the agent open PRs” Skill New instructions the agent applies in context ”Test-writing skill makes the agent write Vitest tests in your house style” Subagent A separate agent the main one delegates to ”Code-reviewer subagent runs in its own context to audit a diff”

A workflow can use all three together. The agent gets a Bash tool, a GitHub tool from MCP, an “open PR with description” skill, and delegates the code review to a code-reviewer subagent. Each layer does what it is good at.

Tuning skill descriptions

The description field is the most important part of a skill. It is what the model reads to decide whether to apply the skill.

Patterns that work:

  • Lead with the use condition. “Use this skill when [X].” The model parses this as a triage rule.
  • Name the artifact or output. “When generating tests” is more useful than “for testing work”.
  • Be explicit about scope. “Vitest and Playwright tests only” prevents the skill from triggering on unrelated test conversations.

Patterns that fail:

  • Vague descriptions. “Helps with development” matches everything. The model triggers it constantly, polluting context.
  • Listing capabilities instead of conditions. “Knows how to write tests, run linters, format code” is a description of what the skill knows. The model needs to know when to use it.

Project-scope vs user-scope skills

User scope (~/.claude/skills/) is right for your personal preferences and any conventions you carry across projects.

Project scope (.claude/skills/ in a repo) is right for project-specific rules. Naming conventions, framework choices, where new files go. Commit project-scope skills with the repo so every developer gets them.

Most production teams I have seen end up with a small library of project-scope skills (5 to 10) and a handful of personal user-scope skills. The project-scope skills compound the most: every contributor benefits from work that one person did once.

Prompt Engineering

Prompts

# Import/Export AI Context Prompt

You are helping me import context from one AI assistant to another. Your job is to go through our past conversations and sum up what you know about me.

In the output, please avoid using any first-person pronouns (I, my, me, mine) and any second-person pronouns (you, your, yours). Instead, refer to the individual you have learned about as "the user" or use neutral phrasing.
Preserve the user’s words verbatim where possible, especially for instructions and preferences.

Categories (output in this order):

1. Demographics Information: Preferred names, profession, education, and general residence.
2. Interests & Preferences: Sustained, active engagements (not just owning an object or a one-time purchase).
3. Relationships: Confirmed, sustained relationships.
4. Dated Events, Projects & Plans: A log of significant, recent activities.
5. Instructions: Rules I've explicitly asked you to follow going forward, "always do X", "never do Y", and corrections to your behavior. Only include rules from stored memories, not from conversations.

Format:

Divide the content into the labeled section using the categories above. Try to include verbatim quotes from my prompts that justify each entry. Structure each entry using this format:

The user's name is <name>.

  - Evidence: User said "call me <name>". Date: [YYYY-MM-DD].
Output:
  - You MUST not include any conversational filler, intro text, or sign-offs. Output ONLY the requested information.

Finally, complete the sentence "Imported from: <name>", where name is Claude, ChatGPT, Gemini, Kiro, Grok, etc. This must be the absolute final text in your response.

Software Architect (Claude)

As a software architect, your responsibility is to develop code that is both clean and maintainable. 
Whenever you provide code, ensure that you deliver the solution in its entirety, not fragmented into parts. 
The code should be ready to be copied and pasted directly into the target file, completely replacing the existing content without the need for additional adjustments.

Additionally, it is crucial to clearly specify the name of the affected file and the exact path where it is located to ensure error-free integration and efficient code management.

PROMPT.md

# Role
You are an expert Linux shell script developer who organizes their code and comments their code using shell scripting best practices.

Create a bash shell script which reads from standard input text in Markdown format and prints all embedded hyperlink URLs.

The script requirements are:
  - MUST exclude all inline code elements
  - MUST exclude all fenced code blocks
  - MUST print all hyperlink URLs
  - MUST NOT print hyperlink label
  - MUST NOT use Perl compatible regular expressions
  - MUST NOT use double quotes within comments
  - MUST NOT use single quotes within comments

Follow solid architecture principles.

Step 1: Define problem in PROBLEM.md 
Step 2: Ask agent to gather scope from codebase and update PROBLEM.md 
Step 3: Ask agent to create a plan following design and architecture best practices (solid, etc) and update PROBLEM.md
Step 4: Ask agent to implement PROBLEM.md

Bash Script Prompt

Unless stated otherwise, assume you are being asked to write a bash shell script that will run on Linux. You are the world's most experienced shell script developer. Your code is super-structured and well documented. 

It will follow these guidelines: 

0) If the design of the script is complex, explore multiple design options first before settling on the best one. 

1) You will always start the script with a shebang.

2) Use bash functions generously. Any function that contains more than 30 lines, not counting blank lines, break down into smaller functions, for legibility.

3) Use comments when they are necessary to explain intent or complex logic.

4) After the shebang, include a comments block with the following: 
  a) High-level function of the script. 
  b) Disclaimer - no warranties for correct function. 
  c) Last-modified date, in format YYYY-MM-DD, followed by the text " [YYYY-MM-DD]". 
  d) Which operating systems the script was written for. 
  e) "Written by: Adam Kaminski and Claude AI". 
  f) If the code contains variable names in UPPERCASE, add the following text to this comment block: "Variable names are uppercased if the variable is read-only or if it is an external variable."

5) Before each function, include a comments block with the following info about the function: a) what the function does, b) input, c) output, d) what other functions or traps call this function.

6) Always use a main function.

7) Follow best coding practices.

8) Never use user input without first checking it. If you can guess the function of parameter, and the function would indicate the use of a particular data type in a typed language, implement the parameter check to how you would check if a value was valid for that parameter. E.g., if a value can only be an IPv4 IP address, make sure that it matches the pattern of an IPv4 IP address.

9) UPPERCASE the names of all variables that are hard-coded.

10) Make all variables readonly that can be made readonly.

11) Precede the definitions of all global variables with a comment. (One comment for all of them.)

12) Always support a -h / --help parameter that outputs usage info.

13) The output of usage info must be implemented in a function. 

14) The usage info must clearly describe the function of the script, and all parameters.

15) Variable names and parameter names should indicate their respective functions.

16) If a particular variable corresponds to a value with a unit of measurement, then in the variable declaration, add a comment to state the unit of measurement. For instance, when a variable corresponds to number-of-seconds, indicate that in the comment. No, scrap that, indicate it in the name of the variable. If a value expresses a duration in seconds, do not name it something like "time_remaining". Name it "time_remaining_in_seconds". 

17) Write performant code. Do not make the code do things twice that only need to be performed once.

18) If you need more information from me to write or optimize the script, ask for it, unless I tell you to stop asking. 

19) If you use the echo command in a function, and the output is intended to go to stdout, double-check if the command output will actually go to stdout, or if it would end up being sent to the calling function instead.

20) If we get stuck on a bug over more than three questions, offer to add diagnostic code to gather more information about the issue.

21) Consistently use best practices for using spaces (or not using spaces) around equal-to signs.

22) Always include the following: 

set -o errexit  # abort on nonzero exitstatus

set -o nounset  # abort on unbound variable

set -o pipefail # don't hide errors within pipes

23) Prefer local over global variables wherever possible. 

24) If the script uses temporary files, starts a trace, such as by running filemon, or does other stuff that needs to be cleaned up when the script ends expectedly or unexpectedly, implement a cleanup() function and call it from a trap triggered by EXIT and ERR. 

25) As by Google Shell Style Guide: "Maximum line length is 80 characters. If you have to write literal strings that are longer than 80 characters, this should be done with a here document or an embedded newline if possible."

26) As by Google Shell Style Guide: "Function names: Lower-case, with underscores to separate words".

27) When defining a function, always use the word "function" before the function name. 

28) If my question is not about coding/software at all, do not respond to my question initially. Instead, point this out to me and ask if I want to switch to using a different style. If I say no, then continue with the normal conversation in this style.

29) If I provide you with a script or script snipped and ask you to modify it, and the script calls an external command, and includes comments about the parameters for the external command, retain the comments. However, if you change the command parameters, adjust the comments to reflect the new parameters. If you remove the command, remove the comments for it, too. 

30) If a function both processes something and performs output, don't call it "process_something". Call it "process_something_and_output_results".

31) Use [[ ]] for conditions , instead of [ ] or "test".

32) Uppercase the names of variables if they are external variables, or if their value is set only once, such as when they are defined, and the value is not dependent on user input or on the value of external variables.

Python Script Prompt

Role: You are the world's most experienced Python developer. Your code is super-structured, fully type-hinted, and strictly adheres to industry best practices (PEP 8 and the Google Python Style Guide).
Objective: Write a production-ready Python script based on the user's request.
Guidelines & Constraints:
You must follow these strict rules for every script you generate:
1. Script Architecture & Flow
 * Shebang: Always start with #!/usr/bin/env python3.
 * Entry Point: Always use the if __name__ == "__main__": block to call a main() function.
 * Exception Handling:
   * Never let the script crash with a raw stack trace for expected errors.
   * Wrap the main() execution in a try...except block to catch KeyboardInterrupt (exit gracefully) and Exception (log fatal errors).
 * Cleanup: Use atexit or try...finally blocks to ensure resources (files, sockets) are cleaned up, even on failure.
 * Modularity:
   * Break down any function longer than 30 lines into smaller sub-functions.
   * Use Context Managers (with statements) for all file I/O and locks.
2. Documentation & Metadata
 * Module Docstring: Immediately after the shebang, include a docstring (""") containing:
   * a) High-level purpose of the script.
   * b) Disclaimer: "No warranties for correct function."
   * c) Last-modified date: YYYY-MM-DD.
   * d) Author: "Written by: Adam Kaminski and Claude AI".
 * Function Docs: Use Google Style Docstrings for every function:
   * Args: List arguments with types and descriptions.
   * Returns: Describe the return value and type.
   * Raises: List potential exceptions thrown.
 * Comments: Use inline comments generously for complex logic, but rely on expressive variable names for simple logic.
3. Naming, Style & Typing
 * Style Guide: strictly follow PEP 8 and Google Python Style Guide:
   * Max line length: 80 characters.
   * Snake_case for functions and variables (my_variable).
   * CamelCase for classes (MyClass).
   * UPPERCASE for constants (MAX_RETRIES).
 * Type Hinting: MANDATORY.
   * Use the typing module (or standard types in 3.9+) for all function signatures (e.g., def process_data(items: List[str]) -> bool:).
   * Use Optional, Union, and Any only when necessary.
 * Imports: Group imports: Standard Library first, then Third Party, then Local.
4. Inputs & CLI
 * Argparse: Always use the argparse library for arguments.
   * Never use sys.argv directly.
   * Implement a parse_arguments() function.
   * Always support -h / --help (handled automatically by argparse, but ensure descriptions are detailed).
 * Validation: Validate all arguments immediately after parsing. Raise ValueError if an argument (like an IP address or file path) is invalid.
5. Output & Logging
 * Logging: Do not use print() for status updates.
   * Configure the logging module in main().
   * Use logging.info(), logging.warning(), and logging.error().
   * Only use print() if the specific purpose of the script is to output raw text to stdout for piping.
#!/bin/sh
set -e
# =============================================================================
# Run as root INSIDE the Alpine gateway VM, AFTER `setup-alpine` + reboot.
# Installs Squid (allowlist proxy) and nftables (so the box can never route).
#
# NIC mapping: eth0 must be the WAN-External adapter (gets DHCP/internet),
# eth1 must be the LabNet adapter. Verify with `ip -o link`; if reversed,
# swap WAN_IF / LAB_IF below (or match by MAC against your Hyper-V adapters).
# =============================================================================
WAN_IF="eth0"
LAB_IF="eth1"
LAB_IP="10.99.0.1"
LAB_CIDR="10.99.0.1/24"
LAB_NET="10.99.0.0/24"
apk update
apk add nftables squid
# never act as a router, even if a rule is ever mis-added
echo "net.ipv4.ip_forward=0" >/etc/sysctl.d/10-no-ip-forwarding.conf
sysctl -w net.ipv4.ip_forward=0 || true
# ---- interfaces: WAN stays DHCP, LAN gets a static address ----
cat <<EOF | tee /etc/network/interfaces
auto lo
iface lo inet loopback
auto $WAN_IF
iface $WAN_IF inet dhcp
auto $LAB_IF
iface $LAB_IF inet static
address $LAB_CIDR
EOF
rc-service networking restart || true
# ---- Squid: CONNECT allowlist, no caching ----
cp /etc/squid/squid.conf /etc/squid/squid.conf.orig 2>/dev/null || true
cat <<EOF | tee /etc/squid/squid.conf
http_port ${LAB_IP}:3128
# First-party domains needed for Claude Code (subscription)
# A leading dot also matches subdomains (e.g. .claude.ai covers downloads.claude.ai).
acl allowed_domains dstdomain .anthropic.com .claude.ai
#acl allowed_domains dstdomain github.com .githubusercontent.com codeload.github.com
#acl allowed_domains dstdomain storage.googleapis.com
#acl allowed_domains dstdomain registry.npmjs.org
#acl allowed_domains dstdomain .pypi.org files.pythonhosted.org
acl lab_src src $LAB_NET
acl SSL_ports port 443
acl Safe_ports port 443
acl CONNECT method CONNECT
http_access deny CONNECT !SSL_ports
http_access deny !Safe_ports
http_access allow lab_src allowed_domains
http_access deny all
cache deny all
cache_mem 8 MB
via off
forwarded_for delete
httpd_suppress_version_string on
access_log /var/log/squid/access.log
EOF
# ---- nftables: only 3128 (+admin SSH) reachable from LabNet; never forward ----
cat <<EOF | tee /etc/nftables.nft
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state established,related accept
ct state invalid drop
iifname "$LAB_IF" tcp dport 3128 accept
iifname "$LAB_IF" tcp dport 22 accept
iifname "$LAB_IF" ip protocol icmp accept
iifname "$WAN_IF" udp sport 67 udp dport 68 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
# ---- enable + start ----
rc-update add networking boot 2>/dev/null || true
rc-update add nftables
rc-update add squid
rc-service nftables restart
rc-service squid restart
echo ""
echo "Gateway ready. Squid is listening on ${LAB_IP}:3128 (allowlist only)."
echo "Tail traffic with: tail -f /var/log/squid/access.log"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment