This document catalogs all existing features in File City to ensure nothing breaks during refactoring.
File City is a macOS application that visualizes file system directories as 3D cities using Metal-accelerated graphics. Each file/folder becomes a building, with visual properties determined by file metadata.
- Recursive scanning with configurable max depth (default: 2)
- Node count limiting (max 300 nodes by default)
- File metadata extraction: name, size, type, modification date
- Git repository detection (checks for
.gitfolder) - Symlink support (distinct visual representation)
- Hidden file filtering (respects macOS hidden attribute)
- Create folder - Modal dialog prompts for name
- Create file - Modal dialog prompts for name
- Rename - Works on selected file/folder
- Move - NSOpenPanel to select destination
- Trash - Confirmation dialog, uses macOS trash
- Open - Opens files with default app
- Reveal in Finder - Shows file in Finder window
- Root directory navigation - Browse to any folder
- Parent directory - Go up one level
- Double-click to enter - Directories become new root
- URL opening - Supports dragging directories onto app icon
- Launch arguments -
--root /pathto open specific directory - Environment variable -
FILE_CITY_ROOTsets default directory - Default fallback - Opens
~/projectsif no root specified
- Single selection - Click in 3D view or list
- Multi-selection - Cmd+click to add/remove
- Selection sync - 3D view and list view stay in sync
- URL-based selection - Selection persists across rescans
- Grid layout - Buildings arranged in square grid
- Road spacing - Gaps between buildings for "roads"
- Size-based sorting - Larger folders placed first
- Depth-based sorting - Shallower paths prioritized
- Type-based sorting - Folders before files before symlinks
| ShapeID | Name | Description |
|---|---|---|
| 0 | Standard | Simple cube/box |
| 1 | Taper | Narrows at top (spire) |
| 2 | Pyramid | Comes to a point |
| 3 | SlantX | Wedge slanted on X axis |
| 4 | SlantZ | Wedge slanted on Z axis |
| 5 | Cylinder | Round building |
| 6 | Plane | Aircraft shape (wings) |
- Multi-tier buildings for large folders
- Tier count based on height (2-4 tiers)
- Base → Mid → Upper → Crown sections
- Footprint shrinking as tiers go up
- Crown shapes vary (taper, pyramid, slant)
- Height - Log scale based on folder size
- Footprint - Larger for folders than files
- Material ID - Hash-based for variety
- Texture Index - Semantic mapping (0-31 indexes)
- Rotation - Wedges rotate based on camera yaw
| Index | Semantic Meaning |
|---|---|
| 0 | File City |
| 1 | AppShell |
| 2 | Core |
| 3-13 | Various project types |
| 14 | Swift files |
| 15 | Code files (JSON, JS, etc.) |
| 16 | Text/documents |
| 17 | Images |
| 18 | Audio |
| 19 | Video |
| 20 | Archives |
| 21 | Databases |
| 22-31 | Random styles |
| 32 | Road texture |
| 33 | Car texture |
| 34 | Plane texture |
| 35 | Font atlas |
- Auto-detect git repos - Folders with
.gitsubdirectory - Beacon towers - Visual indicators on git repo buildings
- Clean/dirty status - Green beacon = clean, red = dirty
- Hover over beacon - Shows branch and status
- Status formatting - Untracked, Modified, Staged, etc.
- Async status check - Background refresh of git status
- Commit history loading - Up to 200 commits
- Timeline slider - Scrub through history (0=oldest, 1=live)
- Historical tree loading -
git ls-treefor past states - Tree caching - Cached historical states for smooth scrubbing
- Live preview - Updates city while dragging slider
- "Now" button - Return to live mode
- Real-time file change detection
- Debounced rescanning (250ms delay)
- Write detection (limited without root)
- SMJobBless installation - Standard macOS privilege escalation
- fs_usage monitoring - Full read/write tracking
- Unix socket communication -
/tmp/filecity-activity.sock - Process filtering - Tracks LLM tools (claude, codex, gemini, cursor, etc.)
- Event throttling - 150ms dedup window
- Helicopters on write - Fly to target building
- Beams on read - Vertical light effect
- Info panel - Shows process name and file path
- Glow effect - Buildings glow during activity
- Duration - 1.4 second activity pulse
- Left sidebar - Favorites from Finder
- Middle panel - File list view (NSTableView)
- Right panel - 3D Metal view
- Sortable columns - Name, Date, Size, Kind
- Multi-selection - Shift/Cmd+click
- Drag and drop - Reorder, move to folders
- Context menu - Open, Rename, Trash, Copy, Reveal
- Keyboard shortcuts:
- Enter - Rename
- Cmd+Delete - Trash
- Cmd+C - Copy
- Cmd+V - Paste
- Reads macOS Finder favorites
- SF Symbol icons
- Click to navigate
- Hover info - Name, kind, size, date, path
- Git status - Branch, changes
- Activity info - Process, operation, file
- Cmd+F to focus search field
- Fuzzy matching - Searches file names
- Debounced (150ms)
- Results filter list view
- Fixed pitch/yaw - Classic isometric view
- Scroll to zoom - Distance-based
- Two-finger pan - Move camera target
- Pinch to zoom - Magnification gesture
- Auto-fit - Centers on city when loading
- Toggle with F key
- WASD movement - Standard FPS controls
- Mouse look - Rotate camera (when captured)
- Click to capture mouse
- ESC to release/exit
- Gravity mode - Falls, can jump (Space)
- Flying mode - Double-tap Space to toggle
- Sprint - Double-tap W
- Collision detection - Can't walk through buildings
- Rooftop landing - Land on building tops
- Hold Shift - Grapple to target
- Targets: Buildings, planes, helicopters, cars, beacons
- Pull toward target - Fast movement
- Attach and ride - Stay connected to moving objects
- Auto-generated paths - Drive on roads
- Multiple colors (12 palette)
- Multi-part model - Body, glass, wheels, lights
- Tesla Model 3 shape - Custom vertex deformation
- Flight paths - Generated from road grid
- Hover to speed up - Looking at plane increases speed
- Click to explode - Debris physics
- Respawn - New path after explosion
- Banner - Trailing banner with directory name
- Spawn on file writes - Fly to target building
- Activity indicator - Visual feedback for LLM writes
- Spawn on file reads - Vertical light
- Activity indicator - Visual feedback for LLM reads
- Grapple to plane - Get close
- Press E to board - Enter cockpit
- Press E to exit - Return to first-person
- W/S - Pitch (nose down/up)
- A/D - Roll (bank left/right)
- Space - Boost
- Mouse - Camera look offset
- Thrust/lift/drag/gravity - Realistic model
- Banking turns - Roll affects yaw
- Stall prevention - Minimum speed maintained
- Auto-leveling - Roll/pitch return to level
- Minimum altitude - Can't crash into ground
- Instanced rendering - Efficient GPU rendering
- Depth testing - Proper occlusion
- Alpha blending - Transparency support
- Texture arrays - 36 texture slots
- Custom samplers - Linear filtering, repeat mode
- Selection highlight - Yellow tint
- Hover highlight - Brightness boost
- Activity glow - Orange (write) / Blue (read)
- Git beacon shapes - Different for clean/dirty
- Waving banner - Animated text
- Building textures - Generated from seed strings
- Font atlas - Generated for text rendering
- Deterministic - Same path = same appearance
- Ray-box intersection - Hit detection
- Shape-aware - Different bounds for pyramid, wedge, etc.
- Distance sorting - Returns closest hit
- Inflated bounds - Easier to click
- Separate pass - After block picking
- Click to interact - Explode planes
- Hover detection - Speed up planes
struct FileNode {
id: UUID
url: URL
name: String
type: NodeType (.file, .folder, .symlink)
sizeBytes: Int64
modifiedAt: Date
children: [FileNode]
isHidden: Bool
isGitRepo: Bool
isGitClean: Bool
}struct CityBlock {
id: UUID
nodeID: UUID
name: String
position: SIMD3<Float>
footprint: SIMD2<Int32>
height: Int32
materialID: Int32
textureIndex: Int32
shapeID: Int32
isPinned: Bool
isGitRepo: Bool
isGitClean: Bool
}struct GitCommit {
id: String (full hash)
shortHash: String (7 chars)
timestamp: Date
subject: String
}testIntersectStandardBlock- Basic hit detectiontestMissStandardBlock- Miss above blocktestIntersectRaisedBlock- Hit elevated blocktestIntersectPyramidTip- Hit pyramid shapetestMissPyramidEmptySpace- Miss around pyramidtestIntersectTaperedBlock- Hit tapered shapetestIntersectCylinderBlock- Hit cylinder shape
- Git beacon ray-picking logic tests
- Basic sanity tests
make build- Build debugmake install- Install to /Applicationsmake run- Build and launchmake test- Run unit testsmake clean- Clean build artifacts
File City/
├── File City.xcodeproj
├── File City/
│ ├── AppShell/ # UI layer
│ ├── Core/ # Business logic
│ │ ├── Models/
│ │ ├── Scanner/
│ │ ├── Mapper/
│ │ ├── Renderer/
│ │ ├── Watcher/
│ │ ├── Physics/
│ │ ├── Search/
│ │ ├── Actions/
│ │ └── Services/
│ └── Resources/
│ ├── Shaders/
│ └── Textures/
├── File CityTests/
├── File CityUITests/
└── Helper/ # Privileged daemon
Use this checklist to verify features after refactoring:
- Open directory via menu/dialog
- Navigate to parent
- Double-click to enter folder
- Drag directory onto app icon
- Launch with --root argument
- Create folder
- Create file
- Rename
- Move
- Trash
- Open file
- Reveal in Finder
- Single click to select
- Cmd+click for multi-select
- Selection syncs between views
- Buildings render correctly
- All shape types display properly
- Hover highlights work
- Selection highlights work
- Zoom works
- Pan works
- F toggles mode
- WASD movement
- Mouse look
- Collision detection
- Jump/fly toggle
- Sprint
- Grapple
- Repos detected
- Beacon towers appear
- Clean/dirty status
- Time travel slider
- Historical tree loading
- Helicopters spawn on write
- Beams spawn on read
- Info panel shows activity
- Cars drive on roads
- Planes fly
- Click to explode plane
- Board/exit plane
- Flight controls work
- Cmd+F focuses search
- Typing filters list
- Results update in real-time
- Columns sort correctly
- Context menu works
- Keyboard shortcuts work
- Drag and drop works