# Auto Git

> Set up automatic, per-round git commits for a code project so the user's work is committed every round and never lost. It runs git init, writes a sensible .gitignore, installs a Stop hook that auto-commits each round (pushing is a separate, opt-in hook), and makes the initial commit — then keeps committing as work continues, and keeps the project's progress files (status.md, progress.md, plan.md, and the like) current each round. Trigger it proactively whenever a new code project is being started or scaffolded, even if the user never mentions git: when they describe or kick off building an app, tool, or library, create the first source files, or ask you to write a CLAUDE.md for a codebase. Also trigger on explicit requests such as /auto-git, "turn on auto commit", "set up version control", "commit my changes automatically as we go", or "stop losing my work". Lean toward activating at the start of a coding project rather than missing it. Do NOT trigger for one-off git actions — a single "commit this", "push my

- Skill: `hfjddjksaj/auto-git` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add hfjddjksaj/auto-git`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hfjddjksaj/auto-git/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: hfjddjksaj (https://skillmd.com/u/hfjddjksaj)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hfjddjksaj/auto-git

---


# auto-git

Automatic, per-round git safety net for code projects. The goal is simple: the
user should never lose a round of work, and their history should be readable
without them having to think about committing.

## The two-part design (read this first)

This skill combines two mechanisms because they have different strengths:

1. **A Stop hook — the backbone.** A project-local `autocommit` hook commits
   any uncommitted changes after every round, automatically, whether or not
   anyone remembers. The harness runs it, so it cannot be forgotten. This is
   what *guarantees* nothing is lost. It **only commits** — everything it does
   is local.

   Two optional companions are offered separately during setup and **never
   installed by default** (see step 4):

   - `progress-check` — if a round changed files but left both progress files
     (`status.md`, `progress.md`) untouched, it blocks the stop once with a
     reminder so you update them while you still have the context (it never
     writes content itself, and a `stop_hook_active` guard means it can never
     loop).
   - `autopush` — pushes after `autocommit`, and only when the branch already
     has an upstream and is ahead of it. Commit and push are deliberately
     separate hooks: committing is a local safety net that costs nothing, while
     pushing publishes work to a remote, and that should be its own decision.

2. **You writing real commit messages — the polish.** A hook is a dumb shell
   script; it can only write a generic timestamped message. A commit message
   that actually says what changed can only come from you, during the turn.
   So when you're working in an auto-git project, you commit meaningful changes
   yourself as the last step of a round. The hook then finds a clean tree and
   does nothing (or sweeps up anything you left behind).

The result: meaningful messages whenever you're active, and a guaranteed commit
every round regardless.

## When to activate

Activate (run the setup below) when a **code project** is being started or set
up and auto-git is not already installed. Signals that it's a code project:

- The user writes or asks for a `CLAUDE.md`, or gives a project overview that
  describes building software.
- Source files or package manifests are present or being created:
  `package.json`, `requirements.txt` / `pyproject.toml`, `go.mod`,
  `Cargo.toml`, `*.csproj` / `*.sln`, `pom.xml` / `build.gradle`, `Gemfile`,
  `composer.json`, a `src/` directory of code, etc.
- The user asks to set up version control, auto-commit, or "stop losing work".

Do **not** activate for pure writing, research notes, or one-off git questions.
If it's ambiguous whether the user wants this, ask once rather than assuming.

## Setup procedure

Every step is idempotent — check the current state before acting, and re-running
setup on an already-configured project should change nothing.

### 0. Bail out early if already set up

If `.claude/settings.json` already contains a `Stop` hook that runs
`autocommit`, auto-git is installed. Briefly confirm the pieces exist
(`.gitignore`, the hook scripts, the initial commit) and stop. Don't duplicate
anything.

**Three exceptions — migrate before you stop.** Updating this skill never
reaches projects that were set up earlier, so an existing install has to be
repaired on the spot:

1. **Refresh stale hook scripts (do this whenever it applies).** Every script in
   `scripts/` carries a `# auto-git-version: N` stamp within its first two
   lines. Compare each against the same stamp in the project's
   `.claude/hooks/`. If an installed script has a **lower stamp, or none at
   all**, it predates fixes it needs: overwrite it from `scripts/` — every
   script the project has installed, not just the one you happened to check.
   An unstamped `autocommit` is the version that pinned itself to
   `CLAUDE_PROJECT_DIR` and commits the **main checkout instead of the worktree
   Claude is in**; it also pushes, which is now `autopush`'s job alone.

   Also check the registered Stop command itself: if it uses a **relative** path
   (`bash .claude/hooks/autocommit.sh`), rewrite it to the absolute
   `$CLAUDE_PROJECT_DIR` form from step 4. A relative path is resolved against
   the session's cwd, so the hook dies with `No such file or directory` the
   moment Claude works anywhere but the main checkout — a git worktree, most
   commonly.

   Refreshing scripts must not change *which* hooks are registered. If the
   project has no `autopush`, leave it that way — its absence means the user
   didn't opt in, and silently starting to push their work would be exactly the
   surprise this skill exists to avoid. Offer it only if they ask (step 4).
