Skip to main content

Project Settings

Per-project settings that override global defaults, including the override-vs-inherit pattern, project environment variables, worktree setup, and the background resource-management systems.

Updated
Reviewed

Project settings override global defaults on a per-project basis. To reach them, open the scope switcher dropdown in the sidebar header and select Project. The option only appears when a project is open. For the app-wide defaults these layer on top of, see Global Settings.

Tip
The dialog remembers your last-active tab in each scope independently. Switching between Global and Project returns you to whatever tab you were last viewing in that scope.

The override-vs-inherit pattern

Most project settings have a global default behind them. The override-vs-inherit pattern is how Daintree shows you whether the field you're looking at uses the global value or its own override.

When a project setting overrides the global default, a small blue dot appears next to the label and the input gets a thin blue rim. Hover the row and a Reset to global button appears. When the setting inherits, the description below the input goes italic and shows the inherited value. Clearing an overridden field reverts it to inherited.

Note
Clearing an overridden field reverts it to inherited, so you don't have to click Reset to global explicitly. The button mainly earns its keep when the global value itself is empty and you want the field to read as inherited rather than blank.

General (project)

Set the project display name, emoji, color, and custom SVG icon. Configure the dev server URL and load timeout. Turn in-repo settings on or off; when on, it writes project configuration to a .daintree/ directory in the project root (specifically .daintree/project.json and .daintree/settings.json).

Context

Control what content goes into the context Daintree builds from your project:

  • Excluded Paths using gitignore-style patterns
  • Copy Tree Settings for context size limits, file size limits, and include/exclude patterns

Variables (project)

The Variables tab defines KEY=VALUE pairs that Daintree injects into every new terminal session spawned in this project. That gives each project an isolated environment without touching your shell configuration or .env files. Use it for project-specific API endpoints, feature flags, tool configuration, or any value your agents and terminals need at runtime.

Variables are scoped to the project, not individual worktrees. Every worktree in a project shares the same set. Values stay local on your machine and are never written to .daintree/ files or committed to your repository, so each team member configures them separately. See Projects for more on project scope.

The editor splits into two blocks:

  • Inherited (Global): a read-only block at the top showing variables from the global Environment tab. Sensitive values display as ********. Each row carries a blue Global pill when it's inherited unmodified, or an amber Overridden pill when the project has its own value for that key.
  • Project: the editable block below, where you add, edit, and delete the project's own variables. A row that overrides an inherited key is visually linked back to the Inherited block.

Variable names must start with a letter or underscore and contain only letters, digits, and underscores. An invalid name shows an inline error on save. Duplicate names are flagged. Empty key rows are silently ignored. Changes apply on save and only affect new terminals; existing terminals keep the environment they spawned with until they're respawned.

Note
A Move N values out of shared settings action with a shield-alert icon means sensitive-looking keys (anything containing KEY, SECRET, TOKEN, or PASSWORD) are still sitting in .daintree/daintree.json, which is committable. Click the action to move them into the local-only sensitive store. They're still plaintext, just no longer in the file that gets committed.

Worktree Setup

Configure what happens when a new worktree is created in this project:

  • Run Commands executed in terminals on worktree creation
  • Default Worktree Recipe applied to new worktrees
  • Branch Prefix (none, username, or custom prefix)
  • Worktree Path Pattern overrides the global pattern for this project
  • Terminal settings for shell, shell arguments, working directory, and scrollback. Each uses the override-vs-inherit pattern described above.

See Worktrees for more on worktree configuration.

Recipes

Create, edit, and delete terminal recipes scoped to this project. See Recipes for the full guide.

Commands

Define project-specific /slash command overrides and aliases that layer on top of global commands. See Unified Input for details on the command system.

Notifications (project)

Override global notification settings on a per-project basis. Project overrides layer on top of global settings, so you can silence a noisy project or add extra alerts for a critical one.

See Notifications & Sound for the notification system reference.

Code Forge (project)

Pick which git remote Daintree uses for code-forge integration in this project, and optionally pin a specific provider regardless of hostname. Useful for a repo with multiple remotes where the default origin isn't the one you want for issues, PRs, and pulse data. Whatever you set here shows up as the Override badge on that remote in Code Forge › General › Active project routing.

Environment variables across scopes

There are three places in Daintree to set environment variables. They have different scopes and different editors, so it's worth knowing which one does what.

  • Global Environment tab (Terminal group): variables Daintree itself reads on launch. A key/value editor with explicit Save and Discard. Covered under Environment.
  • Project Variables tab (Project scope): variables injected into every terminal Daintree spawns for that project. Adds a read-only Inherited (Global) block above the editable rows. Covered above under Variables (project).
  • CLI Agents › per-agent › Runtime settings › Env block: per-agent variables that go into the agent's launch environment. The Default scope holds the agent's global env vars; a custom preset gets Env overrides that inherit from the Default scope until you promote an inherited row into an override. Covered under Presets and scopes.

The env-var editor

The CLI Agents env block uses Daintree's full env-var editor: a bordered table with Key, Value, and Actions columns. The per-row mechanics worth knowing:

  • Per-row left stripe: red on an empty key after blur, amber on a duplicate key or a value that looks like a secret, green when the row overrides an inherited entry
  • Eye toggle: appears on a row where the key matches Daintree's sensitive-name list or the value looks secret-like. It masks the value by default; reveal is session-scoped and resets when you reopen the dialog.
  • Key suggestion popover: the chevron next to the key cell opens an agent-specific list of recommended keys (e.g. ANTHROPIC_API_KEY for Claude). Arrow keys plus Enter to insert.
  • "Looks like a secret" advisory: when a value looks like a secret, an inline amber note reads "Looks like a secret — prefer ${ENV_VAR}". It's advisory only; the value still commits. The point is to nudge you toward referencing your shell environment instead of pasting the literal value.
  • Inherited rows: when the editor has an inherited set (a custom preset inheriting from the Default scope), inherited entries render as muted rows below the editable ones. A + Override button promotes a row to editable; once it's editable, the action button becomes Revert to inherited value. Clearing the value of an override on blur silently reverts it.
  • Import .env: opens the dialog below

