Majorelle theme configurations for VS Code, iTerm2, and Oh My Zsh.
This repo is also meant to give other people and their agents a compact glimpse into the author's personal setup.
vscode/contains a local VS Code theme extension with 3 themes (Majorelle,Majorelle Medium,Majorelle Light), plussettings.json,keybindings.json, andapply-view-layout.shas the source of truth for user-level config.iterm/contains 3.itermcolorspresets with the same names.oh-my-zsh/majorelle.zsh-themecontains the shell prompt theme.hooks/contains Claude Code hook scripts used by the extension's attention view.
The VS Code theme in this repo is a local extension, not a published marketplace extension.
Do not assume code --install-extension ./vscode will work. On this machine, the reliable install path was copying the folder to:
~/.vscode/extensions/soli.majorelle-0.1.0Then set the active theme in:
"workbench.colorTheme": "Majorelle Light"Any of the 3 theme names above are valid values.
vscode/settings.json is the source of truth for user settings that belong to this setup. On a new machine, merge the entries into ~/Library/Application Support/Code/User/settings.json — do not overwrite, preserve anything already there that isn't managed by this repo.
Currently tracked entries:
workbench.colorTheme: "Majorelle Light"workbench.editorAssociations— open.mdfiles in preview by defaultpython.terminal.activateEnvironment: falseterminal.integrated.tabs.title: "${sequence}"files.excludeadditions (e.g.**/__pycache__)- Minimal UI chrome (next section)
These settings hide non-essential workbench chrome:
"workbench.statusBar.visible": false,
"window.commandCenter": false,
"workbench.layoutControl.enabled": false,
"workbench.activityBar.location": "hidden",
"explorer.openEditors.visible": 0Additional view toggles that VS Code does not expose via settings.json (Outline, Timeline, Source Control Repositories) are applied by vscode/apply-view-layout.sh — see below.
The extension contributes a view inside the Explorer sidebar that lists Claude Code sessions whose agent has finished responding and is waiting on the user. The view is scoped per workspace: only sessions whose cwd is inside one of the current window's workspace folders are shown, so other projects' sessions never bleed in.
How it works:
- Four hooks in
hooks/write to a shared state file at~/.claude/attention.json:attention-stop.shruns onStopand records the entry withkind: "stop". It walks its process tree up to the firstzsh/bash/fishancestor to capture the PID of the shell that VS Code's terminal owns.attention-notify.shruns onNotification(permission prompts, idle alerts) and records the entry withkind: "notification", using the notification message as the label snippet.attention-clear-notification.shruns onPostToolUseand flipsnotification-kind entries back tokind: "running"once the approved tool finishes (subject to a 2-second minimum age). The notify hook stashes the prior running label in arunning_textfield so this flip can restore it — the row stays visible with the play icon untilStopfires.stop/runningentries are left alone.attention-running.shruns onUserPromptSubmitand records the entry withkind: "running", using the user's prompt as the label snippet. It overwrites any previousstop/notificationstate; a laterStoporNotificationhook will overwrite it back when the agent pauses or finishes.
- The extension picks a different codicon per
kind:bell-dotforstop,warningfornotification,playforrunning. - The extension watches
~/.claude/attention.json, filters by workspace folder, and renders one tree item per session. - Clicking an item calls
Terminal.processIdfor each open terminal and focuses the one matchingshell_pid. If the terminal is gone, a notification explains so.
The hooks are wired in this repo's own .claude/settings.json using $CLAUDE_PROJECT_DIR so the paths stay portable when the repo is cloned elsewhere. That scoping means the attention view only lights up for Claude sessions started inside this project — which is usually what you want. To cover every project, copy the same two hook entries into ~/.claude/settings.json instead (or additionally) with absolute paths.
Requires jq on PATH (already required by apply-view-layout.sh).
vscode/keybindings.json is the source of truth for keybindings that belong to this setup. Merge into ~/Library/Application Support/Code/User/keybindings.json the same way as settings.
- ⌘ T — open a new terminal in the editor area (replaces the default "Go to Symbol in Workspace")
- ⌘ G — open a terminal,
cdinto the codex project, and launch codex. Gated behindconfig.codex.projectKeybindingso it is inert unless explicitly enabled. The path inside is machine-specific; update it when cloning elsewhere. - ⌘ I —
majorelle.openInBrowser(provided by this extension)
Hidden view layout (non-settings-portable)
VS Code stores the visibility of some views (Outline, Timeline, Source Control Repositories, Open Editors) as JSON blobs inside ~/Library/Application Support/Code/User/globalStorage/state.vscdb (SQLite), not in settings.json. A full profile export would sync them but also drags in ~600 KB of unrelated state.
The minimal alternative is vscode/apply-view-layout.sh, which patches only the two relevant rows. Usage:
- Quit VS Code (it locks
state.vscdbwhile running). - Run
bash vscode/apply-view-layout.sh. - Relaunch VS Code.
Requires sqlite3 and jq on PATH.
Open Editors is redundantly covered by both explorer.openEditors.visible: 0 (in settings) and the script — this is intentional so either alone is sufficient.
Install the theme by copying:
oh-my-zsh/majorelle.zsh-themeto:
~/.oh-my-zsh/themes/majorelle.zsh-themeThen set:
ZSH_THEME="majorelle"in ~/.zshrc.
The prompt was intentionally simplified during setup:
- single-line prompt
- current folder only, using
%1~ - git branch info on the same line
- no extra prompt symbol such as
$ - command entry stays on the same line
If the theme changes, preserve this behavior unless explicitly asked otherwise.
The .itermcolors files can be opened with iTerm to import them into the Color Presets... menu.
Separate iTerm profiles can also be created for:
MajorelleMajorelle MediumMajorelle Light
These should be cloned from the current default profile so font, shell, and other profile settings remain intact while only the color preset changes.
Do not use custom shell escape sequences or explicit profile Tab Color overrides for the top chrome.
The correct fix for making the iTerm tab bar match the terminal background was setting iTerm's global appearance theme to Minimal:
defaults write com.googlecode.iterm2 TabStyleWithAutomaticOption -int 5Or manually:
iTerm2 > Settings > Appearance > General > Theme > Minimal
This worked better than custom tab-color hacks and should be the default recommendation for future setup.
0= Light1= Dark2= Light (High Contrast)3= Dark (High Contrast)4= Automatic5= Minimal6= Compact
AGENTS.mdshould be a symlink toCLAUDE.md.- Repo files (
vscode/settings.json,vscode/keybindings.json, the theme JSONs,oh-my-zsh/majorelle.zsh-theme, the.itermcolorspresets,vscode/apply-view-layout.sh) are the source of truth. When applying to a machine, sync outward from the repo. - When merging
settings.jsonorkeybindings.jsoninto the user's VS Code config, merge — do not overwrite. Preserve entries already present that aren't tracked in this repo.