Skip to content

Configuration ​

Documentation in progress

Some sections are still incomplete.

ThinkTerm is configured with a Lua file, the same way WezTerm is. The option names, the module name, and the syntax are unchanged — a ThinkTerm config still opens with:

lua
local wezterm = require 'wezterm'

What differs is where the file is read from and where the data is written.

Two stores, not one ​

The Lua file is the one you edit by hand, and it carries the terminal's own options.

Beside it, ~/.config/thinkterm/settings.json is written by the Settings window, and holds the choices that have a control there — the theme, window opacity, keyboard shortcuts, scrolling and the overlay scrollbar, interface fonts and sidebar widths, the interface language, the renderer, tab icons. It is not meant to be edited by hand. Where the two overlap, a choice made in Settings is nearly always the one in force; the exceptions are below.

The file is also rewritten as you work — a sidebar dragged or hidden, the window moved — and none of that reloads the Lua config, so it costs no reloaded fonts and no closed command palette. An edit made to it from outside, by an editor or another program, is picked up at once and applied the way the Settings window would apply it, rather than sitting unused until the next save writes the older copy back over it.

The Settings window ​

Settings opens from the gear at the foot of the sidebar, with ⌘, on macOS, or with Ctrl+Shift+, elsewhere. Its pages, and where each is described:

PageHoldsDescribed in
GeneralLanguage, Renderer, Restore Main Window Frame, which config file loaded, the session server, Restore pane contents, Restart and QuitThis page, The Window, Remote
AppearanceTheme, Effective Color Scheme, App Icon, Typography, Window Opacity, on macOS 26 the Glass effect, the shade of the sidebars, tab bars and terminal, and the icons and status marks of the sidebarThe Window, Window opacity, Icons and status
Tab IconsThe program icons on pane tabsThe Window
Sidebar & PluginsThe right-hand panels, Status, installed pluginsThe Window, Plugins, Agent Status
TerminalDefault Shell, font, Scrolling, Scrollbar, Minimum text contrast, Cursor shape and Cursor blink, Mouse and clipboard, Split animation, Remote Split Resize, Bottom QuoteThis page, The Window, Copy and paste, Remote, Privacy and Security
WorkspacesRemote Files idle timeout, Download Folder, Remote Drop Destination, Notification Sounds, System Notifications and, on macOS, Dock Icon CountFiles and Notes, Agent Status, This page
AgentsWhich coding agents are recognised, and howAgent Status
WebBrowser access and the links handed outWeb
Share & SyncShare terminals, which lets other accounts on this machine watch your terminals, marked experimental—
PermissionsmacOS only: which permissions the programs in your terminals haveThis page
ArchivedArchived ProjectsSpaces, Projects and Threads
KeymapA keyboard that shows what each key does, and assigns shortcuts to commandsKeyboard and Commands
Command PaletteThe palette's shortcut, rows, font size and searchKeyboard and Commands
ImportOne-time imports of a WezTerm config, the folders your editors, coding agents and cmux worked in, and Herdr sessionsThis page
AccessibilityShow button shapes, which keeps the round background of the sidebar's add buttons showing—
BackupExport and import of ThinkTerm's stateThis page
Software UpdateUpdate checks, how often they run, and installingThis page, Updates
AboutVersion, build, links, and where the files liveThis page

Developer has a switch that shows further pages, for working on ThinkTerm itself rather than for everyday use. The search box above the list finds a page by the settings on it.

About and bug reports ​

Settings › About shows the version, build, platform and licence, and opens the source code, the release notes, the config file, the data folder, the third-party notices and the privacy policy. Copy Info puts the details a bug report needs on the clipboard: the version and build, the target platform and operating system, the config file and data folder paths and, once an update check has run, the latest release it saw. The paths include your home folder's name, so look before pasting it somewhere public.

Where Settings and the config file overlap ​

A few choices can be made in both places. In these, Settings has the last word, and each has a way to hand the choice back to the file:

