🎃 A fast, out-of-the-box terminal built for AI coding.

RAW Doc

Cli

CLI Reference

Run kaku in your terminal to see all available commands.

kaku ai

Open the AI settings panel inside Kaku. Configure external coding tools (Claude Code, Codex, Gemini CLI, Copilot CLI, Kimi Code, etc.) and Kaku Assistant.

bash
kaku ai

kaku chat

Start Kaku's standalone AI chat from any shell. This is a discoverable alias for
the bundled k helper, so it works even when k is not on your PATH.

bash
kaku chat                 # open interactive chat
kaku chat "explain this" # one-shot prompt

The chat uses ~/.config/kaku/assistant.toml, shares the same conversation and
memory files as the Cmd + L overlay, and supports /new, /resume, /clear,
/status, /memory, and /exit in interactive mode.

kaku config

Open the Kaku configuration TUI for common settings and Lua overrides. It
ensures ~/.config/kaku/kaku.lua exists and is also accessible from the
settings panel with Cmd + ,.

bash
kaku config

kaku doctor

Run diagnostics and verify that Kaku's shell integration, PATH entries, and optional tool installations are healthy. Use this first if something feels broken.

bash
kaku doctor
kaku doctor --shell fish # check fish even when $SHELL points to zsh
kaku doctor --shell fish --fix # repair the selected integration

kaku update

Check for and install the latest Kaku release.

bash
kaku update

kaku reset

Remove Kaku-managed shell and tmux integration, Kaku-managed git delta defaults,
selected Kaku state, and managed theme blocks in ~/.config/kaku/kaku.lua.
User-authored Lua outside managed blocks is preserved. Use with caution and run
kaku init again if you want shell integration back.

bash
kaku reset
kaku reset --shell fish # use fish for restart and restore guidance

kaku init

Set up Kaku's shell integration for zsh or fish. When both shells are installed,
an interactive run asks which one to configure. Use --shell to make the choice
explicit in scripts or when $SHELL does not match your daily shell. Also
installs optional CLI tools (Starship, Delta, Lazygit, Yazi) via Homebrew.

bash
kaku init
kaku init --shell fish
kaku init --shell zsh --update-only

If the kaku command goes missing from your shell, restore it with:

bash
/Applications/Kaku.app/Contents/MacOS/kaku init --update-only
exec zsh -l

kaku cli

Interact with the Kaku multiplexer from scripts and external tools.

bash
kaku cli split-pane                          # split current pane
kaku cli split-pane -- bash -c "echo hello" # split and run a command
kaku cli --help # list all subcommands
kaku cli split-pane --help # help for a specific subcommand

Useful for integrating Kaku with AI tools or shell scripts that need to open panes or tabs programmatically.

---

Config Versions

Config Version History

config_version is a monotonically increasing integer. The single source of truth is
assets/shell-integration/config_version.txt; the release gate
(scripts/check_release_config.sh) requires it to increment on every release, even when
nothing in the schema changed. Do not hardcode the current number in agent guides or
instruction files; read the txt file instead.

Rules for bumping

- A schema change must update the bundled defaults (assets/macos/Kaku.app/Contents/Resources/kaku.lua),
user docs, release checks, and migration behavior together, in one change.
- Only keys that existed in the previous released version need migration code. A feature
introduced in the current cycle ships its default directly: no migration, no version-gated
branches, no release-note migration mention. Check with
git show V<previous release>:assets/macos/Kaku.app/Contents/Resources/kaku.lua | grep <key>.
- A bump with no schema change is normal and expected; record why in this file.

History

