Install
$ agentstack add skill-tommylower-cortex-nightcap ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
nightcap
A stdlib-only Python script that turns raw agent transcripts into a narrative journal. Every night (or on demand) it:
- discovers recent sessions:
~/.claude/projects/*/*.jsonl(skippingagent-*subagent files) and~/.codex/sessions/**/rollout-*.jsonl, filtered by file mtime within a lookback window (default 3 days) - parses each transcript down to user/assistant text, filtering noise (command wrappers, system reminders, environment context). grabs cwd (first-seen wins, since cwd can drift mid-session), timestamps, model, and the session title
- applies a substance filter: a session needs ≥2 user messages and ≥200 user chars, or 1 message ≥1500 chars. one-shot trivia never gets journaled
- condenses to ~24k chars (user messages truncated at 700, assistant at 400, middle trimmed)
- summarizes via
claude -pinto 1-3 first-person paragraphs in the owner's voice, using whichever model is configured (opus by default) - writes one markdown entry per session and records it in
/.state.jsonso nothing is journaled twice. failed summaries stay pending and retry next run
Filenames are YYYY/YYYY-MM-DD-HHMM--.md, keyed on session start time. Nice side effect: duplicate transcripts from resumed sessions collapse into one entry.
A NIGHTCAP-SUMMARIZER sentinel leads the summarizer prompt and is in the noise filters, so nightcap never journals its own headless runs.
entry format
# 2026-06-10 — Integrate GitHub repository as a skill
- date: 2026-06-10, 15:18 to 15:31
- agent: Claude Code (claude-opus-4-8)
- project: `/Users/you/dev/somerepo`
- chat: `claude --resume (from /Users/you/dev/somerepo)`
- transcript: `~/.claude/projects/.../.jsonl`
1-3 paragraphs of first-person narrative: tone and energy, the kind of
thinking (debugging, designing, planning), what the session was actually
about, and how the agent helped.
The chat: line is a working resume command (claude --resume / codex resume ), so every entry links back to the live conversation.
setup
If you are an agent setting nightcap up for someone, ask them two things before scheduling: their voice (or derive it from how they write) and their model. Nightcap runs on any model the claude CLI accepts:
opus— best narrative quality and voice adherence. the defaultsonnet— balanced quality and costhaiku— cheapest and fastest, for heavy session volume; expect looser voice adherence- or any full model ID
Write the choice into the model key of the config.
# 1. try it
scripts/nightcap.py --dry-run # list what would be journaled
scripts/nightcap.py --limit 1 # write one entry to check the voice
# 2. personalize (optional but recommended)
mkdir -p ~/.config/nightcap
cp assets/config.example.json ~/.config/nightcap/config.json
# then edit: your name, speaker label, voice rules, journal location, model
# 3. schedule nightly (macOS launchd, 23:30 or next wake)
SCRIPT="$(pwd)/scripts/nightcap.py"
sed -e "s|__SCRIPT_PATH__|$SCRIPT|g" -e "s|__HOME__|$HOME|g" \
assets/local.nightcap.plist > ~/Library/LaunchAgents/local.nightcap.plist
launchctl load ~/Library/LaunchAgents/local.nightcap.plist
On Linux, schedule the same command with cron or a systemd timer instead.
configuration
~/.config/nightcap/config.json (or --config , or NIGHTCAP_CONFIG env var). Every key is optional:
| key | default | meaning | | --- | --- | --- | | journal_dir | ~/notes/agent-journal | where entries and .state.json live | | name | the user | who the journal belongs to; the summarizer writes as this person | | speaker_label | USER | label for your lines in the condensed transcript (use your first name) | | voice | plain understated prose | stylistic rules for the narrative (casing, punctuation, tone) | | model | opus | model for claude -p --model. any model the CLI accepts (opus, sonnet, haiku, or a full model ID) | | claude_bin | found on PATH | explicit path to the claude CLI if it isn't on launchd's PATH |
Structural rules are fixed regardless of voice: first person, past tense, 1-3 short paragraphs, no headers, no lists, no invented specifics.
usage
scripts/nightcap.py # sweep now
scripts/nightcap.py --dry-run # preview pending sessions
scripts/nightcap.py --days 7 # widen the lookback window
scripts/nightcap.py --limit 3 # cap entries written this run
Journal entries are personal: keep journal_dir out of any public repo (gitignore it if it lives inside one).
troubleshooting
- no entries written: check
--dry-runoutput. sessions already in.state.jsonor below the substance thresholds are skipped silently - summarizer failures: the run logs to stderr (
~/Library/Logs/nightcap.logunder launchd) and retries those sessions next sweep - wrong or missing claude CLI under launchd: set
claude_binin the config, launchd's PATH is minimal - entries in the wrong voice: edit
voicein the config; the next sweep uses it (already-written entries are not rewritten)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: tommylower
- Source: tommylower/cortex
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.