In SettingsStands in front ofTo follow the config file again
Settings › Terminal › Default Shelldefault_prog, for new terminals on this machineChoose Follow thinkterm.lua (default_prog), shown as System default when the file sets none
Settings › Terminal › Font Size, 8 to 48font_size, applied to open terminals at onceReset the row
A scheme picked through Settings › Appearance › Effective Color Scheme, or Change Theme in the command palettecolor_schemeUse configured default in Change Theme
Settings › Terminal › Minimum text contrasttext_min_contrast_ratioOff
Settings › Command Palette › Font Sizecommand_palette_font_sizeReset the row
A shortcut set in Settings › KeymapThe same key in keys, and the built-in default for itReset on the shortcut, or Reset All Shortcuts
Settings › Appearance › Window Opacitywindow_background_opacity, and on macOS macos_window_background_blurReset to Default
Settings › Terminal › Cursor shape set to Bar or UnderlineThe shape in default_cursor_styleChoose Block
Settings › Terminal › Cursor blink set to Smooth or HardWhether the cursor blinks, which default_cursor_style otherwise decides, and with Hard also cursor_blink_ease_in and cursor_blink_ease_outChoose Off
Settings › Software Update › Check Automatically and Check Frequencycheck_for_updates and check_for_updates_interval_seconds, once the row has been usedNone; see the update check

Default Shell lists the shells found on this machine and takes effect the next time a terminal opens. Only this machine's terminals follow it, including those kept in its session server; a remote server runs what its own configuration says. A shell that has been uninstalled since it was chosen falls back to the system default rather than leaving no terminal at all.

On Windows the list also offers Git Bash, started as a login shell, when Git for Windows is found under Program Files, under %LOCALAPPDATA%\Programs\Git or in a Scoop install. Where wsl.exe is present it lists up to three WSL distributions, the default one first, each as <name> (WSL); Docker Desktop's own docker-desktop distributions are left out.

The font itself is not one of them: Settings › Terminal › Font Family only shows the font the config file names, and font in the file is where it is changed.

One overlap goes the other way. enable_scroll_bar = true in the config file replaces ThinkTerm's overlay scrollbar with WezTerm's own, whatever Settings › Terminal › Scrollbar says.

A shortcut set in Settings › Keymap is kept in settings.json and wins over the same key in keys and over the built-in default; the config file itself is never rewritten. A shortcut that runs a Lua function from the config file can only be changed in the file. See Keyboard and Commands.

Window Opacity is a slider from 30% to 100% in steps of 5, marked Beta, and it reads Default until it has been moved. Moving it sets window_background_opacity for every window, and while a macOS window is see-through it adds a background blur of 20 unless the file sets macos_window_background_blur itself. It is greyed out on Linux, where window_background_opacity in the file still works, and Settings notes that it is not yet stable on Windows; there win32_system_backdrop stays the file's to choose, and the frosted glass appears with the opacity once ThinkTerm restarts. See The Window.

Without a scheme picked, a light interface also brings a light terminal scheme of its own — see The Window.

The colour scheme and the window opacity chosen in Settings take effect whether or not a config file exists.

Where the config file is read from ​

ThinkTerm loads the first file it finds, in this order:

  1. --config-file PATH on the command line
  2. $THINKTERM_CONFIG_FILE
  3. $WEZTERM_CONFIG_FILE
  4. thinkterm.lua next to the executable — Windows only
  5. wezterm.lua next to the executable — Windows only
  6. ~/.config/thinkterm/thinkterm.lua
  7. ~/.config/thinkterm/wezterm.lua
  8. ~/.thinkterm.lua

Two more command-line flags sit alongside the first. --skip-config (-n) skips the search entirely and runs on built-in defaults, and --config name=value, which can be repeated, overrides single options on top of whatever file loaded. All three are global flags, so they go before the subcommand.

$THINKTERM_CONFIG_DIR and $WEZTERM_CONFIG_DIR are not part of that search. ThinkTerm sets them once a config has loaded, pointing at the directory the file came from, so that programs you launch can find it. Setting them yourself does not select a config.

The two Windows-only entries are deliberate. A config sitting beside the executable takes precedence so that ThinkTerm can be carried on a USB drive and run on a machine that has no config of its own, or someone else's.

The wezterm.lua filenames are not leftovers either: they let an existing WezTerm config be dropped into ThinkTerm's own directory without renaming it.

What ThinkTerm takes from a WezTerm install ​

Your WezTerm config file is not loaded. None of the locations above point at ~/.config/wezterm/wezterm.lua, and ThinkTerm never writes to it.

The separation is not total, though, and two paths are worth knowing about.

WEZTERM_CONFIG_FILE is honoured. It sits in the search order above, so if that variable is exported in your environment — as it may well be if that is how you set WezTerm up — ThinkTerm loads the file it names. WezTerm also sets it in every terminal it opens, so a ThinkTerm started from a shell inside WezTerm loads WezTerm's config. Set THINKTERM_CONFIG_FILE, or unset the WezTerm one, to keep the two installations apart.