| Version | Release | Change |
|---|---|---|
| v21 | - | Adds smart_tab_mode. Introduces the optional SmartPrompt value for window_close_confirmation (the bundled default later flipped to SmartPrompt so a stateful pane is no longer dropped silently on Cmd+Q). Accepts the removed language option as a deprecated field for backward compat. |
| v22 | - | Adds a precmd guard so the dark-theme comment color override still applies when the user pre-loads fast-syntax-highlighting or zsh-syntax-highlighting in their own .zshrc. |
| v23 | - | Flips the bundled smart_tab_mode default to suggestion_first so Tab accepts a visible autosuggestion, falling back to completion. No schema change, so no migration; users who set completion_first keep it. |
| v24 | - | Migrates $schema keys in user yazi configs to the #:schema comment form that yazi 26.5.6+ requires. No schema change; the repair runs in three places that must stay in sync: setup scripts, the yazi wrapper, and kaku.lua. |
| v25 | - | No schema change. Bumps so an updated install regenerates the bundled zsh integration, picking up the fast-syntax-highlighting path-to-dir style that no longer underlines existing directories. |
| v26 | V0.12.4 | No schema or bundled-integration change; increments only because the release gate requires a bump every release. The release highlight reuses the Cmd+Click-opens-links improvement. |
| v27 | V0.13.0 | Adds tab_title_show_foreground_process, an opt-in setting for showing foreground process names in auto-generated tab titles. No migration is needed because this key did not exist in V0.12.4. |
| v28 | - | No schema change. Bumps so existing installs regenerate the bundled zsh integration with the self-contained SSH wrapper required by shell snapshot tools. |
| v29 | V0.15.0 | No schema change. Bumps so existing installs regenerate the bundled shell integrations with the aligned ssh wrappers: fish keeps user-defined ssh functions and gains the 1Password fix, env-prefix ssh aliases work, and mosh gets the same TERM fallback. |
| v30 | V0.16.0 | No schema change. Bumps so existing installs regenerate shell integrations that authenticate inline AI control messages with a local capability before terminal output can trigger assistant requests, and that scope the Starship prompt setup to Kaku instead of every zsh. |
| v31 | V0.17.0 | Adds the optional file_link_editor setting for choosing which editor opens local terminal file links, bare-domain Cmd+Click links (e.g. github.com without a scheme), and Option+Click cursor movement within the current input line. Also regenerates shell integrations with the #511 fixes: the inline AI capability file is read tolerantly (zsh/fish read treat a missing trailing newline as EOF failure), user-var guards report failure with return 1 instead of masking it, and the fish widget only enters the waiting state after the request was actually emitted. The Rust side also writes the capability file with a trailing newline for new installs. |
| v32 | V0.18.0 | No schema change, and no bundled-integration change either; increments only because the release gate requires a bump every release. The release highlights reuse the new Move Tab to New Window command and the multi-display menu bar clamp fix. |

When you bump the version, add a row here in the same change.

---

Configuration

Configuration

Config File

Kaku auto-creates ~/.config/kaku/kaku.lua with a commented template on first launch. Open it with kaku config or Cmd + ,.

The file loads the bundled Kaku defaults first, then applies your overrides on top:

lua
local wezterm = require 'wezterm'

local function resolve_bundled_config()
local resource_dir = wezterm.executable_dir:gsub('MacOS/?$', 'Resources')
local bundled = resource_dir .. '/kaku.lua'
local f = io.open(bundled, 'r')
if f then f:close(); return bundled end
return '/Applications/Kaku.app/Contents/Resources/kaku.lua'
end

local config = {}
local bundled = resolve_bundled_config()
if bundled then
local ok, loaded = pcall(dofile, bundled)
if ok and type(loaded) == 'table' then config = loaded end
end

-- Your overrides go here:
config.font_size = 16
config.window_background_opacity = 0.95

return config

The full boilerplate with all available commented examples is auto-generated by kaku init. Most users only need to uncomment the lines they want to change.

---

Common Overrides

Start with the generated file and keep overrides small. Add only the settings you want to change:

lua
config.font_size = 16
config.window_background_opacity = 0.95

-- Choose one only if you do not want to follow macOS appearance:
-- config.color_scheme = "Kaku Dark"
-- config.color_scheme = "Kaku Light"

Keep terminal behavior, appearance, key bindings, launch behavior, and other WezTerm-compatible settings in kaku.lua.

Manage Kaku Assistant settings with kaku ai. That command writes ~/.config/kaku/assistant.toml for model, base URL, auth, API keys, and tool settings. The Lua/TOML split is intentional: kaku.lua stays compatible with WezTerm-style terminal configuration, while assistant.toml is managed by the AI setup flow.

---

Appearance

Theme

Kaku follows macOS appearance by default and switches between Kaku Dark and
Kaku Light automatically. To return to this behavior, choose Auto in
kaku config or remove an explicit config.color_scheme override. To force
one theme:

lua
config.color_scheme = "Kaku Dark"   -- always dark
config.color_scheme = "Kaku Light" -- always light

Color overrides

Remap specific hex colors to keep theme consistency with apps that output their own colors. color_overrides applies to rendered backgrounds, including palette-backed ANSI backgrounds and truecolor backgrounds. foreground_color_overrides applies only to truecolor text:

lua
config.color_overrides = {
['#6E6E6E'] = '#3A3942',
}

config.foreground_color_overrides = {
['#FFFFDB'] = '#575653',
}

Font

Kaku defaults to JetBrains Mono with PingFang SC as CJK fallback. Change font:

lua
config.font = wezterm.font("Fira Code")

Kaku disables ligatures by default. Re-enable:

lua
config.harfbuzz_features = {}

Font size

Kaku auto-selects 15px (low-res) or 17px (high-res) based on your display. Override:

lua
config.font_size = 16

Line height

lua
config.line_height = 1.28  -- default

The default favors readable text spacing. Character-cell graphics (QR codes, neofetch logos, TUI charts) stretch with the row height; set 1.01.1 if you want them near-square. See the FAQ for details.

Window transparency

lua
config.window_background_opacity = 0.92
config.macos_window_background_blur = 20 -- optional blur (0–100)

Traffic lights (macOS)

By default, Kaku embeds the macOS traffic light buttons into the tab bar area using INTEGRATED_BUTTONS|RESIZE. To hide the traffic lights while keeping resize edges and tab-bar dragging:

