| name | repo-bootstrap |
| description | Bootstrap or retrofit a new repository with proven agent docs, README and brand assets, Claude Code settings, ccx, capt-hook guards, tests, linting, CI, and release conventions. Supports Python packages and CLIs using uv, Click, pytest, ruff, and ty; Go CLIs using cobra, slog, Task, and golangci-lint; Swift packages and CLIs using SPM, Swift Testing, SwiftFormat, and SwiftLint; and synced-project SwiftUI iOS apps. Optional publishing covers Great Docs on GitHub Pages, trusted PyPI releases, and Homebrew releases for Go and Swift CLIs. Use when creating a repository from scratch, scaffolding a Python, Go, or Swift package, CLI, or iOS app, or applying these conventions to a young repository. |
Bootstrap a New Repo
Scaffold a repo from battle-tested conventions in layers: a base layer every
repo gets (agent docs, Claude Code settings, guard hooks, code search), and a
language layer on top โ python for Python packages (uv toolchain, starter
package, CI, plus opt-in features โ a Great Docs site and tag-driven PyPI
releases), go for Go CLIs (cobra, slog, golangci-lint + gofumpt, Taskfile, CI,
plus an opt-in release feature โ goreleaser to a shared Homebrew tap), swift
for Swift CLIs and libraries (SPM, swift-argument-parser, Swift Testing,
SwiftFormat + SwiftLint, XcodeBuildMCP, plus the same opt-in release feature โ a
universal-binary cask via the shared release-swift.yml), or swift-app for
SwiftUI iOS apps (synced-folder Xcode project, Swift Testing, the same lint stack
and XcodeBuildMCP wiring; no release feature โ app distribution is product work).
Templates render deterministically through one CLI; your judgment goes into naming,
prose, and the follow-up edits โ not file copying.
Scope: this skill scaffolds conventions and a minimal skeleton only โ it does
not implement the project's features, in any language. Filling TODO(bootstrap)
prose markers (Phase 4) is the only content work; the starter command stays a
hello-world placeholder (the python, go, and swift layers each scaffold one; other
languages get a hand-written equivalent). STOP at the skeleton: no business logic,
real commands, services/daemons, or release/distribution tooling beyond basic CI โ the
go and swift release features (Homebrew tap release workflows) ship only when the
user selects them. Building the product is separate work that begins after Phase 6.
The whole skill is driven by a single command:
BOOTSTRAP="python3 ${CLAUDE_PLUGIN_ROOT}/skills/repo-bootstrap/scripts/bootstrap.py"
$BOOTSTRAP identity | check-name NAME | scaffold [flags] | verify [flags]
Work the phases below in order. Each ends with an Exit criteria line โ don't
advance until it holds. Every decision is made once, in Phase 1, and then flows
downstream as flags.
Terminology
- Layer โ
base (all repos), or one of python, go, swift (SPM package/CLI),
swift-app (Xcode iOS app), bun (single-binary TypeScript CLI/TUI) โ each implies base.
- Feature โ a layer-scoped opt-in toggled by
--features. Python: docs (Great
Docs site + Pages workflow), pypi (trusted-publishing release workflow), and the
opt-in maturin (native PyO3 wheels โ only meaningful with pypi, off unless named).
Go, Swift, and Bun: release (go: goreleaser โ shared Homebrew tap; swift: shared
release-swift.yml โ universal-binary cask; bun: shared release-bun.yml โ native-runner
bun --compile matrix โ binary cask on the same tap). Not offered on
swift-app โ requesting it there is silently dropped (App Store/TestFlight
distribution is product work). A feature requested outside its layer
is silently dropped. Each gates whole files and inline sections of shared files
(README, AGENTS, pyproject / goreleaser / the PyPI or release-bun caller).
- Template โ a file under
templates/; only ever rendered by bootstrap.py scaffold, never hand-copied.
- Placeholder โ a
{{NAME}} token in a template, rendered by bootstrap.py scaffold from --var inputs.
- Partial โ a
{{> _partials/<name>.md}} token that inlines a README seed from templates/_partials/ at scaffold time. The seed is render-only โ it carries no dest and is never written to the target repo.
- Rendered artifact โ
AGENTS.md, CLAUDE.md, .claude/settings.json, .mcp.json, .gitignore, and the plugin installer are generated by cc-guides from a .claude/fragments/<target>/ layout dir: scaffold writes a layout.toml (an ordered list of repo-local *.fragment.* pieces + imports of shared cc-skills:<name> fragments from github:yasyf/cc-skills@main) plus the local prose fragments, then the post-write step runs cc-guides render, which composes each <target> in place (markdown/shell get a banner; JSON is deep-merged raw). The layout dir's path below .claude/fragments/ is the artifact path unless the layout.toml declares target = "<path>", which the dot-leading artifacts use so the layout dir never shadows the file it renders: gitignore/ โ .gitignore, mcp.json/ โ .mcp.json, pre-commit-config.yaml/ โ .pre-commit-config.yaml. cc-guides is a hard prerequisite (brew install yasyf/tap/cc-guides); there is no Python fallback. See reference/base-conventions.md and the cc-guides README.
- TODO marker โ a
TODO(bootstrap): line in scaffolded output that you must replace with real prose afterward.
Phase 0 โ Identity & environment
Resolve author identity first (never hardcode or guess it):
$BOOTSTRAP identity
It prints AUTHOR_NAME=, AUTHOR_EMAIL=, GITHUB_USER= resolved from git config
and gh. Any value reported as MISSING on stderr must come from the user โ ask,
don't invent. Then make sure you're in a git repo on the default branch: if the
directory isn't a repo yet, git init -b main. Then create a colocated jj repo
unless one already exists (.jj/ present): jj git init --git-repo . โ it backs
jj onto the git repo so the scaffolded .claude/jj-config.toml is live from the
first commit (see reference/base-conventions.md).
Now that the repo has an absolute path, mark it trusted for Claude Code so the
first session in it skips the trust dialog: $BOOTSTRAP trust --target .. This
sets hasTrustDialogAccepted for the repo in ~/.claude.json (an atomic,
machine-local side effect โ not a committed file); on cc-pool machines every
pooled account inherits the trust through the shared overlay.
Exit criteria: identity values known (resolved or supplied by the user); the
target is a git repo on main with a colocated jj repo (.jj/).
Phase 1 โ Decide layer & features (the only decision phase)
First decide the layer. Apply the python layer for a Python project (uv / PyPI);
apply the go layer for a Go CLI; apply the swift layer for a Swift CLI or
library (SPM); apply the swift-app layer for a SwiftUI iOS app (Xcode project);
apply the bun layer for a TypeScript CLI or TUI that ships as a single compiled
binary (bun toolchain); otherwise scaffold base only. Base always applies. For an unsupported language,
scaffold base only, then hand-write a skeleton that
mirrors the shape of a layered starter, not its substance: a minimal package/module
layout, exactly one hello-world command that builds and runs, one smoke test, a
CI workflow that builds and tests, and the language STYLEGUIDE rules โ use
reference/python-stack.md and reference/go-stack.md as the worked examples (the
hello-world command stays a placeholder). STOP at the skeleton: no business logic,
real commands, services/daemons, or release/distribution tooling. For the go and swift
layers, Homebrew release workflows ship only via the opt-in release feature
(off by default); for a hand-written language they're product work the user must
explicitly ask for.
A second language in a subdir? When a repo carries a secondary language beside
the primary โ a Go CLI whose helper package or capt-hook hooks are Python, say โ
add --secondary-layer <lang> (currently python) plus --var SECONDARY_CODE_ROOT=<dir>.
The secondary layer contributes only its styleguide at <dir>/STYLEGUIDE.md and an
AGENTS.md ## <Lang> Style pointer โ never a second toolchain (no extra root
go.mod/pyproject.toml/CI). It must differ from --layer. This is how the primary
language keeps the root STYLEGUIDE.md while the secondary lands beside its own code.
Then gather everything else in one AskUserQuestion round:
- All layers: project name, one-line description, visibility (public or
private GitHub repo โ it sets the license and feature defaults below and the
gh repo create flag in Phase 6), license (first option "default for
visibility": PolyForm-Noncommercial-1.0.0 if public, none if private; MIT for
permissive open source), extras (superset, env, plugin โ see the table in
Phase 2; multiSelect, default none; pick plugin when the repo ships a Claude
Code plugin that provisions a released binary). The scaffold requires --extras
explicitly โ pass none when no extras are chosen.
- Python additionally: dist name, package name, Python floor + pin versions, and
the features as a
multiSelect "Optional Python features" โ docs (Great Docs on
GitHub Pages) and pypi (tag-driven trusted-publishing release). Default both
selected for a public repo, neither for private โ PyPI publishing is inherently
public, and Pages on a private repo needs a paid plan. A PyO3 native-extension repo
also selects maturin (off by default; it builds per-platform wheels and requires pypi).
- Go additionally: the Go toolchain version (
GO_VERSION, e.g. 1.26), and the
feature as a multiSelect "Optional Go features" โ release (goreleaser
build + a Homebrew cask pushed to yasyf/homebrew-tap). Default unselected
(off) regardless of
visibility โ release/distribution tooling is product work the user opts into, and
it needs the tap repo plus a HOMEBREW_TAP_TOKEN secret. Daemons, signed apps,
and extensions are product-specific and are not scaffolded by repo-bootstrap.
- Swift additionally: the library module name (
MODULE_NAME, UpperCamelCase โ
default the UpperCamel of a multi-word project name; it must differ from the
project name beyond letter case (case-insensitive filesystems merge the two
Sources/ dirs), so a single-word project suffixes the module โ fusekit โ
FusekitKit, not Fusekit. The project name names the executable target), the tools version
(SWIFT_TOOLS_VERSION, default 6.2), and the one feature as a multiSelect
"Optional Swift features" โ release (a universal arm64+x86_64 binary, signed and
notarized with the required MACOS_* secrets, published as a Homebrew cask to
yasyf/homebrew-tap via the shared immutable release-swift.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b). Default
unselected (off), same rationale as go.
- Swift app additionally:
MODULE_NAME (names the <Module>App type and the
test target's import), the reverse-DNS bundle prefix (BUNDLE_ID_PREFIX, default
com.<github-user> โ the bundle id derives as <prefix>.<project>), and the iOS
floor (IOS_DEPLOYMENT_TARGET, default 26.0). No features.
- Bun additionally: the bun toolchain pin (
BUN_VERSION, exact X.Y.Z such as
1.3.14 โ it becomes the .bun-version file that CI's setup-bun and the release
matrix both read; find the current release with bun --version), and the one
feature as a multiSelect "Optional Bun features" โ release (a single
compiled binary per target, built on native runners (platform-native deps rule out cross-compiling),
signed and notarized with the required MACOS_* secrets, published as a Homebrew cask
to yasyf/homebrew-tap via the shared immutable release-bun.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b). Default
unselected (off), same rationale as go/swift.
Write DESCRIPTION in the writing-docs opener register โ it becomes the README
opener, the GitHub About description, the pyproject or module description, the
Great Docs hero.tagline, and the gen-image --tagline (one fragment, five
surfaces).
Before Phase 2, reconcile the answers into concrete flags: a "default for
visibility" license answer becomes LICENSE_ID=PolyForm-Noncommercial-1.0.0
(public) or LICENSE_ID=none (private); the feature picks become --features.
Feature โ flag mapping: each selected feature becomes one token in --features
(python: docs,pypi, docs, or pypi, plus maturin for a native-extension repo;
go: release; swift: release; bun: release); deselect everything โ
--features "". Omitting the flag
selects the layer's on-by-default features โ fine for python (defaults to
docs,pypi; maturin is opt-in and must be named), but for go, swift, and bun always
pass --features explicitly (release when selected, else ""), because release
defaults off. For swift-app pass --features "" โ it offers none, and a requested
release is silently dropped. Don't scaffold a docs site or release pipeline the
user didn't ask for and then strip it by hand โ that's what the flags prevent.
Naming rule (python): the PyPI dist name must equal the CLI command โ short and
memorable. The import package may differ. Worked example: dist + CLI capt-hook,
package captain_hook, repo captain-hook. Before committing to a dist name:
$BOOTSTRAP check-name DIST_NAME
(AVAILABLE โ proceed; TAKEN โ pick another; UNKNOWN โ have the user verify;
INVALID โ not a valid PyPI name.) check-name checks the exact token only; PyPI's similarity
guard also rejects names that ultranormalize (lowercase, strip -/_/.) to an existing project,
so sweep separator variants too (reference/python-stack.md ยง The Naming Triad).
Naming rule (go): the binary, Go module leaf, and repo all share the project name
(cmd/<name>, module github.com/<user>/<name>) โ no dist/package split, and
check-name (a PyPI check) is python-only.
Naming rule (swift): the executable and repo share the project name (swift run <name>; with feature release the shared workflow requires the SPM executable
product to equal the repo name โ that's the whole calling contract). MODULE_NAME
is the importable library module โ the same split as python's dist/package โ and
must differ from the project name beyond letter case (suffix single-word names:
FusekitKit). For swift-app, MODULE_NAME names the app type (<Module>App) and
the module tests import; the app bundle and folders carry the project name, so a
swift-app project name allows only alphanumerics and hyphens (it becomes the
bundle id suffix โ no underscores).
Naming rule (bun): the binary and repo share the project name โ no module split
(the entry point is fixed at src/index.ts). With feature release the shared
release-bun.yml compiles the binary named after the repo and packages a cask under
that name; that plus the .bun-version pin is the whole calling contract.
Placeholder reference
| Var | Meaning | Example |
|---|
PROJECT_NAME | Repo name | captain-hook |
DESCRIPTION | Opener fragment (writing-docs register) | Claude Code hooks, one decorator each. |
AUTHOR_NAME | From bootstrap.py identity | โ |
AUTHOR_EMAIL | From bootstrap.py identity | โ |
GITHUB_USER | GitHub login | yasyf |
LICENSE_ID | SPDX id, or none for no license | PolyForm-Noncommercial-1.0.0 |
DIST_NAME | PyPI dist == CLI command (python) | capt-hook |
PACKAGE | Import package (python) | captain_hook |
PYTHON_MIN / PYTHON_PIN | Supported floor / dev pin (python) | 3.13 / 3.14 |
GO_VERSION | Go toolchain version (go) | 1.26 |
MODULE_NAME | Library module / app type (swift, swift-app); โ project name | CaptHook |
SWIFT_TOOLS_VERSION | Package.swift tools version (swift) | 6.2 |
BUNDLE_ID_PREFIX | Reverse-DNS prefix (swift-app) | com.yasyf |
IOS_DEPLOYMENT_TARGET | iOS floor (swift-app) | 26.0 |
BUN_VERSION | bun toolchain pin, exact X.Y.Z โ .bun-version (bun) | 1.3.14 |
BINARY_NAME | Released binary the plugin provisions (extra plugin) | ccx |
RELEASE_REPO | GitHub repo that releases the binary (extra plugin) | yasyf/cc-context |
BREW_PACKAGE | Fully-qualified brew formula or cask (extra plugin) | yasyf/tap/ccx |
PLUGIN_NAME | Plugin name, feeds the per-release descriptor (extra plugin) | cc-context |
Derived automatically: REPO_URL, DOCS_URL (GitHub Pages), PY_TARGET,
MODULE_PATH (go: github.com/<user>/<name>), BUNDLE_ID (swift-app:
<prefix>.<name>), YEAR.
Features are independent of --var: they gate files and template sections, not
placeholder values.
Exit criteria: layer and visibility chosen; names, license, and extras chosen;
for python, the two features chosen and the dist name check-named; for go,
GO_VERSION and the go feature chosen;
for swift, MODULE_NAME /
SWIFT_TOOLS_VERSION and the release feature chosen; for swift-app,
MODULE_NAME / BUNDLE_ID_PREFIX / IOS_DEPLOYMENT_TARGET chosen; for bun,
BUN_VERSION and the release feature chosen.
Phase 2 โ Scaffold
$BOOTSTRAP scaffold \
--target . --layer python --extras env --features docs,pypi \
--var PROJECT_NAME=... --var "DESCRIPTION=..." \
--var "AUTHOR_NAME=..." --var AUTHOR_EMAIL=... --var GITHUB_USER=... \
--var LICENSE_ID=PolyForm-Noncommercial-1.0.0 \
--var DIST_NAME=... --var PACKAGE=... \
--var PYTHON_MIN=3.13 --var PYTHON_PIN=3.14
For the go layer:
$BOOTSTRAP scaffold \
--target . --layer go --extras none --features "" \
--var PROJECT_NAME=... --var "DESCRIPTION=..." \
--var "AUTHOR_NAME=..." --var AUTHOR_EMAIL=... --var GITHUB_USER=... \
--var LICENSE_ID=MIT --var GO_VERSION=1.26
For the swift layer (SPM package/CLI):
$BOOTSTRAP scaffold \
--target . --layer swift --extras none --features "" \
--var PROJECT_NAME=... --var "DESCRIPTION=..." \
--var "AUTHOR_NAME=..." --var AUTHOR_EMAIL=... --var GITHUB_USER=... \
--var LICENSE_ID=MIT --var MODULE_NAME=... --var SWIFT_TOOLS_VERSION=6.2
For the swift-app layer (SwiftUI iOS app):
$BOOTSTRAP scaffold \
--target . --layer swift-app --extras none --features "" \
--var PROJECT_NAME=... --var "DESCRIPTION=..." \
--var "AUTHOR_NAME=..." --var AUTHOR_EMAIL=... --var GITHUB_USER=... \
--var LICENSE_ID=none --var MODULE_NAME=... \
--var BUNDLE_ID_PREFIX=com.... --var IOS_DEPLOYMENT_TARGET=26.0
For the bun layer (single-binary TypeScript CLI/TUI):
$BOOTSTRAP scaffold \
--target . --layer bun --extras none --features "" \
--var PROJECT_NAME=... --var "DESCRIPTION=..." \
--var "AUTHOR_NAME=..." --var AUTHOR_EMAIL=... --var GITHUB_USER=... \
--var LICENSE_ID=MIT --var BUN_VERSION=1.3.14
Set --features from Phase 1 โ python: docs,pypi (both), pypi/docs (one), or
"" (neither; omitting the flag equals docs,pypi โ maturin is opt-in, name it
explicitly); go, swift, and bun: release or "" โ always pass it explicitly (release
is off by default, so omitting selects no features); swift-app: "". For
base layer, drop the language --vars and --features. --extras is always
required; pass --extras none if none were chosen. To add a second language beside
the primary, append --secondary-layer python --var SECONDARY_CODE_ROOT=<dir> (see
Phase 1).
Rules:
- Never copy from
templates/ by hand and never leave a {{...}} token in the
repo. The CLI renders, validates inputs, and fails loudly on leftovers.
cc-guides is a prerequisite. After writing files, scaffold runs cc-guides render in the target to compose each .claude/fragments/ layout dir
(AGENTS.md, CLAUDE.md, .claude/settings.json, the plugin installer) into its
artifact; a missing binary is a hard error (brew install yasyf/tap/cc-guides).
A composed artifact is generated โ edit the fragments under its
.claude/fragments/ layout dir and re-run cc-guides render (bootstrap only; in an
onboarded repo, commit and push the fragment โ the Guides workflow renders).
- Idempotent: identical files are
SKIPped; differing files are reported as
CONFLICT and nothing is written (resolve per-file, or re-run with --force).
LICENSE_ID=none writes no LICENSE and drops every license reference (README
badge and License section, pyproject license/license-files). Licenses without
a bundled template (bundled: PolyForm-Noncommercial-1.0.0, MIT) print a
MANUAL line โ fetch the text from the SPDX list:
curl -fsS https://raw.githubusercontent.com/spdx/license-list-data/main/text/<SPDX-ID>.txt > LICENSE.
--dry-run previews without writing.
For python, follow the scaffold with uv sync --extra dev (creates uv.lock โ
commit it), uv run pytest, and uvx prek install to activate the commit hooks
(.pre-commit-config.yaml; ruff auto-formats and fixes import order, ty prints
whole-project type warnings โ never blocking โ on every commit).
For go, follow the scaffold with go mod tidy (resolves cobra and writes go.sum โ
commit it), then go vet ./..., task build, and task test (go test -race ./...);
run uvx prek install to activate the gofumpt + golangci-lint commit hooks.
For swift, follow the scaffold with swift build (resolves swift-argument-parser and
writes Package.resolved โ commit it, the go.sum/uv.lock analogue), swift test,
and uvx prek install to activate the SwiftFormat + SwiftLint commit hooks (they call
the brew binaries โ brew install swiftformat swiftlint once per machine).
For swift-app there is no generation step โ the committed pbxproj IS the project
(synced folders mean new .swift files need no project edit, ever). Sanity-build with
xcodebuild build -project <name>.xcodeproj -scheme <name> -destination 'generic/platform=iOS Simulator' CODE_SIGNING_ALLOWED=NO, then uvx prek install
as above.
For bun, follow the scaffold with bun install once โ it resolves @types/bun +
typescript and writes bun.lock (commit it, the go.sum/uv.lock analogue: CI runs
bun install --frozen-lockfile and fails without it). Then bun run typecheck and
bun test. There are no commit hooks (bun ships no formatter here), so no uvx prek install step.
Two integrations are armed after the repo is published (Phase 6), because they
need an origin remote: the session reviewer (uvx capt-hook review enable) and,
when cc-notes is installed, cc-notes (cc-notes init). Do not run them here โ
capt-hook review enable rejects a repo with no origin, and cc-notes' refspecs have
nothing to target until the remote exists. See reference/hooks.md.
What lands where
| Destination | Layer | Notes |
|---|
.claude/fragments/AGENTS.md/ โ AGENTS.md, plus STYLEGUIDE.md, README.md | base; python/go/swift/swift-app/bun override | AGENTS.md composes from a layout dir: repo-local <name>-development-guide + <name>-style fragments around cc-skills: imports (ask-before-assuming, code-review-response, parallelize, writing-plans, ccx, version-control); the Releases rule ships as a releases fragment gated on pypi (python) / release (go, swift, bun). Every README follows the writing-docs skeleton (references/readme.md); the language versions gate the get-started path, agent-block invocation, and docs teaser on --features; swift-app shares the swift STYLEGUIDE.md |
.claude/fragments/CLAUDE.md/ โ CLAUDE.md and .claude/fragments/gitignore/ โ .gitignore, plus CHANGELOG.md, LICENSE | base; .gitignore language override | CLAUDE.md composes from the shared cc-skills:claude-rules import (no local fragment): body @AGENTS.md plus Claude-only rules (AskUserQuestion, task tracking, plan execution & orchestration); the rules stay fleet-synced from cc-skills plugin/guides/md/; .gitignore is a cc-guides artifact too, composing cc-skills:gitignore-* (base + a language variant, -docs with feature docs) then a repo-local gitignore-local overlay last; LICENSE omitted with license none |
.github/workflows/guides.yml | base | the cc-guides shim: one job calling the reusable Guides workflow (yasyf/cc-guides/.github/workflows/guides.yml@main) โ push/cron/dispatch render and commit the artifacts, PRs get pr-check. Copied verbatim from the cc-guides README; the machinery lives there |
.claude/fragments/mcp.json/ โ .mcp.json | base; swift layers add mcp-swift | a rendered artifact composed by cc-guides: cc-skills:mcp-base (empty {"mcpServers":{}} โ code search ships via the cc-context@cc-context plugin (the ccx facade), not a per-project server), the swift layers adding cc-skills:mcp-swift (the xcodebuildmcp server, command: xcodebuildmcp, args: [mcp] โ the sanctioned build/test/run/simulator driver), and a {} mcp-overrides.fragment.json last for repo-specific servers. The pack fragments live in cc-skills plugin/guides/json/; edit them there, not in the scaffolded repo |
.claude/fragments/.claude/settings.json/ โ .claude/settings.json | base; python/go/swift/bun override | a rendered artifact composed by cc-guides: cc-skills:settings-base (hooks-free โ hook registration comes from the captain-hook plugin, not settings; disables the built-in Artifact tool (disableArtifact: true); registers the yasyf/cc-skills, yasyf/cc-notes, yasyf/cc-context marketplaces; enables codex@skills, slop-cop@skills, llm-prompts@skills, writing-docs@skills, cc-context@cc-context, cc-notes@cc-notes) deep-merged with the layer variant (settings-go adds go/task perms; settings-python adds uv perms + ty env; settings-swift adds swift/xcodebuild/xcodebuildmcp/swiftformat --lint/swiftlint; settings-bun adds bun/bunx/tsc perms) and a placeholder-free {} settings-overrides.fragment.json for repo-specific overrides. The pack fragments live in cc-skills plugin/guides/json/; edit them there, not in the scaffolded repo |
.claude/jj-config.toml | base | jj VCS config; settings.json env points JJ_CONFIG at it |
.claude/ty-quiet.toml | python | [rules] all = "ignore"; settings.json env points TY_CONFIG_FILE at it so ty is silent inside Claude sessions (no thrashing on diagnostics). CI (uvx prek run ty), commits made outside Claude sessions, and editors run without that env and keep the real [tool.ty] config (all = "warn" โ diagnostics print, nothing blocks) |
.claude/hooks/STYLEGUIDE.md | base | the Python style guide for the repo's .claude/hooks/ capt-hook hooks; ships in every scaffold (hooks are Python whatever the primary language), with a ## Hook Style AGENTS.md pointer. The packs themselves need no scaffold: capt-hook's builtins activate automatically (general/fixes/steering/performance everywhere, python/go by file detection) and the ccx/cc-present guard packs load from their enabled plugins (see reference/hooks.md) |
<SECONDARY_CODE_ROOT>/STYLEGUIDE.md | --secondary-layer python | a Python style guide beside a secondary language's code (never at the root), with a ## Python Style AGENTS.md pointer; only present when --secondary-layer is set |
.claude/skills/xcodebuildmcp-cli/SKILL.md | swift, swift-app | the vendored XcodeBuildMCP project skill (help-first CLI discovery); AGENTS.md mandates it before any XcodeBuildMCP call |
pyproject.toml, .python-version | python | pyproject gains a docs dependency group only with feature docs |
.claude/fragments/great-docs.yml/ โ great-docs.yml | python + feature docs | omitted entirely without docs; a cc-guides rendered artifact: a repo-local head (module, repo, urls, hero) + cc-skills:great-docs-fleet (shared display keys) + cc-skills:great-docs-prerender (the pre_render titles entry โ gd-build materializes the script into docs/scripts/.gd-build/ at build time โ the docs .gitignore ignores .gd-build/ at any depth; see reference/docs-site.md) |
.github/workflows/ci.yml | python, go, swift, or swift-app | always; go runs go vet/go test -race/go build + golangci-lint + govulncheck; swift runs one macos-26 job (macOS minutes bill 10ร โ deliberately not a matrix): swiftformat --lint, swiftlint, swift build, swift test (SPM cache keyed on Package.resolved); swift-app the same but xcodebuild test on an iOS Simulator destination |
.claude/fragments/pre-commit-config.yaml/ โ .pre-commit-config.yaml | python, go, or swift | a rendered artifact composed by cc-guides: cc-skills:precommit-base (the repos: key + the prek-native builtin hygiene hooks) plus the language fragment โ cc-skills:precommit-python (ruff + ty), cc-skills:precommit-go (gofumpt + golangci-lint), cc-skills:precommit-swift (swiftformat + swiftlint as repo: local system hooks against the brew binaries; the upstream hooks build from source via SPM โ minutes-long). The pack fragments live in cc-skills plugin/guides/yml/; edit or rev-bump them there, not in the scaffolded repo. Via prek, activate with uvx prek install |
.swiftformat, .swiftlint.yml | swift, swift-app | nicklockwood SwiftFormat (NOT Apple's swift-format), minimal SwiftLint (force_unwrapping opt-in, warnings never block) |
.claude/fragments/.github/workflows/docs.yml/ โ .github/workflows/docs.yml | python + feature docs | Pages docs build, a cc-guides rendered artifact: a repo-local preamble (triggers, paths filter) + the shared cc-skills:docs-build-{head,sync,tail} + cc-skills:docs-publish pieces; the build step runs gd-build (Quarto pinned 1.9.38, version-gated perf patches, pre_render titles absorbed โ see reference/ci-and-release.md) |
.github/workflows/release-pypi.yml | python + feature pypi | caller: build via shared immutable release-pypi-build.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b, then OIDC publish + github-release in-repo (PyPI Trusted Publishing must run in the caller, not the reusable workflow); feature maturin adds maturin: true |
<PACKAGE>/{__init__,__main__,cli}.py, <PACKAGE>/py.typed | python | Click + loguru starter |
tests/{__init__,test_cli}.py | python | strict CliRunner tests |
go.mod, cmd/<name>/main.go, internal/{cli,version,log}/*.go, Taskfile.yml, .golangci.yml, .editorconfig | go | cobra + slog starter (one hello command + one smoke test); go.sum comes from go mod tidy |
.goreleaser.yaml, .github/workflows/release.yml | go + feature release | goreleaser builds and signs the matrix without publishing; the shared exact-ID pipeline verifies and publishes the release, then its native Homebrew cask to yasyf/homebrew-tap; release.yml is a one-liner pinned to immutable release-go.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b (gates on verify-tag-on-main). A formula (services/deps) is a documented recipe, not scaffolded โ see reference/go-ci-and-release.md |
.github/workflows/release.yml | swift + feature release | a zero-config one-liner forwarding to the shared immutable release-swift.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b reusable workflow (goreleaser can't build Swift): verify-tag-on-main, universal swift build, exact --version/tag assertion, codesign + notarytool, GitHub release, synthesized binary cask to the tap. No goreleaser config, no cask template โ see reference/swift-ci-and-release.md |
Package.swift, Sources/<Module>/, Sources/<name>/, Tests/<Module>Tests/ | swift | logic-in-library + thin ArgumentParser executable (one hello subcommand + Swift Testing smoke tests); Package.resolved comes from swift build |
<name>.xcodeproj/{project.pbxproj, xcshareddata/xcschemes/<name>.xcscheme} | swift-app | the committed synced-folder project (objectVersion 77, fixed synthetic UUIDs) โ never regenerate it, never let Xcode "upgrade" it; adding source files needs no project edit |
<name>/App/*.swift, <name>/Assets.xcassets/*, <name>Tests/ | swift-app | SwiftUI @main app + ContentView, stock asset catalog, Swift Testing smoke test (@testable import <Module>) |
.superset/config.json | extra superset | worktree bootstrap (env copy, direnv, uv sync on python, jj init + identity) |
.env | extra env | DEBUG=1; the one local env file, always gitignored |
.claude/fragments/plugin/scripts/install-binary.sh/ โ plugin/scripts/install-binary.sh | extra plugin | the canonical plugin binary provisioner, a rendered binrun wrapper โ bin/<name> symlinks to it, and it locates binrun and execs the sidecar bin/<name>.binrun descriptor. Scaffold writes a layout.toml importing cc-skills:binrun-shim with a binary arg; cc-guides render composes it into the wrapper. The plugin also ships its bin/<name>.binrun descriptor, rendered per release. See reference/go-ci-and-release.md ยง binrun descriptor + wrapper |
docs/assets/{logo.png,readme-banner.webp,social-preview.jpg} | base | generated, not scaffolded โ Phase 3 creates them via the gen-image skill's brand pipeline; the README banner (inside the H1) and Great Docs logo auto-detection point here, and Phase 6 uploads the social card as the repo's GitHub social preview |
docs/assets/demo.png + docs/scripts/demo.sh (or .cli-demo/demo.tape) | base | generated, not scaffolded โ Phase 4's demo step freezes a real run of the get-started command and commits the generator beside it; verify NOTEs a README demo reference with no asset or no committed generator |
Exit criteria: scaffold exited 0 (no CONFLICTs, no leftover {{...}}, the
post-write cc-guides render composed AGENTS.md/CLAUDE.md/.claude/settings.json
from their .claude/fragments/ layout dirs);
LICENSE present (or MANUAL line resolved, or license none); for python,
uv sync --extra dev succeeded and uv.lock is committed; for go, go mod tidy
succeeded and go build ./... passes (go.sum committed); for swift,
swift build and swift test pass (Package.resolved committed); for bun,
bun install succeeded and bun.lock is committed (bun run typecheck + bun test
pass); for swift-app,
the xcodebuild build โฆ generic/platform=iOS Simulator sanity build passes (or
Xcode/the iOS platform is absent locally and CI owns it).
Phase 3 โ Brand images (mascot + banner + social card)
Every repo gets three generated brand assets, produced by the gen-image
skill's brand pipeline โ apply that skill for this phase; it owns the image
CLI, API-key resolution, model choice, and compression. If the gen-image plugin
is not installed, install it from this marketplace (gen-image@skills,
marketplace yasyf/cc-skills) or apply the No brand images escape hatch.
docs/assets/logo.png โ square 1024x1024 mascot character, transparent
background. With feature docs, Great Docs auto-detects it as the navbar logo
and favicon โ zero config (reference/docs-site.md). Stays PNG: Great Docs
detection only matches svg/png.
docs/assets/readme-banner.webp โ wide 1536x512 dark banner: project name and
tagline on the left, the same mascot on the right. The scaffolded README
already references it.
docs/assets/social-preview.jpg โ 1536x768 (2:1) social card from the same
banner generation; Phase 6 uploads it as the repo's GitHub social preview
(GitHub accepts only PNG/JPG/GIF under 1 MB there โ hence JPEG).
gen-image compresses every output to under 1 MiB locally โ small enough for
jj's snapshot limit and GitHub's upload cap.
Default-on for every layer. Skip only when the user declines or gen-image's key
resolution comes up empty (its SKILL.md owns the chain) โ then apply the No
brand images escape hatch instead of leaving a dangling README reference.
Pick the mascot concept first: a cute character that puns on the project's name or
purpose (a crab for a fleet tool, an octopus for an orchestrator). Then invoke the
gen-image skill's brand pipeline from the repo root:
brand --name PROJECT_NAME --tagline "DESCRIPTION" --concept "MASCOT_CONCEPT" \
--out-dir docs/assets
It generates the mascot first, composes the banner from it so the character
matches, writes all three files above, and prints every output path.
View all three files with Read โ re-run with a refined --concept if the
mascot misses, or regenerate if the in-image name/tagline text is wrong. On a
re-run where all three files already exist, skip unless the user asked for a
regeneration. Retrofitting a repo that already has a logo but no social card?
Re-run with --from-logo โ it reuses the existing logo.png and regenerates
only banner + social card (--concept not needed).
Exit criteria: docs/assets/logo.png (square, transparent),
docs/assets/readme-banner.webp (1536x512), and docs/assets/social-preview.jpg
(1536x768) exist and look right when viewed with Read โ or the escape hatch was
applied and the README banner line removed.
Phase 4 โ Replace TODO(bootstrap) markers
Every TODO(bootstrap): marker is judgment work for you. Find them all with
rg -n 'TODO\(bootstrap\)', and read the matching reference before editing.
For prose markers โ anything a human reads rather than a tool parses โ apply the
writing-docs skill before drafting: its technical-builder voice governs the
README opener and use cases and the great-docs hero tagline. Run
slop-cop check <file> --lang=markdown on each prose file you fill (slop-cop is a Go binary; if it's not on PATH, use the /slop-cop-check skill โ never uvx slop-cop).
README.md (opener, get-started demo, agent block, use cases, previews) โ
read the writing-docs skill's references/readme.md first, then
reference/base-conventions.md for the bootstrap-only mechanics.
- Demo โ once the starter CLI runs, capture the get-started demo: freeze a
real run of the exact command the README shows and record the one-liner in
docs/scripts/demo.sh (commit both). When the tool is flow-shaped (TUI,
progress, multi-step), offer the cli-demo skill's animated SVG instead and
commit .cli-demo/demo.tape. No tooling โ the No terminal demo escape
hatch (fenced output block).
AGENTS.md (repository structure tree) โ read reference/base-conventions.md
first.
great-docs.yml (navbar color, accent color, hero tagline โ keep the tagline
equal to the README opener fragment) โ read reference/docs-site.md first.
(Only present with feature docs.)
Exit criteria: rg -n 'TODO\(bootstrap\)' returns nothing.
Phase 5 โ Verify
$BOOTSTRAP verify --layer python --target .
Set --layer go for a go repo, --layer swift / --layer swift-app for the swift
layers, --layer bun for a bun repo. Add --no-license when license none was chosen โ
the LICENSE check inverts to require the file absent. Runs every check and reports
PASS/FAIL per check: leftover-token scan, LICENSE presence (or absence), hook
inline tests, and either (python) uv sync โ pytest โ uv build โ wheel smoke,
(go) go vet โ golangci-lint (skipped with a NOTE if not installed) โ go build
โ go test -race โ binary smoke, (swift) swift build โ swift test โ
swiftformat/swiftlint (NOTE-skipped if not installed) โ a swift run <name> --help
smoke, (bun) bun install โ bun run typecheck โ bun test, or (swift-app) swiftformat/swiftlint โ an xcodebuild build against the
generic iOS Simulator destination (NOTE-skipped without Xcode or with the iOS
platform component not downloaded; the simulator test suite is CI's job and is
NOTEd, not run). Fix failures and re-run; never skip a FAIL.
Remaining TODO(bootstrap) markers are listed as a NOTE โ clear them before calling
the repo done โ and so is a README banner reference whose image is missing (Phase 3 was
dropped: generate the images, or apply the escape hatch), a banner without
social-preview.jpg beside it (generate it with --from-logo), or a README demo
reference whose asset or committed generator (docs/scripts/demo.sh /
.cli-demo/demo.tape) is missing (Phase 4's demo step, or the No terminal
demo escape hatch). For base layer,
drop the --layer flag (it defaults to base).
Exit criteria: verify prints All checks passed.
Phase 6 โ Commit & publish
Atomic, conventional-prefix commits โ one logical change each, conditioned on the
layer and features actually scaffolded:
chore: scaffold repo conventions (AGENTS, STYLEGUIDE, settings, hooks) (the capt-hook review enable / cc-notes init registrations are committed later, in the publish step below, since they need origin)
feat: initial <package> package and CLI skeleton (python) / feat: initial CLI skeleton (cmd + internal packages) (go โ include go.mod/go.sum) / feat: initial Swift package and CLI skeleton (swift โ include Package.resolved) / feat: initial iOS app skeleton (xcodeproj + synced folders) (swift-app)
ci: add CI workflow (python; append "docs, and PyPI release workflows" per enabled features. go; append "and goreleaser release" with feature release. swift; append "and cask release" with feature release)
docs: README and CHANGELOG (append "and Great Docs config" with feature docs)
docs: add mascot logo, README banner, and social card (skip if Phase 3 was skipped)
Then, optionally, publish and wire one-time setups:
gh repo create --source . --push --description "$DESCRIPTION" plus --public
or --private per the Phase 1 visibility โ always set the description, and the
--description string must equal the README opener fragment (one fragment on
every surface); (feature
docs) also pass --homepage "$DOCS_URL" (Pages on a private repo requires a
paid GitHub plan). For an existing remote, gh repo edit with the same flags
(visibility via --visibility public|private --accept-visibility-change-consequences).
- (any layer, only after
gh repo create so origin exists) arm the session reviewer:
uvx capt-hook review enable. It registers the captain-hook plugin in .claude/settings.json,
wires the SessionEnd review run hook, and watches the repo (machine-local) so ended sessions
mine durable corrections into hook PRs. It needs an authenticated claude and gh and an
origin remote โ the reviewer opens PRs against origin, so an origin-less repo is rejected.
uvx capt-hook review disable turns it off. See reference/hooks.md.
- (when
cc-notes is installed: command -v cc-notes) run cc-notes init to adopt the
git-native notes/tasks layer: it installs the refs/cc-notes/* refspecs (which target origin)
and the reconcile CI workflow under .github/. The cc-notes guard-pack nudges need no
registration step โ they ship inside the cc-notes@cc-notes plugin's capt-hook/ pack, already
enabled by the scaffolded .claude/settings.json, and they gate on the cc-notes binary being
on PATH, so adoption stays conditional: without the binary the pack is silent. If cc-notes
isn't installed, skip init and mention it as an optional add-on (install the binary, then
cc-notes init); the plugin registration also gives the repo the using-cc-notes skill even
without the binary. See reference/hooks.md.
- Commit and push what the two steps above wrote:
chore: arm session reviewer and cc-notes
covering the .claude/settings.json plugin registration (and, when cc-notes ran, the
refs/cc-notes/* refspecs and reconcile CI), then git push. For an
unpublished repo, skip all three steps โ the reviewer and cc-notes sync have no origin to
target; adopt them later once you publish.
- (any layer) if
reposync is installed locally (command -v reposync), register the
new repo so it converges across the user's machines: reposync repo add . from the repo
root (repos live under ~/Code, reposync's default_location). reposync reads the
freshly pushed origin, records the repo, propagates it to peer hosts, and clones it
wherever it's missing. Best-effort โ skip silently when reposync isn't on PATH, and it
never blocks the bootstrap. It needs the GitHub remote to exist, so run it after
gh repo create --push; for a repo you didn't publish, either skip it (register later
once published) or reposync repo add --local-only . to track it on this host only.
- (feature docs) enable GitHub Pages with the Actions build type:
gh api repos/{owner}/{repo}/pages -X POST -f build_type=workflow
(reference/ci-and-release.md).
- (feature pypi) register the PyPI pending trusted publisher for
DIST_NAME,
then run the first release: CHANGELOG entry โ tag v0.1.0 on a commit that's on
main โ push tag โ watch it to completion with scripts/watch-release.sh (per-job
results, release assets, PyPI check; see reference/ci-and-release.md). The release's
verify-tag-on-main gate refuses tags off main.
- (feature release, go or swift) ensure the
yasyf/homebrew-tap repo exists, then set the release
secrets from 1Password right after the repo is created:
bash "${CLAUDE_PLUGIN_ROOT}/skills/repo-bootstrap/scripts/set-release-secrets.sh" <owner>/<repo>.
It pushes HOMEBREW_TAP_TOKEN (the tap PAT โ required for the cask push) plus the five
MACOS_* sign/notarize secrets (MACOS_SIGN_P12, MACOS_SIGN_PASSWORD,
MACOS_NOTARY_ISSUER_ID, MACOS_NOTARY_KEY_ID, MACOS_NOTARY_KEY) from
op://OpenClaw/<NAME>/credential. It fails before changing any repo unless all six values
are present; mint missing macOS credentials once per reference/go-ci-and-release.md ยง macOS
signing & notarization. Then run the first release: CHANGELOG entry โ tag
v0.1.0 on a commit that's on main โ push tag โ watch it with scripts/watch-release.sh
(drop --pypi; see reference/ci-and-release.md). Go: release.yml forwards to the shared
immutable release-go.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b reusable workflow, which gates on
verify-tag-on-main, builds and signs once without publishing, verifies the exact assets, publishes
the GitHub release by numeric ID, and only then publishes a native Homebrew cask to the
tap (reference/go-ci-and-release.md). Swift: release.yml forwards to the shared
immutable release-swift.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b reusable workflow โ same gate, then a universal swift build,
codesign + notarytool, the GitHub release, and a synthesized binary cask pushed to the tap
(reference/swift-ci-and-release.md). Bun: release.yml forwards to the shared
immutable release-bun.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b reusable workflow โ same gate, then a per-target
bun build --compile matrix on native runners, codesign + notarytool on the darwin
legs, the GitHub release, and a synthesized binary cask pushed to the tap
(reference/bun-ci-and-release.md). No PyPI/Pages for any of them.
- Set the repo's social preview to
docs/assets/social-preview.jpg. GitHub has
no API for it โ use the agent-browser-with-cookies skill (install
agent-browser-with-cookies@skills from this marketplace if absent) to run an
authenticated session from the user's existing GitHub login: it extracts the
github.com cookies (one Touch ID tap) and opens
https://github.com/{owner}/{repo}/settings. Upload the card straight from disk
into the social-preview file input:
agent-browser --session abwc upload '#repo-image-file-input' docs/assets/social-preview.jpg
(snapshot the page and find the input if that selector has moved; no need to push
the image first โ the bytes go from disk to GitHub). Verify with
gh api graphql -f query='{ repository(owner: "{owner}", name: "{repo}") { usesCustomOpenGraphImage } }'
โ it flips to true (re-check after ~30s for cache) โ then
agent-browser --session abwc close. Not logged into github in any local browser
(or no Touch ID)? Ask the user to upload it by hand (repo Settings โ Social preview).
Exit criteria: commits made; for a published repo, remote created with description
(and homepage, with feature docs) set, and โ when reposync is installed โ the repo
registered for cross-host sync, and any enabled feature's one-time setup done (or
explicitly deferred with the user).
Escape hatches
- Existing repo: scaffold skips identical files and reports conflicts without
writing; resolve each conflict deliberately (merge by hand, then re-run โ it will
SKIP everything that matches).
- No PyPI / no docs site: don't hand-strip โ re-scaffold with the feature off.
--features docs drops PyPI (release workflow, badges, uvx install, the docs-site
install widget โ README falls back to clone + uv run); --features pypi drops the docs site (great-docs
config, Pages workflow, docs badge + teaser section โ the README switches to the
inline tail, docs dependency group); --features ""
drops both.
- No release pipeline (go): release is off by default โ
--features "" scaffolds no
.goreleaser.yaml / release.yml and the README falls back to go install (clone +
task build in its details block). Re-scaffold with --features release to add it;
don't hand-add or hand-strip.
- No release pipeline (swift): same shape โ
--features "" scaffolds no release.yml
and the README falls back to clone + swift run. Re-scaffold with
--features release to add it.
- Release on an app: not offered โ
release is swift-package-only; App Store /
TestFlight distribution is product work. (A macOS .app cask is a hand-composed
pipeline: see the sign-notarize-app recipe in reference/go-ci-and-release.md.)
- Library, not a CLI (go): the go layer scaffolds a
cmd/<name> binary. For a library,
scaffold the go layer, then delete cmd/ and expose packages at the module root (or under
<name>/); drop the cobra dependency and the release feature. The starter internal/cli
becomes the example package to replace.
- Library, not a CLI (swift): delete the executable target (
Sources/<name>/ and its
products/targets entries in Package.swift), drop the swift-argument-parser
dependency and the release feature. The Sources/<Module>/ library and its tests stay.
- App with a companion CLI/package (the room-scan shape): scaffold
swift-app, then
add a local SPM package by hand and link its library product into the app via an
XCLocalSwiftPackageReference โ recipe in reference/swift-stack.md.
- No Xcode locally (swift-app): verify NOTE-skips the app build (and the iOS-platform
component check); CI's
macos-26 job is authoritative.
- Other licenses: PolyForm-Noncommercial-1.0.0 (the public-repo default) and MIT
render from bundled templates; any other SPDX id prints a
MANUAL line to fetch from the SPDX
list (see Phase 2) and is set in pyproject.toml. MIT is the choice for permissive
open source (see reference/base-conventions.md). none (the private-repo
default) scaffolds no license at all; when retrofitting with none, delete any
existing LICENSE by hand โ the scaffold never deletes, and verify --no-license
fails while it remains.
- No capt-hook hooks wanted: set
"captain-hook@captain-hook": false under
enabledPlugins in settings-overrides.fragment.json (then re-run cc-guides render) โ
disabling the plugin drops dispatch entirely, builtin and plugin packs alike. Delete
.claude/hooks/ too if the repo's local hooks should go with it.
- No commit hooks wanted: delete the
.claude/fragments/pre-commit-config.yaml/
layout dir and the rendered .pre-commit-config.yaml (deleting only the rendered file
resurrects it on the next cc-guides render), and skip
uvx prek install. If you already ran uvx prek install, also run
uvx prek uninstall โ deleting the config alone orphans the hook and aborts every
commit. (python) To drop only the ty hook, delete its repo: block there and the CI
ty step. (go) The config runs gofumpt + golangci-lint; the go capt-hook pack blocks
manual invocation, so if you drop the hook, also shadow that guard with a local
.claude/hooks/ override (see reference/hooks.md).
- No Codex: the second-opinion nudge ships in the
general pack โ override it with a
local .claude/hooks/commands.py (a local hook shadows the pack's; see reference/hooks.md),
then set "codex@skills": false under enabledPlugins in
settings-overrides.fragment.json and re-render (cc-guides render).
- No brand images: skip Phase 3 (user declined, or no
OPENAI_API_KEY) and
strip the banner image from the README H1 (#  โ
# <project>). Nothing else to clean up โ Great Docs auto-detects no logo,
and verify only NOTEs a banner the README still references.
- No terminal demo: replace the README's demo
<img ...> line with a fenced
output block of a real run, and commit no generator (delete
docs/scripts/demo.sh / .cli-demo/demo.tape if present) โ verify only
NOTEs a demo asset the README still references.
- No prompt-writing nudge: the nudge ships in the
general pack โ override it with a
local .claude/hooks/prompts.py (see reference/hooks.md), then set
"slop-cop@skills" / "llm-prompts@skills" to false under enabledPlugins in
settings-overrides.fragment.json and re-render (keep slop-cop@skills if you keep the docs nudge).
- No docs nudge: the nudge ships in the
general pack โ override it with a local
.claude/hooks/docs.py (see reference/hooks.md), then set "writing-docs@skills": false
under enabledPlugins in settings-overrides.fragment.json and re-render (keep
slop-cop@skills if the prompt-writing nudge remains).
- Monorepos: out of scope โ this skill scaffolds single-package repos.
Reference map
Read these on demand โ each is self-contained:
reference/base-conventions.md โ AGENTS/CLAUDE/STYLEGUIDE/README/CHANGELOG
anatomy, commit conventions, license guidance, .claude settings explained.
reference/python-stack.md โ every python-layer choice with rationale
(uv/uv_build, flat layout, Click, loguru, pytest, ruff, ty + pyright, naming triad),
pyproject walkthrough.
reference/go-stack.md โ every go-layer choice with rationale (cmd/+internal layout,
cobra, slog, golangci-lint + gofumpt, table-driven tests, version stamping, the
errorโexit-code idiom).
reference/hooks.md โ what each scaffolded hook does, testing with
uvx capt-hook test, tailoring and removal, version requirements.
reference/ci-and-release.md โ the three python workflows, one-time PyPI trusted
publisher + GitHub Pages setup, release procedure.
reference/go-ci-and-release.md โ the go CI workflow, the goreleaser base config,
the cask-by-default Homebrew publish flow via the shared immutable release-go.yml reusable
workflow, the formula recipe (native brews: or render-formula), the two signing
modes, and opt-in recipes (zig CGO, build tags, universal binaries, embed-prebuild,
format: binary, extra cask, auto-tag-on-push); shared-tap one-time setup.
reference/swift-stack.md โ every swift/swift-app choice with rationale (SPM
logic-in-library layout, swift-argument-parser, Swift Testing, SwiftFormat +
SwiftLint and the swiftformat-vs-swift-format trap, the synced-folder xcodeproj
anatomy, MODULE_NAME/bundle-id naming, the no-DEVELOPMENT_TEAM signing story,
XcodeBuildMCP wiring, the app + local-SPM-package recipe).
reference/swift-ci-and-release.md โ the swift CI workflows (macos-26 rationale,
simulator-destination drift, SPM caching), the release feature flow via the shared
immutable release-swift.yml@41f8de6765b3b833ef333b0b98f5683f0e46685b reusable workflow (universal binary, codesign +
notarytool, synthesized cask), version stamping, one-time setup, and why apps get
no release feature.
reference/bun-ci-and-release.md โ the bun CI workflow (.bun-version pin,
committed bun.lock), the release feature flow via the shared
immutable release-bun.yml reusable workflow (native-runner matrix and why bun
can't cross-compile here, codesign + notarytool, synthesized 4-platform cask),
the JIT entitlements escape hatch, version stamping, one-time setup, and
runner-label drift.
reference/docs-site.md โ Great Docs config, build/preview commands, enabling
narrative sections and curated reference.