WezTerm's config directory is still searched for Lua modules and colour schemes. ~/.config/wezterm/ and ~/.wezterm/ sit on the Lua package.path, and ~/.config/wezterm/colors/ is searched for colour schemes. So require 'mymodule' in a ThinkTerm config will find a module you wrote for WezTerm. It is the config file itself that is kept separate, not the whole directory.

Importing ​

Settings › Import brings in what another program on this computer already has: the settings of a WezTerm config, the folders your editors, coding agents and cmux have worked in, and the sessions of Herdr. Every import happens once — nothing stays linked to its source afterwards.

The page has three steps, Source, Review and Complete. The first lists the sources as cards, and Continue reads the one you chose. Back returns to the cards, and Import more on the last step starts over from them. WezTerm is always listed. Project folders appears only when ThinkTerm finds one of the supported editors, coding agents or cmux on this computer, and Herdr, which carries a Beta badge, is offered on macOS, Linux and Windows.

The first time ThinkTerm opens, its welcome page lists the same things when it finds them, each with a button that opens this page on that source's Review step — see Install.

Settings from WezTerm ​

The WezTerm card copies chosen settings out of an existing WezTerm config into ThinkTerm's. Afterwards the two files are independent, and a later change to the WezTerm file reaches ThinkTerm only if you import again.

It looks for the WezTerm config in these places and uses the first that exists:

  1. ~/.wezterm.lua
  2. $XDG_CONFIG_HOME/wezterm/wezterm.lua, or ~/.config/wezterm/wezterm.lua when XDG_CONFIG_HOME is unset
  3. wezterm/wezterm.lua under each directory in $XDG_CONFIG_DIRS — macOS and Linux only

WEZTERM_CONFIG_FILE plays no part here, though it does in ThinkTerm's own config search above.

Continue loads that file — it is Lua, so it runs as it would in WezTerm — and the Review step shows where the WezTerm config and ThinkTerm's own were found, then lists what the file sets that can be imported. Only settings the file sets itself are offered: one it leaves at WezTerm's default is not, so an import never writes WezTerm's defaults over ThinkTerm's. The first time, every one found is selected, with Select All and Clear beside the count. Fifteen settings can be imported:

color_scheme, window_background_opacity, macos_window_background_blur, inactive_pane_hsb, font, font_size, line_height, cell_width, default_prog, default_cwd, front_end, window_decorations, disable_default_key_bindings, keys, key_tables

That list bounds what the importer copies for you, not what ThinkTerm supports. Any other WezTerm option still works when written into a ThinkTerm config by hand.

Reload source reads the file again. It and Import Selected are greyed out when no WezTerm config was found, and Import Selected also when nothing is ticked. Import Selected writes the chosen values, as a plain Lua table, to ~/.config/thinkterm/imported_from_wezterm.lua. That file belongs to the importer: each import replaces it whole, so a change made in it is lost the next time. Make changes in your own config instead.

What happens next depends on whether you already have a ThinkTerm config in ~/.config/thinkterm/:

  • Without one, the import also creates ~/.config/thinkterm/thinkterm.lua, which loads the imported file and returns the result. Nothing more is needed.
  • With one — thinkterm.lua, or wezterm.lua — your file is left untouched, and the imported values do nothing until it loads them. Add this before the line that returns your config, where config is the table it returns:
lua
local imported = require 'imported_from_wezterm'
for key, value in pairs(imported) do
  config[key] = value
end

Anything assigned after the loop overrides the imported value.

A config kept anywhere else is not noticed. If yours is ~/.thinkterm.lua, the thinkterm.lua the import creates comes earlier in the search order and is loaded instead of it.

Project folders from editors, coding agents and cmux ​

The Project folders card, captioned From editors and coding agents, offers folders you have worked in. Three kinds of program feed it:

  • Editors. The folders that VS Code and the editors built on it have opened: VS Code, VS Code Insiders, Code - OSS, VSCodium and its Insiders build, Cursor, Windsurf, Antigravity, Kiro, Positron, Trae and Void. Each is looked for only in its own user-data folder. A multi-root workspace, which an editor records as a .code-workspace file rather than a folder, is skipped.
  • Coding agents. The folders Claude Code, Codex and Pi were started in, read from the session records each keeps: Claude Code's project list in ~/.claude.json, Codex's sessions under ~/.codex/sessions and Pi's under ~/.pi/agent/sessions.
  • cmux, on macOS. Each workspace's folder, and the folders of its terminals, from the session cmux saves to ~/Library/Application Support/cmux. They are dated by the last time cmux saved that session.