lua
config.window_decorations = "RESIZE"

RESIZE preserves the ability to resize the window from its edges and drag it by the tab bar; it only removes the close/minimize/zoom buttons.

Padding

lua
config.window_padding = { left = '24px', right = '24px', top = '40px', bottom = '20px' }

Sizes accept px, pt, cell, and %. px is a physical pixel value and
does not scale with display DPI, so the same value can look smaller on a
high-density display. Use pt for DPI-scaled spacing or cell for spacing
relative to the terminal cell size, for example top = '15pt'.

---

Terminal Behavior

Cursor

lua
config.default_cursor_style = "BlinkingBar"
config.cursor_thickness = "2px"
config.cursor_blink_rate = 500

Scrollback

lua
config.scrollback_lines = 10000  -- default

File link editor

Set an editor command for local file links printed in the terminal. Kaku appends
the resolved path, or path:line:column when the link includes a location.
Shell-style quoting is supported for command arguments:

lua
config.file_link_editor = "zed"
-- config.file_link_editor = "cursor --goto"

This setting takes priority over Kaku's automatic VS Code detection. When it is
unset, Kaku keeps the existing VS Code and $VISUAL / $EDITOR fallback behavior.

Copy on select

Enabled by default. Disable:

lua
config.copy_on_select = false

Strip leading whitespace on copy

When copying indented multi-line text (e.g. from a code block), remove the
shared leading whitespace so the pasted result starts at column 0:

lua
config.copy_strip_leading_whitespace = true  -- default: false

Restore previous session

Re-open the tabs and panes from your last session on launch. Enabled by
default; set it to false to disable saving and restoring the session:

lua
config.restore_previous_session = false  -- default: true

Working directory inheritance

lua
config.window_inherit_working_directory = true   -- new windows
config.tab_inherit_working_directory = true -- new tabs
config.split_pane_inherit_working_directory = true -- new splits

Tab bar

Hidden when only one tab is open. Auto-generated tab titles show the current
directory by default. You can change the position, shorten path titles, or opt
into showing the foreground command alongside the path:

lua
config.tab_bar_at_bottom = false                   -- move to top
config.tab_title_show_basename_only = true -- show "dirname" instead of "parent/dirname"
config.tab_title_show_foreground_process = true -- show "dirname·codex" while commands run

Background tabs that emit BEL show a small dot in the tab title by default.
Disable the indicator if you do not want tab-level bell notifications:

lua
config.bell_tab_indicator = false

Scrollbar

Disabled by default. Enable via kaku config (toggle the scrollbar style option) or in Lua:

lua
config.enable_scroll_bar = true

If you want the mouse wheel to scroll inside alternate-screen apps such as
nano and vim, instead of peeking into Kaku's primary scrollback, enable:

lua
config.alternate_screen_wheel_scrolls_terminal = true

Selection drag + mouse wheel

Controls what the mouse wheel does while you are dragging out a selection
with the left mouse button held down. Defaults to "Extend" (Kaku v0.11+),
which matches macOS NSTextView apps such as Safari, TextEdit, VS Code,
iTerm2 and Terminal.app: the wheel scrolls the scrollback and the
selection grows to follow the cursor across screens.

lua
-- Default (recommended): scroll AND extend the selection so you can grab
-- text that spans more than one screen of output.
config.selection_wheel_scroll_behavior = "Extend"

-- Scroll the scrollback but leave the selection range untouched.
config.selection_wheel_scroll_behavior = "ScrollOnly"

-- Drop the wheel event entirely. This is the legacy Kaku v0.10 behavior;
-- selecting text that does not fit on one screen requires releasing the
-- mouse, scrolling, and re-selecting.
config.selection_wheel_scroll_behavior = "Ignore"

Default change in v0.11: earlier Kaku versions behaved as if

"Ignore" were set. Set selection_wheel_scroll_behavior = "Ignore" to

restore the old behavior.

macOS Option key

Left Option sends Meta (useful for Vim/Neovim word navigation). Right Option sends compose characters.

lua
config.send_composed_key_when_left_alt_is_pressed = false  -- default: left = Meta
config.send_composed_key_when_right_alt_is_pressed = true -- default: right = Compose

---

Updates

Kaku checks GitHub for new releases in the background (enabled by default) and
quietly downloads a newer version when it finds one. It never installs on its
own: it shows a notification, and clicking it asks you to confirm first, since
applying an update closes every window and stops running tasks.

Turn off background checks entirely:

lua
config.check_for_updates = false

Change how often it checks (default 10800, i.e. every 3 hours):

lua
config.check_for_updates_interval_seconds = 86400  -- once a day

You can always update manually with kaku update or from the app menu,
regardless of these settings.

---

Custom Keybindings

Always insert into config.keys, never replace it. Replacing erases all Kaku defaults.

lua
-- Navigate pane right
table.insert(config.keys, {
key = 'RightArrow',
mods = 'CMD|SHIFT',
action = wezterm.action.ActivatePaneDirection('Right'),
})

