| name | wiki-setup |
| description | Bootstrap the wiki's repo registry from a GitHub organization. Use when the user runs /wiki-setup, asks to "set up the wiki", "onboard an org", "populate repos.yml", "discover our repos", "import repos from GitHub", or is starting a fresh wiki clone with an empty repos.yml. Asks for the org, discovers its repos via `gh`, filters by activity + contributors, asks the default fetch cadence, previews, then writes repos.yml. Does NOT scan code or run a sync — that's /wiki-sync. |
/wiki-setup — onboard a GitHub org into repos.yml
The one job: turn an organization name into a curated, owner-stamped repos.yml ready for
/wiki-sync. Discovery + filtering is deterministic (scripts/discover-repos.py calls gh);
this skill owns the questions and the confirm-before-write. Read CLAUDE.md first — this
only edits repos.yml, never scans code, never advances .sync-state.json, never commits.
Arguments
<org> (optional) — the GitHub org/login. If absent, ask in step 1.
--dry-run — do everything except write repos.yml (show the preview, then stop).
Procedure
1. Get the org + check auth
2. Ask the discovery filter (AskUserQuestion)
Repos vary wildly in liveness. Offer (single-select):
- All repos — everything non-archived, non-fork. (
--window all --min-contributors 1)
- Active in last 12 months, >1 contributor — drops dead + solo-author repos.
(
--window 12m --min-contributors 2)
- Active in last 3 months, >1 contributor — only the hot core.
(
--window 3m --min-contributors 2)
- (Other → a custom window like
6m / 2y.)
Why >1 contributor: solo repos are usually experiments/personal forks, not shared systems the
wiki should explain. Why activity: a repo untouched for a year rarely earns a concept page.
3. Ask the default fetch cadence (AskUserQuestion)
This becomes defaults.cadence in repos.yml (how often /wiki-sync re-scans a repo).
- 7 days (default, recommended) — weekly refresh.
- 14 days — calmer.
- 1 day — fast-moving org.
- (Other → custom like
3d / 1w.)
4. Run discovery (deterministic — may take a minute)
Warn the user first: the contributor + owner lookups are one or two gh api calls per
repo that survives the activity filter, so on a large org this runs for a minute or more.
Run it in the background and poll, rather than blocking.
python3 scripts/discover-repos.py --org <org> --window <w> --min-contributors <n> --cadence <c> --now <ISO8601>
- Pass
--now = today's date (from context) so the activity window is deterministic.
- Do NOT pass
--write yet. Without it the script is read-only and returns the plan.
- It prints progress to stderr and a JSON object to stdout:
totals, kept[] (name, url, branch, pushed_at, contributors, owner, owner_source, domains,
is_new), dropped[] (name + reason), proposed_yaml, notes[].
The pipeline is cheap→expensive on purpose: ONE gh repo list (activity via pushedAt), then
contributor + CODEOWNERS calls only on survivors. Owner precedence matches CLAUDE.md §4:
CODEOWNERS * rule → else an @<org>/eng placeholder flagged # TODO verify owner.
5. Preview + confirm (AskUserQuestion)
Render a scannable table of kept[], sorted by recency (the script already sorts):
| repo | last push | contrib | branch | inferred owner | domain | new? |
Then summarise totals (listed / kept / new / already-present / dropped) and surface notes[]
(rate-limit hits, --limit truncation, repos kept despite an unavailable contributor count).
Show a short sample of dropped[] with reasons so the user can spot a wrongly-excluded repo.
Ask: Write these to repos.yml? / Adjust the filter (re-run step 2) / Cancel.
- If
--dry-run → stop here regardless.
- Owner placeholders (
@<org>/eng) and inferred-without-* owners are flagged in the YAML with
# TODO verify owner — call these out so the user knows what still needs a human.
6. Write (merge-safe)
On confirm, re-run with --write:
python3 scripts/discover-repos.py --org <org> --window <w> --min-contributors <n> --cadence <c> --now <ISO8601> --write
The script appends only new repos and preserves every existing repos.yml entry verbatim
(hand-tuned owner/cadence/domains/paths win) — re-running is safe and idempotent. It bumps
defaults.cadence to the chosen value.
7. Offer to name this wiki (OPTIONAL — identity, not part of repo onboarding)
This step is a convenience, separate from the core repos.yml job; the wiki works fine
without it. A wiki can carry a name that /wiki-ask uses to address it from other directories
(and that travels with the clone, so teammates inherit it). Only do this if it isn't already named
and the user wants it:
python3 plugins/wiki-ask/skills/wiki-ask/scripts/wiki-locate.py name "$PWD"
- If
name_source is meta, it's already named — skip silently.
- Otherwise ask the user whether to name it now (it's optional; they can do it later with
/wiki-name). If yes, take a short kebab-case name (suggest the derived name, e.g. the
git-remote slug) and an optional description, then write the committed vault/.wiki-meta.json:
python3 plugins/wiki-ask/skills/wiki-ask/scripts/wiki-locate.py set-name "$PWD" "<name>" --desc "<description>"
If they decline, move on — naming is not required for /wiki-sync or in-repo /wiki-ask.
8. Report + next step
Scannable summary: org, filter used, counts (added / already-present / dropped), any owner
placeholders the user must fix, any notes[], and the wiki name if one was set. End by
pointing at the next command:
repos.yml updated. Review the # TODO verify owner lines, then run /wiki-sync to scan the
repos and grow the wiki. (This skill did not scan or commit.)
If a name was set, add: To ask this wiki from any directory, run make register and commit
vault/.wiki-meta.json so teammates share the name.
Hard rules (see CLAUDE.md §8)
Only edits repos.yml and vault/.wiki-meta.json (the wiki's name); never scans code, never
touches .sync-state.json/.state/, never commits. No secrets in the file. Preserve existing entries (merge, don't clobber). Every repo
gets an owner (real or flagged placeholder) so the downstream validator can flag the unconfirmed
ones. Report truncation/rate-limit notes[] — no silent caps.