Only the folder paths and the dates they were last used come over. Nothing inside a folder is read, and neither is what was said in an agent's sessions.

The Review step lists the folders, the most recently used first, with a button per editor, agent or cmux to narrow the list. A folder used in the last 30 days starts ticked. One that is already a Project in the chosen Space reads Already in the sidebar and starts unticked. Add to chooses the local Space they go into — the one Settings was opened from, when that is local — and each ticked folder becomes a Project with one Thread. A line under the list counts the folders that were opened over SSH, in WSL or in a container, which cannot be added yet.

Sessions from Herdr ​

The Herdr card imports one Herdr session into a new Space named Herdr — <session>. Each Herdr workspace becomes a Project holding one Thread, with that workspace's tabs and panes. It is marked Beta. ThinkTerm looks for sessions in Herdr's config folder, ~/.config/herdr or $XDG_CONFIG_HOME/herdr, and on Windows %APPDATA%\herdr unless XDG_CONFIG_HOME is set: the default session, and each one under sessions/.

Continue reads the sessions. If there is one, its preview opens at once; with several, each has a Preview button, and a session already imported carries an Imported badge. The preview, headed Review your import, names the new Space, counts its Projects, primary tabs and terminals, and lists each Project's terminals. Refresh preview reads the session again. If the session's structure, running state or saved layout changes after the preview, the import stops and asks for a refresh first. Importing a session that was imported before warns you, because it creates another Space.

Herdr's own files are left unchanged, so starting Herdr again can restore its old layout and resume what it had saved.

Which of two modes applies depends on whether the session is running:

Running sessionSaved layout
ButtonMove running sessionImport layout
What it doesMoves the session's terminals into ThinkTerm; the existing processes keep runningOpens fresh shells in the saved directories
Not carried overFull scrollback and images. A full-screen program may need a redrawSaved launch commands and agent resume commands are not run
NeedsHerdr's live_handoff capability, and a compatible protocol versionThe saved directories to exist, in a layout format this ThinkTerm understands

On Windows, Herdr cannot hand over running terminals, so only Import layout is there: it reads the layout Herdr saves a few seconds after each change, whether or not Herdr is running, and brings over its tabs, splits and folders, each pane with a fresh shell. That is the shell chosen in Settings › Terminal › Default Shell, else default_prog when it names a shell, else the command processor. Herdr can stay open, and what runs in it is left alone.

The import is refused, with the reason shown, when a requirement is not met. Both modes need the session to belong to your account and its directory to be accessible. A running session also needs Herdr and ThinkTerm to share the temporary directory, the sockets and the ThinkTerm executable, and on Linux /tmp must not be mounted noexec.

With Spaces on remote servers, Which machine to import from lists This computer and each of those hosts; a host that is not connected connects when chosen. Importing from a remote host reads that server's Herdr, and the processes stay on that server. The session must belong to the remote connection's account.

If the connection drops during an import, the page offers Check import result, which reconnects and recovers the outcome of that request. Use it rather than starting a second import. When the import finishes, Open Space opens the new Space.

Where the data lives ​

macOS

  • Config file — ~/.config/thinkterm/
  • Workspace data — ~/Library/Application Support/ThinkTerm/
  • Terminal state — ~/Library/Application Support/thinkterm/
  • Cache — ~/Library/Caches/thinkterm/
  • Runtime — ~/.local/share/thinkterm/

Linux

  • Config file — ~/.config/thinkterm/
  • Workspace data — ~/.local/share/ThinkTerm/
  • Terminal state — ~/.local/share/thinkterm/
  • Cache — ~/.cache/thinkterm/
  • Runtime — $XDG_RUNTIME_DIR/thinkterm/

Windows

  • Config file — %USERPROFILE%\.config\thinkterm\
  • Workspace data — %APPDATA%\ThinkTerm\
  • Credentials — %LOCALAPPDATA%\ThinkTerm\ssh\
  • Terminal state — %APPDATA%\thinkterm\
  • Cache — %LOCALAPPDATA%\thinkterm\
  • Runtime — ~/.local/share/thinkterm/

Four things above are easy to trip over.