-- Split pane horizontally
table.insert(config.keys, {
key = 'Enter',
mods = 'CMD|OPT',
action = wezterm.action.SplitHorizontal({ domain = 'CurrentPaneDomain' }),
})

Full list of available actions: WezTerm KeyAssignment reference.

---

Advanced

Enterprise proxy headers

Add custom HTTP headers to Kaku Assistant API requests (for corporate proxies or API gateways):

toml

~/.config/kaku/assistant.toml


custom_headers = ["X-Customer-ID: your-id", "X-Org: your-org"]

Note: Authorization and Content-Type are reserved and cannot be overridden.

Extend Command Palette

Add a custom command to Command Palette (Cmd + Shift + P) via kaku.lua:

lua
wezterm.on('augment-command-palette', function(window, pane)
if not pane then return {} end

local cwd_obj = pane:get_current_working_dir()
if not cwd_obj then return {} end

-- Finder can only reveal local paths. file_path is already URL-decoded,
-- so directories containing spaces or non-ASCII characters work too.
local host = cwd_obj.host
if cwd_obj.scheme ~= 'file'
or (host and host ~= '' and host ~= 'localhost' and host ~= wezterm.hostname():lower()) then
return {}
end
local cwd = cwd_obj.file_path
if not cwd then return {} end

return {
{
brief = 'Reveal in Finder',
doc = 'Reveal current directory in Finder',
action = wezterm.action_callback(function()
wezterm.run_child_process({ 'open', '-R', cwd })
end),
},
}
end)

Full WezTerm Lua API

Kaku uses WezTerm's configuration system. Any WezTerm config option works in kaku.lua. For the complete reference, see:

- WezTerm config options
- WezTerm Lua API

---

Faq

FAQ

Is there a Windows or Linux version?

Not currently. Kaku is macOS-only while the macOS experience is being polished. Windows and Linux may come later.

Can I use a transparent window?

Yes. Add to ~/.config/kaku/kaku.lua:

lua
local config = require("kaku").config
config.window_background_opacity = 0.92
config.macos_window_background_blur = 20 -- optional blur, 0–100
return config

How do I turn off copy on select?

lua
config.copy_on_select = false

How do I customize keybindings?

Append to config.keys, do not replace it:

lua
config.keys[#config.keys + 1] = {
key = "RightArrow",
mods = "CMD|SHIFT",
action = wezterm.action.ActivatePaneDirection("Right"),
}

See keybindings.md and configuration.md for more examples.

Can I control working directory inheritance?

Yes, individually for windows, tabs, and splits:

lua
config.window_inherit_working_directory = true
config.tab_inherit_working_directory = true
config.split_pane_inherit_working_directory = true

All are enabled by default.

How do I disable Kaku Assistant?

Run kaku ai, open Kaku Assistant settings, and set Enabled to Off. Or edit ~/.config/kaku/assistant.toml directly:

toml
enabled = false

How do I use a custom LLM provider?

Run kaku ai, keep Auth Type set to API key, and enter your Base URL, API Key,
Simple Model, and Deep Model manually. Choose API Mode chat_completions
for /v1/chat/completions, or responses for /v1/responses. If the Responses
provider supports hosted search, set Native Web Search to On; no separate
search provider or search API key is required.

How do I restore default config?

bash
kaku reset

This removes Kaku-managed shell and tmux integration, Kaku-managed git delta
defaults, selected Kaku state, and managed theme blocks in
~/.config/kaku/kaku.lua. User-authored Lua outside managed blocks is
preserved. Run kaku init again if you want shell integration back.

The kaku command is missing. How do I recover it?

bash
/Applications/Kaku.app/Contents/MacOS/kaku init --update-only
exec zsh -l

Then run kaku doctor to verify everything is healthy.

How do I use Kaku's CLI from scripts?

bash
kaku cli split-pane
kaku cli split-pane -- bash -c "echo hello"
kaku cli --help

See cli.md for full reference.

How do I enable the scrollbar?

Open kaku config and toggle the scrollbar option, or add to ~/.config/kaku/kaku.lua:

lua
config.enable_scroll_bar = true

How do I scroll inside nano, vim, or another full-screen terminal app?

Enable alternate-screen wheel forwarding:

lua
config.alternate_screen_wheel_scrolls_terminal = true

How do I change the font? My font change isn't taking effect.

Font changes require explicitly setting config.font in your config:

lua
config.font = wezterm.font('Your Font Name')

Note: Kaku's theme-aware font weight system only applies to the default JetBrains Mono stack. Once you set a custom font, Kaku will no longer override its weight automatically.

My window_padding change isn't working.

window_padding values require a 'px' unit suffix:

lua
config.window_padding = { left = '24px', right = '24px', top = '40px', bottom = '20px' }

Plain numbers (without 'px') are interpreted as terminal cell units, which may not match your intent.

The screen jumps to the top while Claude Code is generating output.