2. **Worktree-ignore repair.** If `.gitignore` has no `.claude/worktrees/` line,
   add it (step 3). Then check whether a worktree already got committed:
   `git ls-files -s .claude/worktrees` printing anything means the main branch
   is carrying a phantom gitlink. Drop it with
   `git rm --cached -r --quiet .claude/worktrees` and commit — that only adds a
   commit, rewrites nothing, and leaves the worktree on disk untouched.
3. **Layout migration.** If the project has a `progress.md` but no `status.md`,
   it was set up under the old single-file layout. Do the split from step 5 and
   the note upgrade from step 6.

Then stop.

Note: `autocommit` present without `progress-check` is a normal,
complete install — `progress-check` is opt-in, and its absence usually means
the user declined it. Don't re-offer it on every re-run; add it (per step 4,
inserted *before* the `autocommit` entry) only if the user asks for it.

### 1. Initialize the repository (if needed)

**Nested-repo guard first:** before running `git init`, check
`git rev-parse --is-inside-work-tree`. If it succeeds, you're already inside a
repo — compare `git rev-parse --show-toplevel` to the current directory. If they
match, this directory is already a repo (skip init). If the toplevel is a
*parent* directory, you'd be creating a repo nested inside another one — stop and
ask the user first, since that's rarely what they want.

Otherwise initialize:

```
git init -b main        # sets the initial branch to main
```

If the running git is too old for `-b`, fall back to `git init` and rename the
branch after the first commit with `git branch -M main`.

### 2. Ensure a git identity is configured

Commits made by the hook run non-interactively, so a git identity **must** be
configured or every commit — including the initial one — fails silently with
exit 128. Do this *after* `git init`, because setting a repo-local identity
requires the repo to already exist. Check:

```
git config user.email
git config user.name
```

If either is empty (no global or local value), ask the user for the name/email
to use, then set it — locally for this repo unless they prefer global:

```
git config user.email "them@example.com"
git config user.name "Their Name"
```

### 3. Write `.gitignore`

The point is to keep "irrelevant" files out of history: build output,
dependencies, secrets, and OS/editor junk.

- If no `.gitignore` exists, create one from `assets/gitignore-base.txt`, then
  append the language-specific block(s) for whatever stack you detected. The
  per-language blocks are in `references/gitignore-languages.md` — read it and
  copy the relevant sections.
- If a `.gitignore` already exists, **do not overwrite it.** Read it, and append
  only the critical entries it's missing (especially the secrets block: `.env`,
  `*.pem`, `*.key`, credentials). Mention to the user what you added.

Two entries are mandatory either way:

- **The secrets block.** Secrets must never be committed.
- **`.claude/worktrees/`.** Claude Code puts its worktrees there, inside the
  main checkout. Without this line `git add -A` records a worktree as a phantom
  gitlink on the main branch — see the *Git worktrees* section.

### 4. Install the Stop hooks — ask for explicit approval first

A Stop hook runs a shell command automatically after every round, so Claude Code
treats installing one as security-sensitive: under auto-accept / auto mode the
change is intercepted by the safety classifier rather than applied silently.
That's correct behavior — a hook should never appear without the user knowing.
So don't try to slip it in via auto-accept. Make installation a **deliberate,
approved step**.

**Show the user exactly what will be installed, then get a yes/no before writing
anything.** Present the hook script's path and the precise command that will run
each round, and ask with a clear approve/decline prompt (use AskUserQuestion, or
an equivalent explicit choice) — for example: *"Install the auto-commit Stop
hook? It will run `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/autocommit.sh"` after
every round to commit your changes."*