The config path does not follow platform convention. ~/.config/thinkterm/ is used on every operating system, Windows included — it is not %APPDATA%. Config and data therefore live apart on every platform, Linux included, where the config sits under ~/.config and the data under ~/.local/share.

Two data directories differ only in case. Workspace data — the Space, Project and Thread structure, snippets, and on Unix the SSH host book and its encryption key — is written to ThinkTerm/. Terminal and multiplexer state goes to thinkterm/. On macOS and Windows the filesystem is case-insensitive by default, so the two normally collapse into a single directory — on a case-sensitive APFS volume they do not. On Linux they are always separate. Both belong to ThinkTerm wherever they land.

On Windows, credentials are kept out of the roaming profile. The SSH host book and its encryption key are not in %APPDATA% with the rest of the workspace data; they live under %LOCALAPPDATA%, so that a domain sign-out does not copy them to a profile server. An older install's copies are moved there as a pair the first time ThinkTerm needs them. The browser listener's certificate and private key are kept there for the same reason.

The runtime directory does not follow convention either. The multiplexer socket, the pid file and the TLS material live in $XDG_RUNTIME_DIR/thinkterm/ on Linux, and fall back to ~/.local/share/thinkterm/ on macOS and Windows — a .local/share path on two platforms that otherwise have nothing there. It is worth knowing when thinkterm cli cannot find a server.

A Notes Vault is not stored in either. It is a directory you choose, holding ordinary Markdown files; ThinkTerm records only the binding to it.

Data carried over from WezTerm ​

When WezTerm's data directory exists — ~/Library/Application Support/wezterm/ on macOS, ~/.local/share/wezterm/ on Linux, %APPDATA%\wezterm\ on Windows — ThinkTerm copies four things from it into its own terminal-state directory as it starts:

ItemWhat it is
pluginsThe Lua plugins wezterm.plugin.require has fetched
recent-commands.jsonThe command palette's recent commands
recent-emoji.jsonThe character selector's recent picks
repl-historyThe debug overlay's Lua history

Each is copied only while ThinkTerm has none of its own, so in practice it happens once, and it never overwrites anything. WezTerm's copies stay where they are, and nothing else in that directory is read.

Backing up and restoring ​

Settings › Backup exports ThinkTerm's own state to a folder you choose, and brings it back from one. Nothing is backed up unless you export it.

An export creates a folder named ThinkTerm Backup followed by the date and time. It holds plain JSON files, listed in a thinkterm-backup.json beside them:

FileHolds
workspace_threads.jsonSpaces, Projects and Threads
ssh_hosts.jsonThinkTerm's own SSH host book
snippets.jsonSnippets
recent-commands.jsonRecent commands

The Spaces are written from what ThinkTerm holds in memory, so the export has what is on screen even if the last save has not reached the disk. On macOS and Linux each file is written with mode 0600.

secret.key is deliberately left out. Saved passwords travel in the host book still encrypted with this machine's key, so on another machine they have to be entered again. The Lua config, settings.json and a Notes Vault are not included either; they are ordinary files to copy as you would any other.

An import cannot swap those files under a running window, which holds them in memory and would write them back. So it checks every file of the backup first, then waits: it is applied by the next launch that finds no other ThinkTerm window running, before anything reads the state, and the page offers Quit ThinkTerm to get there. Each file it replaces is kept beside the original as <name>.before-import-<time>.json. If any file cannot be put in place, the ones already replaced get back what they had, so a failed import changes nothing; the failure is shown on the Backup page and is not retried.

One thing is merged rather than replaced. Spaces that the local session server still holds are added back the next time ThinkTerm connects to it, with the server's names winning where both have one. An import brings back what the backup holds; it does not remove what the server kept.

Interface language ​

Settings › General › Language changes the language of ThinkTerm's own interface immediately, with no restart. Follow System takes it from your system settings and shows which language that resolved to.

The interface ships in English, Simplified Chinese, Japanese, French, German and Russian. This covers ThinkTerm's own chrome only — terminal content, and everything WezTerm renders, is unaffected.

Command names follow the language too: in the command palette, on the macOS menu bar and on the Keymap page. The menu bar is rebuilt the moment you switch. The palette remembers what you run by its English name, so its recents survive a change of language, and an English word still finds a command through the menu it sits in.