This is a known interaction between trackpad scroll and Claude Code's streaming output. If you accidentally scroll to the top mid-stream, pressing the down arrow or scrolling back down returns you to the current output. A fix for the jump behavior has been tracked and shipped in recent releases.

Cmd+Shift+Y sends a local path when inside an SSH session.

The yazi remote-files feature (Cmd+Shift+R) is designed for SSH sessions and mounts the remote filesystem via sshfs. Cmd+Shift+Y is for local yazi. Use Cmd+Shift+R when you are inside an SSH pane.

The y shell wrapper doesn't sync my directory on exit.

Make sure the Kaku fish/zsh shell integration is sourced. Check with kaku doctor. The y wrapper requires the shell init to be loaded. A bare yazi call will not sync the directory.

Homebrew can't find the binary / wrong Kaku gets updated.

There is an older unrelated package named kaku on Homebrew. Install Kaku with the tap to avoid conflicts:

bash
brew install tw93/tap/kakuku

If you see checksum errors with kaku update, use brew upgrade tw93/tap/kakuku directly.

Claude Code notifications don't appear.

Kaku's notification permission may not be granted. Go to System Settings > Notifications > Kaku and enable Allow Notifications. Then restart Kaku.

The global hotkey doesn't work on non-QWERTY keyboards (e.g. Colemak).

Cmd + Opt + Ctrl + K uses the physical QWERTY K position. On Colemak, this corresponds to a different key. Remap it in your config:

lua
table.insert(config.keys, {
key = 'k', -- adjust to your layout's physical key
mods = 'CMD|OPT|CTRL',
action = wezterm.action.EmitEvent('toggle-global-window'),
})

QR codes and terminal graphics look vertically stretched.

Kaku's default line_height = 1.28 favors comfortable text spacing. Terminal graphics built from characters, such as QR codes, neofetch logos, and TUI bar charts, scale with the row height, so they render about 28% taller than in terminals with no extra line spacing. This is a typography trade-off, not a rendering bug: block characters must fill the whole cell so TUI borders and progress bars stay seamless.

If you want near-square graphics, lower the line height in ~/.config/kaku/kaku.lua:

lua
config.line_height = 1.1  -- or 1.0 to match terminals without extra spacing

Note that no terminal renders half-block QR codes perfectly square: with common monospace fonts the cell is naturally a bit taller than 2:1 even at line_height = 1.0.

Can I use Kaku with tiling window managers (yabai, AeroSpace)?

Kaku is compatible with yabai and AeroSpace. If you see continuous flickering, it is usually caused by the tiling WM fighting with Kaku's fullscreen/resize logic. Disabling Kaku's native fullscreen (config.native_macos_fullscreen_mode = false) or excluding Kaku from the tiling WM's managed window list typically resolves it.

---

Features

Features

Kaku Assistant

Kaku Assistant has two modes: automatic error recovery and on-demand command generation from natural language.

Setup

Run kaku ai to open the AI settings panel. Enable Kaku Assistant and edit the model, auth, base URL, and API key fields directly.

| Field | Description |
| :--- | :--- |
| Auth Type | API key or Follow Codex |
| Simple Model | Used for # command generation, command fixes, and lightweight chat |
| Deep Model | Used for primary Cmd + L / k chat and tool use |
| Base URL | OpenAI-compatible API root, such as https://api.openai.com/v1 |
| API Key | Provider API key when Auth Type is API key |

For custom providers configured directly in Kaku, keep Auth Type set to API key,
enter the provider's OpenAI-compatible Base URL, and set the model names manually.
With Auth Type set to Codex, Kaku follows the user-level Codex connection under
CODEX_HOME (falling back to ~/.codex), including API-key or ChatGPT login,
the selected model provider, Base URL, query parameters, and provider headers.
Project configs, named profiles, and CLI overrides are intentionally excluded.
Unsupported authentication modes fail before Kaku sends a request.

AI Chat Panel

Press Cmd + L to open the built-in AI chat panel. It streams Markdown answers,
highlights code blocks, can include terminal context, and can use approved tools
for project files, shell commands, web search, and memory. Press Shift + Tab
inside the panel to toggle between the Simple Model and Deep Model when they
are different.

From a shell, use k or kaku chat for the same conversation store:

bash
k "summarize the current project"
kaku chat

The standalone CLI is intentionally simpler than the overlay: it streams plain
terminal text and supports /new, /resume, /clear, /status, /memory,
and /exit.

Error recovery

When a command exits with a non-zero status, Kaku Assistant automatically sends the failed command, exit code, working directory, and git branch to the LLM and displays a suggested fix inline. Press Cmd + Shift + E to paste the suggestion into the terminal. Dangerous commands (e.g. rm -rf, git reset --hard) are pasted but never auto-executed.

The assistant does not trigger on: Ctrl+C exits, help flags, bare package manager calls, git pull conflicts, or non-shell foreground processes.

Natural language to command