- If the user **approves**, copy the script(s) and write the hook(s) (below).
  They'll also see Claude Code's own edit-permission prompt for `settings.json`
  — that's expected, and now they know to accept it.
- If the user **declines**, skip the hooks entirely and continue with the rest of
  setup. Everything else still works — git init, `.gitignore`, progress files,
  and the per-round commits you make by hand. Tell the user plainly that without
  the hook there's no automatic safety net, so they're relying on your
  end-of-round commits.

**The optional `progress-check` hook — always ask, never install by default.**
When the user approves `autocommit`, offer this one as a separate, explicit
choice, and spell out the consequence so they can actually decide — for example:

> *"Optionally, also install the `progress-check` Stop hook? What it changes:
> whenever a round modified files but left both `status.md` and `progress.md`
> untouched, the hook blocks the stop once and I keep working — updating the
> progress files and committing — before the round truly ends. That keeps them
> reliably current, but some rounds take one extra beat, and it can also fire
> when you edited files yourself and only asked me a question. If you skip it,
> nothing else changes: autocommit still commits everything; progress updates
> just rely on my per-round routine alone."*

Install it only on an explicit yes. On a no — or no clear answer — don't
register it, and don't re-ask in later rounds.

**The optional `autopush` hook — always ask, never install by default.**
`autocommit` never pushes; committing is local and costs nothing, while pushing
publishes the user's work, so it is a separate hook and a separate decision.
Offer it as its own explicit choice — for example:

> *"Optionally, also install the `autopush` Stop hook? It pushes after each
> round's commit, but only when the current branch already has an upstream and
> is ahead of it — no remote configured means it does nothing at all. It never
> creates remotes or upstreams and never force-pushes. Say no and everything
> stays local until you push yourself."*

Install it only on an explicit yes. If the project has no remote yet, still ask
rather than assuming — the hook is harmless until an upstream exists, and it is
the user's call whether adding a remote later should start publishing
automatically.

When approved, copy the hook script(s) for this OS and register them:

- **Windows:** copy `scripts/autocommit.ps1` → `.claude/hooks/` (plus
  `scripts/progress-check.ps1` and `scripts/autopush.ps1`, each only if opted
  in). Hook commands:
  - progress-check (if opted in): `pwsh -NoProfile -File "$CLAUDE_PROJECT_DIR/.claude/hooks/progress-check.ps1"`
  - autocommit: `pwsh -NoProfile -File "$CLAUDE_PROJECT_DIR/.claude/hooks/autocommit.ps1"`
  - autopush (if opted in): `pwsh -NoProfile -File "$CLAUDE_PROJECT_DIR/.claude/hooks/autopush.ps1"`
  (fall back to `powershell -NoProfile -ExecutionPolicy Bypass -File ...` if
  `pwsh` isn't available). The `.sh` scripts work on Windows too — Claude Code
  runs hook commands through Git Bash — so either pair is fine there.
- **macOS / Linux:** copy `scripts/autocommit.sh` (plus
  `scripts/progress-check.sh` and `scripts/autopush.sh`, each only if opted in)
  → `.claude/hooks/` and mark them executable (`chmod +x`). Hook commands:
  - progress-check (if opted in): `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/progress-check.sh"`
  - autocommit: `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/autocommit.sh"`
  - autopush (if opted in): `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/autopush.sh"`

**Always register the absolute `$CLAUDE_PROJECT_DIR` form, never a bare relative
path.** The harness expands that variable in the command string (on Windows
too), and a relative path is resolved against the *session's* cwd — which stops
being the main checkout as soon as Claude enters a git worktree, and the hook
then fails with `No such file or directory`. Quote the path: project paths
contain spaces.

Register by **merging** into any existing `.claude/settings.json` (never
clobber other settings or hooks). With `autocommit` alone the shape is:

```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "<autocommit command from above>" }
        ]
      }
    ]
  }
}
```

Each hook the user opted into joins that same inner array. With all three:

```json
        "hooks": [
          { "type": "command", "command": "<progress-check command from above>" },
          { "type": "command", "command": "<autocommit command from above>" },
          { "type": "command", "command": "<autopush command from above>" }
        ]
```

**Order matters, and it is always this one:** `progress-check` → `autocommit` →
`autopush`. `progress-check` has to see the dirty tree before `autocommit`
sweeps it clean, and `autopush` can only push what `autocommit` has already
committed. Drop whichever entries the user declined; the survivors keep their
relative order.

If a `Stop` array already exists, add these entries to it rather than replacing
it. Don't add duplicates if these commands are already present.

### 5. Set up progress tracking (status.md + progress.md)

auto-git also keeps the project's progress files current, so the state of the
work is always readable and survives context loss between sessions. There are
**two files, with opposite semantics** — the whole point is that they never blur
into each other:

| file | what it is | write semantics |
| --- | --- | --- |
| `status.md` | a snapshot of the project **now** | overwrite — delete what no longer applies |
| `progress.md` | the project's **history** — how it got here | append-only — never edit past entries |

During setup, create both from `assets/status-template.md` and
`assets/progress-template.md` if they don't already exist (never overwrite an
existing one).

