Skip to main content

Lesson 20: 2.1.x Advanced Features

Learning Objectives

After completing this lesson, you will be able to:

  • Use wildcard permission patterns
  • Configure enhanced hooks for skills, agents, and commands
  • Fork and rewind sessions
  • Use external editor (Ctrl+G)
  • Use enhanced vim motions
  • Set up task dependencies
  • Configure WezTerm support (2.1.33)

Prerequisites

  • Completed Lessons 1-19 - Core operations and advanced features
  • Permissions knowledge - Lesson 4 recommended
  • Hooks experience - Lesson 8 recommended
  • Vim familiarity - For vim motions section

Estimated Time: 40 minutes


Wildcard Permission Patterns

What Are Wildcard Permissions?

Wildcards allow you to create flexible permission rules that match multiple commands.

Wildcard Syntax

Basic wildcard:

{
"permissions": {
"allowedOperations": [
"Bash(*)", // Match all Bash commands
"Bash(npm *)", // Match all npm commands
"Bash(git *)", // Match all git commands
"Bash(* test)", // Match commands ending with "test"
"Bash(git * main)", // Match git commands with "main" argument
"Read(*.md)", // Match all .md files
"Edit(src/*)" // Match all files in src/
]
}
}

Wildcard Patterns

Pattern types:

  1. Match all:

    • Bash(*) - All bash commands
    • Read(*) - All files
    • Edit(*) - All files
  2. Prefix match:

    • Bash(npm *) - All npm commands
    • Bash(git *) - All git commands
    • Bash(python *) - All Python commands
  3. Suffix match:

    • Bash(* test) - Commands ending with "test"
    • Bash(* install) - Commands ending with "install"
    • Read(*.md) - Files ending with .md
  4. Middle match:

    • Bash(git * main) - Git commands with "main"
    • Bash(npm run *) - All npm run scripts
    • Edit(src/**/*.ts) - TypeScript files in src/
  5. Multiple wildcards:

    • Bash(* * *) - Commands with 3+ parts
    • Bash(git * origin *) - Git commands with origin

Wildcard Examples

Example 1: Development workflow

{
"permissions": {
"allowedOperations": [
// Git operations
"Bash(git *)",
"Bash(gh *)", // GitHub CLI

// Package management
"Bash(npm *)",
"Bash(npx *)",
"Bash(yarn *)",
"Bash(pnpm *)",

// Testing
"Bash(* test)",
"Bash(npm test)",
"Bash(pytest *)",
"Bash(jest *)",

// Building
"Bash(npm run build *)",
"Bash(* build)",

// File operations
"Read(src/*)",
"Edit(src/*)",
"Write(src/*)"
]
}
}

Example 2: Project-specific permissions

{
"permissions": {
"allowedOperations": [
// Allow all operations in tests directory
"Read(tests/*)",
"Edit(tests/*)",
"Write(tests/*)",
"Bash(* tests/*)",

// Read-only in src
"Read(src/*)",

// Specific write operations
"Edit(src/components/*.tsx)",
"Edit(src/api/*.ts)",

// Documentation - full access
"Read(*.md)",
"Edit(*.md)",
"Write(*.md)"
]
}
}