Type # <description> at the prompt and press Enter to generate a shell command from plain English. Kaku intercepts the line before the shell sees it, sends your query along with the current directory and git branch to the LLM, and injects the resulting command back into the prompt ready to review and run.

text

list all files modified in the last 7 days


find and kill the process on port 3000


compress the src folder excluding node_modules

The # prefix works in both zsh and fish. The original query stays visible while the request is in flight. If the model cannot produce a safe command, it injects a short explanation instead. Dangerous commands are loaded but flagged for review, never auto-executed.

assistant.toml fields

The config lives at ~/.config/kaku/assistant.toml:

| Field | Description |
| :--- | :--- |
| enabled | true to enable, false to disable |
| api_key | Your provider API key |
| model | Simple Model for # command generation, command fixes, and lightweight chat; Follow Codex resolves the Codex model |
| chat_model | Deep Model for primary Cmd + L / k chat and tool use; Follow Codex resolves the Codex model |
| chat_model_choices | Optional curated list of chat models for the overlay picker |
| auto_fix_ignored_exit_codes | Optional exit codes that should not trigger automatic command-fix suggestions, e.g. [2] |
| base_url | OpenAI-compatible API root URL |
| api_mode | chat_completions (default) or responses |
| native_web_search | Add the provider-hosted web_search tool in Responses mode, with no separate search API key |
| custom_headers | Extra HTTP headers for enterprise proxies, e.g. ["X-Customer-ID: your-id"] |
| web_search_provider | Optional search backend: brave, pipellm, or tavily |
| web_search_api_key | API key for the selected search backend |
| web_fetch_script | Optional custom URL-to-Markdown fetch script |
| chat_tools_enabled | Set to false to disable tool calling for chat providers without tool support |
| auth_type | Advanced auth mode, e.g. api_key or codex |
| memory_curator_model | Optional cheaper model for background memory curation |

Older configs may still contain fast_model; Kaku treats it as the Simple Model
and folds it back into model the next time the assistant settings are saved.

For a Responses-compatible endpoint, select responses under API Mode in
kaku ai, or configure it directly:

toml
base_url = "https://api.openai.com/v1"
api_mode = "responses"
native_web_search = true

Kaku sends these requests to {base_url}/responses. Native web search runs at
the model provider, so web_search_provider and web_search_api_key are not
needed. Keep chat_completions for providers that only implement
/chat/completions.

When auth_type = "codex", base_url, api_key, and api_mode do not define
the connection. Kaku reads Codex's user configuration instead. New Codex-mode
setups default both model fields to Follow Codex; either field can still be
set to an explicit model as a Kaku-only override. The chat model switcher
discovers available models from {Codex provider base_url}/models with that
provider's resolved authentication, headers, and query parameters. Explicit
Kaku model overrides are preserved when changing authentication modes. If the
Codex config has no model, Kaku uses the first model returned by that endpoint.

---

Terminal Interactions

Cmd+Click opens URLs and file paths, and also bare domains such as
github.com that have no scheme prefix. The matcher is tuned to leave code
identifiers alone: method calls like df.info() and namespaces like
System.Net never turn into links.

Option+Click moves the shell cursor within the current input line, including
across soft-wrapped continuation rows. It never crosses a hard newline, so
clicks into scrollback are ignored rather than mangling history.

---

Window Snapshots

Kaku saves multi-tab and multi-pane window layouts automatically when you close
or hide a window. Use Shell > Restore Previous Window or
Cmd + Option + Shift + T to reopen the last saved layout. Kaku tolerates
missing or corrupted snapshot files and simply reports that no snapshot is
available.

---

AppleScript

Kaku ships a minimal AppleScript dictionary so it shows up in Script Editor and other automation tools. The exposed surface is intentionally small and read-only apart from quit.

applescript
tell application "Kaku"
get name -- "Kaku"
get version -- e.g. "0.10.0"
get frontmost -- true / false
quit -- optional saving ask|yes|no
end tell

Open /Applications/Kaku.app in Script Editor → File → Open Dictionary to browse the full dictionary. There is no do script verb — Kaku does not expose shell execution to AppleScript.

---

Lazygit Integration

Press Cmd + Shift + G to launch lazygit in the current pane. Kaku auto-detects the lazygit binary from PATH or common Homebrew locations.

When a git repo has uncommitted changes and lazygit has not been used in that directory yet, Kaku shows a one-time hint to remind you it is available.

Install lazygit with brew install lazygit or via kaku init.

---

Yazi File Manager

Press Cmd + Shift + Y to launch yazi in the current pane. The shell wrapper y also launches yazi and syncs the shell working directory on exit.

Theme sync: Kaku automatically updates ~/.config/yazi/theme.toml to match the active color scheme (Kaku Dark or Kaku Light). No manual yazi theme setup needed.

Install yazi with brew install yazi or via kaku init.

---

Remote Files

Press Cmd + Shift + R to mount the current SSH session's remote filesystem locally via sshfs and open it in yazi.

Kaku auto-detects the SSH target from the active pane. The mount lives at ~/Library/Caches/dev.kaku/sshfs/<host>.

