Skip to content

androsovm/NightShift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

46 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NightShift

Every backlog has that pile of tasks nobody gets to. Missing tests, stale docs, TODO comments from 2024, a small feature that's been "next sprint" for three months. Important enough to track, never urgent enough to do.

I wanted Claude Code to just... do them. While I sleep. The machine is on anyway -- why should Claude sit idle all night?

NightShift pulls tasks from your issue tracker (GitHub Issues, YouTrack, Trello, or just a YAML file), feeds them to Claude Code one by one, runs quality gates on the result, and opens draft PRs. You wake up, review the PRs over coffee, merge the good ones.

That's it. You sleep, robots work.

nightshift
  NIGHTSHIFT   next run in 5h 12m   4 pending  2 projects   |   last: 3βœ“ 1βœ—

β”Œβ”€ TASK QUEUE ────────────────┬─ TASK DETAIL ──────────────────────┐
β”‚ ── ACTIVE (2) ──────────── β”‚ Title:    Security audit           β”‚
β”‚ ● [high] Security audit     β”‚ Project:  myapp                    β”‚
β”‚ β—‹ [med]  Resolve TODOs      β”‚ Category: builtin                  β”‚
β”‚ ── BUILT-IN (1) ────────── β”‚ Frequency:once                     β”‚
β”‚ Β· [low]  Update docs weekly β”‚ Priority: ● high                   β”‚
β”‚ ── INACTIVE (1) ────────── β”‚ Intent:   Audit the codebase for   β”‚
β”‚ β—‹ [med]  Write missing testsβ”‚           common security issues...β”‚
β”œβ”€ PROJECTS ──────────────────── RUN DETAIL ───────────────────────│
β”‚ myapp   ~/Projects/myapp    β”‚ Run 20260322  03:00  6m 47s        β”‚
β”‚ api     ~/Projects/api      β”‚ βœ“ Fix imports         2m 10s       β”‚
β”‚                             β”‚ βœ“ Remove dead code    1m 17s       β”‚
β”‚                             β”‚ βœ— Add type hints      3m 20s       β”‚
β”‚                             β”œβ”€ RUN HISTORY ───────────────────────│
β”‚                             β”‚ 20260322  3/22 03:00  2βœ“ 1βœ—  6m    β”‚
β”‚                             β”‚ 20260321  3/21 03:00  4βœ“ 0βœ—  8m    β”‚
β”‚                             β”‚ β–β–ƒβ–…β–‡β–ˆβ–…β–ƒ pass rate                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ [q] Quit [t] Add [x] Toggle/Remove [r] Run [s] Sync [m] Model  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

How it works

  1. You label issues in GitHub/YouTrack/Trello with any tag you choose (or write tasks in YAML)
  2. nightshift sync pulls them into a local queue
  3. At 3 AM (or whenever you set it), NightShift wakes up and for each task:
    • creates a branch
    • runs baseline tests
    • hands the task to Claude Code
    • checks the result against quality gates (blast radius, linter, test regression)
    • opens a draft PR if everything passes
  4. You review the PRs in the morning

Every change goes through quality gates before a PR is created. If Claude breaks tests or touches too many files -- the task fails, no PR is opened, you see the details in the dashboard.

Installation

# Requires Python 3.13+, uv recommended
uv tool install .

# Or for development
git clone https://github.com/androsovm/NightShift.git
cd NightShift
uv sync --extra dev

Prerequisites

Quick Start

nightshift init          # interactive setup wizard
nightshift doctor        # verify environment
nightshift               # open TUI dashboard
nightshift run --dry-run # preview what would happen
nightshift run           # let it rip

The setup wizard walks you through 5 steps: pick your projects, configure task sources, set safety limits, add API tokens, choose a schedule. You can go back at any step.

TUI Dashboard

Run nightshift with no arguments. Everything is a keystroke away:

Key Action
t Add a built-in task (docs, tests, lint, etc.)
x Toggle active/inactive for source tasks, remove built-in tasks
m Change model for selected task
p Cycle task priority (low β†’ medium β†’ high)
r Run selected task
R Run all pending tasks
e Retry a failed task
s Sync tasks from sources
d Run doctor health check
j/k Navigate lists
Tab Switch panels
? Help
q Quit

The task queue is split into three sections:

  • Active β€” source-received and manual tasks in the execution queue
  • Built-in β€” template-based tasks with a frequency: once, weekly, or monthly. Recurring tasks auto-requeue after their interval upon successful completion
  • Inactive β€” tasks you've deferred with [x]. They won't run until reactivated. Press [x] again to move them back to Active

Built-in Task Templates (WIP)

Don't want to write tasks from scratch? Press [t] in the TUI -- pick a template, project, model, and frequency (once / weekly / monthly). Still a work in progress, more templates coming:

