GitHub Repo Standardizer
Detect a repository's current state, then polish its surface: issue forms,
PR template, label taxonomy, CI, CODEOWNERS, rulesets, docs. Works on
repo metadata and config files only — code logic is never touched.
Idempotent — safe to re-run; fills gaps and reconciles drift without
duplicating or clobbering.
When to use
- User says "standardize / tidy up / professionalize this repo"
- A new repo was just created and needs templates, labels, CI, and rules from day one
- A repo looks bare: no templates, no labels, no CI, no branch protection
Preflight (mandatory, in order)
Requires: gh CLI (authenticated), git, jq, python3 — verify
they exist before starting (which gh git jq python3).
1. Authenticate — check gh login first
gh auth status 2>/dev/null || echo "NOT_LOGGED_IN"
- Logged in → continue; print
gh api user -q .login so the user knows which account will act.
- Not logged in → STOP. Tell the user (do not guess):
- Run
gh auth login (web/device flow), or
- Export a token:
export GH_TOKEN=ghp_xxx — needs repo, workflow (for CI files) and, for org repos, admin:org (or admin:repo_hook / org membership admin) scopes.
- Never paste tokens into chat, logs, or files. If the user pastes a token in chat, advise them to revoke it and re-issue.
- If
gh auth login is impossible in this environment (headless), suggest gh auth login --with-token reading from a file the user created.
Verify the acting account can write to the target:
# user repos: no extra check needed beyond token scopes
# org repos: must be a member/admin of the org
gh api "orgs/ORG/memberships/$(gh api user -q .login)" -q .role 2>/dev/null || echo "NO_ORG_ACCESS"
admin/member → OK. 404 → stop and ask the user to add the account to the org first.
2. Detect repository type
gh repo view OWNER/REPO --json name,owner,visibility,defaultBranchRef,isArchived,isFork \
-q '{name:.name, ownerType:.owner.type, visibility:.visibility, defaultBranch:.defaultBranchRef.name, archived:.isArchived, fork:.isFork}'
| Field |
Meaning |
Consequence |
ownerType |
User = personal, Organization = org |
Org repos can also use org-level rulesets; both support repo-level rulesets |
visibility |
PUBLIC / PRIVATE / INTERNAL |
Private: skip public-facing docs pressure, keep CI secrets minimal; public: README badges + CONTRIBUTING/SECURITY matter |
archived / fork |
Read-only / fork |
Skip write modules; report why |
If the repo was not explicitly named by the user, confirm before touching an
org or private repository.
3. Audit current state
gh label list --repo OWNER/REPO --limit 200
gh api repos/OWNER/REPO/contents/.github -q '.[].path' 2>/dev/null || echo "no .github dir"
gh api repos/OWNER/REPO/contents/.github/workflows -q '.[].name' 2>/dev/null || echo "no workflows"
gh api repos/OWNER/REPO/rulesets -q '.[] | {name:.name, enforcement:.enforcement}' 2>/dev/null || echo "no rulesets"
gh api repos/OWNER/REPO/branches -q '.[].name' 2>/dev/null
for f in README.md CONTRIBUTING.md SECURITY.md LICENSE .gitignore; do
gh api "repos/OWNER/REPO/contents/$f" -q .name 2>/dev/null || echo "missing: $f"
done
4. Detect test framework (for CI module)
Check for these signals (first match wins):
gh api repos/OWNER/REPO/contents/package.json -q .name 2>/dev/null # node → templates/ci-node.yml
gh api repos/OWNER/REPO/contents/pyproject.toml -q .name 2>/dev/null # python → templates/ci-python.yml
gh api repos/OWNER/REPO/contents/go.mod -q .name 2>/dev/null # go → templates/ci-go.yml
gh api repos/OWNER/REPO/contents/Cargo.toml -q .name 2>/dev/null # rust → templates/ci-rust.yml
No signal → propose the generic CI (or ask the user whether CI is wanted at all).
5. Ask about language (before planning)
- Ask the user which language
CONTRIBUTING.md and the PR template should be
written in (default: English, or the project's primary language for local
projects). Translate the templates accordingly when generating — never
assume a language.
- (README languages are asked separately in Module F.)
6. Ask about automation (decides the Governance labels)
Ask the user whether the repo has any automation bots or AI writers
running on it — e.g. dependabot, a Stale bot, ClawSweeper, or an AI coding
agent that auto-files PRs / auto-fixes issues.
- Why ask:
r:* / clawsweeper:* / triage:* / close:* labels are
signal labels, not categories — a bot reads them and acts (auto-close,
auto-lock, auto-fix, auto-merge). Without running automation those labels
are dead weight, so the answer decides whether the Governance dimension is
added at all (Module A, Step 2).
- Yes → plan the
Governance / auto-close rules dimension (add only the
r:* rules matching the project's real reject criteria).
- No → skip that dimension entirely — never add
r:* / bot labels to a
repo with no automation.
Workflow
- Preflight (above). If auth or access fails, stop with a clear message.
- Dry-run plan — show the user a concise table of what will be created/updated/skipped. Get confirmation for: rulesets, branch deletion/protection changes, org-level changes, and anything destructive.
- Apply modules (each idempotent; run in this order).
- Verify — re-query and print an
applied / skipped / failed checklist.
Module A — Labels (design first, then idempotent upsert)
Step 1 — Profile the project (adjust the taxonomy, never copy blindly):
- Rating labels → design a themed tier system for THIS project
(never copy an existing repo's set verbatim):
- Reference example — OpenClaw's official repo uses themed tiers with
emoji icons and a low→high color gradient (EXAMPLE ONLY, do not copy):
rating: 🧂 unranked krab → rating: 🦪 silver shellfish →
rating: 🦐 gold shrimp → rating: 🦀 challenger crab →
rating: 🐚 platinum hermit → rating: 🦞 diamond lobster
- International project → universal grades also work
(
grade: S/A/B/C/D or ★–★★★★★)
- Always redesign: pick a theme that fits the project (animals, gems,
ranks, stars…) and the audience's language. Do not reuse any existing
repo's rating labels as-is.
- Teams: if the repo has an explicit division of labor
(CODEOWNERS, CONTRIBUTING, a team list in docs) → add one
team: * label
per group (e.g. team: frontend, team: algorithm). No team list → skip.
- Project type (library / app / coursework / org-infra) → decide which
dimensions below are needed (
dependencies, security, docs, …).
- Language: write every label name and description in the language chosen
in Preflight step 5 (default English; local project → its primary language).
Never assume — translate every label name and description into the chosen
language (emoji glyphs stay as-is).
- Exception — bot labels:
r:* / clawsweeper:* / triage:* /
close:* names are matched literally by automation code (almost always
English). Keep those names in the bot's language — a translated name
breaks the bot. Only their description may use the user's language.
Step 2 — Compose categories. Baseline lives in templates/labels.json
(plain names, no emoji); extend or trim per the profile in Step 1.
Emoji policy — rating tiers are the ONLY mandatory-emoji labels. Every
rating:* / issue-rating:* tier MUST carry an emoji with a clear low→high
gradient (e.g. rating: 🦞 diamond lobster). All other labels: emoji is the
agent's call — add icons where they aid scanning, omit them where they
clutter. Consistency rule: within one dimension, either ALL labels carry
an emoji or NONE do — never a mixed half-emoji dimension (e.g. don't ship
🐛 bug next to a plain enhancement).
Every dimension is opt-in except Type. Add a dimension only if the repo
actually needs it; skip it otherwise. The menu below mirrors OpenClaw's
official label taxonomy (the richest open reference) — cover every dimension
that applies, but never force one the repo doesn't use.
Priority uses P0–P3 (OpenClaw's convention — P0 = emergency).
Examples in the tables below show the optional emoji style — apply them
all or none per dimension (baseline ships plain P0–P3):
| Label |
Meaning |
Color |
🔴 P0 |
Emergency: data loss, security bypass, crash loop, unusable core |
b60205 |
🟠 P1 |
High: blocks planned work, needs attention soon |
d93f0b |
🟡 P2 |
Medium: normal priority |
fbca04 |
🟢 P3 |
Low: nice to have |
1a7f37 |
Dimension menu (write each label in the user's chosen language):
| Dimension |
Labels (examples) |
Add when |
| Type (always) |
🐛 bug ✨ enhancement 📚 documentation ❓ question 🙋 help wanted 🌱 good first issue |
always |
| Priority |
🔴 P0 🟠 P1 🟡 P2 🟢 P3 |
recommended |
| Status |
🚧 in progress 🧱 blocked ✅ ready to merge 🎉 merged 🚫 wontfix |
recommended |
| Impact |
impact: security impact: data-loss impact: availability … |
recommended; required for security-sensitive repos |
| Rating (PR quality) |
rating: 🦞 diamond lobster … themed tiers |
PR-quality gate exists |
| Issue rating |
issue-rating: 🦞 diamond lobster … |
issue-quality gate exists (may fold into Rating) |
| Merge risk |
merge-risk: 🚨 security-boundary merge-risk: 🚨 availability … |
maintainer review process exists |
| Size |
size: XS size: S size: M size: L size: XL |
large repo / team estimation |
| Area / module |
area: core area: api area: cli … |
multi-module project |
| Bug detail |
bug: behavior bug: crash |
crash-prone / many bug reports |
| Governance / auto-close rules |
r: spam r: support r: no-ci-pr … clawsweeper:* triage:* |
automation bot enforces close/lock/review rules |
| Close reason |
close: duplicate close: superseded close: invalid … |
close-automation bot exists |
| Triage |
triage: bug triage: blocked triage: needs-review … |
triage workflow exists |
| Proof |
proof: 🎥 video proof: 📸 screenshot |
reproduction evidence required |
| Dependencies |
📦 dependencies |
dependabot / dependency PRs |
| Security |
🔒 security |
security-sensitive repo |
| Regression |
↩️ regression |
stable project (was-working-now-fails) |
| Stale |
🕰️ stale 🚫 no-stale |
stale automation exists |
| Team |
team: <group> |
explicit division of labor |
| Duplicate / invalid |
👯 duplicate 🚫 invalid |
active public repo with many issues |
| Channel |
channel: discord channel: telegram … |
multi-channel product (OpenClaw-style) |
| App / platform |
app: ios app: android app: web-ui … |
multi-platform app |
| Extensions / plugins |
extensions: <name> plugin: <name> |
plugin/extension ecosystem |
Governance rules (r: / bot labels) — gated by Preflight step 6. Only
consider this dimension if the user answered "yes" to automation bots / AI
writers; skip it entirely otherwise. Auto-close and bot-state labels are
signal labels, not categories — a bot (or Actions workflow) reads them and
acts (auto-close, auto-lock, auto-fix, auto-merge). They are useless without
the matching automation, so skip them unless a governance bot actually runs
on the repo. If one does, add only the r:* rules matching the project's real
off-topic / reject criteria (e.g. r: spam, r: support, r: no-ci-pr) plus
the bot's own state labels (clawsweeper:*, triage:*, close:*). Never copy
OpenClaw's set verbatim — its rules encode OpenClaw's specific product
boundaries.
Impact dimension — the security "blast radius" judgement (generalized
from OpenClaw; trim to the repo's actual failure modes):
| Label |
Meaning |
impact: security |
security boundary, credentials, authz, sandbox, sensitive data |
impact: data-loss |
loses/corrupts/drops user, session, or config data |
impact: availability |
crash, hang, restart loop, or process outage |
impact: auth-provider |
auth / routing / model choice / secret resolution breaks |
impact: session-state |
session / memory / state drifts or corrupts (stateful systems) |
impact: message-loss |
messages/events lost, duplicated, or misrouted (messaging systems) |
impact: ux-blocker |
user blocked with no terminal/logs/support (GUI products) |
impact: ux-friction |
confusing flow / support burden (GUI products) |
impact: other |
meaningful impact outside the owned taxonomy |
Step 3 — Color rules (mandatory):
- Diverse palette: colors must be rich and varied — the whole label set
should look like a palette, not a monochrome block. Even within one
category, spread the hues (e.g. priority labels: red / orange / yellow /
green, or four clearly different hues).
- Semantic hints (not hard mappings):
ready to merge / merged / done
→ greens (never gray or red); wontfix → gray; in progress → blue.
Everything else: pick colors that look good together and match the label's
meaning loosely — but prefer variety over strict one-meaning-one-color.
- Emoji policy: rating tiers are emoji-mandatory — every
rating:* / issue-rating:* label needs a clear low→high emoji gradient
(e.g. rating: 🦞 diamond lobster). Everywhere else, emoji is the agent's
call: use icons where they aid scanning, omit them where they clutter.
Consistency: within one dimension, all labels carry an emoji or none
do — never a mixed half-emoji dimension. If used, the emoji must match
the label's meaning, never decorative-only.
- Rating labels need docs: when rating labels are added, also add
LABELS.md (Step 4) describing each label's meaning and the explicit
low→high order, so the ranking is unambiguous.
- Neighboring labels must be distinguishable. Forbidden: all-one-color,
adjacent duplicates, or colors that contradict the label content.
Step 4 — Rating-label docs (only if rating labels exist). Generate
LABELS.md from templates/LABELS.md (or extend an existing docs file):
list every rating label with its meaning and the explicit low→high order,
plus the rest of the taxonomy. Commit and push it together with the labels.
Step 5 — Idempotent upsert. GitHub has no PUT /labels/{name}
endpoint. Upsert = check existence (GET /labels/{name}), then
POST /labels (create) or PATCH /labels/{name} (update). Works for both
map-form and array-form labels.json:
R="repos/OWNER/REPO"
jq -c 'if type == "array" then .[] else to_entries[] | {name: .key} + .value end' templates/labels.json | while read -r l; do
name=$(echo "$l" | jq -r .name); color=$(echo "$l" | jq -r .color); desc=$(echo "$l" | jq -r .description)
enc=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$name")
if gh api "$R/labels/$enc" >/dev/null 2>&1; then
gh api -X PATCH "$R/labels/$enc" -f name="$name" -f color="$color" -f description="$desc" --silent && echo "label updated: $name"
else
gh api -X POST "$R/labels" -f name="$name" -f color="$color" -f description="$desc" --silent && echo "label created: $name"
fi
done
- URL-encode label names (spaces, slashes).
- To reconcile drift (deleted manual labels), show the diff and ask before removing labels that are already in use.
Module B — Issue forms + config
Create .github/ISSUE_TEMPLATE/ with config.yml plus one YAML form per
template (bug / feature / question). Push via a commit:
- Replace placeholders in
config.yml (OWNER/REPO in the
Discussions / Security contact URLs) — see Template placeholders.
- Write the forms in the user-chosen language (Preflight step 5): translate
form names, labels, descriptions, and placeholder text;
title: prefix
and labels: values stay as-is (they must match the label taxonomy).
mkdir -p .github/ISSUE_TEMPLATE
cp templates/issue-form-*.yml templates/config.yml .github/ISSUE_TEMPLATE/
git add .github/ISSUE_TEMPLATE && git commit -m "chore: add issue forms" && git push
- If templates already exist, diff them; only overwrite identical or clearly
stale files (ask first if the user may have customized them).
- If there is no git clone, clone first (
gh repo clone OWNER/REPO), edit, push.
Module C — PR template
mkdir -p .github
cp templates/PR_TEMPLATE.md .github/PULL_REQUEST_TEMPLATE.md
git add .github/PULL_REQUEST_TEMPLATE.md && git commit -m "chore: add PR template" && git push
- Write the template in the user-chosen language (Preflight step 5).
The PR template has no placeholders to replace.
Module D — CI workflow
Pick the workflow from the framework detection (templates/ci-*.yml —
they trigger on $default-branch, so they work for any default branch
name). Write to .github/workflows/ci.yml, commit, push. Keep existing
workflows; only add ci.yml if none exists.
Node projects: ci-node.yml installs dependencies lockfile-aware
(npm ci / pnpm install --frozen-lockfile / yarn install --frozen-lockfile, with plain npm install as fallback) — no manual
adjustment needed for pnpm / yarn repos.
Note: pushing workflow files requires a token with the workflow scope; if
the push is rejected with 403, tell the user their token lacks workflow.
Module E — Branch rules
Prefer rulesets (modern) over legacy branch protection:
# list existing
gh api repos/OWNER/REPO/rulesets -q '.[].name'
# create (example: protect default branch)
gh api -X POST repos/OWNER/REPO/rulesets --input - <<'EOF'
{
"name": "protect-default-branch",
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": {"include": ["refs/heads/DEFAULT_BRANCH"], "exclude": []}
},
"rules": [
{"type": "pull_request", "parameters": {"required_approving_review_count": 1, "dismiss_stale_reviews_on_push": true, "require_code_owner_review": false, "require_last_push_approval": true, "required_review_thread_resolution": true}},
{"type": "required_linear_history"},
{"type": "deletion"},
{"type": "non_fast_forward"},
{"type": "required_signatures"}
]
}
EOF
- Idempotency: if a ruleset with the same name exists, update it with
PUT repos/OWNER/REPO/rulesets/{id} — full replace, include the complete
body (name, enforcement, conditions, rules, bypass_actors). There is no PATCH
for rulesets (PATCH returns 404).
- Optional admin bypass: add
"bypass_actors": [{"actor_id": 5, "actor_type": "RepositoryRole", "bypass_mode": "always"}] (id 5 = admin)
so maintainers can push directly to the protected branch; non-admins still
go through pull requests.
pull_request parameters are all required in current API versions:
required_approving_review_count, dismiss_stale_reviews_on_push,
require_code_owner_review, require_last_push_approval,
required_review_thread_resolution. Omitting any → HTTP 422.
target: "branch" + ref_name.include: refs/heads/<default>; also offer
"tag" rules if tags matter.
- Org repos: optionally offer org-level rulesets (
/orgs/{org}/rulesets).
Module F — Docs
README (ask about languages FIRST):
- Ask the user: which languages should the README support? (suggest the
project's primary language + English for international projects)
- If a README already exists, ask whether to adapt it into more languages —
never add languages without asking.
- Language switcher convention (pattern from
programmingHLS/ccmm):
- Default file stays
README.md (usually English).
- Extra languages:
README.<lang>.md (e.g. README.zh.md, README.ja.md).
- Top of every file, a switcher line — current language as plain text,
others as relative links:
README.md: < English | 简体中文 > (简体中文 links to README.zh.md)
README.zh.md: < English | 简体中文 > (English links to README.md)
- Keep structure, badges, and anchors parallel across language files.
README.md: if missing or bare, generate one from templates/README.md
(badges, install, usage, modules table). Keep the user's existing content if
it is already substantive — only append a badges block. Replace
placeholders (badge URLs, clone URL, owner credit) per Template
placeholders.
CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md: copy from
templates if missing (write CONTRIBUTING.md in the user-chosen language
from Preflight step 5; replace OWNER/REPO in SECURITY.md's
advisory link per Template placeholders).
VISION.md: optional direction doc (modeled on OpenClaw's VISION.md) —
generate a short vision from templates/VISION.md (origin, guiding
principles, current state, direction, contribution rules) if the user
wants one (replace PROJECT_NAME per Template placeholders).
THIRD_PARTY_NOTICES.md: add when the project adapts third-party content
(licenses, fonts, code of conduct) — list each source and its license.
docs/ARCHITECTURE.md: for non-trivial projects, generate a short
architecture doc (structure, flow, constraints) from the audit.
LICENSE: ask the user which license (default MIT) before creating.
CHANGELOG.md: create from templates/CHANGELOG.md (Keep a Changelog
format) if missing; log notable changes per release (replace
YYYY-MM-DD in the placeholder date line per Template placeholders).
Module G — AI assistant guides (CLAUDE.md / AGENTS.md)
- Add a
CLAUDE.md (guidance for Claude Code) and an AGENTS.md (guidance
for any AI coding agent) when missing — see templates/CLAUDE.md and
templates/AGENTS.md (replace OWNER/REPO and the i18n placeholder
per Template placeholders).
- If they already exist, diff and fill gaps rather than overwrite.
- Typical content, derived from the repo audit (Modules A–F):
- Project: one-paragraph summary, status, stack.
- Commands: build / test / lint / run (from CI detection + package scripts).
- Conventions: commit style (see CONTRIBUTING), label taxonomy, i18n
requirements, secrets policy (never hardcode keys), file map.
- Caveats: known risks, areas to be careful with.
- CLAUDE.md vs AGENTS.md: CLAUDE.md is Claude-specific; AGENTS.md is
agent-agnostic (works for Cursor/Copilot/OpenClaw too). Keep AGENTS.md free
of Claude-only references.
Verification
gh label list --repo OWNER/REPO --limit 200 | wc -l
gh api repos/OWNER/REPO/contents/.github/ISSUE_TEMPLATE -q '.[].name' 2>/dev/null
gh api repos/OWNER/REPO/contents/.github/PULL_REQUEST_TEMPLATE.md -q .name 2>/dev/null
gh api repos/OWNER/REPO/contents/.github/workflows/ci.yml -q .name 2>/dev/null
gh api repos/OWNER/REPO/rulesets -q '.[] | {name:.name, enforcement:.enforcement}'
Report a final table: module | status (applied/skipped/failed) | note.
Template placeholders (replace on copy)
Templates stay generic — OWNER/REPO, OWNER_USERNAME, PROJECT_NAME,
YYYY-MM-DD are placeholders the agent fills in when copying a template
into the target repo. Unreplaced placeholders ship broken links (badges,
clone URL, discussions, security advisory, CODEOWNERS handle) into the
user's repo.
| Placeholder |
Replace with |
OWNER |
target repo owner login (user or org) |
REPO |
target repo name |
OWNER_USERNAME |
owner's default reviewer / team handle |
PROJECT_NAME |
project display name |
YYYY-MM-DD |
current date |
Resolve the values once up front, then substitute in every copied file
(config.yml, README*.md, SECURITY.md, CODEOWNERS, AGENTS.md /
CLAUDE.md, VISION.md, …):
O=OWNER R=REPO N=PROJECT_NAME D=$(date +%F)
sed -i "s|OWNER_USERNAME|$O|g; s|OWNER/REPO|$O/$R|g; s|PROJECT_NAME|$N|g; s|YYYY-MM-DD|$D|g" \
.github/ISSUE_TEMPLATE/config.yml README.md SECURITY.md .github/CODEOWNERS AGENTS.md
- Replace
OWNER_USERNAME before OWNER/REPO — the former contains the
OWNER prefix, so order matters with naive sed.
- Only
config.yml, README*.md, SECURITY.md, CODEOWNERS, AGENTS.md /
CLAUDE.md, VISION.md, CHANGELOG.md carry placeholders; the issue
forms, PR template, CI workflows, and CoC are placeholder-free.
- CI templates need no substitution, but translate their human-facing
text if the user chose a non-English language.
Rules of thumb
- Idempotent: every module can run twice with the same result.
- Never clobber user content: diff first, ask before overwriting customized files.
- Auth first: no token, no action — tell the user how to log in, never guess.
- Dry-run before destructive ops: rulesets, branch rules, label deletion, visibility changes.
- Confirm scope: org/private repos and anything the user didn't explicitly name.
Templates
All templates live in templates/:
labels.json, LABELS.md, config.yml, issue-form-bug.yml,
issue-form-feature.yml, issue-form-question.yml, PR_TEMPLATE.md,
ci-node.yml, ci-python.yml, ci-go.yml, ci-rust.yml, CODEOWNERS,
CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md, CLAUDE.md,
AGENTS.md, VISION.md, CHANGELOG.md, templates/README.md,
templates/README.zh.md.
1---2name: repo-standardizer3description: Polish any GitHub repository's surface — labels (emoji rating tiers, P0–P3 priority, impact severity), issue forms, PR template, CI workflows, CODEOWNERS, rulesets, docs. Repo meta & config only — no code logic touched. Use when creating a new repo or polishing an existing one.4---5
6# GitHub Repo Standardizer
7
8Detect a repository's current state, then polish its surface: issue forms,
9PR template, label taxonomy, CI, CODEOWNERS, rulesets, docs. Works on
10repo metadata and config files only — code logic is never touched.
11**Idempotent** — safe to re-run; fills gaps and reconciles drift without
12duplicating or clobbering.
13
14## When to use
15
16- User says "standardize / tidy up / professionalize this repo"
17- A new repo was just created and needs templates, labels, CI, and rules from day one
18- A repo looks bare: no templates, no labels, no CI, no branch protection
19
20## Preflight (mandatory, in order)
21
22> **Requires**: `gh` CLI (authenticated), `git`, `jq`, `python3` — verify
23> they exist before starting (`which gh git jq python3`).
24
25### 1. Authenticate — check gh login first
26
27```bash
28gh auth status 2>/dev/null || echo "NOT_LOGGED_IN"
29```
30
31- **Logged in** → continue; print `gh api user -q .login` so the user knows which account will act.
32- **Not logged in** → STOP. Tell the user (do not guess):
33 1. Run `gh auth login` (web/device flow), **or**
34 2. Export a token: `export GH_TOKEN=ghp_xxx` — needs `repo`, `workflow` (for CI files) and, for org repos, `admin:org` (or `admin:repo_hook` / org membership admin) scopes.
35 - Never paste tokens into chat, logs, or files. If the user pastes a token in chat, advise them to revoke it and re-issue.
36 - If `gh auth login` is impossible in this environment (headless), suggest `gh auth login --with-token` reading from a file the user created.
37
38Verify the acting account can write to the target:
39
40```bash
41# user repos: no extra check needed beyond token scopes
42# org repos: must be a member/admin of the org
43gh api "orgs/ORG/memberships/$(gh api user -q .login)" -q .role 2>/dev/null || echo "NO_ORG_ACCESS"
44```
45
46- `admin`/`member` → OK. `404` → stop and ask the user to add the account to the org first.
47
48### 2. Detect repository type
49
50```bash
51gh repo view OWNER/REPO --json name,owner,visibility,defaultBranchRef,isArchived,isFork \
52 -q '{name:.name, ownerType:.owner.type, visibility:.visibility, defaultBranch:.defaultBranchRef.name, archived:.isArchived, fork:.isFork}'
53```
54
55| Field | Meaning | Consequence |
56|---|---|---|
57| `ownerType` | `User` = personal, `Organization` = org | Org repos can also use org-level rulesets; both support repo-level rulesets |
58| `visibility` | `PUBLIC` / `PRIVATE` / `INTERNAL` | Private: skip public-facing docs pressure, keep CI secrets minimal; public: README badges + CONTRIBUTING/SECURITY matter |
59| `archived` / `fork` | Read-only / fork | **Skip write modules**; report why |
60
61If the repo was not explicitly named by the user, confirm before touching an
62org or private repository.
63
64### 3. Audit current state
65
66```bash
67gh label list --repo OWNER/REPO --limit 200
68gh api repos/OWNER/REPO/contents/.github -q '.[].path' 2>/dev/null || echo "no .github dir"
69gh api repos/OWNER/REPO/contents/.github/workflows -q '.[].name' 2>/dev/null || echo "no workflows"
70gh api repos/OWNER/REPO/rulesets -q '.[] | {name:.name, enforcement:.enforcement}' 2>/dev/null || echo "no rulesets"
71gh api repos/OWNER/REPO/branches -q '.[].name' 2>/dev/null
72for f in README.md CONTRIBUTING.md SECURITY.md LICENSE .gitignore; do
73 gh api "repos/OWNER/REPO/contents/$f" -q .name 2>/dev/null || echo "missing: $f"
74done
75```
76
77### 4. Detect test framework (for CI module)
78
79Check for these signals (first match wins):
80
81```bash
82gh api repos/OWNER/REPO/contents/package.json -q .name 2>/dev/null # node → templates/ci-node.yml
83gh api repos/OWNER/REPO/contents/pyproject.toml -q .name 2>/dev/null # python → templates/ci-python.yml
84gh api repos/OWNER/REPO/contents/go.mod -q .name 2>/dev/null # go → templates/ci-go.yml
85gh api repos/OWNER/REPO/contents/Cargo.toml -q .name 2>/dev/null # rust → templates/ci-rust.yml
86```
87
88No signal → propose the generic CI (or ask the user whether CI is wanted at all).
89
90### 5. Ask about language (before planning)
91
92- Ask the user which language `CONTRIBUTING.md` and the PR template should be
93 written in (default: English, or the project's primary language for local
94 projects). Translate the templates accordingly when generating — never
95 assume a language.
96- (README languages are asked separately in Module F.)
97
98### 6. Ask about automation (decides the Governance labels)
99
100Ask the user whether the repo has any **automation bots or AI writers**
101running on it — e.g. dependabot, a Stale bot, ClawSweeper, or an AI coding
102agent that auto-files PRs / auto-fixes issues.
103
104- **Why ask**: `r:*` / `clawsweeper:*` / `triage:*` / `close:*` labels are
105 **signal labels, not categories** — a bot reads them and acts (auto-close,
106 auto-lock, auto-fix, auto-merge). Without running automation those labels
107 are dead weight, so the answer decides whether the Governance dimension is
108 added at all (Module A, Step 2).
109- **Yes** → plan the `Governance / auto-close rules` dimension (add only the
110 `r:*` rules matching the project's real reject criteria).
111- **No** → skip that dimension entirely — never add `r:*` / bot labels to a
112 repo with no automation.
113
114## Workflow
115
1161. **Preflight** (above). If auth or access fails, stop with a clear message.
1172. **Dry-run plan** — show the user a concise table of what will be created/updated/skipped. Get confirmation for: rulesets, branch deletion/protection changes, org-level changes, and anything destructive.
1183. **Apply modules** (each idempotent; run in this order).
1194. **Verify** — re-query and print an `applied / skipped / failed` checklist.
120
121### Module A — Labels (design first, then idempotent upsert)
122
123**Step 1 — Profile the project** (adjust the taxonomy, never copy blindly):
124
125- **Rating labels** → design a themed tier system for THIS project
126 (never copy an existing repo's set verbatim):
127 - Reference example — OpenClaw's official repo uses themed tiers with
128 emoji icons and a low→high color gradient (**EXAMPLE ONLY, do not copy**):
129 `rating: 🧂 unranked krab` → `rating: 🦪 silver shellfish` →
130 `rating: 🦐 gold shrimp` → `rating: 🦀 challenger crab` →
131 `rating: 🐚 platinum hermit` → `rating: 🦞 diamond lobster`
132 - International project → universal grades also work
133 (`grade: S/A/B/C/D` or `★`–`★★★★★`)
134 - Always redesign: pick a theme that fits the project (animals, gems,
135 ranks, stars…) and the audience's language. Do not reuse any existing
136 repo's rating labels as-is.
137- **Teams**: if the repo has an explicit division of labor
138 (CODEOWNERS, CONTRIBUTING, a team list in docs) → add one `team: *` label
139 per group (e.g. `team: frontend`, `team: algorithm`). No team list → skip.
140- **Project type** (library / app / coursework / org-infra) → decide which
141 dimensions below are needed (`dependencies`, `security`, `docs`, …).
142- **Language**: write every label name and description in the language chosen
143 in Preflight step 5 (default English; local project → its primary language).
144 Never assume — translate every label name and description into the chosen
145 language (emoji glyphs stay as-is).
146 - **Exception — bot labels**: `r:*` / `clawsweeper:*` / `triage:*` /
147 `close:*` names are matched literally by automation code (almost always
148 English). Keep those **names** in the bot's language — a translated name
149 breaks the bot. Only their `description` may use the user's language.
150
151**Step 2 — Compose categories.** Baseline lives in `templates/labels.json`
152(plain names, no emoji); extend or trim per the profile in Step 1.
153
154**Emoji policy — rating tiers are the ONLY mandatory-emoji labels.** Every
155`rating:*` / `issue-rating:*` tier MUST carry an emoji with a clear low→high
156gradient (e.g. `rating: 🦞 diamond lobster`). All other labels: emoji is the
157agent's call — add icons where they aid scanning, omit them where they
158clutter. **Consistency rule: within one dimension, either ALL labels carry
159an emoji or NONE do** — never a mixed half-emoji dimension (e.g. don't ship
160`🐛 bug` next to a plain `enhancement`).
161
162**Every dimension is opt-in except Type.** Add a dimension only if the repo
163actually needs it; skip it otherwise. The menu below mirrors OpenClaw's
164official label taxonomy (the richest open reference) — cover every dimension
165that applies, but never force one the repo doesn't use.
166
167**Priority uses `P0`–`P3`** (OpenClaw's convention — `P0` = emergency).
168Examples in the tables below show the optional emoji style — apply them
169all or none per dimension (baseline ships plain `P0`–`P3`):
170
171| Label | Meaning | Color |
172|---|---|---|
173| `🔴 P0` | Emergency: data loss, security bypass, crash loop, unusable core | `b60205` |
174| `🟠 P1` | High: blocks planned work, needs attention soon | `d93f0b` |
175| `🟡 P2` | Medium: normal priority | `fbca04` |
176| `🟢 P3` | Low: nice to have | `1a7f37` |
177
178**Dimension menu** (write each label in the user's chosen language):
179
180| Dimension | Labels (examples) | Add when |
181|---|---|---|
182| Type (always) | `🐛 bug` `✨ enhancement` `📚 documentation` `❓ question` `🙋 help wanted` `🌱 good first issue` | always |
183| Priority | `🔴 P0` `🟠 P1` `🟡 P2` `🟢 P3` | recommended |
184| Status | `🚧 in progress` `🧱 blocked` `✅ ready to merge` `🎉 merged` `🚫 wontfix` | recommended |
185| Impact | `impact: security` `impact: data-loss` `impact: availability` … | recommended; required for security-sensitive repos |
186| Rating (PR quality) | `rating: 🦞 diamond lobster` … themed tiers | PR-quality gate exists |
187| Issue rating | `issue-rating: 🦞 diamond lobster` … | issue-quality gate exists (may fold into Rating) |
188| Merge risk | `merge-risk: 🚨 security-boundary` `merge-risk: 🚨 availability` … | maintainer review process exists |
189| Size | `size: XS` `size: S` `size: M` `size: L` `size: XL` | large repo / team estimation |
190| Area / module | `area: core` `area: api` `area: cli` … | multi-module project |
191| Bug detail | `bug: behavior` `bug: crash` | crash-prone / many bug reports |
192| Governance / auto-close rules | `r: spam` `r: support` `r: no-ci-pr` … `clawsweeper:*` `triage:*` | automation bot enforces close/lock/review rules |
193| Close reason | `close: duplicate` `close: superseded` `close: invalid` … | close-automation bot exists |
194| Triage | `triage: bug` `triage: blocked` `triage: needs-review` … | triage workflow exists |
195| Proof | `proof: 🎥 video` `proof: 📸 screenshot` | reproduction evidence required |
196| Dependencies | `📦 dependencies` | dependabot / dependency PRs |
197| Security | `🔒 security` | security-sensitive repo |
198| Regression | `↩️ regression` | stable project (was-working-now-fails) |
199| Stale | `🕰️ stale` `🚫 no-stale` | stale automation exists |
200| Team | `team: <group>` | explicit division of labor |
201| Duplicate / invalid | `👯 duplicate` `🚫 invalid` | active public repo with many issues |
202| Channel | `channel: discord` `channel: telegram` … | multi-channel product (OpenClaw-style) |
203| App / platform | `app: ios` `app: android` `app: web-ui` … | multi-platform app |
204| Extensions / plugins | `extensions: <name>` `plugin: <name>` | plugin/extension ecosystem |
205
206**Governance rules (`r:` / bot labels) — gated by Preflight step 6.** Only
207consider this dimension if the user answered "yes" to automation bots / AI
208writers; skip it entirely otherwise. Auto-close and bot-state labels are
209**signal labels, not categories** — a bot (or Actions workflow) reads them and
210acts (auto-close, auto-lock, auto-fix, auto-merge). They are useless without
211the matching automation, so **skip them unless a governance bot actually runs**
212on the repo. If one does, add only the `r:*` rules matching the project's real
213off-topic / reject criteria (e.g. `r: spam`, `r: support`, `r: no-ci-pr`) plus
214the bot's own state labels (`clawsweeper:*`, `triage:*`, `close:*`). Never copy
215OpenClaw's set verbatim — its rules encode OpenClaw's specific product
216boundaries.
217
218**Impact dimension** — the security "blast radius" judgement (generalized
219from OpenClaw; trim to the repo's actual failure modes):
220
221| Label | Meaning |
222|---|---|
223| `impact: security` | security boundary, credentials, authz, sandbox, sensitive data |
224| `impact: data-loss` | loses/corrupts/drops user, session, or config data |
225| `impact: availability` | crash, hang, restart loop, or process outage |
226| `impact: auth-provider` | auth / routing / model choice / secret resolution breaks |
227| `impact: session-state` | session / memory / state drifts or corrupts (stateful systems) |
228| `impact: message-loss` | messages/events lost, duplicated, or misrouted (messaging systems) |
229| `impact: ux-blocker` | user blocked with no terminal/logs/support (GUI products) |
230| `impact: ux-friction` | confusing flow / support burden (GUI products) |
231| `impact: other` | meaningful impact outside the owned taxonomy |
232
233**Step 3 — Color rules (mandatory):**
234
235- **Diverse palette**: colors must be rich and varied — the whole label set
236 should look like a palette, not a monochrome block. Even within one
237 category, spread the hues (e.g. priority labels: red / orange / yellow /
238 green, or four clearly different hues).
239- **Semantic hints (not hard mappings)**: `ready to merge` / `merged` / done
240 → greens (never gray or red); `wontfix` → gray; `in progress` → blue.
241 Everything else: pick colors that look good together and match the label's
242 meaning loosely — but prefer variety over strict one-meaning-one-color.
243- **Emoji policy**: rating tiers are emoji-**mandatory** — every
244 `rating:*` / `issue-rating:*` label needs a clear low→high emoji gradient
245 (e.g. `rating: 🦞 diamond lobster`). Everywhere else, emoji is the agent's
246 call: use icons where they aid scanning, omit them where they clutter.
247 **Consistency: within one dimension, all labels carry an emoji or none
248 do** — never a mixed half-emoji dimension. If used, the emoji must match
249 the label's meaning, never decorative-only.
250- **Rating labels need docs**: when rating labels are added, also add
251 `LABELS.md` (Step 4) describing each label's meaning and the explicit
252 low→high order, so the ranking is unambiguous.
253- Neighboring labels must be distinguishable. Forbidden: all-one-color,
254 adjacent duplicates, or colors that contradict the label content.
255
256**Step 4 — Rating-label docs (only if rating labels exist).** Generate
257`LABELS.md` from `templates/LABELS.md` (or extend an existing docs file):
258list every rating label with its meaning and the explicit low→high order,
259plus the rest of the taxonomy. Commit and push it together with the labels.
260
261**Step 5 — Idempotent upsert.** GitHub has **no** `PUT /labels/{name}`
262endpoint. Upsert = check existence (`GET /labels/{name}`), then
263`POST /labels` (create) or `PATCH /labels/{name}` (update). Works for both
264map-form and array-form `labels.json`:
265
266```bash
267R="repos/OWNER/REPO"
268jq -c 'if type == "array" then .[] else to_entries[] | {name: .key} + .value end' templates/labels.json | while read -r l; do
269 name=$(echo "$l" | jq -r .name); color=$(echo "$l" | jq -r .color); desc=$(echo "$l" | jq -r .description)
270 enc=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$name")
271 if gh api "$R/labels/$enc" >/dev/null 2>&1; then
272 gh api -X PATCH "$R/labels/$enc" -f name="$name" -f color="$color" -f description="$desc" --silent && echo "label updated: $name"
273 else
274 gh api -X POST "$R/labels" -f name="$name" -f color="$color" -f description="$desc" --silent && echo "label created: $name"
275 fi
276done
277```
278
279- URL-encode label names (spaces, slashes).
280- To reconcile drift (deleted manual labels), show the diff and ask before removing labels that are already in use.
281
282### Module B — Issue forms + config
283
284Create `.github/ISSUE_TEMPLATE/` with `config.yml` plus one YAML form per
285template (bug / feature / question). Push via a commit:
286
287- **Replace placeholders** in `config.yml` (`OWNER/REPO` in the
288 Discussions / Security contact URLs) — see Template placeholders.
289- Write the forms in the user-chosen language (Preflight step 5): translate
290 form names, labels, descriptions, and placeholder text; `title:` prefix
291 and `labels:` values stay as-is (they must match the label taxonomy).
292
293```bash
294mkdir -p .github/ISSUE_TEMPLATE
295cp templates/issue-form-*.yml templates/config.yml .github/ISSUE_TEMPLATE/
296git add .github/ISSUE_TEMPLATE && git commit -m "chore: add issue forms" && git push
297```
298
299- If templates already exist, diff them; only overwrite identical or clearly
300 stale files (ask first if the user may have customized them).
301- If there is no git clone, clone first (`gh repo clone OWNER/REPO`), edit, push.
302
303### Module C — PR template
304
305```bash
306mkdir -p .github
307cp templates/PR_TEMPLATE.md .github/PULL_REQUEST_TEMPLATE.md
308git add .github/PULL_REQUEST_TEMPLATE.md && git commit -m "chore: add PR template" && git push
309```
310
311- Write the template in the user-chosen language (Preflight step 5).
312 The PR template has no placeholders to replace.
313
314### Module D — CI workflow
315
316Pick the workflow from the framework detection (templates/ci-*.yml —
317they trigger on `$default-branch`, so they work for any default branch
318name). Write to `.github/workflows/ci.yml`, commit, push. Keep existing
319workflows; only add `ci.yml` if none exists.
320
321- Node projects: `ci-node.yml` installs dependencies lockfile-aware
322 (`npm ci` / `pnpm install --frozen-lockfile` / `yarn install
323 --frozen-lockfile`, with plain `npm install` as fallback) — no manual
324 adjustment needed for pnpm / yarn repos.
325
326- Note: pushing workflow files requires a token with the `workflow` scope; if
327 the push is rejected with 403, tell the user their token lacks `workflow`.
328
329### Module E — Branch rules
330
331Prefer **rulesets** (modern) over legacy branch protection:
332
333```bash
334# list existing
335gh api repos/OWNER/REPO/rulesets -q '.[].name'
336# create (example: protect default branch)
337gh api -X POST repos/OWNER/REPO/rulesets --input - <<'EOF'
338{
339 "name": "protect-default-branch",
340 "target": "branch",
341 "enforcement": "active",
342 "conditions": {
343 "ref_name": {"include": ["refs/heads/DEFAULT_BRANCH"], "exclude": []}
344 },
345 "rules": [
346 {"type": "pull_request", "parameters": {"required_approving_review_count": 1, "dismiss_stale_reviews_on_push": true, "require_code_owner_review": false, "require_last_push_approval": true, "required_review_thread_resolution": true}},
347 {"type": "required_linear_history"},
348 {"type": "deletion"},
349 {"type": "non_fast_forward"},
350 {"type": "required_signatures"}
351 ]
352}
353EOF
354```
355
356- Idempotency: if a ruleset with the same name exists, update it with
357 `PUT repos/OWNER/REPO/rulesets/{id}` — **full replace**, include the complete
358 body (name, enforcement, conditions, rules, bypass_actors). There is no PATCH
359 for rulesets (PATCH returns 404).
360- Optional admin bypass: add `"bypass_actors": [{"actor_id": 5,
361 "actor_type": "RepositoryRole", "bypass_mode": "always"}]` (id 5 = admin)
362 so maintainers can push directly to the protected branch; non-admins still
363 go through pull requests.
364- `pull_request` parameters are **all required** in current API versions:
365 `required_approving_review_count`, `dismiss_stale_reviews_on_push`,
366 `require_code_owner_review`, `require_last_push_approval`,
367 `required_review_thread_resolution`. Omitting any → HTTP 422.
368- `target: "branch"` + `ref_name.include: refs/heads/<default>`; also offer
369 `"tag"` rules if tags matter.
370- Org repos: optionally offer org-level rulesets (`/orgs/{org}/rulesets`).
371
372### Module F — Docs
373
374README (ask about languages FIRST):
375
376- Ask the user: which languages should the README support? (suggest the
377 project's primary language + English for international projects)
378- If a README already exists, ask whether to adapt it into more languages —
379 never add languages without asking.
380- Language switcher convention (pattern from `programmingHLS/ccmm`):
381 - Default file stays `README.md` (usually English).
382 - Extra languages: `README.<lang>.md` (e.g. `README.zh.md`, `README.ja.md`).
383 - Top of every file, a switcher line — current language as plain text,
384 others as relative links:
385 - `README.md`: `< English | 简体中文 >` (简体中文 links to `README.zh.md`)
386 - `README.zh.md`: `< English | 简体中文 >` (English links to `README.md`)
387 - Keep structure, badges, and anchors parallel across language files.
388- `README.md`: if missing or bare, generate one from `templates/README.md`
389 (badges, install, usage, modules table). Keep the user's existing content if
390 it is already substantive — only append a badges block. **Replace
391 placeholders** (badge URLs, clone URL, owner credit) per Template
392 placeholders.
393- `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`: copy from
394 templates if missing (write `CONTRIBUTING.md` in the user-chosen language
395 from Preflight step 5; **replace `OWNER/REPO`** in `SECURITY.md`'s
396 advisory link per Template placeholders).
397- `VISION.md`: optional direction doc (modeled on OpenClaw's VISION.md) —
398 generate a short vision from `templates/VISION.md` (origin, guiding
399 principles, current state, direction, contribution rules) if the user
400 wants one (**replace `PROJECT_NAME`** per Template placeholders).
401- `THIRD_PARTY_NOTICES.md`: add when the project adapts third-party content
402 (licenses, fonts, code of conduct) — list each source and its license.
403- `docs/ARCHITECTURE.md`: for non-trivial projects, generate a short
404 architecture doc (structure, flow, constraints) from the audit.
405- `LICENSE`: ask the user which license (default MIT) before creating.
406- `CHANGELOG.md`: create from `templates/CHANGELOG.md` (Keep a Changelog
407 format) if missing; log notable changes per release (**replace
408 `YYYY-MM-DD`** in the placeholder date line per Template placeholders).
409
410### Module G — AI assistant guides (CLAUDE.md / AGENTS.md)
411
412- Add a `CLAUDE.md` (guidance for Claude Code) and an `AGENTS.md` (guidance
413 for any AI coding agent) when missing — see `templates/CLAUDE.md` and
414 `templates/AGENTS.md` (**replace `OWNER/REPO`** and the i18n placeholder
415 per Template placeholders).
416- If they already exist, diff and fill gaps rather than overwrite.
417- Typical content, derived from the repo audit (Modules A–F):
418 - Project: one-paragraph summary, status, stack.
419 - Commands: build / test / lint / run (from CI detection + package scripts).
420 - Conventions: commit style (see CONTRIBUTING), label taxonomy, i18n
421 requirements, secrets policy (never hardcode keys), file map.
422 - Caveats: known risks, areas to be careful with.
423- CLAUDE.md vs AGENTS.md: CLAUDE.md is Claude-specific; AGENTS.md is
424 agent-agnostic (works for Cursor/Copilot/OpenClaw too). Keep AGENTS.md free
425 of Claude-only references.
426
427## Verification
428
429```bash
430gh label list --repo OWNER/REPO --limit 200 | wc -l
431gh api repos/OWNER/REPO/contents/.github/ISSUE_TEMPLATE -q '.[].name' 2>/dev/null
432gh api repos/OWNER/REPO/contents/.github/PULL_REQUEST_TEMPLATE.md -q .name 2>/dev/null
433gh api repos/OWNER/REPO/contents/.github/workflows/ci.yml -q .name 2>/dev/null
434gh api repos/OWNER/REPO/rulesets -q '.[] | {name:.name, enforcement:.enforcement}'
435```
436
437Report a final table: `module | status (applied/skipped/failed) | note`.
438
439## Template placeholders (replace on copy)
440
441Templates stay generic — `OWNER/REPO`, `OWNER_USERNAME`, `PROJECT_NAME`,
442`YYYY-MM-DD` are placeholders the agent fills in when copying a template
443into the target repo. **Unreplaced placeholders ship broken links** (badges,
444clone URL, discussions, security advisory, CODEOWNERS handle) into the
445user's repo.
446
447| Placeholder | Replace with |
448|---|---|
449| `OWNER` | target repo owner login (user or org) |
450| `REPO` | target repo name |
451| `OWNER_USERNAME` | owner's default reviewer / team handle |
452| `PROJECT_NAME` | project display name |
453| `YYYY-MM-DD` | current date |
454
455Resolve the values once up front, then substitute in every copied file
456(`config.yml`, `README*.md`, `SECURITY.md`, `CODEOWNERS`, `AGENTS.md` /
457`CLAUDE.md`, `VISION.md`, …):
458
459```bash
460O=OWNER R=REPO N=PROJECT_NAME D=$(date +%F)
461sed -i "s|OWNER_USERNAME|$O|g; s|OWNER/REPO|$O/$R|g; s|PROJECT_NAME|$N|g; s|YYYY-MM-DD|$D|g" \
462 .github/ISSUE_TEMPLATE/config.yml README.md SECURITY.md .github/CODEOWNERS AGENTS.md
463```
464
465- Replace `OWNER_USERNAME` before `OWNER/REPO` — the former contains the
466 `OWNER` prefix, so order matters with naive `sed`.
467- Only `config.yml`, `README*.md`, `SECURITY.md`, `CODEOWNERS`, `AGENTS.md` /
468 `CLAUDE.md`, `VISION.md`, `CHANGELOG.md` carry placeholders; the issue
469 forms, PR template, CI workflows, and CoC are placeholder-free.
470- CI templates need no substitution, but **translate** their human-facing
471 text if the user chose a non-English language.
472
473## Rules of thumb
474
475- **Idempotent**: every module can run twice with the same result.
476- **Never clobber user content**: diff first, ask before overwriting customized files.
477- **Auth first**: no token, no action — tell the user how to log in, never guess.
478- **Dry-run before destructive ops**: rulesets, branch rules, label deletion, visibility changes.
479- **Confirm scope**: org/private repos and anything the user didn't explicitly name.
480
481## Templates
482
483All templates live in `templates/`:
484`labels.json`, `LABELS.md`, `config.yml`, `issue-form-bug.yml`,
485`issue-form-feature.yml`, `issue-form-question.yml`, `PR_TEMPLATE.md`,
486`ci-node.yml`, `ci-python.yml`, `ci-go.yml`, `ci-rust.yml`, `CODEOWNERS`,
487`CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `CLAUDE.md`,
488`AGENTS.md`, `VISION.md`, `CHANGELOG.md`, `templates/README.md`,
489`templates/README.zh.md`.