Requirements: sshfs installed (brew install macfuse sshfs) and passwordless SSH auth (key-based) for the remote host.

---

Shell Suite

Kaku ships a curated set of shell plugins that load automatically inside Kaku sessions.

Zsh plugins (built-in)

- z: Smarter cd that learns your most-used directories. Use z <dir>, z -l <dir> to list matches, z -t for recent directories.
- zsh-completions: Extended completions for common CLI tools.
- zsh-syntax-highlighting: Real-time command coloring and error highlighting.
- zsh-autosuggestions: Fish-style history-based completions as you type.

Fish support

Run kaku init to provision ~/.config/kaku/fish/kaku.fish for fish users. kaku doctor verifies both zsh and fish integration paths.

Optional tools (installed via kaku init)

- Starship: Fast, customizable prompt with git and environment info.
- Delta: Syntax-highlighting pager for git diff and grep.
- Lazygit: Terminal git UI.
- Yazi: Terminal file manager.

Smart Tab

Kaku's Smart Tab overrides the Tab key in zsh to provide smarter completion behavior. It supports three modes:

| Mode | Behavior | Environment Variable |
| :--- | :--- | :--- |
| Completion First | Tab shows the completion list; use -> to accept autosuggestions | - |
| Suggestion First (default) | Tab accepts autosuggestions when available, falls back to completion | KAKU_TAB_ACCEPT_SUGGEST_FIRST=1 |
| Off | Disables Smart Tab entirely, restoring native zsh Tab behavior | KAKU_SMART_TAB_DISABLE=1 |

You can also set the mode via kaku config (the Smart Tab option under Behavior) or in kaku.lua:

lua
config.smart_tab_mode = "suggestion_first"   -- default; Tab accepts autosuggestions first
config.smart_tab_mode = "completion_first" -- Tab shows the completion list instead
config.smart_tab_mode = "off" -- disable Smart Tab

If you prefer environment variables (for example, because you share your zshrc across terminals), add one of these before sourcing the Kaku shell integration:

zsh
export KAKU_TAB_ACCEPT_SUGGEST_FIRST=1  # suggestion-first mode

or


export KAKU_SMART_TAB_DISABLE=1 # disable Smart Tab

fish
set -gx KAKU_SMART_TAB_DISABLE 1

Environment variables set in your shell rc take precedence over kaku.lua settings. Smart Tab is only active inside Kaku sessions (TERM_PROGRAM=Kaku).

---

Keybindings

Keybindings

All keybindings use macOS-native modifier keys. Opt = Option/Alt, Ctrl = Control.

Window

| Action | Shortcut |
| :--- | :--- |
| New window | Cmd + N |
| Close pane / tab / hide | Cmd + W |
| Close current tab | Cmd + Shift + W |
| Hide application | Cmd + H |
| Minimize window | Cmd + M |
| Toggle fullscreen | Cmd + Ctrl + F |
| Quit | Cmd + Q |
| Toggle global window | Cmd + Opt + Ctrl + K |

Cmd + W is smart: closes the active pane if there are multiple panes, closes the tab if there are multiple tabs or windows, otherwise hides the app.

Tabs

| Action | Shortcut |
| :--- | :--- |
| New tab | Cmd + T |
| Switch to tab 1–9 | Cmd + 1Cmd + 9 |
| Previous tab | Cmd + Shift + [ |
| Next tab | Cmd + Shift + ] |
| Open Tab Navigator | Cmd + Shift + O |
| Close tab | Cmd + Shift + W |
| Reopen closed tab | Cmd + Shift + T |
| Rename tab | Double-click tab title |

Panes

| Action | Shortcut |
| :--- | :--- |
| Split vertical | Cmd + D |
| Split horizontal | Cmd + Shift + D |
| Toggle split direction | Cmd + Shift + S |
| Zoom / unzoom pane | Cmd + Shift + Enter |
| Navigate panes | Cmd + Opt + Arrows |
| Resize pane | Cmd + Ctrl + Arrows |
| Broadcast input to current tab | Cmd + Opt + I |
| Broadcast input to all tabs | Cmd + Shift + I |

Shell Editing

| Action | Shortcut |
| :--- | :--- |
| Jump word left / right | Opt + Left / Opt + Right |
| Jump to line start / end | Cmd + Left / Cmd + Right |
| Delete to line start | Cmd + Backspace |
| Delete word | Opt + Backspace |
| Newline without execute | Cmd + Enter or Shift + Enter |

Font Size

| Action | Shortcut |
| :--- | :--- |
| Increase | Cmd + = |
| Decrease | Cmd + - |
| Reset | Cmd + 0 |

Kaku Features

