---
title: "Workstation Configuration"
description: "Workstation dotfiles management via symlinks, fish shell setup with custom functions and tmux helpers, systemd user timers, and Claude Code integration overview."
type: context
domain: workstation
tags: [dotfiles, fish, starship, tmux, symlink, systemd, claude-code, workstation]
---

# Workstation Configuration

## Dotfiles Repository

- **Repo**: `cal/dotfiles` (private) on `git.manticorum.com`
- **Local path**: `~/dotfiles/`
- **Strategy**: Symlink — configs live in the repo, symlinked to their expected system paths

### What's tracked

| Category | Repo path | System path |
|----------|-----------|-------------|
| Fish shell | `fish/config.fish` | `~/.config/fish/config.fish` |
| Starship prompt | `starship.toml` | `~/.config/starship.toml` |
| Git config | `git/.gitconfig` | `~/.gitconfig` |
| Git global ignore | `git/ignore` | `~/.config/git/ignore` |
| SSH config | `ssh/config` | `~/.ssh/config` |
| Bash | `shell/.bashrc`, `shell/.bash_profile` | `~/.bashrc`, `~/.bash_profile` |
| Zsh | `shell/.zshrc`, `shell/.zshenv` | `~/.zshrc`, `~/.zshenv` |
| MangoHud | `mangohud/MangoHud.conf` | `~/.config/MangoHud/MangoHud.conf` |
| Zed editor | `zed/settings.json` | `~/.config/zed/settings.json` |
| Restic excludes | `restic/excludes.txt` | `~/.config/restic/excludes.txt` |
| VS Code | `vscode/settings.json`, `vscode/keybindings.json` | `~/.config/Code/User/` |
| Tmux | `tmux/.tmux.conf` | `~/.tmux.conf` |

### Secrets handling

API keys and tokens are **never** committed. Shell configs source secrets from separate untracked files:
- Bash: `~/.bash_secrets` (chmod 600)
- Zsh: `~/.zsh_secrets`

### Install / Uninstall

```bash
cd ~/dotfiles
./install.sh    # Backs up originals to ~/.dotfiles-backup/, creates symlinks
./uninstall.sh  # Replaces symlinks with standalone copies
```

Both scripts are idempotent.

### Adding a new config

1. Copy the file into the appropriate directory in `~/dotfiles/`
2. Add the mapping to the `LINKS` associative array in both `install.sh` and `uninstall.sh`
3. Run `./install.sh` to replace the original with a symlink
4. Commit and push

### Shell setup

Cal migrated from zsh to **fish + starship** (Feb 2026). Bash and zsh configs are retained for compatibility but fish is the primary interactive shell.

## Fish Functions & Aliases

Custom fish functions live in `~/dotfiles/fish/functions/` and are symlinked into `~/.config/fish/functions/`. Completions in `~/dotfiles/fish/completions/` → `~/.config/fish/completions/`.

### Config file (`~/.config/fish/config.fish`)

Abbreviations defined in `config.fish` (loaded interactively):
- `yolo` → `claude --dangerously-skip-permissions`
- `cddev` → `cd /mnt/NV2/Development`

### Tmux helpers

| Function | Usage | What it does |
|----------|-------|-------------|
| `tls` | `tls` | List tmux sessions (friendly "no sessions" message if none) |
| `tma` | `tma [name]` | Smart attach — auto-attaches if 1 session, lists if multiple, attaches to named session. Has tab completions for session names. |
| `tmn` | `tmn [name]` | Create new named session (defaults to current directory name) |
| `cc` | `cc [name]` | Launch Claude Code in a tmux session (named after directory). If already in tmux, creates/switches to a detached session. |

### Adding a new fish function

1. Create the function file in `~/dotfiles/fish/functions/`
2. Symlink it: `ln -s ~/dotfiles/fish/functions/myfunc.fish ~/.config/fish/functions/myfunc.fish`
3. Optionally add completions in `~/dotfiles/fish/completions/`
4. Commit and push the dotfiles repo

## Systemd User Timers

Timers running under `systemctl --user` on the workstation. Not tracked in dotfiles — managed by their respective projects.

### Claude Scheduled Tasks
Config: `~/.config/claude-scheduled/` | Skill: `~/.claude/skills/create-scheduled-task/SKILL.md`

| Timer | Schedule | Purpose |
|-------|----------|---------|
| `claude-scheduled@backlog-triage.timer` | Weekdays 09:15 | Triage open Gitea issues, prioritize, suggest focus |

Uses `claude-scheduled@.service` template unit. Add new tasks by creating a directory under `~/.config/claude-scheduled/tasks/` and a corresponding timer. See the skill for full instructions.

## Claude Code

See [claude-code-config.md](claude-code-config.md) for full details on config file locations, MCP server setup, hooks, and permissions.

Key files:
- `~/.claude.json` — MCP servers (n8n-mcp, gitea-mcp, tui-driver, kb-search)
- `~/.claude/settings.json` — permissions, hooks, env vars, plugins
- `~/.claude/skills/` — custom skill definitions
- `~/.claude/hooks/` — hook scripts (format-code.sh, notify-subagent-done.sh)

## Backups

Original files are backed up by `install.sh` to `~/.dotfiles-backup/<timestamp>/` before being replaced with symlinks. Multiple runs create separate timestamped backup dirs. Old backups can be cleaned up manually.
