Nightshift has three primary layers:
src/cli.py: local command interface (nightshift ...).src/server.py: FastAPI server and dashboard/API bridge.src/runner.py+src/task_queue.py: execution loop and persistence.
- A run is started via CLI (
nightshift start ...) or API (POST /start). NightshiftRunnercreates a run in sqlite and generates task rows.- Tasks are prioritized (
SmartPrioritizer) and executed in order. - Agent calls are sent through
OpencodeAgentClient. - Findings/errors are persisted in sqlite and rendered into reports.
- Report and diff artifacts are written under
~/.nightshift/reports.
- Database:
~/.nightshift/nightshift.db(orNIGHTSHIFT_DATA_DIRoverride). - Core tables:
runstasks(scoped byrun_id)findings
Run scoping is important: status, reports, and diffs should query by run context to avoid cross-run leakage.
Order of precedence:
- Explicit command/API arguments
- Environment variables
config.toml(~/.nightshift/config.tomlby default)- Built-in defaults
Key config behavior is implemented in src/config.py.
src/model_manager.py resolves the failover chain by:
- Taking configured preferred models.
- Discovering currently available OpenCode models (
opencode models). - Keeping preferred models that exist.
- Falling back to a ranked discovered chain when needed.
src/dashboard.html is a static UI served from / by FastAPI.
It polls /status, /models, /reports, and /schedules.