| Action | Shortcut |
| :--- | :--- |
| Clear screen + scrollback | Cmd + K |
| Open Settings panel | Cmd + , (type to filter model lists inside the panel) |
| Open Command Palette | Cmd + Shift + P |
| Open AI panel | Cmd + Shift + A |
| Open AI Chat | Cmd + L |
| Apply Kaku Assistant suggestion | Cmd + Shift + E |
| Restore previous window snapshot | Cmd + Opt + Shift + T |
| Open lazygit | Cmd + Shift + G |
| Open yazi file manager | Cmd + Shift + Y |
| Browse remote files (SSH) | Cmd + Shift + R |
| Open Doctor panel | Ctrl + Shift + L |

The Command Palette is the quickest way to find built-in commands when you do not remember a shortcut.

Mouse

| Action | Trigger |
| :--- | :--- |
| Copy selection to clipboard | Release left mouse button after selecting |
| Open link | Cmd + Click |
| Move cursor to clicked column | Opt + Click (same row, shell prompt only) |

Custom Keybindings

Add bindings to ~/.config/kaku/kaku.lua by appending to config.keys. Do not assign a new table, this would erase Kaku's defaults.

lua
-- ~/.config/kaku/kaku.lua (after loading bundled config)
table.insert(config.keys, {
key = 'RightArrow',
mods = 'CMD|SHIFT',
action = wezterm.action.ActivatePaneDirection('Right'),
})

-- Example: rebind AI Chat to Cmd+Shift+Space (original default):
table.insert(config.keys, {
key = 'Space',
mods = 'CMD|SHIFT',
action = wezterm.action.EmitEvent('kaku-ai-chat'),
})

For the full list of available actions, see WezTerm KeyAssignment reference.

---

Release Checklist

Release Checklist

macOS Tab Bar Matrix

Before shipping a release that touches windowing, titlebar coloring, tab bar
layout, or transparency, build the app with make app and verify these macOS
config combinations manually:

| Tab position | Tab style | Opacity | Window state | Expected result |
| --- | --- | --- | --- | --- |
| Top | Fancy | Opaque | Windowed | Tab text/icons stay visible below integrated traffic lights. |
| Top | Fancy | Transparent | Windowed | Tab text/icons stay visible; transparent titlebar has no gap. |
| Top | Retro | Opaque | Windowed | Tab text/icons stay visible below integrated traffic lights. |
| Top | Retro | Transparent | Windowed | Tab text/icons stay visible; transparent titlebar has no gap. |
| Bottom | Fancy | Opaque | Windowed | Bottom tab bar is visible and top content clears traffic lights. |
| Bottom | Fancy | Transparent | Windowed | Bottom tab bar is visible; top titlebar area has no gap. |
| Bottom | Retro | Opaque | Windowed | Bottom tab bar is visible and top content clears traffic lights. |
| Bottom | Retro | Transparent | Windowed | Bottom tab bar is visible; top titlebar area has no gap. |
| Top | Fancy | Opaque | Fullscreen | Native titlebar does not cover the rendered tab bar. |
| Bottom | Fancy | Opaque | Fullscreen | Bottom tab bar remains visible after entering and leaving fullscreen. |

The key regression guard is update_titlebar_background() in
window/src/os/macos/window.rs: native titlebar coloring must remain opt-in for
opaque windows, otherwise NSTitlebarContainerView can cover the Metal-rendered
top tab bar.

---

CONTRIBUTING

Contributing to Kaku

Setup

bash

Clone the repository


git clone https://github.com/tw93/Kaku.git
cd Kaku

Install Rust if it isn't already available (Homebrew keeps rustup keg-only)


brew install rustup
echo "export PATH=\"$(brew --prefix rustup)/bin:\$HOME/.cargo/bin:\$PATH\"" >> ~/.zprofile
exec zsh -l
rustup toolchain install 1.95.0

Install required tools (cargo-nextest, cargo-watch, nightly rustfmt)


make install-tools

Install pre-commit hook (format + test before each commit)


make install-hooks

Development

| Command | Purpose |
|---------|---------|
| make fmt | Auto-format code (requires nightly) |
| make fmt-check | Check formatting without modifying files |
| make check | Compile check, catch type/syntax errors |
| make test | Run unit tests |
| make dev | Fast local debug: build kaku-gui and run from target/debug |
| make build | Compile binaries (no app bundle) |
| make app | Build debug app bundle → dist/Kaku.app |

Recommended workflow:

bash
make fmt        # format first
make check # verify it compiles
make test # run tests
make dev # fast local run without packaging

You can override log level for make dev:

bash
RUST_LOG=debug make dev

Build Release

bash

Build application and DMG (release, universal binary)


./scripts/build.sh

Outputs: dist/Kaku.app and dist/Kaku.dmg

Build for current architecture only (faster, for local testing)


./scripts/build.sh --native-arch

Build app bundle only (skip DMG creation)


./scripts/build.sh --native-arch --app-only

Build and open the app automatically


./scripts/build.sh --native-arch --open

Pull Requests

1. Fork and create a branch from main
2. Make changes
3. Run make fmt && make check && make test
4. Commit and push
5. Open PR targeting main

CI runs format check → unit tests → cargo check → universal build validation in order.

---