**`status.md` — the snapshot.** It answers "where is this project right now?":

```markdown
# Status

## Current status
## Active decisions & constraints
## Next steps
## Known issues
```

Every section has overwrite semantics — updating means rewriting it to current
truth and **deleting** what no longer applies: completed steps, superseded
decisions, fixed issues. Deleting here is safe and expected: anything worth
remembering was written to `progress.md` when it happened, and every previous
version is one `git log -p -- status.md` away. Two writing rules keep the
snapshot trustworthy:

- **Claims carry pointers.** "Auth done (src/auth.ts)" — a later session can
  verify that in seconds; "auth done" alone it can only believe or doubt.
- **Size tracks task complexity, not elapsed time.** A `status.md` that only
  ever grows has become a ledger — trim it on the spot.

**`progress.md` — the history.** Append-only, **newest entry at the top**, one
entry per *meaningful node*:

```markdown
# Progress

## 2026-08-05 14:30 — Login endpoint landed
- JWT verification in src/auth.ts
- Fixed sessions not refreshing on expiry

## 2026-08-05 11:02 — Project initialized
- Scaffold + .gitignore
```

"Meaningful node" is the filter that keeps this file worth reading: a feature
landing, a decision made, a real bug fixed, a direction changed, a milestone
reached. **Not every round.** Typo fixes, formatting passes, and tiny tweaks get
no entry — `git log` already has them, and padding the history with them is what
turns it into noise. Past entries are the record: never rewrite or delete them,
only prepend new ones.

