Setting up docs/.scrolls/
is a small set of markdown files that act as a project's working memory across sessions: what it does, what state it's in, what's known-missing and why, what's next, and what traps to avoid. A
pointer sends every future session to
first, so state gets picked up instead of re-discovered from scratch each time. This skill scaffolds that system for a project that doesn't have it yet.
This skill's own
directory holds the source templates — copy from there, never edit those files in place.
Cross-platform
Unlike the other four scrolls skills, this one has no bundled
/
script to choose between — nothing here needed porting. File creation happens through your own Read/Write/Edit tools (not raw shell commands), and the one external command this skill relies on (
git rev-parse --show-toplevel
) behaves identically whether invoked from bash or PowerShell — both support the same
command-substitution syntax used throughout this file. Works the same on macOS, Linux, and Windows without any environment-specific branching.
Options
The user may pass these after
as plain text, in any order — there's no real argv parser here, so read the invocation text yourself and pull out:
- / / — a custom docs folder, relative to the current working directory unless given as an absolute path (starts with ). Use this for monorepos or non-standard layouts, e.g. puts the scrolls at
packages/api/docs/.scrolls
. This is the one option where you're naming the docs folder directly rather than picking a base directory — see the CLAUDE.md placement note in step 4 for the tradeoff that comes with going deep.
- / — pin everything to the git repository's top level (
$(git rev-parse --show-toplevel)
), regardless of which subdirectory you actually invoked this from. Fails with a clear message if the current directory isn't inside a git repository — there's no repo root to find.
- / — pin everything to the current working directory explicitly. This is what happens by default anyway when none of // are given — the flag exists so you (or the user) can say so on purpose, e.g. to skip the mismatch check in step 1.
- / — before creating anything, scan recursively under for a scrolls folder that already exists somewhere nearby (same bounded, pruned, -guarded search / use), so a duplicate isn't created by accident. Doesn't change where the new scrolls folder goes if you proceed — see step 1.
- / — name the scrolls folder instead of the default , so it isn't dotfile-hidden. Omit for the default (hidden).
,
, and
are three different ways to answer the same question ("where does the
folder go?") — pass at most one. If more than one is given, stop and ask which was meant.
is independent and combines freely with any of them (or with none).
Steps
1. Resolve BASE_DIR and don't clobber existing work
Compute
— the directory that will contain both the
folder and
:
- / given:
BASE_DIR = $(git rev-parse --show-toplevel)
. If that command fails (not inside a git repository), stop and tell the user — there's no repo root to pin to here; suggest instead.
- / given, or / given: skip straight to computing below — uses and bypasses entirely (see the note under ).
- Nothing given (the common case): . But first, if the current directory is inside a git repository, run
git rev-parse --show-toplevel
and compare it to . If they're the same, or this isn't a git repo, there's nothing to flag. If they differ, tell the user plainly: running from here will create the scrolls at , separate from anything that might already exist at the repository root (), and ask whether that's what they want — the current directory (the default; proceed with it if there's no strong preference either way) or the repo root instead (equivalent to re-running with ). Don't block indefinitely on this — cwd wins if it's a toss-up, since that's this skill's documented default.
If
/
was given, do this scan next, before touching the filesystem: search recursively under
(skip this if
was given — a custom
is an explicit, deliberate location, not something to second-guess) for any directory named
or
containing a
, pruning the same heavy/vendor directories
/
prune (
,
,
,
,
,
,
,
,
,
,
), bounded to a reasonable depth (8 is what the other scrolls skills use). If this finds an existing scrolls folder anywhere under
other than the exact
you're about to create, surface it and ask whether the user meant to run
against that one instead of creating a new, separate one here — proceed with creation only if they confirm that's what they want (e.g. a deliberately separate scrolls system for a sub-project).
Then:
DOCS_BASE = the --path value if -p was given, else "${BASE_DIR}/docs"
SCROLLS_DIR = "scrolls" if --unhide/-u was passed, else ".scrolls"
SCROLLS_PATH = "${DOCS_BASE}/${SCROLLS_DIR}"
replaces every
you'll see referenced below and in the templates — the rest of this skill talks about "the scrolls path" generically. If the user already has a hidden
set up and wants it converted to visible later, that's a separate, dedicated operation — point them at
rather than re-running this skill.
If
already exists with files in it, stop and ask the user whether they want you to fill in only the missing files or leave it alone — never overwrite an existing scroll file silently, since
/
/etc. may hold real accumulated state. The same caution applies to
: never blow away existing content. If
was passed but a
folder already exists there (or vice versa), don't create a second, parallel scrolls folder — tell the user and point at
instead.
2. Gather just enough project context
Don't interview the user at length — a minimal setup should be fast. Infer what you can in a few seconds:
- Project name: from 's , 's , , or failing that the directory's basename.
- One-line tagline: from the same manifest's field, or the first line of an existing , or omit it — it's optional flavor text, not load-bearing.
- Quick orientation: one short paragraph on the project's actual shape — main entry point(s), the one or two files/directories that matter most, and the primary language/stack. Get this by a quick look at the repo root and manifest files, not a deep audit. If the project is genuinely empty (brand new, no code yet), say so plainly rather than inventing structure.
If any of this is ambiguous (e.g. a monorepo with several
s), a single clarifying question is fine — but default to acting rather than blocking on questions the repo already answers.
3. Create the seven files
Copy each file from
into
on disk, substituting the
,
,
, and
placeholders with what you gathered in step 2 and computed above.
is an absolute filesystem path when it came from
/
/the default (all resolve through
, which is always absolute) — that's fine for the actual file writes, but
the text you substitute for inside the templates is not the same string:
- //default (-derived): substitute the short form, (e.g. ) — never the absolute . This is what keeps the files portable: always ends up living at too (step 4), so a reference relative to is correct regardless of whether was or the git root, and regardless of which machine or clone reads it later. Baking in an absolute path here would break the moment the repo is cloned somewhere else.
- /: substitute the full -based as given, unchanged from before (e.g.
packages/api/docs/.scrolls
) — this path is already relative, and where ends up for this case is judgment-dependent (see step 4), so keep the existing behavior rather than guessing at a shorter form.
| Template | → | Purpose |
|---|
| | Reading order + when-to-update table. The entry point every session reads first. |
| | Feature list, filled in as features ship. |
| | Snapshot of current state — overwritten each session, not appended. |
| SCROLLS_PATH/GAP_ANALYSIS.md
| What's known-missing or partial. |
| SCROLLS_PATH/GAP_CONTEXT.md
| Why each gap exists (deliberate cut vs. oversight vs. blocker). |
| | Prioritized, ticketed backlog. |
| | Constraints / Traps / Ditches / Wisdom sections. |
This is the
minimal set — exactly the six files
walks through, plus
itself. Don't invent extra scroll files (security reviews, architecture-decision records, subsystem deep-dives) up front; those get added later, organically, by whoever's doing that specific work, following the pattern
's own last section describes. Leave
blank (drop the placeholder entirely, don't leave literal
text) if you found nothing worth using — it reads fine as
You're picking up work on **Foo**.
with no tagline clause.
and
are the only templates containing
— substitute it per the rule above (short form for
/
/default, full
for
), not a placeholder string, and use the
same substitution in both files.
Templates are intentionally close to empty (placeholder bullets like "(none tracked yet)") — resist the urge to pre-populate
with a guessed feature list or
with invented tickets. A minimal scaffold's job is to hold the
shape; the content accumulates from real sessions. The one exception is
's "Quick orientation" section, which is worth getting right since it's the one piece of static context every session leans on immediately.
4. Point CLAUDE.md at STARTER.md
Read
assets/templates/CLAUDE_MD_BLOCK.md
and substitute
in it the same way as
— that's the block to install.
- //default (-derived): goes at — the same directory that now contains . This is fixed and unambiguous: is exactly what //the mismatch check in step 1 resolved, so there's no separate "project root" judgment call to make here anymore.
- /: where belongs is genuinely judgment-dependent, since a custom might point at an independent monorepo package (its own , short local references — closer to what would produce if you'd ed into that package first) or be one piece of a larger repo meant to stay under a single root referencing the full path. Use whatever location the project's other tooling already expects; if genuinely unclear, ask rather than guessing — this is the one case where a wrong guess is expensive (a broken reference baked into checked-in docs).
Once you know where
goes:
- No there yet: create one containing exactly that block.
- exists but has no scrolls-path reference: insert the block near the top of the file (before other instructions, since "read this first" only works if it's read first), separated by blank lines from surrounding content. If the file already opens with its own top-level heading, add the block's heading as a subsection instead of a second top-level — match the existing file's heading structure rather than fighting it.
- already references (or the short form, if that's what applies here): leave it alone; note this to the user instead of duplicating the block.
5. Report back
Summarize what was created vs. what already existed and was left untouched, and name the two or three things most worth the user's attention next: filling in
's quick-orientation paragraph if you had to guess at it, and writing the first real
entry once something ships.