Import .env

The Import .env button next to the env-var editor opens a two-step modal for pasting .env file contents.

Step 1: Paste. The textarea takes raw .env content. Keys must match [A-Za-z_][A-Za-z0-9_]*. Quoted values, comments, and export prefixes are supported. As you paste, a summary line below the textarea reads "N variables detected · M conflicts · K new · D duplicate keys in paste (last value kept)". Parse errors render as an amber callout listing the offending lines. The primary button reads Import N variables when there are no conflicts, and Review N conflicts when there are.

Step 2: Conflict resolution. Shown only when at least one pasted key already exists in the editor. Two radio options: Keep existing ("Only add new keys — leave colliding values untouched") or Overwrite conflicts ("Replace colliding values with the pasted ones"). Below the radios, a scrollable diff list shows each conflicting key with the old value in strikethrough, an arrow, and the new value in accent color. The primary button reads Import, keep existing or Import, overwrite conflicts depending on your selection. Resolution is binary across the whole import; you can't pick per-key.

Terminal env filter

Separately from your configured variables, Daintree filters the inherited shell environment before it spawns any terminal process. This keeps credentials from your shell out of agent and terminal sessions.

The filter strips variables that match a built-in blocklist of common credential names (such as ANTHROPIC_API_KEY, DATABASE_URL, GITHUB_TOKEN, AWS_SECRET_ACCESS_KEY, and others), plus any variable whose name contains credential-related keywords like SECRET, PASSWORD, TOKEN, PRIVATE_KEY, or CREDENTIAL at word boundaries.

The filter is hardcoded and not user-configurable. Variables in the DAINTREE_* namespace are always stripped from inheritance and re-injected fresh by Daintree itself. Your project-configured environment variables bypass the filter entirely, since they're intentional configuration rather than inherited credentials. For the full mechanism, see Security & Privacy.

Note
Variable values are injected verbatim. Expansion syntax like $HOME or ${PATH} is not supported inside the editor. If your shell RC file (e.g. ~/.zshrc) unconditionally exports the same variable, the shell value wins over the injected one. Project environment variables are also not injected into worktree lifecycle scripts (setup and teardown commands in .daintree/config.json).

Automatic Resource Management

Note

The systems in this section run entirely in the background. There are no user controls for them. They're documented here so you know what Daintree is doing on your behalf. For a troubleshooting-angle treatment of the resource systems, see Performance.

Adaptive Resource Profiles

Every 30 seconds, Daintree evaluates several system signals: its own memory usage, whether you're on battery power, the number of active agents, plus thermal pressure, CPU speed limiting, and low system-wide available memory. Those signals produce a pressure score that selects one of three internal profiles: Performance, Balanced, or Efficiency. For how Efficiency decides between destroying and freezing cached project views, see Session Management. This system is also covered from a troubleshooting angle at Performance.

The Balanced profile matches Daintree's standard behavior. Performance mode speeds up polling and allows more WebGL contexts for terminal rendering. Efficiency mode slows background polling and hibernates idle projects more aggressively (after 15 minutes of inactivity instead of 30). This internal hibernation is distinct from the user-configured Auto-hibernation in Settings > General, which runs on a separate timer measured in hours and isn't triggered by memory pressure.

Profile transitions are rate-limited to avoid oscillation. Upgrading to a less restrictive profile takes 90 seconds of sustained lower pressure. Downgrading to a more restrictive profile takes 30 seconds of sustained higher pressure. There is no UI indicator showing which profile is active.

Memory Pressure Mitigation

Separately from resource profiles, Daintree watches per-process memory and responds in two escalating tiers when an individual process exceeds its threshold. This system is also covered from a troubleshooting angle at Performance.

Tier 1 fires immediately when memory pressure is detected. Daintree clears internal caches, releases hidden webviews, and trims terminal state. Tier 2 fires after three consecutive pressure intervals and hibernates idle projects. A 10-minute cooldown prevents repeated hibernation of the same projects.

Disk Space Monitoring

Every 5 minutes, Daintree checks free space on the application data volume (not necessarily your system drive). Two thresholds trigger notifications:

  • Warning (below 500 MB): a toast notification appears for 8 seconds. If Daintree isn't focused, a native OS notification is sent as well.
  • Critical (below 100 MB): a persistent toast stays visible until you free space. Session backups and terminal snapshots are paused automatically so they stop consuming disk, and resume once space is available.

Notification cooldown is 30 minutes to avoid repeated alerts, though a transition from warning to critical always notifies immediately. This system is also covered from a troubleshooting angle at Performance. For broader troubleshooting steps, see Troubleshooting.

Sleep Prevention

While any agent is running, Daintree prevents the system from suspending the app. That keeps CPU and network active so a long-running agent task finishes without interruption. The display can still dim or turn off normally.

Sleep prevention releases automatically when all agents finish. A 4-hour safety cap releases the blocker even if agent state tracking hits a problem.

PTY Host Resource Governor

The terminal host process has its own resource guard. If the PTY host heap exceeds 85% of its limit, all terminal output is throttled. Output resumes when the heap drops below 60% or after 10 seconds, whichever comes first. You may notice a brief pause in terminal output during a high-volume burst. That's expected behavior, not a bug. This system is also covered from a troubleshooting angle at Performance.