If you've been using Claude Code and wondering why some configuration options feel limited, you're not imagining things. A deep dive into the source code of @anthropic-ai/claude-code@2.1.87—sitting right there in your node_modules as a publicly distributed npm package—reveals dozens of capabilities that simply aren't documented anywhere. From an internally-named "YOLO Classifier" permission system to hooks that can rewrite commands mid-flight, the gaps between what Anthropic ships and what they document are substantial.

The Hook System Goes Way Deeper Than Docs Suggest

The official documentation tells you hooks receive JSON on stdin and that exit code 2 blocks operations. What it doesn't mention is that hooks can return JSON on stdout with event-specific fields that modify Claude Code's behavior in real time. PreToolUse hooks accept updatedInput to rewrite tool inputs before execution, permissionDecision to force allow or deny without prompting, and additionalContext to inject text into the conversation mid-stream. SessionStart hooks are particularly powerful—they can return watchPaths to set up automatic file watching that triggers FileChanged events, initialUserMessage to prepend content to the first user message, and additionalContext for session-wide persistent context. Here's a practical example: a PreToolUse hook that automatically adds --dry-run to any git push command before it executes. Your settings.json configures the matcher and script path, while the shell script at ~/.claude/hooks/dry-run-pushes.sh intercepts the JSON input, checks if it's a git push operation, and returns updatedInput with the dry-run flag appended. Three undocumented hook fields fundamentally change how you can use them. The once: true setting fires the hook exactly once per session then auto-removes it—perfect for first-time setup tasks like creating .env files from templates. The async: true field runs hooks in the background without blocking Claude, ideal for audit logging that adds zero latency to your workflow. And asyncRewake: true is the clever one—it runs non-blocking like async, but if the script exits with code 2, it wakes the model back up and blocks the operation. This enables secret scanners that silently pass when everything's clean but halt execution if they detect hardcoded passwords or API keys.

Skills Have Hidden Depth You Haven't Touched

The documented skill frontmatter covers name, description, allowed-tools, argument-hint, when_to_use, and context. The actual parser reveals six more fields that open up entirely new possibilities. The model field lets you override which Claude model runs the skill—use haiku for cheap fast tasks like quick linting, opus for deep architecture reviews where reasoning quality matters most. Effort controls how hard the model thinks: low, medium, high, or max, mapping directly to the internal effort system that governs reasoning depth per response. Perhaps most interesting is the hooks field scoped to individual skills—they register when a skill fires and deregister automatically when it completes. You can build a strict-typescript skill that runs type-checking synchronously on every Write or Edit operation while linting happens in the background via async, all without affecting your global hook configuration. The agent field delegates the entire skill execution to a custom agent you've defined separately, enabling composition of complex workflows from reusable pieces. disable-model-invocation prevents auto-invocation entirely—only explicit /skill-name calls work—which is essential for destructive or expensive operations you don't want firing accidentally. And shell: bash lets you specify which shell interpreter runs the skill's commands, giving you control over environment differences across systems.

Agents Can Actually Learn and Remember

Custom agents defined in .claude/agents/ support frontmatter fields that turn static assistants into persistent learners. The memory field accepts three values—user for global cross-project persistence, project for per-repository memories shared with teammates, and local for private per-project notes that gitignore automatically excludes from version control. This means you can build a codebase-guide agent that accumulates knowledge about your architecture decisions, common code locations, and coding conventions over multiple sessions. After a few conversations, it starts answering questions from memory before even grepping the actual codebase—genuine learning without any model retraining involved. The omitClaudeMd: true field skips loading the CLAUDE.md instruction hierarchy entirely, which is perfect for a "fresh-eyes" reviewer that applies industry standards rather than your project's potentially idiosyncratic conventions. Combined with effort: high and color: blue to distinguish it visually in multi-agent scenarios, you get an independent auditor that approaches your code without project-specific blind spots. There's also criticalSystemReminder_EXPERIMENTAL—a field whose name literally includes "EXPERIMENTAL" as a warning from Anthropic's own engineers. This injects a short message at every conversation turn even after compaction, useful for persistent safety reminders like "always run migrations with --dry-run first." Don't build critical infrastructure on it, but it's handy for deployment guardrails.

The YOLO Classifier and Self-Improvement System

The autoMode configuration field controls what gets auto-approved in auto mode, and internally Anthropic calls this system the "YOLO Classifier"—yes, that's the actual variable name in yoloClassifier.ts. You configure it with three arrays: allow patterns get instant approval, soft_deny patterns always require confirmation, and environment accepts plain English context strings that the classifier reads to understand your setup. You can write things like "This is a local dev machine with no production database access" or "The test suite uses a dedicated isolated test database." The classifier factors this into safety decisions for ambiguous commands—specific briefings produce better outcomes than generic defaults. Think of it as giving Claude Code a briefing about your environment before you start working. Two additional settings activate Claude Code's self-improvement capabilities: autoMemoryEnabled makes sessions automatically extract durable memories via a background agent that writes to ~/.claude/projects//memory/ after each conversation, and autoDreamEnabled activates nightly consolidation when you've accumulated 5+ sessions. The dream process merges duplicates, resolves contradictions, converts relative dates to absolute, and prunes stale entries. Together they create a compound learning loop—sessions produce memories, dreams consolidate them, consolidated memories inform future sessions. Turn both on and after a few weeks you'll notice Claude Code remembering your preferences and project patterns without being explicitly told.

Key Takeaways

  • Hooks can return JSON on stdout with fields like updatedInput, permissionDecision, watchPaths, and additionalContext—not just exit codes
  • Skill frontmatter supports model override (haiku/opus), effort control (low to max), scoped hooks, and agent delegation
  • Agent memory: project enables persistent learning across sessions for individual codebases
  • The autoMode environment array accepts plain English context that shapes the YOLO Classifier's safety decisions
  • Enable self-improvement with autoMemoryEnabled and autoDreamEnabled for compound learning over time

The Bottom Line

The gap between what Claude Code can do and what its documentation describes is genuinely surprising. These features aren't hidden because they're experimental—they're production-ready capabilities that simply never made it into the official docs. If you're serious about customizing Claude Code for your workflow, cracking open node_modules/@anthropic-ai/claude-code might be the best documentation investment you make.