**Migrating an older project (do this, don't skip it).** If the project has a
`progress.md` that is really a *snapshot* — either the four sections above, or
this skill's oldest shape with a "Current status" plus an append-only `## Log`
— split it now:

1. Create `status.md` and move the snapshot sections into it verbatim.
2. Leave `progress.md` holding history only. If there was a `## Log`, convert
   its entries into top-level `## <date> — <summary>` entries, **reordered
   newest-first**. If there was no log at all, start it with a single entry
   noting the split and the state at that point.
3. Update the project's `CLAUDE.md` note (step 6) to the two-file wording.

Never drop content during the split — every line either moves to `status.md` or
stays in `progress.md`.

Leave any other progress-type files the project already has (`plan.md`,
`TODO.md`, `ROADMAP.md`, a changelog, etc.) in place — you'll keep them current
each round too. Don't fabricate a planning structure the user didn't ask for
beyond these two files.

### 6. Record the per-round instructions in CLAUDE.md

Future sessions won't have this skill loaded, so leave a durable reminder that
carries the per-round behavior forward. Append this section to the project's
`CLAUDE.md` (create the file if it doesn't exist), unless an equivalent note is
already there:

```markdown
## Auto-git: per-round routine

Two progress files, opposite semantics — keep them distinct:

- `status.md` — a snapshot of the project **now**. Overwrite semantics.
- `progress.md` — the project's **history**. Append-only, newest at the top.

At the end of any round that changed the project, do these before finishing:

1. **Rewrite `status.md`** to current truth — sections (Current status / Active
   decisions & constraints / Next steps / Known issues) updated, and anything
   completed, superseded, or fixed **deleted**. Deleting is safe: what mattered
   is already in `progress.md`, and old versions are in `git log`. Give claims
   pointers to where they live in the code ("auth done — src/auth.ts"). If the
   file only ever grows, it is drifting into a ledger — trim it.
2. **Append to `progress.md` only if this round was a meaningful node** — a
   feature landed, a decision made, a real bug fixed, a direction changed. Add
   a new `## YYYY-MM-DD HH:MM — <one-line summary>` section at the **top** of
   the file, with a few bullets under it. Never edit or delete existing
   entries. Trivial rounds (typos, formatting, small tweaks) get no entry —
   `git log` already has them.
3. **Refresh other progress files** that already exist — check off completed
   items in `plan.md` / `TODO.md`, add a changelog line, etc.
4. **Update `CLAUDE.md` itself only when this round changed something it
   documents** — architecture, key decisions, commands, or structure. Don't
   rewrite it every round.
5. **Commit** with a clear, descriptive message as the final step. A Stop hook is
   a safety net that commits anything left over. Commit locally; never rewrite
   history or force-push. Whether commits also get pushed automatically depends
   on whether this project installed the separate `autopush` hook — check
   `.claude/settings.json` rather than assuming either way.

Rounds that only answered a question and changed nothing need no update or commit.

**Hook freshness — do this once when you notice it, not every round.** The
scripts in `.claude/hooks/` carry a `# auto-git-version: N` stamp. If the
auto-git skill is available in the session and its `scripts/` carry a higher
number, the copies here predate fixes they need: overwrite them from the skill,
leave the set of registered hooks unchanged, and commit. The copies are
per-project, so updating the skill never reaches this project on its own.
```

**Upgrade an older note in place — don't just skip it.** "An equivalent note is
already there" means one that already carries this two-file discipline, not merely
any auto-git mention. If the project's `CLAUDE.md` has an *older or weaker* version
of this note — one that treats `progress.md` as the snapshot, or that still tells
sessions to keep an append-only "Log" inside it — rewrite it to the wording above
instead of leaving it stale, and split the files per step 5. Preserve any deliberate
project-specific choices the old note encoded (non-default progress-file names, a
project working language, an explicit no-push policy) and change only
the progress-file discipline. One caveat: if the project's progress files are
gitignored, keep the "delete freely, history is in `git log`" clause out of its note
— with nothing versioned, `status.md` deletions lose history unless the corresponding
`progress.md` entry was written, so make writing that entry the precondition for
trimming. This in-place upgrade is what keeps existing projects from drifting when
this skill is later updated — updating the central skill never touches a project
that was set up earlier, so the note has to be refreshed the next time setup runs
there.

### 7. Make the initial commit

Stage everything that isn't ignored and commit the baseline — include all files
currently present:

```
git add -A
git commit -m "chore: initial commit (auto-git baseline)"
```

Then tell the user what you set up in a couple of lines: repo initialized,
`.gitignore` written, `status.md` + `progress.md` created, which Stop hooks are
installed (and which they declined), and the initial commit made. Be explicit
about pushing: if they skipped `autopush`, say plainly that nothing will ever
leave the machine on its own; if they took it, say it stays dormant until they
add a remote and an upstream.

## Working in an auto-git project (every round after setup)

When a round changed the project, wrap it up in this order before you finish:

1. **Rewrite `status.md`.** It is the snapshot of the project *now*: sections to
   current truth, deleting anything completed, superseded, or fixed, claims with
   pointers into the code. This happens every round that changed something.
2. **Prepend to `progress.md` — only if the round was a meaningful node.** A
   feature landed, a decision made, a real bug fixed, a direction changed. New
   `## YYYY-MM-DD HH:MM — <summary>` entry at the top, a few bullets under it,
   existing entries untouched. A round that fixed a typo or reformatted
   something gets nothing here.
3. **Refresh the rest.** Check off / adjust any existing `plan.md`, `TODO.md`,
   changelog, etc. Update `CLAUDE.md` *only* if this round changed something it
   documents (architecture, decisions, commands, structure) — don't churn it
   every round.
4. **Commit last.** Stage and commit with a message that describes what actually
   changed — a real subject line, not a timestamp. Committing last (after the
   progress updates) means those updates land in the same commit and the hook
   doesn't have to sweep up after you.

Group a round's work into one sensible commit when you can; a couple of commits
is fine if the round did genuinely separate things. Pushing is not automatic
unless this project installed the optional `autopush` hook — without it, commits
stay local until someone pushes.

A round that only answered a question and changed nothing needs no progress
update and no commit. And if you forget the wrap-up, nothing is lost: if the
optional `progress-check` hook is installed it blocks once with a reminder so
you can catch up, and either way the `autocommit` hook commits the leftovers
with a generic message — the routine just keeps `status.md`, `progress.md`, and
git history readable.

## Git worktrees

Claude Code can move a session into a git worktree (its own live under
`.claude/worktrees/<branch>`). Three things follow, and the hooks are built for
all three:

- **The session's cwd becomes the worktree**, while `CLAUDE_PROJECT_DIR` keeps
  pointing at the main checkout. So the hook command must reference the script
  through `$CLAUDE_PROJECT_DIR` (that's where `.claude/hooks/` physically
  lives), while the script itself must operate on the **cwd**, which is the tree
  actually being edited. The scripts resolve that from the hook payload's `cwd`
  field, falling back to the process cwd and then `CLAUDE_PROJECT_DIR`, and use
  the first one that's inside a git work tree. Result: work on a worktree branch
  is committed to *that* branch, and the main checkout is left alone.
- **`.claude/hooks/` and `.claude/settings.json` are tracked, so a worktree gets
  its own copies.** That is deliberate. It means a session started *directly*
  inside a hand-made worktree still loads the hooks, and auto-git is active
  there with nothing copied by hand. It also means anyone who clones the repo
  inherits the hooks — which is intended, and is why installing them takes
  explicit approval in step 4.
- **`.claude/worktrees/` must be gitignored** (step 3). Being under `.claude/`
  does not exclude it — nothing else in there is excluded either. Without that
  line, `git add -A` in the main checkout sees a nested repository and records
  the worktree as a phantom gitlink on the main branch, which then re-commits
  every time the worktree's branch moves. Step 0 repairs projects set up before
  the line existed.

## Safety rules (non-negotiable)

These exist because auto-committing tools are dangerous when they're too
aggressive — the whole point is to help, never to surprise or destroy:

- **Local-first, no history rewriting.** Never `git reset --hard`, `rebase`,
  `commit --amend`, force-push, or anything that discards work. Only ever add
  commits.
- **Committing never publishes.** `autocommit` only commits; it cannot push.
  Pushing lives in `autopush`, a separate hook the user has to opt into, so a
  project never starts sending work to a remote because it got a safety net.
- **Push only when it's safe.** `autopush` pushes solely when the current branch
  already has an upstream tracking branch and is ahead of it. It never creates
  remotes, sets upstreams, or force-pushes. If a push fails (e.g. the remote
  moved), it stays quiet and leaves the commit local — it does not retry
  destructively.
- **Never commit a worktree into its parent.** `.gitignore` must contain
  `.claude/worktrees/`. Without it, `git add -A` in the main checkout records
  the worktree as a phantom gitlink on the main branch.
- **Never commit secrets.** The `.gitignore` secrets block is mandatory. If you
  notice a secret-looking file that isn't ignored, flag it rather than committing
  it.
- **Idempotent.** Re-running setup must never duplicate hooks or clobber the
  user's `.gitignore` / settings.

## Bundled resources

- `scripts/autocommit.ps1` — Windows Stop-hook script (the commit safety net;
  it does not push).
- `scripts/autocommit.sh` — macOS/Linux Stop-hook script.
- `scripts/autopush.ps1` — Windows Stop-hook script (safe push; **opt-in only** —
  asked separately during setup, registered *after* autocommit when accepted).
- `scripts/autopush.sh` — macOS/Linux counterpart.
- `scripts/progress-check.ps1` — Windows Stop-hook script (stale progress-file
  reminder; **opt-in only** — asked separately during setup, registered before
  autocommit when accepted).
- `scripts/progress-check.sh` — macOS/Linux counterpart.
- `assets/gitignore-base.txt` — universal `.gitignore` starting point.
- `assets/status-template.md` — starting structure for `status.md` (the
  overwrite-semantics snapshot of current state).
- `assets/progress-template.md` — starting structure for `progress.md` (the
  append-only, newest-first history).
- `references/gitignore-languages.md` — per-language `.gitignore` blocks to
  append based on the detected stack.

