- Backfill CHANGELOG.md with v2.4.0 entry summarizing the
v2.1.112 → v2.1.119 sync work
- Refresh SECURITY.md footer (Last Updated April 27, 2026;
Next Review April 2027)
- Fix model ID in 09-advanced-features/config-examples.json:
claude-opus-4 → claude-opus-4-7 (3 occurrences) for
consistency with documented model IDs
- Remove RELEASE_NOTES.md stub that duplicated and contradicted
CHANGELOG.md
Closes#99
- Replace shell-interpolated JSON build with the argv-based Python pattern
from session-end.sh, so notes containing quotes or backslashes don't
produce invalid JSON.
- Add mkdir/cp/chmod install block before the Configuration section so
the path in settings.json resolves to a real file.
Lesson 10 stated CLI > User > Project, contradicting Lesson 04 (CLI >
Project > User) and the official Claude Code docs. Project-level agents
override user-level agents when their names collide.
- Fix priority order in 10-cli/README.md (lines 437-439)
- Add cross-link to Lesson 04 for the full priority table
- Update matching quiz question Q7 in lesson-quiz question-bank
Closes#98
* feat(hooks): add SessionEnd progress logger and local progress tracker
Adds a SessionEnd hook that prompts for modules studied at session end
and appends a record to ~/.claude-howto-progress.json — outside the repo
so progress survives git pull without being overwritten.
Also adds local-progress/index.html: a self-contained visual tracker
with checkboxes for all 10 modules, per-module notes, an overall progress
bar, and Export/Import to sync with a local JSON backup file.
Key patterns demonstrated:
- SessionEnd vs Stop (fires once on exit, not after every response)
- /dev/tty for interactive input in hooks (stdin carries the JSON payload)
- $CLAUDE_PROJECT_DIR for portable paths (never hardcode /Users/...)
- Guard clause to prevent global hook running in unrelated projects
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* fix(hooks): address PR review — bash 3.2 compat, JSON escaping, textarea XSS
- Replace pipeline+while with IFS for-loop (bash 3.2 compatible)
- Pass NOTES as Python arg to avoid broken JSON on quotes/backslashes
- Set textarea.value instead of innerHTML to prevent XSS from imported JSON
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Per official docs (https://code.claude.com/docs/en/model-config#adjust-effort-level),
the `max` effort level is supported on Opus 4.7, Opus 4.6, and Sonnet 4.6 — not
Opus 4.7 only. Only `xhigh` is Opus 4.7 exclusive.
Updates 5 occurrences in 09-advanced-features/README.md to reflect the actual
support matrix:
- Opus 4.7: low, medium, high, xhigh, max
- Opus 4.6 / Sonnet 4.6: low, medium, high, max
uk/ and vi/ locales need a separate translation sync (still reference Opus 4.6
era only and lack xhigh entirely).
Split the "Skill" participant into two distinct entities to better
illustrate the three-level loading architecture:
- Skill Instructions (Level 2): SKILL.md body
- Skill Resources (Level 3): Bundled files (templates, scripts, etc.)
Also fixed inaccurate "bash: read" notation - Claude uses the Read
tool, not bash commands.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* test(scripts): cover repo-root boundary in check_cross_references
Locks in the boundary behavior added in #91: links resolving outside
the repo root are silently skipped, in-repo broken links still error,
and valid in-repo links still pass.
* test(scripts): cover missing-README detection in numbered lesson dirs
`(file_path.parent / link_path).resolve()` could silently follow a
crafted `../../outside/path` link that escapes the repository root.
Paths that resolve outside the repo root are now skipped rather than
checked for existence.
Co-authored-by: Claude Code <noreply@anthropic.com>
All 6 packages were fully unpinned, allowing a compromised upstream
release to silently introduce malicious code on `pip install`. Pin to
current stable versions to ensure reproducible, auditable builds.
Co-authored-by: Claude Code <noreply@anthropic.com>
`diff` is not a valid Claude Code tool name — the agent would silently
lose its diff capability at runtime. Use `bash` to invoke diff instead.
Applies to all four locales: en (07-plugins), vi, zh, uk.
Co-authored-by: Claude Code <noreply@anthropic.com>
Sync all English tutorials with Claude Code v2.1.112 and the new Opus 4.7
model (claude-opus-4-7). Introduces the xhigh effort level (new default on
Opus 4.7), two new built-in slash commands (/ultrareview,
/less-permission-prompts), auto mode without --enable-auto-mode for Max
subscribers on Opus 4.7, PowerShell tool on Windows, Auto-match-terminal
theme, and plan files named after prompts. All 18 EN doc footers bumped to
Claude Code v2.1.112.
Version callouts in README.md, zh/README.md, and uk/README.md updated to
v2.1.112. Changelog entry prepended.
Repo version now tracks Claude Code version (2.3.0 → 2.1.112 is intentional
per new convention).
* docs: sync to Claude Code v2.1.110 with TUI, push notifications, session recap, and new commands
- 01-slash-commands: add /tui, /focus, /recap, /undo, /proactive to command table and recent changes
- 07-plugins: document monitors manifest key for background monitor support (v2.1.105)
- 09-advanced-features: add TUI mode, push notifications, session recap, ENABLE_PROMPT_CACHING_1H
- 10-cli: add --exclude-dynamic-system-prompt-sections flag and CLAUDE_CODE_PERFORCE_MODE env var
- CATALOG.md: update command counts (55+→60+, 63+→68+), add 5 new command rows
- All 12 files: bump footer to April 16, 2026 / Claude Code Version 2.1.110
* fix(catalog): correct version tags for /proactive, /recap, /undo commands
/proactive was added in v2.1.105, /recap and /undo in v2.1.108 — not v2.1.110.
Only /tui and /focus were introduced in v2.1.110.
The pre-tool-check.sh example had three bugs rooted in the same
misunderstanding of the Claude Code PreToolUse hook protocol
(stdin/stdout/stderr + exit code contract):
1. Substring matching on `rm -rf /`
The pattern was unanchored, so grep treated it as a substring and
falsely blocked any command containing `rm -rf /` — including benign
calls like `rm -rf /tmp/build` or `rm -rf /var/cache/foo`. Fixed by
anchoring the slash to a whitespace-or-end-of-line boundary.
2. WARN tier was dead code
The warning layer printed to stderr and then `exit 0`. Claude Code
silently discards stderr on exit 0, so the warnings were never seen
by Claude, the user, or any log. Fixed by adding an audit log file
at `$CLAUDE_PROJECT_DIR/.claude/hooks/audit.log` that records every
invocation with its decision (BLOCK/WARN/ALLOW). The audit log is
now the reliable observability mechanism for the WARN tier.
3. BLOCK reasons printed to stdout instead of stderr
On `exit 2`, Claude Code reads stderr to surface the block reason
to Claude. The echoes before `exit 2` defaulted to stdout, so
Claude Code reported `"No stderr output"` and Claude had to read
the hook source file to infer why a command was blocked. Fixed by
explicitly redirecting the block-reason echoes to stderr with `>&2`.
Also escaped the regex metacharacters in the fork-bomb pattern
`:(){:|:&};:` so it matches literally under `grep -E`, and updated the
header docstring to document the stdout/stderr/exit-code convention so
future readers don't make the same mistakes.
Verified with 6 smoke tests covering: benign command (ALLOW), warn-tier
relative path, substring edge case (`rm -rf /tmp/...` no longer falsely
blocked), exact root match (`rm -rf /`, `rm -rf / ; echo` still blocked),
fork-bomb literal, and `git push --force` (WARN only). stdout is empty
in all cases; all reasons correctly routed to stderr or the audit log.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: sync to Claude Code v2.1.101 with new feature coverage
Bumps all English docs from v2.1.97 to v2.1.101, adds mandatory Sources
footer block (previously missing), and documents three new features
shipped between v2.1.98 and v2.1.101:
- /team-onboarding (v2.1.101) — new built-in command for generating
teammate ramp-up guides. Added to 01-slash-commands and CATALOG.
- /ultraplan (v2.1.91+, cloud-env auto-creation in v2.1.101) — full
section in 09-advanced-features covering launch methods, status
indicators, and execution options. Replaces prior 3-line stub.
- Monitor tool (v2.1.98) — full section in 09-advanced-features with
stream-filter and poll-emit patterns and the grep --line-buffered
warning. Added to resources.md feature table.
Vietnamese and Chinese translations are not touched in this sync.
* fix(docs): address review feedback on v2.1.101 sync
- Correct /team-onboarding availability date (April 10 → April 11, 2026)
- Fix uninitialized \$last variable in Monitor poll-and-emit example
- Update CATALOG.md New Features heading to April 2026 and add Monitor
Tool, /team-onboarding, and Ultraplan auto-create entries
- Replace 3KB stub README with full 31KB translation matching original structure
- Fix apostrophe anchor mismatch in 04-subagents (U+02BC vs U+0027)
- Fix duplicate heading in 06-hooks (Prompt-хуки → Хуки на основі промптів)
Ref: luongnv89/claude-howto#63
Full Ukrainian translation of the comprehensive concepts guide (87KB, 3135 lines).
All code blocks, Mermaid diagrams, and JSON configs preserved as-is.
Ref: luongnv89/claude-howto#63
Modules 06-hooks, 07-plugins, 09-advanced-features, 10-cli had
truncated translations (18-58% content loss). Retranslated from
scratch using original English sources.
All files now match expected ~40% size increase for Cyrillic.
Ref: luongnv89/claude-howto#63
Complete Ukrainian translation of QUICK_REFERENCE.md - the quick
reference card for all Claude Code features.
- Installation quick commands for all features
- Feature cheat sheet with paths and usage
- Common use cases (code review, docs, DevOps, CI/CD)
- File locations reference diagram
- Learning path (Day 1 through Week 3+)
- New features (March 2026) section
- Tips, FAQ, and getting started checklist
Progress: 4/67 files (P1: 4/5 core documents)
Ref: luongnv89/claude-howto#63
Complete Ukrainian translation of INDEX.md - the comprehensive
index of all example files in the repository.
Translation follows uk/TRANSLATION_NOTES.md guidelines:
- Technical terms per glossary
- File paths and code blocks preserved in English
- Table structure and formatting maintained
- All 883 lines translated
- i18n-source-sha frontmatter added for version tracking
Progress: 2/67 files (P1: 2/5 core documents)
Ref: luongnv89/claude-howto#63
The latest Claude Code release is 2.1.97, not 2.3.0 (which is this
guide's own version). Update all 20 "Claude Code Version" footer lines
to accurately reflect the documented Claude Code version.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Update all documentation footers from generic "April 2026 / 2.1+" to
the specific sync date (April 9, 2026) and documented version (2.3.0).
Also add version/date footers to zh/CATALOG.md and
zh/01-slash-commands/README.md which were missing them.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
P0 Critical:
- Remove /vim (removed in v2.1.92) from CATALOG.md, zh/CATALOG.md active tables
- Move /vim to deprecated section in zh/01-slash-commands/README.md
- Fix fake hook events (PreCommit/PrePush/PostPush) in config-examples.json
- Replace with real PreToolUse hook pattern
- Update deprecated model IDs: claude-sonnet-4-5 → claude-sonnet-4-6 (x4)
- Fix notify-team.sh comment: PostPush → PostToolUse with explanation
- Mark # memory shortcut as discontinued in 02-memory/README.md
P2 Conflicts resolved:
- effort:max confirmed valid in current CLI; no changes needed
- Remove WebSocket MCP transport (not supported; only stdio/sse/http valid)
from 05-mcp/README.md, CATALOG.md, QUICK_REFERENCE.md
P4 Cosmetic:
- Update hook count 25 → 26 in QUICK_REFERENCE.md
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* docs: sync all tutorials with latest Claude Code official docs (April 2026)
Update 44 documentation files to reflect the latest Claude Code features
from code.claude.com. Key content changes include new slash commands
(/ultraplan, /powerup, /sandbox), deprecated command removals (/pr-comments,
/vim), corrected skill description budget (1%/8K), new hook events
(PermissionDenied, InstructionsLoaded, ConfigChange), expanded Agent Teams
section, new plugin components (LSP, bin/, settings.json), and new CLI
flags (--bare, --tmux, --effort, --channels). Added "Last Updated: April
2026" metadata footer to all documentation files.
* fix(docs): correct env var values and alphabetical ordering
- CLAUDE_CODE_NEW_INIT=true → =1 in 02-memory and 09-advanced-features
- CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=true → =1 in 09-advanced-features
- Fix /powerup vs /plugin alphabetical order in slash commands table
* fix(docs): correct env var values in locale files (vi, zh)
Propagate CLAUDE_CODE_NEW_INIT=true → =1 and
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=true → =1 corrections
to Vietnamese and Chinese translations.
Extend the release workflow to build separate EPUB artifacts for en, vi,
and zh in parallel via a matrix job, then publish all built files under
a single GitHub Release. Using fail-fast: false so a failure in one
language does not block releasing the others.
Also refactor build_epub.py to drive language-specific paths, filenames,
and titles from a mapping, and add zh support (title/subtitle + choice).
* fix(hooks): make hook scripts compatible with Windows Git Bash and use stdin JSON protocol
- Replace `grep -P` (Perl regex) with `sed` for JSON field extraction,
as Windows Git Bash does not support `grep -P`
- Replace positional arg (`$1`) with stdin JSON parsing to match the
actual Claude Code hook protocol (hooks receive data via stdin, not args)
- Fix JSON double-quote escaping in grep patterns that silently fails
on Windows Git Bash
- Remove python3 dependency for JSON parsing, making scripts portable
- Add Windows Git Bash to compatibility notes in script headers
Affected scripts: security-scan.sh, validate-prompt.sh, log-bash.sh, format-code.sh
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(hooks): address review issues in Windows Git Bash compatibility scripts
- security-scan.sh: wrap output in hookSpecificOutput format required by
PostToolUse protocol; restore secret/token detection pattern that was
dropped; escape file path and issues for safe JSON construction
- validate-prompt.sh: extract "user_prompt" field first (Claude Code
UserPromptSubmit protocol), falling back to "prompt"
- log-bash.sh: document sed truncation limitation for commands with
double-quoted strings
- format-code.sh: fix misleading comment about updatedInput output
* fix(hooks): produce valid JSON from security-scan.sh
- Use \\n (JSON newline escape) when building ISSUES, not real newlines,
so the value passes safely through printf into the JSON string
- Remove the real-newline-to-\\n sed pass (no longer needed)
- Output is now verifiably valid JSON per python3 json.loads
* fix(hooks): fix grep -E POSIX compat and semgrep/trufflehog stdout mixing
- Replace \s with [[:space:]] in grep -E patterns (security-scan.sh lines
34,44): \s is a Perl extension, silently fails on macOS BSD grep and
BusyBox — password/secret detection was a no-op on macOS
- Suppress stdout of semgrep/trufflehog (>/dev/null) to prevent their
output mixing with hookSpecificOutput JSON, which would produce invalid
JSON and cause the additionalContext to fail parsing
- Fix format-code.sh hook comment: PreToolUse → PostToolUse (matches
README example and actual hook behavior)
---------
Co-authored-by: Bruce <binyuli1993@foxmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add performance-optimizer subagent and dependency-check hook
Agent-Logs-Url: https://github.com/khanhnkq/claude-howto/sessions/ef3fb01c-a9c0-466e-9ad2-f255f306add2
Co-authored-by: khanhnkq <180888435+khanhnkq@users.noreply.github.com>
* fix(hooks): use basename for manifest matching in dependency-check.sh
FILE=$1 receives an absolute path (e.g. /home/user/project/package.json).
The case statement and all [[ "$FILE" == ... ]] guards matched bare filenames,
so every invocation would hit the *) exit 0 branch and skip all vuln scans.
Extract BASENAME=$(basename "$FILE") and use it for all pattern matching.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Luong NGUYEN <luongnv89@gmail.com>