Template What it does
docs Update README, docstrings, inline comments
tests Write unit tests for uncovered code paths
types Add type annotations to functions
lint Fix all ruff/eslint/flake8 warnings
todos Implement TODO/FIXME comments
dead-code Remove unused imports, functions, files
deps Update minor/patch dependency versions
security Audit for OWASP top-10 vulnerabilities
refactor Simplify functions >50 lines

Each template comes with a pre-filled intent, scope, and constraints so Claude gets a clear, focused assignment.

Configuration

Global config (~/.nightshift/config.yaml)

schedule:
  time: "03:00"
  timezone: Europe/Berlin
  max_duration_hours: 4
projects:
  - path: /home/user/projects/myapp
    sources: [yaml]
max_prs_per_night: 10

Project config (.nightshift.yaml in project root)

sources:
  - type: github
    repo: user/myapp
    labels: [nightshift]

limits:
  max_tasks_per_run: 5
  task_timeout_minutes: 45
  max_files_changed: 20
  max_lines_changed: 500

default_model: claude-sonnet-4-6

# Inline YAML tasks
tasks:
  - id: remove-dead-code
    title: Remove dead code in utils.py
    intent: Find and remove unused functions
    scope: [src/utils.py]
    priority: medium

Writing a good task

The more context you give Claude, the better the result. Here's a task with all the fields:

tasks:
  - id: add-health-endpoint
    title: Add /healthz endpoint
    priority: high
    model: claude-sonnet-4-6
    estimated_minutes: 20
    intent: |
      Add a GET /healthz endpoint that returns {"status": "ok", "version": "..."}
      reading the version from pyproject.toml. Include a test that checks
      the response status and JSON schema.
    scope:
      - src/api/routes.py
      - tests/test_routes.py
    constraints:
      - Do not add new dependencies
      - Follow the existing route registration pattern in routes.py
      - Version must be read at import time, not on every request
  • intent -- what to do and why. Be specific.
  • scope -- which files Claude should focus on. Keeps changes contained.
  • constraints -- what NOT to do. Surprisingly important for good results.

Secrets (~/.nightshift/.env)

API tokens stored with chmod 600:

GITHUB_TOKEN=ghp_...
YOUTRACK_TOKEN=perm:...
TRELLO_KEY=...
TRELLO_TOKEN=...

Task Sources

Source Filter On completion
YAML tasks: in .nightshift.yaml, status: pending Sets status to done
GitHub Issues label: nightshift, state: open Closes issue + comment with PR link
YouTrack tag: nightshift Removes tag + posts comment
Trello list: "NightShift Queue" Moves card to "Done"
Built-in Added via TUI [t] with frequency (once/weekly/monthly) Once: removed. Weekly/monthly: auto-requeued

Safety

NightShift is paranoid by design:

  • Draft PRs only -- never pushes to main, never merges anything. You always have the final say.
  • Quality gates -- blast radius limits (max files/lines changed), linter checks, test regression detection. If anything looks off, the task fails and no PR is created.
  • Claude Code runs with --dangerously-skip-permissions -- required for unattended operation. Only run on repositories you trust.
  • Tokens stored in ~/.nightshift/.env with chmod 600. Never logged, never committed.

CLI Commands

Command Description
nightshift Launch TUI dashboard
nightshift init Interactive setup wizard
nightshift add Add a project to existing config
nightshift sync Import tasks from configured sources
nightshift run [--dry-run] [-p PROJECT] Execute a run
nightshift status Show latest run results
nightshift log [N] Run history / task details
nightshift tasks list Show task queue
nightshift tasks add Add a task manually
nightshift doctor Environment health check
nightshift install Set up scheduled runs (launchd/systemd)
nightshift uninstall Remove scheduled runs

Writing a Plugin

NightShift supports third-party task sources via Python entry points.

# nightshift_jira/source.py
from nightshift.models.config import SourceConfig
from nightshift.models.task import Task

class JiraSource:
    async def fetch_tasks(self, project_path: str, config: SourceConfig) -> list[Task]:
        # ... fetch from Jira API
        return tasks

    async def mark_done(self, task: Task, pr_url: str) -> None:
        # ... transition issue, post comment
        pass
# In your plugin's pyproject.toml
[project.entry-points."nightshift.sources"]
jira = "nightshift_jira.source:JiraSource"
# .nightshift.yaml
sources:
  - type: jira
    options:
      url: https://mycompany.atlassian.net
      project_key: PROJ

Sleep Prevention

For NightShift to run on schedule, the machine must stay awake overnight.

  • macOS: System Settings > Energy > Options > "Prevent automatic sleeping when the display is off". Or: sudo pmset -c disablesleep 1
  • Linux: systemctl mask sleep.target suspend.target

nightshift doctor will warn if sleep prevention is not configured.

Development

git clone https://github.com/androsovm/NightShift.git
cd NightShift
uv sync --extra dev
uv run pytest

License

MIT

About

Make the robots work at night

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages