v2.1.110 dropped late April 15 with the feature fullscreen users have been requesting: live TUI switching. Run /tui fullscreen mid-conversation to switch to flicker-free rendering without restarting your session. /tui normal switches back. The tui setting persists your preference across sessions.
Push notification tool. Claude can now send mobile push notifications proactively — when it finishes a long task, hits an error, or needs your attention. Requires Remote Control connected and "Push when Claude decides" enabled in /config. This is the first time Claude Code can push TO you instead of you polling for status.
Remote Control gets real commands. /autocompact, /context, /exit, and /reload-plugins now work from mobile/web Remote Control clients. Combined with push notifications, your phone is becoming a genuine command surface for headless sessions.
Other UX changes:
/focusis now a separate command —Ctrl+Oonly toggles normal/verbose transcript (no more three-state cycling)autoScrollEnabledconfig lets you freeze auto-scroll in fullscreen- Write tool now tells the model when you edit its proposed content in the IDE diff before accepting
/pluginInstalled tab surfaces items needing attention and supportsfto favorite
Security fixes worth noting:
PermissionRequesthooks returningupdatedInputnow re-check againstpermissions.deny— previously, a hook could return modified input that bypassed deny rulessetMode:'bypassPermissions'now respectsdisableBypassPermissionsMode- "Open in editor" hardened against command injection from untrusted filenames
Stability fixes: MCP tool calls no longer hang indefinitely when SSE/HTTP server connection drops. Plugin install now honors dependencies declared in plugin.json. stdio MCP servers no longer disconnect on first stray non-JSON output line (regression from v2.1.105).
Update: npm install -g @anthropic-ai/claude-code@latest
Every installed skill's name and description enters your system prompt on every turn. That metadata tax is invisible until you measure it. A wallfacer.ai practitioner with 87 Google Workspace skills found they were burning 2,861 tokens per turn just on skill listings — before typing anything.
The fix: move skill files out of auto-discovery and replace them with a single keyword-rich stub.
Step 1 — Relocate skills outside discovery:
mv .claude/skills/gws-gmail/ .claude/skills-lazy/gws-gmail/
mv .claude/skills/gws-drive/ .claude/skills-lazy/gws-drive/
# repeat for each skill in the group
Claude Code discovers skills from .claude/skills/ — anything under .claude/skills-lazy/ is invisible to auto-discovery but still readable by the model.
Step 2 — Create a stub skill:
Write .claude/skills/gws/SKILL.md with a description covering all child skills:
name: google-workspace
description: "Google Workspace toolkit (87 skills): Gmail send/search/draft,
Drive upload/share, Calendar create/reschedule, Sheets read/write/formula,
Docs create/edit, Slides, Forms. Email, files, scheduling, collaboration."
---
When a user requests a Workspace operation, read the matching skill from
`.claude/skills-lazy/gws-{name}/SKILL.md` and follow its instructions.
Result: 2,861 → 1,363 tokens. 53% reduction per turn.
The tradeoff is two-hop resolution — when a lazy skill IS needed, the model reads the stub, then reads the child skill. That costs a few hundred extra tokens on that specific turn. But the math works: if you run 20 turns and use a lazy skill on 3 of them, you save ~1,500 tokens/turn × 17 turns vs. spending ~300 extra tokens × 3 turns. Net savings: ~24,600 tokens per session.
The pattern scales to any skill group: deployment tools, testing utilities, project-specific commands, MCP server helpers.
Amplifying researchers ran Claude Code and Codex through identical prompts across 12 sessions (6 each), building authentication, file uploads, search, admin controls, webhooks, and production config. The results expose patterns every operator shipping AI-generated code should know.
Password hashing divergence. Claude Code chose bcrypt in all 6 sessions. Codex used stdlib solutions — PBKDF2-SHA256 or scrypt. Both are defensible, but the split reveals a philosophical gap: Claude favors established packages, Codex prefers runtime-provided tools.
JWT consistency gap. Claude used established libraries (PyJWT, python-jose, jsonwebtoken) every time. Codex sometimes hand-rolled JWT signing with raw HMAC — including a == string comparison in one Python session. That's a textbook timing attack vector.
The stat that matters most: 0 out of 12 sessions added rate limiting to login endpoints. Neither agent volunteered security headers in any session. Both tools optimize for functionality, not defense-in-depth.
Static analysis is blind here. Bandit and Semgrep reported zero issues across all 12 sessions. The real problems — missing rate limiting, hand-rolled crypto, absent security headers — only surfaced through dynamic testing with Nuclei and manual requests against running applications.
Overall compliance scores:
- Claude Code: 84.7% tier-1
- Codex: 83.3% tier-1
- Framework matters more than agent: FastAPI scored 92-96% for both, Next.js scored 73-75% for both
The supply chain tradeoff is worth naming explicitly. Claude's library-first approach increases your dependency surface. Codex's stdlib preference reduces dependencies but puts you on the hook for auditing hand-rolled crypto. Neither is strictly better — but you need to know which trade you're making.
Operator takeaway: Always run dynamic tests against AI-generated auth code. Static analysis is necessary but insufficient. Add rate limiting and security headers yourself — no AI coding tool will volunteer them.
AI coding tools accelerate feature delivery but also accelerate architectural decay. You ship 10 features in a week and nobody notices that three new cross-domain dependencies crept in. Code reviews catch line-level issues; they rarely catch structural drift.
Unkode (Apache 2.0, Python) is a Claude Code skill that makes architecture visible as structured data you can diff.
How it works:
Run /unkode to generate unkode.yaml — your architecture as structured data: modules, components, dependencies, deployment topology. First-time generation costs ~4,000 tokens for a large codebase.
On subsequent runs, /unkode performs incremental sync — diffing changes against the existing YAML. Cost: 500-1,000 tokens per branch update. A Python script converts YAML to Mermaid diagrams in arch_map.md deterministically — zero AI tokens, zero hallucination risk.
Optional GitHub Action comments architecture diffs on PRs, showing what changed structurally in each pull request. Color-coded: green for new modules, red for removed dependencies, yellow for coupling changes.
Why the approach matters more than the specific tool: Architecture documentation in diffable YAML that updates incrementally is architecture documentation that actually stays current. The Mermaid rendering is deterministic. The PR integration makes drift visible at review time — not six months later during a post-mortem.
Status: Just launched (deepcodersinc/unkode). Early-stage but the pattern is sound and immediately reproducible.
Measure your skill metadata overhead, then cut it by 30-50% with a lazy-loading stub.
Prerequisites: Claude Code v2.1.91+, at least 5 installed skills or plugins that register skills.
What you'll do: Audit skill metadata token cost, move grouped skills behind a single stub, and verify the before/after savings.
Steps:
- Count your skills and establish a baseline:
Start a Claude Code session, type a short message, then run /cost. Note the input tokens on the first turn — this includes all skill metadata.
- Identify a group of 3+ related skills you don't invoke every session. If you don't have a natural group, pick any 3+ skills from the same domain (testing, deployment, data, etc.).
- Move them out of auto-discovery and create a stub:
# Move the group
for skill in test-unit test-integration test-e2e test-coverage; do
mv ".claude/skills/${skill}" ".claude/skills-lazy/${skill}" 2>/dev/null
done
# Create the stub
mkdir -p .claude/skills/testing
cat > .claude/skills/testing/SKILL.md << 'STUB'
---
name: testing-toolkit
description: "Testing toolkit: unit tests, integration tests, e2e tests,
coverage reports, test scaffolding, fixture generation, mock setup."
---
When a testing operation is requested, read the full skill from
`.claude/skills-lazy/{skill-name}/SKILL.md` and follow its instructions.
Available: test-unit, test-integration, test-e2e, test-coverage
STUB
- Start a fresh Claude Code session. Run
/costafter your first message. Compare input tokens to your step-1 baseline.
- Test activation: ask Claude to run your unit tests (or whatever matches a lazy-loaded skill). Watch it read the stub, then read the full skill from the lazy directory.
Expected outcome: 20-50% reduction in per-turn metadata tokens, depending on how many skills you moved. Individual skill functionality preserved via two-hop resolution.
Verify: /cost shows lower input tokens on first turn. Trigger a lazy-loaded skill — Claude should read the stub, follow the pointer to .claude/skills-lazy/, and execute normally. If it fails to find the skill, check that your stub description contains keywords matching the user request.