Example 3: Safe operations (don't-ask mode)

{
"permissions": {
"allowedOperations": [
// Read operations - always safe
"Read(*)",
"Bash(cat *)",
"Bash(ls *)",
"Bash(git log *)",
"Bash(git status)",
"Bash(git diff *)",

// Test commands - safe
"Bash(npm test)",
"Bash(npm run test *)",
"Bash(* test)",

// Linting - safe
"Bash(npm run lint)",
"Bash(prettier --check *)",
"Bash(eslint *)"
]
}
}

Wildcard Best Practices

  1. Start specific, then generalize:

    {
    "allowedOperations": [
    "Bash(npm test)", // Specific first
    "Bash(npm run test *)", // Then pattern
    "Bash(* test)" // Most general last
    ]
    }
  2. Use negative patterns with deniedOperations:

    {
    "permissions": {
    "allowedOperations": ["Bash(git *)"],
    "deniedOperations": [
    "Bash(git push *)", // Ban push
    "Bash(git force *)", // Ban force
    "Bash(git clean -fd)" // Ban clean
    ]
    }
    }
  3. Combine with patterns:

    {
    "permissions": {
    "allowedPatterns": [
    {
    "pattern": "^Read\\(.*\\.md\\)$",
    "operation": "Read"
    },
    {
    "pattern": "^Bash\\(npm (test|lint)\\)$",
    "operation": "Bash"
    }
    ]
    }
    }

Enhanced Hooks System

Hooks for Skills, Agents, and Commands

In 2.1.x, hooks can be defined in:

  • Skill frontmatter
  • Agent definitions
  • Slash command frontmatter
  • Settings files

Hook Types

Available hook events:

  1. Session hooks:

    • session-start - When starting a session
    • session-end - When ending a session
  2. Tool hooks:

    • pre-tool - Before any tool use
    • post-tool - After tool completion
  3. Permission hooks:

    • permission-request - When permission is needed
  4. Agent hooks:

    • subagent-start - When sub-agent starts
    • subagent-stop - When sub-agent stops
  5. Command/Skill hooks:

    • Hooks scoped to specific commands/skills

Skill Hooks

Pre/post tool hooks in skills:

---
name: deploy
hooks:
pre-tool:
command: ./scripts/pre-deploy.sh
once: false
post-tool:
command: ./scripts/post-deploy.sh
timeout: 300000
---

# Deploy

Deployment with automatic pre/post hooks.

Permission hooks in skills:

---
name: auto-approve
hooks:
permission-request:
command: ./scripts/approve-dev-commands.sh
---

# Auto-Approve Dev Commands

Automatically approve safe development commands.

Agent Hooks

Hooks in agent definitions:

// .claude/agents/backend.json
{
"name": "backend",
"agentType": "general-purpose",
"systemPrompt": "You are a backend developer.",
"hooks": {
"subagent-start": {
"command": "./scripts/backend-start.sh"
},
"subagent-stop": {
"command": "./scripts/backend-stop.sh"
}
}
}

Slash Command Hooks

Hooks in command frontmatter:

---
name: /deploy
hooks:
pre-tool:
command: ./scripts/check-env.sh
post-tool:
command: ./scripts/notify-deployment.sh
---

# Deploy Command

Deploy the application with environment checks.

Advanced Hook Features

Hook with additional context (2.1.x):

{
"hooks": {
"pre-tool": {
"command": "./scripts/log-tool.sh",
"additionalContext": {
"environment": "production",
"team": "backend"
}
}
}
}

Hook with once: true (run once per session):

---
hooks:
session-start:
command: ./scripts/init-dev-env.sh
once: true
---

Timeout configuration (2.1.x - increased to 10 minutes):

{
"hooks": {
"pre-tool": {
"command": "./scripts/long-running-check.sh",
"timeout": 600000 // 10 minutes (in milliseconds)
}
}
}

Hook Examples

Example 1: Pre-commit hooks

{
"hooks": {
"pre-commit": [
{
"command": "npm",
"args": ["run", "lint"]
},
{
"command": "npm",
"args": ["run", "test"]
},
{
"command": "./scripts/check-coverage.sh"
}
]
}
}

Example 2: Notification hooks

{
"hooks": {
"post-tool": {
"command": "./scripts/notify-slack.sh",
"enabledForTools": ["Bash", "Edit"],
"onlyOnFailure": true
}
}
}

Example 3: Session hooks

{
"hooks": {
"session-start": {
"command": "./scripts/session-start.sh",
"additionalContext": {
"logFile": "/tmp/claude-session.log"
}
},
"session-end": {
"command": "./scripts/session-summary.sh"
}
}
}

Session Forking and Rewind

What is Session Forking?

Forking creates a copy of your session that you can experiment with without affecting the original.

Forking a Session

Method 1: Command line

# Fork current session
claude --fork-session

# Fork and resume specific session
claude --resume session-id --fork-session --session-id new-session-id

Method 2: During session

You> /fork

Claude: I'll create a fork of this session.

[Creating fork...]

Fork created: session-abc123
Original session: session-xyz789

You're now in the forked session. Changes here won't affect the original.

Method 3: From resume screen

claude --resume

[Resume screen shows]
Session List:
session-xyz789 - Original session
[P] Preview [R] Rename

session-abc123 - Forked from session-xyz789
[P] Preview [R] Rename

Rewinding a Session

What is rewind? Undo changes by reverting to a previous point in the conversation.

Method 1: /rewind command

You> /rewind

Claude: How far do you want to rewind?

1. Last message
2. 5 messages ago
3. 10 messages ago
4. Before the last edit
5. Custom point

Choose [1-5]: 4

[Rewinding to before last edit...]

Edits undone:
- src/app.ts (reverted)
- src/utils.ts (reverted)

Session rewound successfully.

Method 2: From VS Code

[In VS Code extension]
Click "Rewind" button → Choose point → Confirm rewinding

Forking Workflows

Workflow 1: Experiment safely

1. Working on feature
2. Want to try something risky
3. Fork session
4. Experiment in fork
5. If works: Apply to original
6. If fails: Fork is discarded, original safe

Workflow 2: Parallel exploration

1. Fork session A → Session B
2. Fork session A → Session C
3. Try approach A in original
4. Try approach B in session B
5. Try approach C in session C
6. Compare results
7. Use best approach

Workflow 3: Debug vs. fix

1. Fork session
2. Original: Continue development
3. Fork: Investigate bug
4. Fork finds root cause
5. Apply fix to original

External Editor (Ctrl+G)

What is External Editor?

Press Ctrl+G to edit your current prompt in your configured text editor (vim, nano, VS Code, etc.).

Setting Up External Editor

Method 1: Environment variable

# Set default editor
export EDITOR=vim
export VISUAL=vim

# Or use other editors
export EDITOR=nano
export EDITOR="code --wait"
export EDITOR=subl

Method 2: Git config

git config --global core.editor vim
git config --global core.editor "code --wait"

Using Ctrl+G

Basic usage:

You> I need to refactor the authentication system to use OAuth2 instead
of basic auth, and I'm not sure if I should...

[Press Ctrl+G]

[Vim opens with your prompt]

# Edit in vim
I need to refactor the authentication system to use OAuth2.
The current implementation uses basic auth with sessions.

Requirements:
- Use OAuth2 with Google provider
- Store tokens securely
- Handle token refresh
- Maintain backward compatibility

[Save and quit vim]

Prompt updated with your edits!

Advanced usage - multi-line prompts:

You> [Press Ctrl+G]

[Vim opens]

Create a REST API for user management with the following endpoints:

- POST /api/users - Create user
- GET /api/users/:id - Get user by ID
- GET /api/users - List users (with pagination)
- PUT /api/users/:id - Update user
- DELETE /api/users/:id - Delete user

Requirements:
- Use Express.js
- Validate input with Joi
- Store in PostgreSQL
- Add unit tests
- Include error handling
- Add authentication middleware

[Save and quit]

Claude: I'll create a REST API for user management with those endpoints.
[Creates comprehensive API implementation]

External Editor in Skills

External editor in "Other" field (2.1.x):

Claude asks: "Which authentication method?"
Options: [1] OAuth, [2] JWT, [3] Other

You: Choose [3] Other

[Press Ctrl+G in Other input field]

[Editor opens]

Custom requirement:
Use Auth0 with social logins (Google, GitHub, Twitter)
and support enterprise SAML.

[Save and quit]

Your custom requirement is submitted!

Enhanced Vim Motions

New Vim Motions (2.1.x)

Claude Code's text input now supports enhanced vim motions for efficient editing.

New Motions

Repeat f/F/t/T:

;    # Repeat last f/F/t/T motion forward
, # Repeat last f/F/t/T motion backward

Yank and paste:

y    # Yank operator (copy)
yy # Yank entire line
Y # Same as yy
p # Paste after cursor
P # Paste before cursor

Text objects:

# Inner text objects (without surrounding characters)
ci" # Change inside quotes
ci' # Change inside single quotes
ci( # Change inside parentheses
ci) # Same as ci(
ci[ # Change inside brackets
ci] # Same as ci[
ci{ # Change inside braces
ci} # Same as ci{
ciw # Change inside word
ciW # Change inside WORD

# Around text objects (with surrounding characters)
ca" # Change around quotes (includes quotes)
ca' # Change around single quotes
ca( # Change around parentheses (includes parens)
ca) # Same as ca(
ca[ # Change around brackets
ca] # Same as ca[
ca{ # Change around braces
ca} # Same as ca{
caw # Change around word
caW # Change around WORD

# Also works with delete (d), yank (y), visual (v)
di" # Delete inside quotes
da" # Delete around quotes (includes quotes)
yi( # Yank inside parentheses
ya( # Yank around parentheses

Indentation:

>>   # Indent line or selection
<< # Dedent line or selection

Join lines:

J    # Join next line to current

Complete Vim Motion Reference

Basic movement:

h    # Left
j # Down
k # Up
l # Right
w # Word forward
b # Word backward
e # End of word
0 # Start of line
$ # End of line
gg # Start of file
G # End of file

Operators:

d    # Delete
c # Change
y # Yank (copy)
p # Paste
v # Visual

Motions:

f<character>   # Find character forward
F<character> # Find character backward
t<character> # Till character forward
T<character> # Till character backward
; # Repeat last f/F/t/T forward
, # Repeat last f/F/t/T backward

Examples:

df)  # Delete until closing paren
cf" # Change inside quotes
y$ # Yank to end of line
dgg # Delete to start of file
ci{ # Change inside braces
daw # Delete around word

Task Dependencies

What Are Task Dependencies?

Tasks can depend on other tasks, creating dependency graphs for complex workflows.

Setting Up Dependencies

Creating dependent tasks:

You> I need to implement user authentication

Claude: I'll create tasks for this work.

[Task 1] Create user model
[ ] Define User schema
[ ] Add database migration
[ ] Create User model class

[Task 2] Create authentication service
- Blocked by: Task 1
[ ] Implement login
[ ] Implement register
[ ] Implement password hashing

[Task 3] Create API endpoints
- Blocked by: Task 2
[ ] POST /api/auth/login
[ ] POST /api/auth/register
[ ] GET /api/auth/me

Tasks will execute in dependency order.

Managing dependencies:

You> Show task dependencies

Claude: Task dependency graph:

Task 1: Create user model
└─ No dependencies

Task 2: Create authentication service
└─ Depends on: Task 1

Task 3: Create API endpoints
└─ Depends on: Task 2

Flow: Task 1 → Task 2 → Task 3

Updating dependencies:

You: Add Task 4 for testing, depends on Task 3

Claude: Added task:

[Task 4] Write tests
- Blocked by: Task 3
[ ] Test login endpoint
[ ] Test register endpoint
[ ] Test authentication middleware

Updated graph:
Task 1 → Task 2 → Task 3 → Task 4

Dependency Workflows

Workflow 1: Sequential dependencies

Database → Models → API → Tests → Docs

Workflow 2: Parallel after setup

Setup → Frontend → Tests
└→ Backend ─┘

Workflow 3: Multiple dependencies

     Database Models

┌──────┴──────┐
│ │
Auth API User API
│ │
└──────┬──────┘

Integration Tests

WezTerm Support (2.1.33)

WezTerm for Agent Teams

Setting teammateMode to WezTerm:

{
"teammateMode": "wezterm"
}

WezTerm configuration:

-- ~/.wezterm.lua
local wezterm = require('wezterm')
local config = {}

config.keys = {
-- Split horizontally
{
key = '|',
mods = 'CTRL|SHIFT',
action = wezterm.action.SplitHorizontal {
domain = 'CurrentPaneDomain',
},
},
-- Split vertically
{
key = '-',
mods = 'CTRL|SHIFT',
action = wezterm.action.SplitVertical {
domain = 'CurrentPaneDomain',
},
},
-- Navigate panes
{
key = 'LeftArrow',
mods = 'CTRL',
action = wezterm.action.ActivatePaneDirection('Left'),
},
{
key = 'RightArrow',
mods = 'CTRL',
action = wezterm.action.ActivatePaneDirection('Right'),
},
}

return config

✅ Check Your Understanding

  1. What does Bash(npm *) match?

    • Only npm
    • All npm commands
    • Commands ending with "npm"
    • Nothing
  2. How do you edit your prompt in an external editor?

    • Ctrl+E
    • Ctrl+G
    • Ctrl+V
    • Ctrl+X
  3. True or False: Skills can have their own hooks.

    • True
    • False
  4. What does ci" do in vim mode?

    • Change inside quotes
    • Delete inside quotes
    • Yank inside quotes
    • Copy quotes
  5. What command forks a session?

    • /clone
    • /fork
    • /copy
    • /new

Answers: 1-b, 2-b, 3-True, 4-a, 5-b


Summary

In this lesson, you learned:

  • Wildcard permissions - Flexible permission patterns
  • Enhanced hooks - For skills, agents, and commands
  • Session forking - Safe experimentation
  • External editor - Ctrl+G for prompt editing
  • Enhanced vim motions - Powerful text editing
  • Task dependencies - Complex workflow management
  • WezTerm support - Agent teams in WezTerm

Congratulations!

You've completed all 20 lessons of the Claude Code tutorial! You're now equipped with:

  • Core operations and permissions
  • Advanced features and workflows
  • Multi-agent automation
  • Agent teams collaboration
  • Cutting-edge 2.1.33 features

Next Steps

  1. Practice - Use features in real projects
  2. Explore - Check out the ecosystem and marketplace
  3. Contribute - Share your skills and MCP servers
  4. Stay updated - Watch for new Claude Code releases

Further Reading


Happy coding with Claude Code! 🚀