Read-only session-start briefing of open tasks, git state, journal todos — reports, never edits code. Use when user says spin up, what was I doing, or pick up where I left off.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add laurigates/claude-plugins --skill session-spinup --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Session Spinup?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/laurigates-session-spinup)More formats (shields.io, HTML) on the badges page.
---
name: session-spinup
description: Read-only session-start briefing of open tasks, git state, journal todos — reports, never edits code. Use when user says spin up, what was I doing, or pick up where I left off.
allowed-tools: Bash(bash *), Read, TodoWrite
created: 2026-05-13
modified: 2026-08-25
compatibility: claude-code
reviewed: 2026-06-24
---
# session-spinup
Read-only orientation at session start — the inverse of
`session-plugin:session-wrap`: where wrap writes loose threads, spinup
reads them back. The failure mode this prevents: the user sits down,
doesn't remember what was open, and starts fresh on something else while
yesterday's PR sits stale.
The deterministic work — project detection, the survey, GitHub-issue
dedup against taskwarrior, staleness, journal extraction — is done by
`scripts/session-survey.sh` (shared with session-wrap, session-end, and
the spinup nudge hook). This skill runs that collector once, then applies
**judgment**: filter the digest to what matters and suggest next moves.
## When to Use This Skill
| Use this skill when... | Use alternative when... |
|------------------------|------------------------|
| User says "spin up", "what was I doing", "pick up where I left off" | Resuming a TDD cycle on known state → `project-plugin:project-continue` |
| Fresh session opens with open threads (hook-nudged) | Cross-project queue health → `taskwarrior-plugin:task-status` |
| Orienting before picking the next move | Unfamiliar codebase orientation → `project-plugin:project-discovery` |
## Configuration
Same file as the other session skills: `.claude/session-plugin.local.md`
(project) → `~/.claude/session-plugin.local.md` (user-global) → none.
When `journal` is configured and the session matches `journal_scopes`,
pass the journal flags to the collector so the briefing includes
unchecked todos from the most recent dated note. Schema:
[session-wrap/REFERENCE.md](../session-wrap/REFERENCE.md).
## The signal filter
The collector gathers everything; **you** surface only what the user
would otherwise miss — 3-6 item target, 10+ means trim.
**SURFACE**: open PR from a recent branch (especially review/CI-stale) ·
`+ACTIVE` task (work was mid-flight) · unchecked journal todo ·
real uncommitted edits · unpushed commits · a checkout behind upstream
(`BEHIND` ≥ 1 — a caveat on the briefing's basis, not a task) · task
whose annotation reads
"blocked on X" where X may now be unblocked · GitHub drift issue (the
`GITHUB_DRIFT` section — assigned, open, untracked locally) · blueprint
tracker state when a tracker exists (ready/blocked counts, in-flight WOs)
· undrained closed WOs (`UNDRAINED_COUNT` ≥ 1 — the tracker lags reality;
a wind-down `/session-end` reconciles).
**DO NOT SURFACE**: completed tasks · merged PRs · closed issues ·
issues already represented by a surfaced task (the collector already
dedups these out of `GITHUB_DRIFT`) · recurring-reminder / dataview
machinery · weeks-stale tasks with no recent annotation (that's
`task-status`'s job) · `+ACTIVE` tasks from a *different* project
(the `STALE_ACTIVE_ELSEWHERE` section — at most one footnote line, never
a scope hijack) · the `BLUEPRINT` section when `MANIFEST=false` or
`TRACKER=false`.
## Context
- Project config: !`find . -maxdepth 2 -path '*/.claude/session-plugin.local.md'`
## Execution
Execute this read-only briefing:
### Step 1: Read config, then run the collector once
Read `.claude/session-plugin.local.md` (project, then `~/.claude/`
fallback) for the taskwarrior project-naming map and journal settings.
Then run the shared collector — it does detection, survey, dedup, and
staleness in one pass and emits a structured digest:
```sh
bash "${CLAUDE_SKILL_DIR}/../../scripts/session-survey.sh" --with-dedup --with-blueprint
```
Add `--project <name>` when the config naming map maps the cwd to a
project other than the repo basename. When the session is in journal
scope, add `--with-journal --journal-path <dir>` (plus
`--journal-todo-heading` / `--journal-todo-stop` if the config overrides
the defaults). The digest sections: `PROJECT`, `GIT`, `PRS`,
`TASKWARRIOR` (each task with its stable UUID + `STALE_DAYS`, plus
`TASK_SCOPE` / `PROJECT_CONFIDENCE` / `TASKS_ALL_PROJECTS` and the
`RECENT_TASK_*` fallback rows), `GITHUB_DRIFT`, `JOURNAL`, `BLUEPRINT`,
`STALE_ACTIVE_ELSEWHERE`.
### Step 1b: If `GH_READY=false`, fetch GitHub state via MCP instead
The `PRS` and `GITHUB_DRIFT` sections carry `GH_READY=`. When it is
`false` (no `gh` CLI or unauthenticated — the normal state in Claude
Code on the web), their zeros mean **not queried**, not "nothing open".
Do not present them as a clean state. Instead:
1. If GitHub MCP tools are available (`mcp__github__list_issues`,
`mcp__github__list_pull_requests` — load via ToolSearch if needed),
fetch the repo's open issues assigned to the user and open PRs
authored by them, then apply the same dedup the collector would
have: drop issues whose number appears as a task `ghid` UDA or as a
`#N` / `issues/N` token in the `TASKWARRIOR` section's descriptions
or annotations. Treat what survives as the `GITHUB_DRIFT` set.
2. If no GitHub path exists at all, the briefing's github line must say
`github: not queried (gh unavailable)` — never omit it silently.
`GH_FAIL_REASON=` says which of these you are in, so retry only where
retrying can work: re-run the collector once for `timeout` (raising
`SESSION_SURVEY_GH_TIMEOUT`), `api-error`, or `unknown`, quoting
`GH_FAIL_DETAIL=` (gh's first stderr line) if it fails again; go straight
to MCP for `auth` (`gh auth login` fixes the CLI path) and `no-cli`; and
for `no-remote` there is nothing to query at all, so say that rather than
reporting a gap. Full remediation table: `session-plugin:session-end`.
### Step 1c: If `PROJECT_CONFIDENCE=low`, do not claim a clean queue
The `TASKWARRIOR` section carries `TASK_SCOPE=` and
`PROJECT_CONFIDENCE=`. The project slug is detected from the repo
**directory basename** — a guess that is wrong for chezmoi source dirs,
worktrees, monorepo subdirs, portfolio checkouts, and repos cloned under
another name. Only `PROJECT_CONFIDENCE=high` licenses "nothing pending
under `project:<name>`". Otherwise:
| `TASK_SCOPE` | What to say / do |
|---|---|
| `remote-name` | The count is real but came from `PROJECT_RESOLVED=` — name **that** slug in the briefing, not the directory basename |
| `ancestor-name` | An **ancestor** repo's slug was adopted (`DETECTION=cwd-repo-basename-ancestor`); the count is real but belongs to `PROJECT_RESOLVED=` — name that slug, not the directory |
| `all-projects-fallback` | Never say the queue is clean. Present the `RECENT_TASK_*` rows as "recently touched (project scope unresolved)" with `TASKS_ALL_PROJECTS` as the denominator, and offer to re-run with `--project <name>` |
| `unknown` / `none` | State `taskwarrior: not queried` — `jq` or `task` was unavailable, so the zeros are unqueried |
`DETECTION=` names how the slug was chosen: `override` (`--project`), `declared`
(a `.claude/session.json` `.project` string), `cwd-repo-basename` (the guess),
`cwd-repo-basename-ancestor` (an adopted ancestor), or `ambiguous`.
Also independently of `TASK_SCOPE`: when `PROJECT_PREFIX_SIBLINGS=<slugs>`
and `PROJECT_PREFIX_SIBLING_TASKS=N` are present, other slugs share the
detected slug's **prefix** — which taskwarrior's own CLI filter
(`task project:<slug>`) would have swept in, making a wrong slug look
verified. Say `N under <slugs>` alongside the count and offer
`--project <slug>`; never present the scoped count as the whole picture.
`PROJECT_EXACT_TASKS=` is the slug alone, without its `.` subprojects.
Independently of `TASK_SCOPE`, when `PROJECT_AMBIGUOUS=<slug>` and
`PROJECT_AMBIGUOUS_TASKS=N` are present the detected slug owns **zero** tasks
while that ancestor slug owns N. Brief it as `0 here, N under <slug>` — never as
a clean queue, even at `PROJECT_CONFIDENCE=high` (a user-asserted `--project` or
a repo declaration deliberately keeps `high`).
A `RECENT_TASK_*` row carries no `ghid` / annotations / `+ACTIVE` flag —
it is a pointer, not a full task. Resolve the slug before acting on one.
### Step 2: Apply the signal filter
Cut the digest to the 3-6 things that matter, using the filter above.
The collector has already done the mechanical drops (dedup, cross-project
separation, staleness numbers); your job is the judgment calls — e.g. is
a "blocked on X" annotation now unblocked, is an 11-day-stale PR worth a
nudge.
### Step 3: Present
Compact briefing, one section per source, reflecting **only** the cwd
project. Say "git state: clean" / "nothing pending under `project:<name>`"
explicitly rather than omitting sections. A `STALE_ACTIVE_ELSEWHERE`
entry gets a single footnote line at the very end, never its own scope.
When the repo has a feature tracker, add one blueprint line —
`blueprint: 14 ready · 2 blocked · in flight: WO-031 · undrained: WO-045`
— omitting empty fragments; omit the line entirely when the tracker is
absent. Example briefing: [REFERENCE.md](REFERENCE.md).
### Step 4: Offer next moves
Suggest 2-4 concrete "next moves" and let the user pick — never
auto-resume a task or start a workflow. Spinup makes the open threads
visible; the user decides.
## Auto-surfacing
A SessionStart hook (`hooks/session-spinup-nudge.sh`) runs the same
collector in `--summary` mode and injects a one-time context note when a
fresh session opens with open threads. It offers; it never runs the
skill. Pre-silence:
`touch ~/.cache/claude-session-spinup-nudge/<session_id>`.
## Agentic Optimizations
| Context | Command |
|---|---|
| Full digest (detection + survey + dedup + staleness + blueprint tracker state) | `bash "${CLAUDE_SKILL_DIR}/../../scripts/session-survey.sh" --with-dedup --with-blueprint` |
| With journal todos | add `--with-journal --journal-path <dir>` |
| Override detected project | add `--project <name>` |
| Coarse counts only (hook shape) | add `--summary` |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!