Skip to content

Configuration Reference

github-actions[bot] edited this page Apr 26, 2026 · 5 revisions

Configuration Reference

Canonical schema for .tuckrc.json (shared) and .tuckrc.local.json (host-local). For the motivating story on why there are two files, see Host Groups — Defaults.

Where config lives

tuck loads config from three layers, in order:

  1. Built-in defaults (see defaultConfig in the source)
  2. ~/.tuck/.tuckrc.json — shared, committed to the repo
  3. ~/.tuck/.tuckrc.local.json — host-local, gitignored

Each layer's values win over the layer before. The local file has a strict schema that only accepts a small set of host-specific fields — anything else is rejected, so you can't accidentally commit host state by writing to the wrong file.

Editing

Two ways:

  • tuck config — interactive menu (no arg) or dotted-path get/set (tuck config set repository.autoPush true). Automatically writes host-specific fields to .tuckrc.local.json and everything else to .tuckrc.json. Pass --local to force-route to .tuckrc.local.json for any local-schema-allowed key (e.g. tuck config set --local hooks.preSync 'echo go'); shared-only keys like repository.autoCommit are rejected with a clear error when --local is set. Refuses reserved key names (__proto__, constructor, prototype) at every dotted-path segment.
  • Hand-edit the JSON — direct edit either file. Run tuck doctor --category manifest after to catch schema violations before they bite.

See Command Reference — tuck config.

Shared .tuckrc.json schema

All fields optional. Values shown are defaults.

repository

{
  "repository": {
    "defaultBranch": "main",
    "autoCommit": true,
    "autoPush": false
  }
}
Field Type Default Purpose
defaultBranch string "main" Default git branch for the ~/.tuck/ repo
autoCommit boolean true Whether tuck sync auto-commits detected changes
autoPush boolean false Whether tuck sync auto-pushes after committing

files

{
  "files": {
    "strategy": "copy",
    "backupOnRestore": true
  }
}
Field Type Default Purpose
strategy "copy" | "symlink" "copy" How tracked files are mirrored. See File strategies.
backupOnRestore boolean true Snapshot tracked files before tuck restore / tuck apply overwrites them. Strongly recommended.

defaultGroups

{
  "defaultGroups": ["work-laptop"]
}

Array of host-group names auto-applied when -g is omitted on any group-aware command. Usually lives in .tuckrc.local.json (per-host), NOT the shared file. See Host Groups.

readOnlyGroups

{
  "readOnlyGroups": ["kali", "work-mac-loaner"]
}

Array of host-group names whose members refuse write-side commands (sync, push, add, remove) with HostReadOnlyError. See Host Groups — Consumer-host mode.

snapshots

{
  "snapshots": {
    "maxCount": 50,
    "maxAgeDays": 30
  }
}
Field Type Default Purpose
maxCount integer 50 Keep at most this many snapshots. 0 disables the count dimension.
maxAgeDays integer 30 Delete snapshots older than this. 0 disables the age dimension.

Both disabled (both 0) = no pruning. See Time Machine & Undo.

hooks

{
  "hooks": {
    "preSync":     "echo 'about to sync'",
    "postSync":    "notify-send 'tuck: sync done'",
    "preRestore":  "",
    "postRestore": "source ~/.zshrc"
  }
}

Four hook types. Each is a shell command (sh/bash on Unix, pwsh on Windows) run in the ~/.tuck/ cwd with a few env vars passed through. Full reference in Hooks.

validation

{
  "validation": {
    "preSync": false
  }
}
Field Type Default Description
preSync boolean false When true, run tuck validate against every tracked file at the start of tuck sync. Findings are reported inline; the sync continues regardless (warn-only).

Opt-in only. Default keeps tuck sync paying zero validation cost. When enabled, the sweep runs after secret-scanning and before any file writes — broken JSON / YAML / shell parses get surfaced before they land in your git history. Users who want hard-blocking can wire tuck validate --format json into a hooks.preSync hook instead (see Hooks). See also tuck validate.

ignore

{
  "ignore": ["~/.cache", "~/.local/share"]
}

Array of paths that tuck scan and tuck add skip automatically. Prefer the .tuckignore file (use tuck ignore add <path>) for path-based ignores — this config field is for programmatic setups. See Command Reference — tuck ignore.

