https://github.com/recusive/nightshift
Autonomous overnight codebase improvement agent for Claude Code. Run it before bed, wake up to production-ready fixes.
https://github.com/recusive/nightshift
ai-agent anthropic automation claude claude-code code-quality developer-tools overnight-agent production-readiness skill
Last synced: 3 months ago
JSON representation
Autonomous overnight codebase improvement agent for Claude Code. Run it before bed, wake up to production-ready fixes.
- Host: GitHub
- URL: https://github.com/recusive/nightshift
- Owner: Recusive
- License: mit
- Created: 2026-04-02T23:56:14.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-03T03:20:36.000Z (3 months ago)
- Last Synced: 2026-04-03T10:43:51.576Z (3 months ago)
- Topics: ai-agent, anthropic, automation, claude, claude-code, code-quality, developer-tools, overnight-agent, production-readiness, skill
- Language: Shell
- Homepage:
- Size: 557 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Nightshift
Your overnight engineer. Autonomous. Thorough. Ready by morning.
Run it before bed. Wake up to a reviewed worktree, a shift log, and a machine-readable record of what the agent actually did.
---
## About
Nightshift is an overnight codebase-hardening runner built by **[Recursive Labs](https://github.com/Recusive)** as part of the [Orbit](https://github.com/Recusive/Orbit-Release) ecosystem.
The original version relied mostly on prompt discipline. This version adds a real control plane:
- a Python orchestrator (the `nightshift/` package)
- pluggable agent adapters (Codex and Claude — pick one, both go through the same pipeline)
- machine-readable shift state (`docs/Nightshift/YYYY-MM-DD.state.json`)
- runner-enforced guard rails, verification gates, and halt conditions
---
## What It Does
Nightshift runs in an isolated git worktree and repeatedly asks an agent to:
1. read the current repo instructions and shift log
2. find a small production-readiness improvement
3. fix it or log it
4. verify it
5. record it
The runner enforces the difference between a productive overnight shift and 8 hours of churn.
### Runner-enforced guard rails
- Max `3` fixes per cycle
- Max `5` files per fix
- Max `12` files touched per cycle
- Max `4` low-impact fixes per shift
- Blocked edits for CI/deploy/infra/generated files and lockfiles
- Hot-file protection via recent git activity
- Halt after repeated failed verification or empty cycles
- Worktree must end clean after every accepted cycle
- Each fix commit must include the shift log update
### Output artifacts
- `docs/Nightshift/YYYY-MM-DD.md` — human-readable shift log
- `docs/Nightshift/YYYY-MM-DD.state.json` — machine-readable cycle state
- `docs/Nightshift/YYYY-MM-DD.runner.log` — raw runner output
- `nightshift/YYYY-MM-DD` — isolated review branch
---
## Architecture
```
Main repo checkout Nightshift worktree
├── untouched ├── agent edits happen here
├── no branch switching ├── isolated nightshift/YYYY-MM-DD branch
└── receives copied logs └── verification happens after each cycle
```
### Key files
| File | Purpose |
|------|---------|
| `nightshift/` | Python package — orchestrator, policy engine, verifier, state manager |
| `nightshift/types.py` | TypedDicts for all data structures (strict typing) |
| `nightshift/constants.py` | DATA_VERSION, DEFAULT_CONFIG, SHIFT_LOG_TEMPLATE, etc. |
| `nightshift/errors.py` | NightshiftError |
| `nightshift/shell.py` | run_command, run_capture, git, command_exists, run_shell_string |
| `nightshift/config.py` | merge_config, resolve_agent, infer_package_manager, infer_verify_command |
| `nightshift/state.py` | read_state, write_json, load_json, append_cycle_state, top_path |
| `nightshift/worktree.py` | ensure_worktree, ensure_shift_log, sync_shift_log, revert_cycle, cleanup_safe_artifacts |
| `nightshift/cycle.py` | build_prompt, command_for_agent, verify_cycle, evaluate_baseline, extract_json |
| `nightshift/cli.py` | run_nightshift, summarize, verify_cycle_cli, build_parser, main |
| `nightshift.schema.json` | Required final-response schema for agent cycles |
| `pyproject.toml` | Project config: mypy strict, ruff lint/format, pytest |
| `requirements-dev.txt` | Pinned dev tool versions (mypy, ruff, pytest) |
| `scripts/check.sh` | Local CI — runs all checks (mirrors GitHub Actions) |
| `.github/workflows/ci.yml` | CI pipeline: lint, typecheck, test, integration, artifact validation |
| `nightshift/SKILL.md` | Interactive nightshift skill instructions |
| `scripts/run.sh` | Thin wrapper around `python3 -m nightshift run` |
| `scripts/test.sh` | Thin wrapper around `python3 -m nightshift test` |
| `.nightshift.json.example` | Optional per-repo config template |
---
## Install
### One-liner
```bash
curl -sL https://raw.githubusercontent.com/Recusive/Nightshift/main/scripts/install.sh | bash
```
This installs Nightshift into both:
- `~/.codex/skills/nightshift`
- `~/.claude/skills/nightshift`
### Repo setup
Add runtime artifacts to `.gitignore`:
```bash
cat <<'EOF' >> .gitignore
docs/Nightshift/worktree-*/
docs/Nightshift/*.runner.log
docs/Nightshift/*.state.json
EOF
```
Optional: copy the config template into the repo root:
```bash
cp ~/.codex/skills/nightshift/.nightshift.json.example .nightshift.json
```
---
## Config
Nightshift looks for `.nightshift.json` in the repo root.
Supported keys:
```json
{
"agent": "codex or claude",
"hours": 8,
"cycle_minutes": 30,
"verify_command": null,
"blocked_paths": [".github/", "infra/", "deploy/"],
"blocked_globs": ["*.lock", "package-lock.json"],
"max_fixes_per_cycle": 3,
"max_files_per_fix": 5,
"max_files_per_cycle": 12,
"max_low_impact_fixes_per_shift": 4,
"stop_after_failed_verifications": 2,
"stop_after_empty_cycles": 2,
"score_threshold": 3,
"test_incentive_cycle": 3,
"backend_forcing_cycle": 3
}
```
If `verify_command` is omitted, Nightshift tries to infer one from common repo manifests such as `package.json`, `Cargo.toml`, `go.mod`, and `pyproject.toml`.
---
## Usage
### Overnight run
```bash
~/.codex/skills/nightshift/scripts/run.sh # prompts for agent choice
~/.codex/skills/nightshift/scripts/run.sh --agent codex
~/.codex/skills/nightshift/scripts/run.sh --agent claude
~/.codex/skills/nightshift/scripts/run.sh 10 # 10 hours
~/.codex/skills/nightshift/scripts/run.sh 6 45 # 6 hours, 45 min per cycle
```
If no `--agent` flag is passed and `.nightshift.json` doesn't set one, the runner asks which agent to use.
### Short validation run
```bash
~/.codex/skills/nightshift/scripts/test.sh
~/.codex/skills/nightshift/scripts/test.sh --agent codex --cycles 2 --cycle-minutes 5
```
### Multi-repo run
```bash
python3 -m nightshift multi /path/to/repo1 /path/to/repo2 --agent codex
python3 -m nightshift multi /path/to/repo1 /path/to/repo2 --agent codex --test --cycles 2
```
Runs a full hardening shift on each repo sequentially. Validates all repos upfront, prints an aggregate summary at the end.
### Direct orchestrator usage
```bash
python3 -m nightshift run
python3 -m nightshift run --agent codex
python3 -m nightshift run --agent claude
python3 -m nightshift test
python3 -m nightshift multi /path/to/repo1 /path/to/repo2 --agent codex
python3 -m nightshift summarize
```
Both agents go through the same runner, same verification, same policy enforcement. The only difference is the CLI command each adapter constructs.
---
## Morning Review
```bash
cat docs/Nightshift/2026-04-02.md
cat docs/Nightshift/2026-04-02.state.json
git log nightshift/2026-04-02 --oneline
git merge nightshift/2026-04-02
git worktree remove docs/Nightshift/worktree-2026-04-02
git branch -d nightshift/2026-04-02
```
The shift log is for humans. The state file is for quick auditing:
- how many cycles ran
- which categories were touched
- which files changed
- whether verification passed
- why the run stopped
---
## Requirements
- Python 3.9+
- Git
- `codex` CLI or `claude` CLI (whichever agent you choose)
---
## Roadmap
- [x] Pluggable agent adapters (Codex, Claude)
- [x] Runner-enforced guard rails
- [x] Structured cycle outputs and state files
- [x] Post-cycle diff scoring before accepting a fix
- [x] Cycle-to-cycle state injection
- [x] Test writing incentives
- [x] Backend exploration forcing
- [x] Validated against real monorepo (Phractal)
- [ ] Smarter category balancing
- [ ] Loop 2: Feature Builder (plan, decompose, build, test)
- [ ] Built-in to Orbit as a native feature
---
## License
MIT