Skip to content
Back to skills

Hyper Recap

ASecurity

Use at cycle completion to write a human-readable recap of what was built and why — "recap this cycle", "summarize what we built", "cycle recap", "write up what changed this cycle". Also when the user invokes /hyperclaude:hyper-recap. Claude-only — no Codex, no agent dispatch — runs after a plan is implemented and reviewed, and writes a recap to .hyperclaude/recaps/. Recaps ONE completed detailed plan / milestone archived under .hyperclaude/plans/done/. Distinct from /hyperclaude:hyper-memory...

  • 3 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
ai-agentsgobashnodecode-reviewgit

Works with

  • terminal

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add zeikar/hyperclaude --skill hyper-recap --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hyper Recap?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hyper Recap
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/zeikar-hyper-recap/badge)](https://www.skillsdirectory.com/skills/zeikar-hyper-recap)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hyper-recap
description: Use at cycle completion to write a human-readable recap of what was built and why — "recap this cycle", "summarize what we built", "cycle recap", "write up what changed this cycle". Also when the user invokes /hyperclaude:hyper-recap. Claude-only — no Codex, no agent dispatch — runs after a plan is implemented and reviewed, and writes a recap to .hyperclaude/recaps/. Recaps ONE completed detailed plan / milestone archived under .hyperclaude/plans/done/. Distinct from /hyperclaude:hyper-memory (durable knowledge extraction, not a one-cycle narrative).
---

# hyper-recap

Cycle-completion recap. An AI-run cycle leaves the codebase changed but the human out of the loop: the request, the judgments taken, the alternatives rejected, and the critic rounds are all in the AI's head or scattered across gitignored artifacts. That is cognitive debt — without a write-up a human can't reconstruct *why* and *how* the AI built what it built. This skill collapses one completed cycle into a single human-readable recap under `.hyperclaude/recaps/`.

**Claude-only — no Codex, no agent dispatch.** It joins the non-Codex-spawning set alongside `hyper-interview`, `hyper-memory`, and `hyper-setup`. It never calls the bridge and never dispatches an agent — it only reads `.hyperclaude/` artifacts + in-session context and writes one markdown file.

The recap unit is **ONE completed detailed plan / milestone** (a plan archived under `.hyperclaude/plans/done/`). Epic-level rollup across milestones is out of scope. This is **NOT a PR draft** — it explains the cycle to a human, it does not propose or format changes for merge.

## When to use

- User typed `/hyperclaude:hyper-recap [path|slug]`.
- A cycle just completed — the plan ran to completion (`implement` / `code-review` done) and was archived under `.hyperclaude/plans/done/` — and the why/how should be captured.
- hyper-auto invokes this skill automatically as its terminal step on a clean composed exit (the sole auto-run path; standalone it stays on-demand).

## When to skip

- **Mid-cycle.** Recaps cover completed cycles only — there is no mid-cycle partial-recap mode. If the target plan is still active (not yet archived), stop and say so (see Target resolution's completion gate).
- **No completed plan exists.** Zero `.hyperclaude/plans/done/*.md` → report "nothing to recap", write NOTHING, stop.

## Invocation argument

**Invocation argument:** $ARGUMENTS

## Target resolution

Every branch resolves to a COMPLETED plan under `.hyperclaude/plans/done/`. Classify `$ARGUMENTS`:

- contains `/` OR ends in `.md` → **path** branch
- a bare non-empty token → **slug** branch
- empty → **no-arg** branch

### Path branch

First **validate** the supplied path via canonical-path comparison — never a lexical/string-prefix check:

1. Canonicalize the repository's `.hyperclaude/plans/` and `.hyperclaude/plans/done/` directories (resolve symlinks and collapse `.`/`..` traversal — `realpath`/`readlink -f` semantics).
2. **Candidate's leaf EXISTS** → canonicalize the whole candidate path and require its parent directory to be EXACTLY one of those two canonicalized directories (a direct child — reject traversal segments, nested subdirectories, and symlinks that resolve outside either directory).
3. **Candidate's leaf does NOT exist** → canonicalize only its PARENT directory (the leaf itself has nothing to resolve) and require that parent to be EXACTLY the canonicalized `.hyperclaude/plans/` directory. This missing-leaf case is allowed ONLY for the active-plan directory, matching the archival-relocation case below: the plan was archived out from under its active path, so it's the DONE sibling, not the missing active leaf, that gets canonicalized and containment-checked next.
4. Any candidate that fails these checks → STOP `path must be under .hyperclaude/plans/ or plans/done/: <path>`. Never basename-match an external path against a done plan.

Then key on the given path EXACTLY (no blind basename swap):

- Explicit `.hyperclaude/plans/done/<...>` path → use it EXACTLY if it exists and is readable; else STOP `plan not found: <path>`. No basename relocation for a done path.
- Explicit active `.hyperclaude/plans/<...>` path:
  - If that EXACT file still exists → it is an un-archived plan → STOP `plan not yet completed — run it to completion first` (completion gate). Do NOT silently retarget a same-basename done plan.
  - Only when the exact active path NO LONGER exists AND `.hyperclaude/plans/done/<basename>` exists → use the done copy (archival relocation). This is the missing-leaf case validated above: the parent (`.hyperclaude/plans/`) canonicalized and passed containment while the leaf was absent; now canonicalize and containment-check the done sibling (`.hyperclaude/plans/done/<basename>`) before reading it.
  - Neither exists → STOP `plan not found: <path>`.

### Slug branch

Scan `.hyperclaude/plans/done/*.md`, derive each file's slug via the **Target slug** rule below, and collect files whose derived slug equals the argument.

- 0 matches → STOP `no completed plan for slug '<slug>'`.
- 1 match → use it.
- ≥2 matches → select the **newest by mtime** (the SAME `ls -1t` ordering the no-arg branch uses — one total ordering over every candidate, regardless of whether a filename carries a `<YYYYMMDD-HHMM>` prefix) AND report the ambiguity: list the matched candidates and which was chosen.

### No-arg branch

Newest `.hyperclaude/plans/done/*.md` by mtime:

```bash
ls -1t .hyperclaude/plans/done/*.md 2>/dev/null | head -1
```

Zero done plans → report "nothing to recap", write NOTHING, STOP.

## Target slug

Derive the target plan's slug `S` from the resolved plan FILENAME (basename without `.md`). This rule derives ONLY the target plan's own `S` and the recap filename — NEVER use it to match other artifacts (see discovery, which reads frontmatter). It replicates `extractSlugFromPlanFilename` (`scripts/codex/slug.mjs` lines 29–33) with explicit no-ASCII / empty handling:

- basename matches `^\d{8}-\d{4}-(.+)$` → `S` = the captured suffix (the normal `<ts>-<slug>` case).
- basename is a bare timestamp — matches `^\d{8}-\d{4}-?$` (timestamp-only or trailing-hyphen) → `S` = **EMPTY**. This is the repo's **no-ASCII** convention (specs/research use a bare empty `slug:` with a `<timestamp>.md` filename); the plain `extractSlugFromPlanFilename` fallback would wrongly yield the timestamp as `S`.
- otherwise (a manually named `<slug>.md` with no timestamp prefix — `hyper-implement` can archive these) → `S` = the whole basename.

**Empty-`S` behavior.** The recap filename is timestamp-only (`.hyperclaude/recaps/<timestamp>.md`, collision-suffixed `-2`/`-3` as usual — never a dangling `<timestamp>-.md`), and the frontmatter `slug:` is the bare empty key (`slug: ` — key, colon, single space, nothing after — matching `hyper-interview`'s no-ASCII fallback, NOT `slug: ""`). Research/spec slug-linkage is UNAVAILABLE for an empty-`S` cycle (an empty slug can't distinguish cycles) — acknowledge that gap in the recap. Plan-reviews still link exactly via the `plan-path` + `cwd` full-path rule.

**Collision-ambiguous `S` behavior.** The plan-writer appends `-2`/`-3`… collision suffixes to plan FILENAMES, but linked research/spec artifacts keep their ORIGINAL frontmatter `slug:` — and plans persist NO canonical `slug:` field, so a filename-derived `S` ending in a number cannot be proven to be a real slug vs a collision suffix. Flag `S` as **collision-ambiguous** when it matches `-\d+$` (e.g. `foo-2` — could be `slug: foo` collided) OR is entirely digits `^\d+$` (e.g. `2` — an empty-slug collision `<ts>-2.md`). For a collision-ambiguous `S`: still use `S` verbatim for the recap FILENAME and frontmatter `slug:` (naming only, no correctness risk), but treat research/spec slug-linkage as UNAVAILABLE (same as empty `S`) and note it — do NOT silently match `slug: foo` or `slug: 2`. This conservatively accepts that a genuine slug ending in `-<digits>` also loses research/spec linkage; plan-reviews still link exactly via `plan-path` + `cwd`.

`recaps/` accumulates like `research/` and is NEVER archived.

## Cycle artifact discovery

Match by **FRONTMATTER, not filename**. Filename extraction is wrong for `<ts>-S-claude.md` (→ `S-claude`) and collision-suffixed `<ts>-S-2.md` (→ `S-2`).

- **plan-reviews (exact membership).** Read each `.hyperclaude/plan-reviews/*.md` frontmatter `plan-path` AND `cwd` (both are recorded — see `scripts/codex/frontmatter.mjs`; `hyper-plan-review` records the caller's path verbatim, which may be relative or an external path). Resolve `plan-path` against that artifact's recorded `cwd` to a canonical absolute path, and include the review ONLY when it equals the target plan's canonical ACTIVE path (`<target-cwd>/.hyperclaude/plans/<basename>`) OR its DONE path (`<target-cwd>/.hyperclaude/plans/done/<basename>`). Basename equality alone is INSUFFICIENT — a review of an unrelated external plan with the same filename must not match. A Claude-seat artifact (`reviewer: claude-adversarial`) carries the same `plan-path` + `cwd` keys and is matched by the `plan-path` + `cwd` resolution above.
- **research + specs (slug-only, caveated).** Read each `.hyperclaude/research/*.md` and `.hyperclaude/specs/*.md` frontmatter `slug:`; include those equal to `S`. Because `S` may be non-unique across completed cycles, present these as "slug-matched (may include artifacts from other same-slug cycles)". If more than one `plans/done/*.md` shares slug `S`, surface that ambiguity explicitly. When `S` is EMPTY (no-ASCII) OR collision-ambiguous (per Target slug — matches `-\d+$` or `^\d+$`), **skip this slug match entirely** and note that research/spec linkage is unavailable — do NOT match on an empty slug (it would sweep in every no-ASCII cycle's artifacts) or on a collision-suffixed `S`.
- **code-reviews (live-only).** Include ONLY paths supplied by the live loop's `reviewArtifacts[]` or otherwise referenced in-session — NEVER slug- or frontmatter-guessed (code-review artifacts use release-level slugs and carry no plan identity).

## Context detection

Mode is determined SOLELY by whether the originating conversation is available in-session. Per-field availability is handled separately — do NOT downgrade the whole mode because one field is missing.

- **`context: live`** — the recap is generated in the SAME session that ran the cycle (user request verbatim available). The AI's judgments and rejected alternatives are recoverable ONLY to the extent they are actually evidenced in the visible lead conversation or a written artifact — delegated planner/fixer subagent reasoning that was never surfaced back to the lead is NOT automatically recoverable just because the mode is `live` (see Recap content's Key decisions row for the same evidence requirement). Enrich per-field where available: code review not run → mark that section "not run"; a task with no commit → "no commit"; a standalone review run with no `reviewArtifacts[]` → use any in-session-referenced code-review paths, else mark "unavailable". A missing `reviewArtifacts[]` or a missing commit does NOT force `artifacts-only`.
- **`context: artifacts-only`** — a fresh session where the conversation is unavailable. Build a **plan-scoped partial recap** from the discovered artifacts (enriched by slug-matched research/specs only when the slug is usable), with an explicit **"Unrecoverable gaps"** note enumerating exactly what cannot be recovered: the verbatim request, the AI's judgment rationale, per-task commit SHAs, and code-review-round associations. `.jsonl` transcript mining is a non-goal. Do NOT fabricate any of these.

## Recap content

**The recap carries the story; the artifacts carry the detail.** Target: the body fits on one screen — link artifacts by path instead of restating them, and prefer a one-line summary over a ledger everywhere the detail is already durable (git log, review artifacts). Required sections, each field's source explicit:

- **TL;DR** — a short opening paragraph: what was asked, what was built, where it stands (branch / release state).
- **Request summary** — verbatim quote when `context: live`. In `artifacts-only`, a summary derived only from the exact resolved plan (its H1 / intro / task list), flagged as not the verbatim request. Slug-matched specs/research may belong to another same-slug cycle, so cite them only as caveated supplementary context, never as the summary's source.
- **Key decisions + why, incl. rejected alternatives** — a **table** of the decisions that shaped the outcome (design forks, rejected alternatives, critic-forced redesigns); process and bookkeeping decisions stay out. In both modes, fill a row's rationale/alternative only from explicit evidence — the visible in-session conversation (`live`) or an artifact that states it (either mode); otherwise mark the cell "unavailable" or label it "inferred from the final plan", so unrecorded rationale is never presented as fact. Slug-matched specs/research are caveated supplementary context only.
- **What changed** — a compact area-level summary (a few bullets naming the areas touched) plus the commit range (`<first>..<last>`, N commits); `git log` carries the per-commit detail, so no per-commit ledger. It distinguishes actual from planned change:
  - In `live`, derive the change set from every cycle commit available in-session — each per-task commit and the implement-loop's final `fix(review): …` convergence commit when present (its subject names the reviewer seat — Codex or Claude) — with `git show --name-status --format= <sha>` (it handles renames and, unlike `--stat`, never abbreviates paths); render the summary from that set. Two things get their own line rather than being folded in: the **"review fixes"** convergence commit when it does not map cleanly to a single task, and — if a failed convergence commit left fixes staged/unstaged — those working-tree files (`git diff --name-status` + `git diff --cached --name-status`) flagged **"uncommitted (convergence commit failed)"**.
  - In `artifacts-only`, label the summary **"planned file scope"** (from the plan's "Files to create/modify") rather than "files changed", and mark commits "unavailable" — planned scope is not evidence of actual change.
- **Critic verdicts** — a per-phase one-liner: rounds consumed, the finding arc in a clause (what themes forced changes), the final verdict, and the artifact paths; name the reviewer seat per round when the artifact carries `reviewer:` — absent the key, the round was Codex. Add a findings table only for findings that materially changed the design. Plan-review rounds (exact, via the `plan-path` + `cwd` resolution above) in both modes; code-review rounds are live-only — sourced from `reviewArtifacts[]` or any code-review artifact referenced in-session (a standalone `hyper-code-review` run counts), consistent with discovery. A finding's exact resolution is often not persisted (intermediate plan revisions are overwritten in place): mark it "unavailable / not persisted" unless a later plan-review round records it resolved, or label it "inferred from the final plan". In `artifacts-only`, mark the code-review association unavailable.
- **Open / deferred items** — from the plan + plan-reviews.

**Diagrams.** Include one only when a picture makes this cycle's *implemented content* easier to understand — the architecture / data flow that was built, the module or component relationships that changed, or the shape of a design decision. Most recaps need none; skip it when prose/tables already suffice. Default to a single mermaid `flowchart LR` of ≤10 nodes whose labels are real names drawn from this cycle — modules, files, artifacts, commit SHAs, or the actual components and decisions. Render either the mermaid diagram or, for terminal-only readers, an ASCII fallback in its place (not both). Artifacts are linked by path, never inlined.

## Write mechanics

```bash
mkdir -p .hyperclaude/recaps
date -u +%Y%m%d-%H%M
```

Base path `.hyperclaude/recaps/<timestamp>[-<slug>].md` — the `-<slug>` segment is present for a normal `S`, OMITTED entirely for an empty `S` (never emit a dangling `<timestamp>-.md`). If the path exists, append `-2`, `-3`, … until free.

Write with the **Write** tool. Author NO `plugin-version` line — the PostToolUse stamp hook adds it post-write. Frontmatter keys, in this order:

```
---
mode: recap
slug: <slug>
generated: <ISO-8601 timestamp>
context: live|artifacts-only
plan: "<source plan path>"
---
```

- `slug:` value: for a normal nonempty `S`, JSON-serialize it (`JSON.stringify(S)`-equivalent — double-quoted with `"` / `\` / control characters escaped) — a manually named plan's whole-basename slug (e.g. `release: v2` from `release: v2.md`) or one containing `#`, quotes, or backslashes would otherwise corrupt the YAML scalar. For an empty `S`, use the bare empty key (`slug: ` — key, colon, single space, nothing after), NOT `slug: ""`.
- `plan:` value MUST be JSON-serialized (`JSON.stringify()`-equivalent — not raw string interpolation into a quoted literal) so spaces / `#` / `:` / quote characters in the path cannot corrupt the YAML scalar, mirroring how the bridge JSON-quotes its path-valued frontmatter.

**Terminal reporting contract.** After a successful Write, report the EXACT written recap path (the resolved `.hyperclaude/recaps/<...>.md`, collision suffix included). On ANY non-success terminal — target resolution, artifact reads, `mkdir`, timestamp generation, the Write itself, or any other I/O — report the failure reason and NO path (never claim a path that was not written). This is the defined outcome hyper-auto's terminal step consumes; a standalone run likewise states where it wrote or why it could not.

## Anti-patterns

- **Calling Codex / the bridge.** This skill is Claude-only.
- **Dispatching any agent** (the `Agent` tool). No agent dispatch.
- **Auto-running inside a loop.** Recap is invoked at cycle completion, not chained from an implement/review loop — with ONE carve-out: hyper-auto's terminal step MAY auto-run it after BOTH inner loops complete cleanly. Never mid-loop, never chained directly from hyper-implement-loop or hyper-plan-loop.
- **Mining `.jsonl` transcripts** to recover an `artifacts-only` gap. A non-goal — mark the gap unrecoverable instead.
- **Epic-level rollup.** The unit is ONE detailed plan / milestone.
- **PR-draft framing.** This explains the cycle to a human; it is not a merge proposal.
- **Inlining artifact bodies** instead of linking them by path.
- **Ledger-dumping** — per-commit tables or per-round finding tables where an area summary / one-line arc plus artifact links suffices. The recap is the story, not the log.
- **Filename-extracting research / plan-review / spec slugs** instead of reading frontmatter `slug:`.
- **Presenting slug-only-matched research / specs as exact cycle membership** when `S` is non-unique.
- **Slug-guessing a code-review artifact** into a recap (release-level slug, no plan identity).
- **Recapping an un-archived active plan** (violates the completion gate).
- **Basename-matching an external or active path** to a different done plan.
- **Basename-only plan-review matching** without resolving `plan-path` against its recorded `cwd`.
- **Presenting planned file scope as actual changes.**
- **Dropping the implement-loop `fix(review):` convergence commit** (or a failed-convergence staged/unstaged working tree) from live "what changed".
- **Using `git show --stat`** for exact file enumeration — use `--name-status`.
- **Asserting unrecorded rationale / finding-resolution as fact** in EITHER mode — mark "unavailable" or "inferred" unless explicitly evidenced by the session or an artifact.
- **Using a slug-matched spec as the authoritative request summary.**
- **Fabricating commit SHAs or code-review associations** in `artifacts-only` mode.
- **Writing a recap when no completed plan exists.**

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.