This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Build
cargo build
# Run tests (uses nextest for faster parallel execution)
cargo nextest run
# Run a single test
cargo nextest run test_name
# Lint (check)
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
# Lint (fix)
cargo fmt --all
cargo clippy --fix --allow-dirty --allow-staged --all-targets --all-features -- -D warnings
# Full CI pipeline (lint + build + test)
mise run ci
# Install dev build and start supervisor with debug logging
mise run install-dev
# Render CLI docs (requires mise and usage tool)
mise run renderPitchfork is a daemon supervisor CLI with a client-server architecture:
- CLI (
src/cli/) - User-facing commands that communicate with the supervisor via IPC - Supervisor (
src/supervisor.rs) - Background daemon that manages all child processes - IPC (
src/ipc/) - Unix domain socket communication using MessagePack serialization
- CLI commands connect to the supervisor at
~/.local/state/pitchfork/ipc/main.sock - If supervisor isn't running, CLI auto-starts it in background
- Supervisor spawns and monitors daemons, handles retries, cron scheduling, and autostop
- State persisted to
~/.local/state/pitchfork/state.tomlwith file locking for concurrency
| File | Purpose |
|---|---|
src/supervisor.rs |
Main supervisor logic, IPC handlers, background watchers |
src/ipc/ |
Client/server IPC with MessagePack over Unix sockets |
src/pitchfork_toml.rs |
Config file parsing and merging |
src/state_file.rs |
Persistent state management |
src/daemon.rs |
Daemon struct and state |
src/cli/start.rs |
Main "start daemon" command logic |
- Interval watcher (10s): Refresh process state, autostop, retry failed daemons
- Cron watcher (60s): Trigger scheduled tasks based on cron expressions
Configs merge in order (later overrides earlier):
/etc/pitchfork/config.toml(system - namespace: global)~/.config/pitchfork/config.toml(user - namespace: global).config/pitchfork.tomlfiles from filesystem root to current directory (project).config/pitchfork.local.tomlfiles from filesystem root to current directory (project)pitchfork.tomlfiles from filesystem root to current directory (project)pitchfork.local.tomlfiles from filesystem root to current directory (project)
| Source | Pipeline | Outputs |
|---|---|---|
settings.toml |
build/generate_settings.rs (compile-time) |
Settings struct + merge/meta Rust code; also docs/settings.data.ts → SettingsTable.vue → docs/reference/settings.md |
| Rust clap + schemars | mise run render: pitchfork usage → usage tool; pitchfork schema |
docs/cli/*.md + docs/cli/commands.json (CLI reference); docs/public/schema.json (JSON Schema for editor autocomplete) |
Update rules:
- Changing user settings (
src/settings.rs) → updatesettings.toml(sole source of truth for codegen) - Changing CLI flags/args/help text (clap) or config struct (schemars) → run
mise run renderto regeneratedocs/cli/,docs/public/schema.json, andpitchfork.usage.kdl
These files are generated and should not be manually edited:
docs/cli/*.mddocs/cli/commands.jsondocs/public/schema.jsonpitchfork.usage.kdl
Partially generated (hand-authored prose + auto-populated component):
docs/reference/settings.md— only the<SettingsTable />section is auto-generated fromsettings.toml; the surrounding prose may be edited by hand.
- Async/Tokio: All I/O is async; use
tokio::select!for concurrent operations - Error handling: Use
miette::Resultfor rich error messages - Serialization: Heavy use of serde with TOML for config/state, MessagePack for IPC
- File locking: Always lock state file for concurrent access (
xx::fslock) - Daemon commands: Prepend
execto eliminate shell process overhead
All commit messages and PR titles MUST follow conventional commit format:
Format: <type>(<scope>): <description>
Types:
feat:- New features that affect the pitchfork CLI/applicationfix:- Bug fixes that affect the pitchfork CLI/application (not CI, docs, or infrastructure)refactor:- Code refactoringdocs:- Documentation changesstyle:- Code style/formatting (no logic changes)perf:- Performance improvementstest:- Testing changeschore:- Maintenance tasks, releases, dependency updates, CI/infrastructure changessecurity:- Security-related changes
Scopes:
- For command-specific changes, use the command name:
start,stop,status,logs,run, etc. - For subsystem changes:
supervisor,ipc,config,state,daemon,cron,deps
Description Style:
- Use lowercase after the colon
- Use imperative mood ("add feature" not "added feature")
- Keep it concise but descriptive
Examples:
fix(supervisor): handle graceful shutdown on SIGTERMfeat(start): add --restart-policy flagfeat(cron): support timezone-aware schedulingdocs: update configuration exampleschore: release 0.2.0chore(ci): fix linting in CI pipelinechore(deps): update dependencies
When posting comments on GitHub PRs or discussions, always include a note that the comment was AI-generated (e.g., "This comment was generated by Claude Code.").