On macOS, Chinese needs PingFang, a font that macOS downloads on demand. When this Mac reads Simplified Chinese before Japanese or Korean and has no PingFang, ThinkTerm draws Han characters, CJK punctuation and kana in Hiragino Sans GB, which ships with macOS, so that characters used only in Simplified Chinese are not drawn as empty boxes. Settings › General › Language then adds a note under the row saying so: download PingFang SC in Font Book and restart ThinkTerm to use it. Where PingFang is installed, or this Mac does not read Simplified Chinese first, Hiragino Sans GB only draws Han characters that no other font has.

Renderer ​

Settings › General › Renderer chooses between OpenGL and WebGpu for the terminal windows and the Settings window. Unlike the language, it takes effect the next time ThinkTerm starts. Left unchosen, it follows front_end in the config file, which is OpenGL on Windows and WebGpu everywhere else unless you set it — so those are the defaults, and OpenGL or Software there means OpenGL.

One of them failing is not fatal. When the renderer in force cannot start — no usable WebGpu adapter, or an OpenGL too old to run ThinkTerm's shaders — the window opens on the other one instead, and the Settings window does the same, so a machine where only one of them works is not locked out of the very control that would switch it. Only when both fail does the window not open. front_end = 'Software' never falls back.

Cursor ​

Settings › Terminal › Display has two rows for the cursor.

Cursor shape is Block, Bar or Underline. Block, the default, leaves the shape to default_cursor_style in the config file, which is a block unless it says otherwise. Bar and Underline replace the shape the config file gives and keep its blink.

Cursor blink is Off, Smooth or Hard. Off, the default, leaves the cursor as the config file has it: steady, unless default_cursor_style asks for a blinking one. Smooth and Hard make the cursor blink. Smooth fades it in and out along the curve of cursor_blink_ease_in and cursor_blink_ease_out; Hard switches it between fully on and fully off, whatever those say. Each phase lasts cursor_blink_rate, which is 600 ms unless you set it.

A program that sets its own cursor style, as an editor does when it changes modes, keeps it. Both choices reach every open window at once, without reloading the config.

The update check ​

The desktop app looks for a new release by itself, and Settings › Software Update has two rows for it: Check Automatically, a switch, and Check Frequency, which offers Every 12 hours, Daily and Weekly and is greyed out while the switch is off. Until you use a row, it follows the config file, check_for_updates for the switch and check_for_updates_interval_seconds for the frequency; once you have used it, the row wins and the file's option is no longer read. A change applies within a minute, without a restart.

A check is due once the frequency has passed since the last one on record, whichever check that was — one you started with Check for Updates counts. So a weekly check stays weekly across launches: a few seconds after ThinkTerm starts it checks only if that long has gone by. Last Checked shows when. With the switch off, ThinkTerm looks only when you press Check for Updates. Updates covers the rest of the flow, and Privacy and Security what the request carries.

Restoring pane contents ​

When ThinkTerm's terminals stop in an orderly way — you quit ThinkTerm with its terminals inside it, the computer shuts down or you log out, or the session server is stopped — ThinkTerm can keep what each pane showed and put it back the next time that Thread's layout is restored. Settings › General › Restore pane contents is the switch.

It is on by default on the machine the desktop app runs on: the app turns it on as it starts, unless it has been set either way, and turning it off is written down so that it stays off. It covers this computer's terminals only. On another machine, such as a remote host, it is off until you run thinkterm cli restore-output on in a terminal there; restore-output off turns it off again and deletes what was kept, and restore-output status says which it is.

What is kept is each local pane's main screen and its scrollback, as text and colours, up to 10,000 rows. The frame of a full-screen program, and images, are not kept. Before anything is written, whatever looks like a password, a token or a private key is replaced with •, so the original never reaches the disk. The records sit in kept-output, in the terminal-state directory listed below. One is removed as soon as its layout is back, and after 15 days if the Thread is never reopened.

A restored pane shows the old output above its new shell, then a dim line, ── closed … · restored … ──, with both times, and the shell starts under it. It is the old output, not the old process: nothing that was running starts again.

A crash or a power cut leaves no time to save, so those bring the layout back without the output.

Folder access on macOS ​

A Project is bound to a folder, and macOS decides whether ThinkTerm may read it. When access is refused, the Project page says so and points at System Settings › Privacy & Security › Files and Folders › ThinkTerm.

Two details are specific to ThinkTerm.

The Project context menu offers Grant Folder Access…. It runs the same picker as the blocked page, then opens the Project's first Thread, so the grant is proved end to end rather than assumed.

