diff --git a/.claude/skills/board-ops/SKILL.md b/.claude/skills/board-ops/SKILL.md index 903d303d..47054420 100644 --- a/.claude/skills/board-ops/SKILL.md +++ b/.claude/skills/board-ops/SKILL.md @@ -199,7 +199,7 @@ Safe alternatives, in order of preference: `ProjectV2SingleSelectFieldOptionInput.id` is an optional `String`, so a mixed list works. Verify afterward that no card lost its value — snapshot `gh project item-list … --format json` before and after and diff; don't just - spot-check. + spot-check. Send those dumps to `$BOARD_TMP` too, for the reason above. Both the `Incoming` Status option and the Urgent/High/Medium/Low Priority options were added this way (#1891), with the before/after diff confirming all @@ -213,8 +213,16 @@ card's value and never touch the field schema. One command, and it is the difference between a five-minute restore and reconstructing statuses by inference: +⚠️ **Write it outside the repo.** [The boards are private](../issue-triage/SKILL.md), +so a snapshot is a full dump of item IDs and every card's Status and Priority. +Left in the working tree it is one `git add -A` away from being published in a +PR (Copilot). + ```sh -gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 > board-snapshot.json +BOARD_TMP=$(mktemp -d) +gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \ + > "$BOARD_TMP/board-snapshot.json" +echo "snapshot: $BOARD_TMP/board-snapshot.json" # note the path; you need it to recover ``` ### Recovering from a deleted option @@ -230,18 +238,24 @@ each single-select field under its lowercased name, so both keys are present), and pass the Priority field id `PVTSSF_lADOCt2Azc4BJVxtzg5iJE4`. ```sh +# 0. Same temp dir the snapshot went to — keep every dump out of the worktree. +BOARD_TMP=${BOARD_TMP:-$(mktemp -d)} + # 1. Which cards lost their value, and what did they hold? -gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 > board-broken.json -jq -r '[.items[]|select(.status==null)|.id]' board-broken.json > lost-ids.json -jq -r --slurpfile L lost-ids.json '($L[0]) as $lost +gh project item-list 28 --owner modelcontextprotocol --format json --limit 600 \ + > "$BOARD_TMP/board-broken.json" +jq -r '[.items[]|select(.status==null)|.id]' "$BOARD_TMP/board-broken.json" \ + > "$BOARD_TMP/lost-ids.json" +jq -r --slurpfile L "$BOARD_TMP/lost-ids.json" '($L[0]) as $lost | [.items[] | select(.id as $i | $lost|index($i)) | .status // "(none)"] - | group_by(.) | map({s:.[0],c:length}) | .[] | "was \(.s): \(.c)"' board-snapshot.json + | group_by(.) | map({s:.[0],c:length}) | .[] | "was \(.s): \(.c)"' \ + "$BOARD_TMP/board-snapshot.json" # 2. Recreate the option, echoing every surviving option's id (see above). # NOTE: the recreated option gets a NEW id — the deleted one never comes back. # 3. Re-apply it to the orphaned cards. -for id in $(jq -r '.[]' lost-ids.json); do +for id in $(jq -r '.[]' "$BOARD_TMP/lost-ids.json"); do gh project item-edit --project-id PVT_kwDOCt2Azc4BJVxt --id "$id" \ --field-id PVTSSF_lADOCt2Azc4BJVxtzg5iI8c --single-select-option-id sleep 0.4 diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index 518c9f26..3b0f475e 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -33,13 +33,21 @@ The bump is part of the milestone's work, so it belongs on the develop branch and flows into `main` with everything else. ```sh -# The branch name carries the version you are bumping TO, so read it first. +# Branch from the REMOTE ref, and read the version only once you are on it. +# A default clone has just `main` checked out, so a local `v2/main` may not +# exist and `package.json` here is `main`'s — the released version, not the one +# you are bumping from (Copilot). +git fetch origin v2/main +git checkout -b v2/chore/-bump- origin/v2/main node -p "require('./package.json').version" # what is on v2/main now -git checkout -b v2/chore/-bump- v2/main npm version minor --no-git-tag-version # or major / patch; bump only, no tag node -p "require('./package.json').version" # confirm, then PR → v2/main ``` +The branch name carries the version you are bumping **to**, so it is named after +that second reading. If you want it before branching: +`git show origin/v2/main:package.json | node -p "JSON.parse(require('fs').readFileSync(0)).version"`. + ⚠️ **Never copy a version out of this file.** It would be a version that has already shipped by the time you read it, and following it would cut a release branch named for the wrong release (Copilot).