categories

{
  "categories": {
    "custom": {
      "patterns": ["~/.config/my-tool/*"],
      "icon": "🔧"
    }
  }
}

Dictionary mapping category name → { patterns, icon? }. Adds custom categories on top of the built-in set (shell, git, editors, terminal, ssh, misc). patterns are globs matched against source paths during tuck scan.

ui

{
  "ui": {
    "colors": true,
    "emoji": true,
    "verbose": false
  }
}
Field Type Default Purpose
colors boolean true ANSI colors in output
emoji boolean true Unicode emoji / icons in prompts
verbose boolean false Enable debug-level logging

chalk's NO_COLOR=1 env var is also honored regardless of this setting.

remote

{
  "remote": {
    "mode": "github",
    "username": "you",
    "repoName": "dotfiles",
    "url": "git@github.com:you/dotfiles.git",
    "providerUrl": "https://gitlab.mycompany.com"
  }
}
Field Type Default Purpose
mode "github" | "gitlab" | "local" | "custom" "local" Provider
url string (none) Custom git URL (for custom mode, or manual override)
providerUrl string (none) Provider instance URL (self-hosted GitLab)
username string (none) Cached username from the provider
repoName string (none) Repo name without owner

See Git Providers for per-provider setup.

security

{
  "security": {
    "scanSecrets": true,
    "blockOnSecrets": true,
    "minSeverity": "high",
    "scanner": "builtin",
    "customPatterns": [],
    "excludePatterns": [],
    "excludeFiles": [],
    "maxFileSize": 10485760,
    "secretBackend": "local",
    "cacheSecrets": true,
    "secretMappings": "secrets.mappings.json"
  }
}

Full reference in Security & Secrets.

encryption

{
  "encryption": {
    "enabled": false,
    "backupsEnabled": false,
    "gpgKey": "0xABCDEF12",
    "files": ["~/.ssh/config"]
  }
}

Optional GPG-based encryption for specific tracked files and/or backup snapshots. Defaults off. If you enable it, set gpgKey to a key identifier that's in your GPG keyring — tuck won't generate a key for you.

Local .tuckrc.local.json schema

Strict — only these fields allowed. Anything else is a schema error.

{
  "defaultGroups": ["kali"],
  "hooks": {
    "postRestore": "sed -i 's|snippet.toml|snippet-kali.toml|' ~/.config/pet/config.toml"
  }
}
Field Type Purpose
defaultGroups string[] Per-host group tags auto-applied when -g is omitted
hooks { preSync?, postSync?, preRestore?, postRestore? } Per-host hook overrides. Each hook type merged independently with the shared hook of the same name.

The strict schema exists to stop "I thought I was editing the local file but really wrote to the shared one" leaks. If you try to add repository.autoPush to .tuckrc.local.json, it's rejected with a clear error — because auto-push behavior is a repo-wide policy, not per-host.

Use tuck config set --local <key> <value> to write any local-schema-allowed key (e.g. hooks.preSync) without hand-editing the file. --local validates against the strict schema above, so the same shared-only keys that would be rejected on hand-edit are also rejected on the CLI.

See Host Groups — Defaults for the load-order + merge rules.

File strategies

copy (default)

Files are copied from source → repo when tracked, and repo → source when restored. Changes require a tuck sync to propagate either direction.

This is the safe default:

  • Edits to the source don't instantly land in git
  • You can preview changes via tuck diff before committing
  • Works on every platform without special permissions

symlink

tuck copies the file into the repo once, then replaces the source path with a symlink pointing at the repo copy. Edits go straight to git.

Pros:

  • No explicit sync needed for modifications — the repo is always current
  • Single source of truth

Cons:

  • Your home dotfile paths become symlinks; some tools (especially older editors, and a few shell features) don't love chasing them
  • Breakage if ~/.tuck/ is ever moved or renamed
  • On Windows, tuck uses directory junctions for folders and copies for files (symlink creation requires admin privileges on Windows — junctions don't)
  • tuck sync is mostly a no-op for symlinked files; nothing to copy. Commits still capture repo-side git operations.

Switch per-file: tuck add ~/.zshrc --symlink. Switch the default in config.

See also

Clone this wiki locally