The session server asks under its own name. When local terminals run in a background session server, that daemon carries its own macOS privacy identity, so the permission it needs is not necessarily the one you already granted to the GUI. If the refusal came from the server, the page says so and offers to open System Settings at the right place.

A refused folder is an error rather than a silent fallback. Earlier builds dropped back to the home directory without saying anything, which meant the refusal never reached the interface and could never be granted.

THINKTERM_NO_PRIVACY_DISCLAIM in the environment skips the step that gives the daemon that separate identity.

Permissions on macOS ​

macOS counts every program you run in ThinkTerm's terminals as ThinkTerm. Settings › Permissions, a page that exists on macOS only, reports four permissions those programs can have: Full Disk Access, Screen & System Audio Recording, Microphone and Camera. Each row reads Allowed, Not allowed, Denied, Not asked yet or Unknown, and its Open System Settings button opens the matching pane of System Settings. Looking never makes macOS ask you anything. Microphone and camera read Not asked yet until a program first wants one. Full Disk Access and screen recording cannot be told from never having been asked, so they read Not allowed.

Full Disk Access carries a warning of its own. Once it is allowed, any program in a terminal — scripts and coding agents included — can read and write Desktop, Documents, Downloads, Mail and other apps' data without macOS asking again. Turn it on only when you need it, and off in System Settings when you are done. It also has to be added by hand: click + in System Settings and drag the program into the list.

Which program that is depends on where local terminals run. With them kept in the background session server, which is the default, the permissions are the server's own, and the last row is headed ThinkTerm Background Service; otherwise it is ThinkTerm. A permission allowed for one is not the other's, which is why a folder you allowed for ThinkTerm may need allowing again. The row's button reveals the program in Finder. Privacy and Security explains why the prompts name ThinkTerm.

Sounds, notifications and the Dock count ​

The Notifications card on Settings › Workspaces has up to three ways to be told about a Thread: Notification Sounds, System Notifications and, on macOS only, Dock Icon Count, which puts on ThinkTerm's Dock icon the number of Threads that have something you have not looked at yet. All three are on by default.

Under each is a choice of moments, Finished, Needs You and Error, all ticked until you take one out. Taking Finished out of Notification Sounds silences the sound for a finished Thread and leaves the one for a wait; the other two work the same way. The Dock count includes a Thread that is Done only while Finished is ticked, and one that needs attention only while Needs You or Error is ticked for what it is waiting on. Agent Status describes the states and the sounds, and Privacy and Security what a system notification carries.

The option reference ​

Almost every option is WezTerm's, unchanged, so the reference for them is upstream:

Three caveats.

ThinkTerm forked WezTerm on 31 March 2026, so options added upstream after that date may not exist here yet.

Some options keep their names and meanings but not their defaults; they are listed below.

And ThinkTerm adds options of its own, which upstream does not document:

OptionControls
agent_status_detectionWhether session status detection runs
web_serversThe browser listeners a multiplexer opens when it starts. See Web
ui_colorsThe colours of ThinkTerm's own interface. colors remains the terminal's palette. See Interface colours
remote_mux_auto_claim_on_openWhether connecting to a remote host on purpose takes control of its terminal at once
note_spellcheck_enabledSpell check in the Markdown editor
note_remote_images_enabledLoading images from remote URLs in notes
note_reading_max_widthThe widest a note's text column grows, in logical pixels (points on macOS). 820 by default; in a wider Notes area the column is centred
right_sidebar_search_respects_gitignoreWhether file search skips ignored files. The file tree still shows them
unfocused_fpsHow often a visible but unfocused window repaints for terminal output. 10 by default; 0 turns the limit off
kitty_image_memory_budget_mibHow much image data each pane may keep, in MiB. 128 by default; 0 means unlimited. See The Window
live_overview_preview_refresh_msHow often a Live Overview card re-reads its terminal. 300 by default

text_min_contrast_ratio is upstream's option, but Settings › Terminal › Minimum text contrast sits over it: a ratio chosen there wins, and Off leaves the config file's value in charge.

Plugins are not configured in the Lua file. See Plugins.

Defaults that differ from WezTerm ​

These options mean what upstream says, but start from a different value when the config file leaves them unset:

