*.swp
*.swo
.DS_Store
node_modules/

# Python
__pycache__/
*.pyc
*.pyo
.coverage

# IDE
.idea/
.vscode/

# Claude local state (worktrees, sessions, etc.)
.claude/

# Jekyll (docs site)
docs/_site/
docs/.jekyll-cache/
docs/.jekyll-metadata
docs/vendor/
docs/Gemfile.lock

# Backup of old config system
bkp/

# Operator-specific config — ship only the .example. The real file
# contains personal chat_id, private repo list, and local paths.
config/orchestrator.yaml

# Historic local artifact — not consumed by ctrlrelay itself. Keeps a
# local list of repos to clone; no reason to track it publicly.
repos.manifest


# Lock file — not committed per AInvirion Python-SDK convention.
uv.lock

# Operator-private notes (runbooks, personal cheatsheets).
notes/

# Rendered service unit files. `ctrlrelay install launchd|systemd`
# substitutes CTRLRELAY_TELEGRAM_TOKEN into a copy of the in-package
# template and writes it to the system path (~/Library/LaunchAgents on
# macOS, ~/.config/systemd/user on Linux). The default install command
# never lands a rendered file inside the repo, but a future flag — or
# an operator running it with --target-dir pointed at the working tree —
# would. Defense-in-depth so a `git add .` after such a slip can't
# scoop the literal token into a commit.
*.plist
*.service
