Chapter 8: Command Line Power
Quick Start (5 minutes)
Let’s run tests and make a git commit – two things you’ll do dozens of times a day – all through Claude Code’s Bash tool.
Step 1: Run your tests
You: Run the tests
Claude: [Using Tool: Bash]
Command: npm test
PASS src/utils/validator.test.js
validateEmail
accepts valid email addresses (3 ms)
rejects invalid email addresses (1 ms)
PASS src/auth/authController.test.js
Authentication
registers new users successfully (45 ms)
prevents duplicate registration (23 ms)
Test Suites: 2 passed, 2 total
Tests: 5 passed, 5 total
Time: 2.341 s
All tests passed!
Step 2: Check what changed
You: Show me git status and diff
Claude: [Using Tools: Bash (parallel)]
Command 1: git status
Command 2: git diff
On branch feature/user-auth
Changes not staged:
modified: src/utils/validator.js
modified: tests/validator.test.js
[Shows diff of changes]
Step 3: Create a commit
You: Commit these changes
Claude: [Analyzes the diff]
I see you've added password strength validation and new test cases.
[Using Tool: Bash]
Commands:
git add src/utils/validator.js tests/validator.test.js
git commit -m "Add password strength validation with tests
- Implement configurable password strength rules
- Add 8 new test cases covering edge cases
- Improve error messages for invalid passwords
Co-Authored-By: Claude <noreply@anthropic.com>"
Commit created successfully.
You just ran tests, reviewed changes, and created a well-crafted commit – all through conversation. No terminal switching, no remembering git syntax.
Core Concepts (20 minutes reading)
8.1 The Bash Tool
Claude Code’s Bash tool executes shell commands in a persistent session. Environment variables and directory changes persist between commands.
Key capabilities:
- Persistent session: State carries between commands
- Parallel execution: Run independent commands simultaneously
- Background processes: Start long-running tasks without blocking
- Output capture: Results returned to Claude for analysis
- Error handling: Claude interprets errors and suggests fixes
Simple command:
You: Run npm install
Claude: [Using Tool: Bash]
Command: npm install
added 243 packages in 8.2s
Multiple independent commands (parallel):
You: Show me git status and current Node version
Claude: [Using Tools: Bash (parallel)]
Command 1: git status
Command 2: node --version
Git: On branch main, working tree clean
Node: v20.11.0
Sequential commands (chained with &&):
You: Install dependencies then run tests
Claude: [Using Tool: Bash]
Command: npm install && npm test
8.2 Development Workflows
Package Management
You: Install express, mongoose, and dotenv as dependencies,
and jest as a dev dependency
Claude: [Using Tool: Bash]
Command: npm install express mongoose dotenv && npm install -D jest
added 87 packages in 5.1s
You: Check for security vulnerabilities
Claude: [Using Tool: Bash]
Command: npm audit
found 3 vulnerabilities (2 moderate, 1 high)
Let me fix them:
Command: npm audit fix
fixed 3 vulnerabilities
Build Workflows
You: Build the project for production
Claude: [Using Tool: Bash]
Command: npm run build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
45.2 kB build/static/js/main.a8f3d1c4.js
1.8 kB build/static/css/main.f9c2e1b3.css
Testing Workflows
Running specific tests:
You: Run only the authentication tests
Claude: [Using Tool: Bash]
Command: npm test -- authController
PASS src/auth/authController.test.js
Tests: 3 passed, 3 total
Linting and formatting:
You: Check for linting errors and fix what you can
Claude: [Using Tool: Bash]
Command: npm run lint -- --fix
Fixed 5 issues automatically
Remaining: 1 error requires manual review
src/utils/validator.js:12 (undefined variable)
8.3 Git Operations with AI
Git workflows become significantly easier with AI assistance. Claude Code analyzes your changes, writes descriptive commit messages, and follows your repository’s conventions.
Essential Git Operations
Creating branches:
You: Create a new branch called "feature/password-reset"
Claude: [Using Tool: Bash]
Command: git checkout -b feature/password-reset
Switched to a new branch 'feature/password-reset'
Intelligent commits:
Claude analyzes your actual changes and writes meaningful commit messages:
You: Commit these changes
Claude: [Checks git status and diff]
I see you've:
- Added rate limiting to the login endpoint
- Created a new rate limiter middleware
- Added tests for rate limiting
[Using Tool: Bash]
Commands:
git add src/middleware/rateLimiter.js src/auth/authController.js tests/rateLimit.test.js
git commit -m "Add rate limiting to login endpoint
- Create configurable rate limiter middleware (100 req/15min default)
- Apply rate limiting to login and signup routes
- Add 6 tests covering rate limit enforcement and reset
Co-Authored-By: Claude <noreply@anthropic.com>"
Following project conventions:
You: Commit using our conventional commits format
Claude: [Checks git log to learn your format]
git commit -m "feat(auth): add rate limiting to login endpoint
BREAKING CHANGE: Login attempts now limited to 100 per 15 minutes
Co-Authored-By: Claude <noreply@anthropic.com>"
Pull Request Creation
You: Create a pull request for this feature
Claude: [Using Tool: Bash]
Commands:
git push -u origin feature/password-reset
gh pr create --title "Add rate limiting to auth endpoints" \
--body "## Summary
- Configurable rate limiter middleware
- Applied to login and signup routes
- 100 requests per 15-minute window (configurable)
## Test plan
- [x] Unit tests for rate limiter
- [x] Integration tests for login endpoint
- [ ] Load testing with k6
Generated with [Claude Code](https://claude.com/claude-code)"
Pull request created: https://github.com/user/repo/pull/42
Handling Merge Conflicts
You: I have a merge conflict, can you help?
Claude: [Checks git status, reads conflicted file]
The conflict is in authController.js:
- Your branch: Added rate limiting
- Incoming: Added better error messages
These changes don't actually conflict. Let me keep both:
[Resolves conflict using Edit tool]
[Stages and commits the merge resolution]
Conflict resolved.
Other Useful Git Operations
Stashing:
You: I need to switch branches but have uncommitted changes
Claude: git stash save "WIP: user profile updates"
git checkout main
// Later: git stash pop
Squashing commits:
You: Squash my last 5 commits into one clean commit
Claude: [Using soft reset since interactive rebase needs an editor]
git reset --soft HEAD~5
git commit -m "Add feature X with bug fixes"
Reverting safely:
You: Undo a commit that's already pushed
Claude: git revert a3f4c2b
[Creates a new commit that undoes changes -- safe to push]
8.4 Background Processes
Some commands take a long time. Claude Code can run them in the background while you continue working.
Starting a dev server:
You: Start the development server in the background
Claude: [Using Tool: Bash (background)]
Command: npm run dev
Next.js 14.0 - Local: http://localhost:3000
Ready in 2.1s
(Running in background - you can continue working)
Monitoring:
You: Check the output from the dev server
Claude: [Using Tool: BashOutput]
Recent output:
GET /api/users 200 in 45ms
GET /api/posts 200 in 23ms
Stopping:
You: Stop the development server
Claude: [Using Tool: KillShell]
Development server stopped.
8.5 Advanced Patterns
Conditional execution:
You: Run tests, and only if they pass, build for production
Claude: npm test && npm run build
(If tests fail, build won't run)
Environment variables:
You: Set NODE_ENV to production and run the build
Claude: NODE_ENV=production npm run build
Working with multiple projects:
You: Build both the frontend and backend
Claude: [Using Tools: Bash (parallel)]
Command 1: cd frontend && npm run build
Command 2: cd backend && npm run build
Frontend: Built successfully
Backend: Compiled TypeScript
Pre-commit checks:
You: Before I commit, make sure everything is good
Claude: [Running in parallel]
npm run lint -- No issues
npm test -- All 23 tests passing
npm run build -- Compiled successfully
Everything looks good! Ready to commit.
Try This Now
Exercise 1: The Full Workflow
In a project you’re working on:
- Make a small change to any file
- Ask Claude Code to run your tests
- Ask Claude Code to create a commit with a descriptive message
- Check
git log --oneline -3to see the result
Exercise 2: Parallel Commands
Ask Claude Code to run these simultaneously:
node --versionnpm --versiongit --version
Notice how Claude runs them in parallel and returns all results at once.
Deep Dive (optional, for mastery)
When Things Go Wrong
Command runs too long and fills context
Problem: You run npm test on a large
project and it outputs thousands of lines, consuming your context
window.
Fix: Use quiet flags and filters:
npm test --silent (minimal output)
npm test -- --testPathPattern=auth (run subset)
npm test 2>&1 | grep -E "(PASS|FAIL)" (filter results)
npm run build > build.log 2>&1 (redirect to file)
Prevention: For large projects, always scope test
runs and use --silent or --quiet flags.
Redirect verbose output to files.
Destructive command executed
Problem: You accidentally ran
git reset --hard or rm -rf on the wrong
directory.
Fix (git):
git reflog (find the commit hash before the reset)
git reset --hard <hash> (restore to that point)
Fix (deleted files):
- If the files were tracked by git:
git checkout -- . - If untracked: check your OS trash, or use Time Machine / backup
- If neither: the files may be gone
Prevention: Claude Code will warn you before
destructive operations. Pay attention to those warnings. Use
git stash instead of discarding, and prefer
git revert over git reset --hard for pushed
commits.
Permission denied on Bash
Problem:
npm ERR! code EACCES
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
Fix:
# Don't use sudo with npm! Instead:
# Option 1: Fix permissions
sudo chown -R $USER /usr/local/lib/node_modules
sudo chown -R $USER ~/.npm
# Option 2: Use nvm (recommended)
nvm install node
nvm use node
# npm install now works without sudo
# Option 3: Change npm's default directory
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
# Add to ~/.zshrc: export PATH=~/.npm-global/bin:$PATH
Background process hangs
Problem: You started a dev server but the port is still occupied after stopping it.
Fix:
# Find what's using the port
lsof -i :3000
# Kill it
lsof -ti:3000 | xargs kill -9
# Or use a different port
PORT=3001 npm run dev
Prevention: Always stop servers cleanly with Ctrl+C. If you close the terminal without stopping, the process keeps running.
npm install fails with ERESOLVE
Problem:
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! peer react@"^17.0.0" from some-package@1.0.0
Fix:
# Quick fix: use legacy peer deps
npm install --legacy-peer-deps
# Clean fix: clear everything and retry
rm -rf node_modules package-lock.json
npm cache clean --force
npm install
Git push rejected (non-fast-forward)
Problem: Remote has commits you don’t have.
Fix:
# Option 1: Pull and merge
git pull origin main
git push origin main
# Option 2: Pull with rebase (cleaner history)
git pull --rebase origin main
git push origin main
# Option 3: Force push with lease (only if you're sure)
git push --force-with-lease origin main
Prevention: Pull before pushing. Communicate with your team before force pushing.
Git authentication failures
Problem:
remote: Support for password authentication was removed
fatal: Authentication failed
Fix: GitHub removed password authentication. Use SSH keys or personal access tokens:
# Set up SSH (recommended):
ssh-keygen -t ed25519 -C "your_email@example.com"
# Add public key to GitHub Settings > SSH keys
git remote set-url origin git@github.com:user/repo.git
# Or use personal access token:
# Generate at GitHub Settings > Developer settings > Personal access tokens
git remote set-url origin https://TOKEN@github.com/user/repo.git
Managing Context with Command Output
Claude Code’s context window (200,000 tokens) can fill up from verbose command output. Here are strategies:
Use quiet/silent flags:
npm install --quiet
npm test --silent
npm run build 2>&1 | tail -5 (just the last 5 lines)
Redirect large output to files:
npm run build > build.log 2>&1
npm test -- --coverage > coverage.txt
Run targeted commands:
# Instead of running all 500 tests:
npm test -- --testPathPattern=auth (just auth tests)
# Instead of full npm audit:
npm audit --audit-level=high (only high severity)
Signs you’re running out of context:
- Responses become shorter or less detailed
- Claude “forgets” earlier parts of the conversation
- Commands seem to time out
What to do: Save your work, start a new conversation, and briefly describe what you’ve been working on.
Chapter Checkpoint
What you learned:
- The Bash tool runs shell commands in a persistent session with parallel execution
- Claude Code analyzes diffs and writes meaningful, convention-following commit messages
- Background processes let you run dev servers and watch modes without blocking
- Chaining commands with
&&ensures sequential operations only proceed on success - Verbose output consumes context; use quiet flags and targeted commands
You can now:
- Run tests, builds, and linting through conversational commands
- Create well-crafted git commits, branches, and pull requests with AI assistance
- Manage background processes (start dev servers, monitor output, stop cleanly)
- Handle merge conflicts with AI-assisted resolution
- Diagnose and fix common command-line failures (permissions, ports, dependencies)
PROMPT TO PRODUCTION