OptionWezTermThinkTerm
front_endOpenGLWebGpu, but OpenGL on Windows
initial_cols80120
initial_rows2432
max_fps60120
default_cwdunsetyour home folder
native_macos_fullscreen_modefalsetrue
color_scheme, on macOSunsetApple System Colors, when colors is not set either
adjust_window_size_when_changing_font_size, on macOSunsetfalse
cursor_blink_rate800600
command_palette_font_size1413

default_cwd matters when a terminal has nothing else to go on — no directory of its own and none reported by the terminal it opened from. It then starts in your home folder rather than in whatever directory ThinkTerm itself was started from. With adjust_window_size_when_changing_font_size off, changing the font size keeps the window's size and changes how many rows and columns fit in it.

Two more are worked out from the terminal's palette when unset. The inactive-pane dimming, inactive_pane_hsb, is lighter on a light colour scheme than on a dark one rather than always the same, and the pane divider colour is blended out of the terminal background. Set them explicitly and they behave exactly as upstream documents.

The colour scheme can also be decided in Settings rather than in the file; see Where Settings and the config file overlap.

Interface colours ​

ui_colors overrides the colours ThinkTerm draws around the terminal — the sidebars, the tab bar, the strips above the panes, the Settings window, the menus. Every slot is optional, and one left unset keeps the colour the theme would have used, so a table that names two colours changes two colours:

lua
config.ui_colors = {
  sidebar_bg = '#282828',
  accent = '#d79921',
}

Colours are written as they are anywhere else in the config file. The slots:

GroupSlots
Surfaceswindow_bg (behind everything), sidebar_bg, workspace_sidebar_bg (a recessed sidebar ground; the page list in Settings), header_bg (the strip above the tabs), card_bg (a card on window_bg), group_bg (rows grouped inside a card), separator
Controlscontrol_bg, control_hover_bg, control_pressed_bg, control_border, track_off (the off half of a switch)
Sidebarsidebar_button_bg, sidebar_button_hover_bg, sidebar_row_hover_bg, sidebar_row_pressed_bg, sidebar_row_active_bg, sidebar_row_active_border
Selection and accentselected_bg, selected_text, accent, accent_hover, on_accent (text and icons on the accent), danger (destructive actions and errors)
Texttext, secondary_text, muted_text
Otherscrollbar_thumb (the overlay scrollbar), spelling_error (the underline under a misspelling)

Under Follow terminal colours the surfaces and text move onto the terminal's background, but accent, accent_hover, on_accent, selected_bg, danger and spelling_error keep their designed values: a scheme's own blue is often hard to read on that scheme's background. Set them here if you want them to match.

Environment variables ​

Every terminal ThinkTerm starts has these set:

VariableValue
THINKTERM1
THINKTERM_VERSIONThe ThinkTerm version
TERM_PROGRAM, TERM_PROGRAM_VERSIONWezTerm and the version. Kept so tools that recognise WezTerm keep working; test THINKTERM to tell ThinkTerm apart
WEZTERM_PANEThe pane's id, which thinkterm cli uses as its default pane
WEZTERM_UNIX_SOCKETThe multiplexer socket, when ThinkTerm has one
THINKTERM_MUX_SERVER_IDWhich multiplexer the pane runs in. thinkterm tui uses it to refuse attaching to the server it is itself running inside
THINKTERM_CONFIG_FILE, WEZTERM_CONFIG_FILEThe config file that loaded, when one did
THINKTERM_CONFIG_DIR, WEZTERM_CONFIG_DIRThe directory it loaded from

And ThinkTerm reads these:

VariableEffect
THINKTERM_CONFIG_FILE, WEZTERM_CONFIG_FILEThe config file to load. See the search order
THINKTERM_DISABLE_SOUNDSet to anything, silences the notification sounds whatever Settings says
THINKTERM_UPDATE_TOKENA GitHub token the update check sends, to lift the anonymous rate limit. A GITHUB_TOKEN in the environment is never sent. See Updates
THINKTERM_NO_PRIVACY_DISCLAIMSkips the separate macOS privacy identity of the session server. See Folder access on macOS
THINKTERM_TUI_CONFIGWhere thinkterm tui reads its settings. See TUI
WEZTERM_LOGLog filtering, as in WezTerm
  • The Window — what the Appearance and Terminal pages change on screen
  • Keyboard and Commands — the command palette and its Settings page
  • Remote — the host book, and keeping local terminals in a session server
  • Plugins — what plugins add and where they are switched
  • Updates — check_for_updates and the rest of the update flow
  • Privacy and Security — what ThinkTerm sends over the network, and when