Essential guide for AI agents working on iTerm2.
Read CLAUDE.md first - it contains mandatory coding practices. Key rules:
- Never write >1 line of JavaScript/HTML/CSS inline - use external files with
iTermBrowserTemplateLoader.swift - Use
it_fatalErrorandit_assert(not standardfatalError/assert) for proper crash logs - Never create dependency cycles - use delegates/closures instead
git addnew files immediately after creation
iTerm2 uses hybrid Objective-C/Swift: core system in Objective-C, modern features in Swift.
Application Flow: App → Window/Tab → Session → Terminal Emulation → Rendering
- Application:
iTermController- Main coordinator - Window/Tab:
PseudoTerminal,PTYTab- Window and tab management - Session:
PTYSession- Session lifecycle, I/O, state - Terminal Emulation:
VT100Parser,VT100Terminal,VT100ScreenMutableState,VT100Screen,VT100Grid - Rendering:
PTYTextView- Metal-accelerated rendering
iTerm2/
├── sources/ # Main application code
├── tests/iTerm2XCTests/ # Unit tests
├── proto/api.proto # Protocol Buffer API
├── tools/ # Build scripts
├── submodules/ # Git submodules
├── WebExtensionsFramework/ # Swift SPM framework (see WebExtensionsFramework/CLAUDE.md)
├── iTerm2.sdef # AppleScript API
├── CLAUDE.md # Code best practices
└── iTerm2.xcodeproj/ # Xcode project
- Escape sequences flow:
VT100Parser/VT100Terminal→VT100ScreenMutableState/VT100Screen→VT100Grid - Look at
VT100ScreenTest.mfor examples - Test changes thoroughly
- WebSocket API: Edit
proto/api.proto, runtools/build_proto.sh - AppleScript: Edit
iTerm2.sdef, implement in*+Scripting.{h,m}files
// ❌ Bad: Strong reference cycle
class Parent { var child: Child? }
class Child { var parent: Parent? }
// ✅ Good: Use weak reference
class Child { weak var parent: Parent? }// ✅ Good
NSString *html = [iTermBrowserTemplateLoader loadTemplateNamed:@"chat"];
// ❌ Bad: Inline HTML
NSString *html = @"<html><body>...</body></html>";// ✅ Good
it_fatalError("Unexpected state")
it_assert(value != nil, "Value required")
// ❌ Bad: Won't create crash logs
fatalError("Unexpected state")
assert(value != nil)Language choice:
- Use Objective-C when modifying existing Objective-C code
- Use Swift for new features
- Use
@objcattributes for Swift/Objective-C interop - The Swift bridging header is
sources/iTerm2SharedARC-Bridging-Header.h- check here for available Objective-C types and constants in Swift
Where code lives:
- Session logic →
PTYSession.{h,m} - Terminal emulation →
VT100Parser,VT100Terminal,VT100ScreenMutableState - UI rendering →
PTYTextView.{h,m} - Tests →
tests/iTerm2XCTests/