PMX: Restructure obtainment, add format skills, tighten CI - #6
Merged
Conversation
✅ Deploy Preview for thepokemax ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
codebend3r
force-pushed
the
obtain-structural-cleanup
branch
from
August 21, 2026 13:19
f4eb6c8 to
d62f8b0
Compare
codebend3r
added a commit
that referenced
this pull request
Aug 22, 2026
- PR bodies drifted in shape across `#3`, `#5`, and `#6` — bullets in two, bold-lead paragraphs in the third, section names picked per PR - skill fixes the contract: lede, `## What changed`, `## Verification`, `## Notes`, with per-subsystem sections when the change spans several - bullets are the default form; prose is confined to the lede - title rules mirror the commit-subject style already in `git log` - `--body-file` is required, not preferred: backticks inside a double-quoted `--body` string are executed by the shell - carries `CLAUDE.md`'s zero-AI-attribution rule into PR titles and bodies
- `METHOD_MAP` has no entry mapping to `'special'` - so `method === 'special'` already implies `!METHOD_MAP[slug]` - second clause could never be false when the first was true
- derive `ObtainMethod` from a new `OBTAIN_METHODS` list — one vocabulary - guard now checks `games[].gen`/`versionGroup`/`versions`/`entries` - rejects entries whose `method` is not a known method - previously `ObtainMethods.tsx` indexed `METHOD_LABEL` on unvalidated strings - verified all 1351 files in `public/obtain/` still pass
- new `REGIONS` + `REGION_OF_VERSION_GROUP` map every version group to its setting - `GAMES_BY_REGION` now derives from `REGIONS` instead of restating it - `ObtainMethods.tsx` drops `VG_REGION`, `REGION_ORDER`, `REGION_LABELS` - kills the `getGen(gen).region` fallback, which was wrong for every remake and was the reason `VG_REGION` had to exist as a patch table - Hisui's note comes from `REGIONS`, not a one-entry label override - rename `crt-obtain-gen`/`crt-obtain-gen-toggle` — the rows are regions, not gens - new `regions.test.ts` pins coverage and ordering against `GENERATIONS`
- `useObtainData` returns `ObtainState` — `idle` / `loading` / `error` / `ready` - the enabled-but-not-yet-started frame now reports `loading` from the hook - drops the compensating `loading || (enabled && !data && !error)` in the view - drops the stale-id reconciliation — `settled.id` scopes failures to their id - `ObtainMethods` takes `state` + `currentGen`, down from five props - `enabled` no longer passed twice from `PokemonCard.tsx` - ready branch split into `ObtainRegions` so the data is non-null by type - loading/idle tests move to `useObtainData.test.ts` where the inputs live
- `Set<string> | null` existed only because the default region was unknown until the file loaded — inside `ObtainRegions` it is known at mount - plain `useState<Set<string>>` with a lazy initializer replaces it - `toggle` no longer closes over a render-scoped `expanded` fallback - not routed through `useExpandedRegions` on purpose: its persisted value would carry one Pokémon's open region onto the next
- `CONDITION_PREFIXES`, `conditionMeta`'s if-chain, and `LEGEND_CONDITIONS` all dispatched on the same slug families — a new family meant three edits - one table now carries prefix, icon, color, label strip, and legend gloss - `LEGEND_CONDITIONS` derives from it instead of restating icon/color by hand - `RODS` deleted — `ROD_METHODS` exported from `@/obtain/pokeapi` and shared by the build parser and the chip renderer - diffed old vs new over all 341 condition slugs in `public/obtain/` — identical - new test pins one chip per family, including the unknown-slug fallback
- `ObtainMethods.tsx` was 410 lines, ~250 of them static label tables - `METHOD_LABEL`, `METHOD_COLOR`, `CONDITION_*`, `LEGEND_*`, `levelRate`, `prettyCondition`, `conditionMeta` now live beside the domain they describe - component drops to 176 lines of rendering - `regionLabel` takes `RegionMeta` instead of an ad-hoc object shape - `LEGEND_CONDITIONS` uses `flatMap` so it narrows without `?? ''` padding - new `obtainLabels.test.ts` pins label/color/gloss coverage to `OBTAIN_METHODS`
- PR bodies drifted in shape across `#3`, `#5`, and `#6` — bullets in two, bold-lead paragraphs in the third, section names picked per PR - skill fixes the contract: lede, `## What changed`, `## Verification`, `## Notes`, with per-subsystem sections when the change spans several - bullets are the default form; prose is confined to the lede - title rules mirror the commit-subject style already in `git log` - `--body-file` is required, not preferred: backticks inside a double-quoted `--body` string are executed by the shell - carries `CLAUDE.md`'s zero-AI-attribution rule into PR titles and bodies
- line 13 claimed `pokemax-commit-format` governed "PR titles and bodies too" — two skills owning PR format is the drift the new skill removes - that bullet now scopes to commit messages; a new bullet hands PR titles and bodies to `create-pull-request` - both still carry the zero-AI-attribution rule, so narrowing one bullet does not open a gap
- `CLAUDE.md` has mandated this skill since `e1a3761` but no file existed at the path it named, so the rule was unenforceable - rules derived by measuring the last 60 commits, not invented: 188 body bullets, 0 ending in a period, 0 prose lines, subject median 53 chars - lands in `.claude/skills/` beside `create-pull-request` rather than `~/.claude/skills/` — pokemax skills belong to the repo - `CLAUDE.md` path updated to match; the `Don't` section reference needed no change since it names the skill without a path
- `ci.yml` ran on `push: branches: ['**']` and `pull_request`, so every commit on a PR branch triggered two identical full runs - push now scopes to `main`; `pull_request` covers branch work - `bun-version: latest` made CI non-deterministic — a bun release could break a green tree with no repo change; both workflows pin `1.4.0`, matching the local toolchain and the `.nvmrc`/`engines` pinning style - `actions/cache@v4` on `~/.bun/install/cache`, keyed by `bun.lock` - `ci.yml` gains `permissions: contents: read`; it inherited the repo default and needs no write scope - `timeout-minutes` on all three jobs so a hung runner cannot burn minutes - `workflow_dispatch` added to `ci.yml` for manual re-runs - concurrency group keys on `github.workflow` too, so `ci.yml` and a future workflow on the same ref cannot cancel each other - deploy keeps its own `test` step on purpose — `workflow_dispatch` can ship a commit CI never gated
- both skills previously banned prefixes outright, matching the 60 commits measured at the time — that rule is now reversed by convention - `PMX: ` is mandatory on every hand-written commit subject and PR title - form follows the sister repo's `CJR:` convention: code, colon, one space - pokemax capitalizes the first word after the prefix; `codebender-portfolio` lowercases it, so the two repos differ past the colon - version bumps take the prefix too — `PMX: 0.3.4` - `(#5)` squash suffixes still come from GitHub, never typed by hand - this subject is the first commit written under the new rule
- `oxfmt` exits 2 when no staged file is a type it formats, printing to stderr and leaving stdout empty - husky runs hooks under `set -e`, so the bare `unformatted=$(…)` assignment inherited that 2 and aborted the commit - any commit staging only `.md`, `.svg`, or `.png` was blocked - `|| true` on the assignment restores the intended behavior: no formattable files means nothing to reformat, so the hook exits 0 - latent since the hook was written; surfaced once `bun install` recreated `.husky/_` in this worktree and the hooks began running at all
- the skill lives in the pokemax repo, so the repo name in the skill name was redundant — `.claude/skills/commit-format/` - frontmatter `name:` and the `# Commit format` heading follow the path - `CLAUDE.md` and `AGENTS.md` updated in both the Do and Don't sections - `AGENTS.md` pointed at `~/.Codex/skills/pokemax-commit-format/SKILL.md`, which never existed; it now names the repo-local file like `CLAUDE.md` - `docs/superpowers/plans/2026-07-31-obtainment-methods.md` still cites the old name and is left alone — it records what was true when it was written
codebend3r
force-pushed
the
obtain-structural-cleanup
branch
from
August 22, 2026 20:22
e1f91a4 to
9c4fa66
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Behavior-preserving structural cleanup of the obtainment feature — one commit per finding from a code-quality audit of #5. The branch also picked up the repo's commit/PR format skills, a CI pass, and a husky fix; see Notes on that scope.
Obtainment restructure
generations.tsnow ownsREGIONS+REGION_OF_VERSION_GROUP;ObtainMethods.tsxdropsVG_REGION,REGION_ORDER,REGION_LABELS, andGAMES_BY_REGIONderives from itgetGen(gen).regionfallback — a second source of truth that was wrong for every remake, which is whyVG_REGIONexisted as a patch tableuseObtainDatareturns oneObtainStateunion (idle/loading/error/ready), replacing{data, loading, error}plus the view's compensatingloading || (enabled && !data && !error)ObtainMethodsgoes from five props to two; the ready branch splits intoObtainRegionsso the data is non-null by typeSet<string> | nullexpansion state becomes plainuseState<Set<string>>— the default region is known at mount insideObtainRegionsCONDITION_PREFIXES,conditionMeta's if-chain, andLEGEND_CONDITIONScollapse into oneCONDITION_FAMILIEStable; the legend derives from it instead of restating icon and color by handRODSdeleted in favor ofROD_METHODS, exported from@/obtain/pokeapiand shared by the build parser and the chip renderersrc/obtain/labels.ts;ObtainMethods.tsxdrops from 410 lines to 176 of renderingObtainMethodderives from a newOBTAIN_METHODSlist andisObtainFilevalidates game and entry shape against it — the renderer previously indexedMETHOD_LABELon unvalidated stringsencountersToEntries: nothing inMETHOD_MAPmaps to'special', so the second half ofmethod === 'special' && !METHOD_MAP[slug]could never be false when the first was trueCommit and PR format skills
CLAUDE.mdhas mandated a commit-format skill sincee1a3761, but no file existed at the path it named — the rule was unenforceable.claude/skills/, not~/.claude/skills/, so they travel with the repocommit-format, notpokemax-commit-format— the repo name is redundant inside the repocreate-pull-requestfixes the body contract: a lede, then per-subsystem sections, then verification and notesPMX:repo-code prefix on every commit subject and PR title, following the sister repo'sCJR:form-F -/--body-fileover-m/--body: backticks inside a double-quoted shell string are executed, and this repo backticks nearly every identifierCLAUDE.mdpreviously pointed the commit skill at PR titles too; that bullet now scopes to commits, and a second bullet hands PRs tocreate-pull-requestAGENTS.mdpointed at~/.Codex/skills/pokemax-commit-format/SKILL.md, which never existed; it now names the repo-local fileGitHub Actions
ci.ymlran on bothpush: branches: ['**']andpull_request, so every commit on a PR branch triggered two identical full runs — push now scopes tomainbun-version: latestmade CI non-deterministic; both workflows pin1.4.0, matching the local toolchain and the existing.nvmrc/enginespinning styleactions/cache@v4added on~/.bun/install/cache, keyed bybun.lockci.ymlgainspermissions: contents: read; it inherited the repo default and needs no write scopetimeout-minuteson all three jobs,workflow_dispatchonci.yml, and the concurrency group now keys ongithub.workflowHusky fix
.husky/pre-commitblocked any commit staging only.md,.svg, or.pngoxfmtexits 2 when no staged file is a type it formats, and husky runs hooks underset -e, so the bareunformatted=$(…)assignment inherited that 2|| trueon the assignment restores the intent: nothing formattable means nothing to reformatbun installrecreated.husky/_and the hooks began running at allVerification
bun run system-checkgreen —oxfmt --checkclean on 128 files,tsc -bsilent,oxlintsilent,vite buildokregions,obtainLabels,obtainTypes)isObtainFile: all 1351 files inpublic/obtain/still pass the tightened guardCONDITION_FAMILIES: old vs new implementations diffed over all 341 distinct condition slugs in the dataset — 0 differences in label, icon, or colorpublic/obtain/regeneration and no data changesgit diffbetween the pre-rewrite tag and the rewritten tip is emptyNotes
CLAUDE.md) share no files. Splitting the tooling commits onto their own branch would review better; left as one branch because the tooling was requested while this one was open.PMX:prefix and the branch force-pushed, with explicit approvaluseExpandedRegionsfor the region collapse state, but that hook persists tolocalStorage, so one Pokémon's open region would carry onto the next, whose regions are a different set. PlainuseStateinstead, with a comment saying why.deploy.ymlkeeps its ownteststep even though CI now coversmain—workflow_dispatchcan ship a commit CI never gatedGameId'lets-go'is the one id that isn't its PokéAPI version-group slug; that divergence is now one named entry intrainers.tsinstead of spread across region tables. Renaming it would touch trainer data, routes, and stored prefs — left alone.scripts/is in notsconfiginclude, sobuild-obtain-data.mtsis never type-checked bytsc -bdocs/superpowers/plans/2026-07-31-obtainment-methods.mdstill cites the old skill name and is left alone — it records what was true when it was writtenCLAUDE.mdotherwise says commit straight tomain