Ship ten starter templates, so a fresh install teaches the loop types - #233
Merged
Conversation
A brand-new library is empty, and an empty ⌘T picker teaches nothing: the person
who most needs to know what a Goal loop is for is exactly the person who has
never written one. Templates are the natural place to explain the taxonomy,
because a template can *demonstrate* a type rather than describe it.
`MAIN_LOOP.md` orders the five types by how much you have to decide before the
loop can start; the tour subtitles them by what makes them stop. The starter set
makes that axis concrete by being it — the lesson is in each template's
settings, not its prose:
- **Main** ×2 — no done check and no cadence, because "I understood it" is not
checkable by a command. *Where does this live?* · *Why did this break?*
- **Goal** ×3 — its three separate cases: a check that decides (*Get the build
green*, whose token sits in the done check so filling it is what teaches that
exit 0 stops the loop), no check at all (*Review the diff on this branch*,
which resolves when the work is finished), and a metric (*Raise test
coverage*).
- **Timed** ×2 — a brief worth *repeating*. *Nightly dependency review* ·
*Watch the build*. These are also the two that follow their file.
- **Turn** ×2 — the two pause rhythms side by side, which is the only way the
difference reads. *Port {area} to {target}* pauses before writes; *Pair on
this* pauses every turn.
- **Composite** ×1 — *Review, fix, verify* carries three children and the two
hand-offs between them, which is what a composite template is for.
Shipped as real markdown files seeded into `~/.graphcode/templates`, not as
constants, so the format teaches itself: open one and the front matter is there.
Seeding runs **once**, guarded by a dotfile marker, and never writes over a name
somebody already used — a starter you delete stays deleted.
Surfaced in two places:
- **An empty canvas** offers three of them — one Main, one Goal, one Timed, so
the row climbs the commitment ladder — each labelled with what makes that type
stop. One click opens the New loop dialog with the brief already applied.
- **The ⌘T picker** groups them under `Starters`, above All projects and below a
project's own committed templates, *until* somebody saves a brief of their
own. After that the scaffolding stops outranking their work and sorts in with
everything else.
`PromptTemplate.isStarter` rides in the file as `starter: true`, so the mark
survives an edit and is visible to anyone reading the folder.
1482 tests (up from 1467), 22 of them new. swiftlint 0 errors — `AppFeature`
was one line over its type-body budget, so `onboardingDismissed`'s body moved to
the trailing extension the way that file's convention says to.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJR8Wuwc4qnaSBUMcYf7Af
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A brand-new library is empty, and an empty ⌘T picker teaches nothing: the person who most needs to know what a Goal loop is for is exactly the person who has never written one. Templates are the natural place to explain the taxonomy, because a template can demonstrate a type rather than describe it.
The set
MAIN_LOOP.mdorders the five types by how much you have to decide before the loop can start; the tour subtitles them by what makes them stop. These ten make that axis concrete by being it — the lesson is in each template's settings, not its prose.Two deliberate choices worth reviewing:
Get the build greenputs its token in the done check ({test_command}), not the brief. That means the most obvious starter isn't one-click — which is the point: filling it is what teaches that a Goal loop stops itself when a command says so, and that⇥walks every field a template left a hole in.Review the diff on this branchhas no done check at all, so the pair with Get the build green teaches that the check is optional and finishing the work resolves the loop too.How they ship
Real markdown files seeded into
~/.graphcode/templates, not constants — so the format teaches itself: open one and the front matter is right there..starters-seededdotfile, so a starter you delete stays deleted rather than reappearing every launch.Where they show up
An empty canvas offers three — one Main, one Goal, one Timed, so the row climbs the commitment ladder — each labelled with what makes that type stop. One click opens the New loop dialog with the brief already applied.
The ⌘T picker groups them under
Starters— above All projects, below a project's own committed templates — until somebody saves a brief of their own. After that the scaffolding stops outranking their work and sorts in with everything else.PromptTemplate.isStarterrides in the file asstarter: true, so the mark survives an edit and is visible to anyone reading the folder.Verification
swiftlint lint— 0 errors.AppFeaturewas one line over its type-body budget, soonboardingDismissed's body moved to the trailing extension the way that file's own convention says to.swift format lint --strict— clean on every touched fileNot verified visually — no GUI automation here, so the starter row's layout on the empty canvas and the
Startersgroup in the picker want a human eye.🤖 Generated with Claude Code
https://claude.ai/code/session_01MJR8Wuwc4qnaSBUMcYf7Af