Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .claude/commands/begin_work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
description: Start work on a GitHub issue — load context, get on the right release branch (creating it if needed), open a feature branch, then plan and implement step-by-step with check-ins
---

# /begin_work

Bootstrap a work session for a GitHub issue. Resolves which `release/X.Y.Z` integration branch holds the work — reusing an existing unmerged branch when one fits, otherwise opening a new one by following the `/start_release` procedure — then creates a feature branch off it for the issue. After setup, drives the work in chunks with checkpoints between each stage so the user stays in the loop.

Work through every step in order. After each step, stop at the **CHECKPOINT** and wait for the user before proceeding.

## Arguments

`$ARGUMENTS` — two whitespace-separated tokens, both required:

1. **issue** — a GitHub issue URL (`https://github.com/Osiris-DevWorks/smart-citizen/issues/NN`) or short form (`#NN`). The repo is implicit (`Osiris-DevWorks/smart-citizen`).
2. **target release** — either an explicit semver `X.Y.Z` (e.g. `1.4.3`) or a bump type (`major` / `minor` / `patch`).

If either argument is missing or malformed, abort with: *"/begin_work requires: <issue-url-or-#NN> <X.Y.Z | major | minor | patch>"*

## 1. Parse and validate arguments
- Extract the issue number from URL or `#NN` shorthand.
- Validate the target release:
- Matches `^\d+\.\d+\.\d+$` → treat as explicit version.
- Is `major` / `minor` / `patch` → compute the explicit version from current `VERSION.TXT` (same math as `/start_release`).
- Otherwise abort.

## 2. Fetch and summarize the issue

```bash
gh issue view <NN> --json number,title,body,labels,state,url
```

- If `state` is `closed`, warn the user.
- Present a short summary: number, title, state, labels, and a one-paragraph summary of the body (keep it tight — the full body is in conversation context).

**CHECKPOINT — confirm the issue summary captures the work, or correct it.** Wait for the user.

## 3. Resolve the target release branch

Target is `release/X.Y.Z` (the version from step 1). Check the world in this order:

- **Already merged to main**: `git branch -r --merged origin/main | grep -F "origin/release/X.Y.Z"`. If matched, abort — *"release/X.Y.Z is already merged to main; pick a higher target."*
- **Exists locally**: `git rev-parse --verify release/X.Y.Z`. If yes, `git checkout release/X.Y.Z`. Confirm `VERSION.TXT` on it equals `X.Y.Z`.
- **Exists on origin only**: `git ls-remote --heads origin release/X.Y.Z`. If matched, `git fetch origin release/X.Y.Z:release/X.Y.Z`, then check out. Confirm `VERSION.TXT`.
- **Does not exist anywhere**: open it by following the procedure in `.claude/commands/start_release.md`. Use the bump type the user passed; if they passed an explicit version, derive the bump type by diffing current `VERSION.TXT` (on `main`) against `X.Y.Z`. The derived bump must be a **single step** (next patch, next minor, or next major). If the requested version skips ahead (e.g. current `1.4.2` → requested `1.6.0`), abort and ask the user to clarify intent.

**Multi-active guard**: before creating a new release branch, run `git branch -a --list 'release/*' --no-merged origin/main`. If any other unmerged `release/*` exists, surface it and ask the user to confirm.

After this step you must be checked out on `release/X.Y.Z` with a clean working tree.

**CHECKPOINT — confirm the release branch is correct (reused / newly created) before opening the feature branch.** Wait for the user.

## 4. Create the feature branch

- Slug the issue title: lowercase, replace non-alphanumerics with `-`, collapse repeats, trim to ~40 chars.
- Branch name: `issue/<NN>-<slug>` (example: `issue/42-fix-channel-switch-race`).
- Create it: `git checkout -b issue/<NN>-<slug>` from the release branch.

Report:
- `Issue: #<NN> — <title>` (with URL)
- `Release branch: release/X.Y.Z` (note whether reused or newly created via /start_release)
- `Feature branch: issue/<NN>-<slug>`
- Scope reminder if `release/X.Y.Z` is a patch: *"Patch branches accept only bug fixes and minor polish — flag scope mismatch if this issue is feature work."*

**CHECKPOINT — ready to plan the work?** Wait for the user.

## 5. Plan the work

Before writing any code:

1. Identify which layers this issue touches. Pull the relevant per-directory `CLAUDE.md` into context (`src/gui/`, `src/utils/`, `src/parser/`, `src/merger/`, `src/models/`, `scripts/`, `tests/` — see root `CLAUDE.md` → *Per-directory guides*).
2. Propose the implementation in **manageable chunks**. One concept at a time per the root `CLAUDE.md` *Communication style* rule. For each chunk, present:
- What you'll change and why.
- The file(s) involved (with paths).
- Any trade-offs the user should decide on.
- **CHECKPOINT — wait for the user to confirm this chunk before moving to the next.**
3. After every chunk is confirmed individually, ask the user to approve the full plan as a whole.

**CHECKPOINT — full plan approved?** Wait for the user.

## 6. Implement step-by-step

Once the plan is approved:

- Implement one chunk at a time, in the order from the plan.
- After each chunk, show the diff for that chunk and pause.
- **CHECKPOINT — wait for the user to confirm this chunk before moving to the next.**
- Tests live in `tests/`. Run `pytest tests/` after any chunk that affects testable code and report the result.

## 7. Final walkthrough

When all chunks are implemented:

1. Run `/standards_check`, `/docs_sync_check`, and `/test_coverage_check` in sequence. Walk the user through findings.
2. Give a step-by-step walkthrough of everything that changed:
- Files modified, grouped by layer (GUI / utils / parser / tests / docs).
- Why each change was made (link back to the plan chunk).
- What tests were added or updated.
- Anything left intentionally untouched and why.

**CHECKPOINT — ready to run `/pull_request`?** Wait for the user.

## Notes

- The release branch (if newly created) and the feature branch are both local-only. The user pushes when ready.
- This command does not open a PR. `/pull_request` does — and now opens it as draft, so the user can keep iterating after the initial open.
- If the issue requires an exploratory spike that will not ship, this is the wrong command — work on a personal branch off `main` instead.
51 changes: 51 additions & 0 deletions .claude/commands/docs_sync_check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
description: Verify user-facing strings, HELP / ABOUT docs, README, and the tutorial match the current app
---

# /docs_sync_check

Cross-check the running app's user-facing surface against the docs and tutorial. Catches drift introduced when a button is renamed in code but the doc still describes the old name, when a control is removed but the tutorial still points at it, or when a new feature ships without a docs update.

## Severities

- **Critical** — a tutorial step in `src/gui/coach_mark.py` references a widget that no longer exists. Will crash or confuse first-time users.
- **Major** — workflow steps in `docs/HELP.md` no longer match the code, or a user-facing string is described in `docs/HELP.md` / `docs/ABOUT.md` under a name that no longer exists in code.
- **Minor** — a feature mentioned in `docs/ABOUT.md` or `README.md` has been removed/renamed but isn't user-facing-critical (e.g. a string label drift that still reads naturally).

## Inputs

- `src/gui/*.py` — user-facing strings (window titles, button/menu/tab labels, dialog text, log lines users see in the Log Tab).
- `docs/HELP.md` — step-by-step user instructions.
- `docs/ABOUT.md` — feature summary.
- `src/gui/coach_mark.py` — `CoachMarkStep` entries that drive the guided tour.
- `README.md` — Features section and Screenshots labels.

## Checks

1. **Tutorial widget validity** *(Critical)*: every `CoachMarkStep` in `coach_mark.py` references a target widget — confirm the widget still exists (grep for its attribute name on `MainWindow` and the relevant tabs). Flag any step whose target was deleted or renamed.
2. **String drift in HELP/ABOUT** *(Major)*: pull every user-facing literal from `src/gui/` and check whether any noun phrase used in `HELP.md` or `ABOUT.md` is no longer present in the code (likely renamed). Flag with the doc file:line plus the suspected new wording from the code.
3. **Workflow currency** *(Major)*: `HELP.md` describes Apply / Restore / Extract / Reset user.ini / Export Loc-Pack / channel switch. If a recent diff changed any of these flows, surface the matching section of `HELP.md` for review.
4. **Feature parity** *(Minor, escalate to Major if HELP.md has a how-to step for the affected feature)*: `HELP.md`, `ABOUT.md`, and README's Features list should match the code. Flag features described in docs that no longer exist, and code features that aren't surfaced in any of the three.

## Output

Group findings by severity. Within each group: `doc-file:line → code-file:line — short description`.

```
**Critical** (tutorial broken):
src/gui/coach_mark.py:54 → (widget removed) — TutorialTour step "Click Extract" targets MainWindow.extract_btn which no longer exists

**Major** (should fix):
docs/HELP.md:120 → src/gui/main_window.py:380 — HELP describes "Reset Overrides" button; code now labels it "Reset user.ini"

**Minor** (consider):
README.md:24 → (no code reference) — Features list mentions "auto-update for source INIs" but the URL-source pipeline was retired in 0.7.0
```

End with a one-line **verdict**:

- **Clean** — no findings.
- **Minor issues** — only Minor findings.
- **Needs attention** — any Critical or Major findings.

After the verdict, **CHECKPOINT — pause and ask the user whether to draft doc updates for the Critical/Major findings, or move on.** Do not edit docs without confirmation — surface, don't auto-correct.
137 changes: 137 additions & 0 deletions .claude/commands/pull_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
description: Open a draft PR for the current branch, run the standards self-review with checkpoints, then offer to mark it ready for review
---

# /pull_request

Open or update a **draft** PR for the current branch, run Smart Citizen's documented self-review with checkpoints between each section, then offer to mark it ready for review.

Work through every section in order. After each section, stop at the **CHECKPOINT** and wait for the user to confirm before continuing. Never auto-fix a standards violation without confirming first.

## Arguments

`$ARGUMENTS` may contain:

- `--testing "description"` — manual-test notes the user has already performed. These flow into the *Testing performed* block of the PR body.
- `--skip-draft` — open the PR as ready-for-review immediately and skip the self-review walkthrough. Use only when the user has run the checks elsewhere or is intentionally bypassing the gate.

If no flags are passed, proceed with the default draft-then-walkthrough flow.

## 1. Branching model

- Confirm the current branch is **not** `main`. PRs target the active `release/X.Y.Z` integration branch, never `main` directly.
- Identify the active integration branch: the highest `release/X.Y.Z` that exists on origin (`git ls-remote --heads origin 'release/*'`). The PR's base must match.
- The version suffix signals scope. A patch branch (e.g. `release/1.4.2`) is reserved for **bug fixes and minor polish**. If the diff includes new features or a meaningful behavior change, flag the scope mismatch — do not proceed silently.

**CHECKPOINT — confirm the branching model setup before proceeding.** Wait for the user.

## 2. PR scope

A PR should cover **one concern**: a single feature, a single bug fix, a batch of related bug fixes (same subsystem, same release-branch scope), a self-contained refactor, or a self-contained doc update. Mixed-concern PRs create review burden — surface candidate splits and let the user decide.

Run these against `git diff --name-only $(git merge-base HEAD origin/main)...HEAD` plus `git diff --shortstat`:

- **File-count signal**: more than 8 files touched outside a deliberate cross-cutting change (project-wide rename, doc reorganization, dep bump) → flag for scope review.
- **Net-line signal**: more than ~400 net lines changed, excluding generated files and lock files → flag for scope review.
- **Concern-mixing signal**: scan paths and patches. If any of these are mixed in one diff, list each cluster with its file list and ask the user to confirm or split:
- feature work in one subsystem + unrelated bug fix in another
- refactor of existing code + a new feature built on top of it (refactor first, ship, then build)
- doc rewrite unrelated to the code change
- "drive-by" formatting or rename edits in files not otherwise needed for the work
- **Title sanity**: if the working title needs "and" or a semicolon to describe both concerns, that's a split signal.

Surface clusters; do not auto-split. If the user confirms the PR is correctly scoped despite a signal trip (e.g. intentional wide-blast refactor), call out the rationale in the PR body so reviewers know what to focus on.

These thresholds are calibration, not laws. A 500-line PR doing one focused thing is easier to review than two 200-line PRs that overlap.

**CHECKPOINT — confirm scope (or explain why a flagged signal is intentional) before opening the draft PR.** Wait for the user.

## 3. Open the draft PR

- Check if a PR already exists for this branch: `gh pr view --json url,body,title,isDraft,number`.
- **No PR exists**: build title and body per *PR title and body* below, then `gh pr create --base release/X.Y.Z --draft --title "..." --body "..."`.
- **Draft PR exists**: refresh body (preserve any `- [x]` ticks the user has already applied) and title if needed via `gh pr edit <number>`.
- **Non-draft PR exists**: pause and ask the user whether to operate on it as-is (no draft revert) or convert to draft (`gh pr ready --undo <number>`). Default: operate as-is.
- Print the PR URL.

If `--skip-draft` was passed, open with `gh pr create` (no `--draft`) and skip directly to step 5; the user takes responsibility for the self-review.

**CHECKPOINT — ready to start the self-review walkthrough?** Wait for the user.

## 4. Self-review walkthrough

Run the three focused checks one at a time. After each check, present findings grouped by severity and stop at the section's CHECKPOINT.

### 4a. Test coverage check
Follow the procedure in `.claude/commands/test_coverage_check.md`. Present findings grouped by severity (Critical / Major / Minor) and end with the verdict line.

**CHECKPOINT — ready for the next check?** Wait for the user.

### 4b. UI / docs / tutorial sync check
Follow the procedure in `.claude/commands/docs_sync_check.md`. Present findings grouped by severity and end with the verdict line.

**CHECKPOINT — ready for the next check?** Wait for the user.

### 4c. Standards spot-check
Follow the procedure in `.claude/commands/standards_check.md`. Present findings grouped by severity and end with the verdict line.

**CHECKPOINT — self-review complete.** Summarize the combined verdict (worst-case of the three). Ask the user one of:

- *"Draft fixes for the Critical/Major findings before marking ready?"*
- *"Mark ready as-is (accepting open findings as known)?"*
- *"Pause — leave the PR as draft, I'll come back to it?"*

Wait for the answer.

## 5. Mark ready (if requested)

When the user is satisfied and explicitly asks to mark ready:

- `gh pr ready <number>`
- Confirm the PR is no longer marked draft.
- Print the final URL.

If the user paused or chose to draft fixes, leave the PR as draft and stop — the user will come back later.

## PR title and body

### Title
- Under 70 chars, imperative, no trailing period.
- Match the repo prefix style when appropriate (`docs:`, `apply:`, `generator:`, `assets:`, etc.).
- If the work was launched via `/begin_work` and the GitHub issue number is known, prefix with `[#NN]`: e.g. `[#42] fix: channel switch loses user.ini overrides`.

### Body

Use a HEREDOC to preserve formatting. When updating an existing PR, fetch the current body, **preserve any `- [x]` ticks** the human has already applied, and refresh items whose surrounding context has changed.

```
## Summary
<1-3 bullets describing what changed and why. If linked to an issue, cite it: "Closes #42.">

## Testing Checklist
- [ ] PR is scoped to one concern (single feature, single bug fix, batch of related bug fixes, self-contained refactor, or self-contained doc update)
- [ ] `pytest tests/` passes locally
- [ ] App launches: `python src/main.py`
- [ ] Affected user-facing flow exercised manually (note which: Apply / Restore / Extract / Reset / Export / Tutorial / other)
- [ ] User-facing strings, `docs/HELP.md`, `docs/ABOUT.md`, and `src/gui/coach_mark.py` reviewed for drift
- [ ] New non-exempt code has matching test coverage in `tests/`
- [ ] Target branch is the active `release/X.Y.Z`, not `main`
- [ ] No direct `QSettings` calls, no hard-coded column indices, no `QProgressBar.setValue()` from workers
- [ ] If new enhancement category: `CATEGORY_SUBTREES` and `DATAFORGE_KEEP_SUBPATHS` both updated
- [ ] `VERSION.TXT` matches the active release branch

## Testing performed
<!-- If --testing "..." was passed, paste that description here verbatim. Otherwise: "Per the Testing Checklist above." -->

## Post-merge QA
Things to validate after this lands on the integration branch:
- [ ] App launches from a clean checkout of the integration branch (no leftover state)
- [ ] The user-facing flow this PR touches works end-to-end on a real Star Citizen install (note channel: LIVE / PTU / EPTU / HOTFIX / TECH-PREVIEW)
- [ ] Tutorial coach-marks still land on the correct widgets if any UI controls moved
- [ ] (Add PR-specific items here — e.g. "Verify channel switch preserves `user.ini` overrides," "Verify new enhancement INI is generated for the ships category," "Verify Apply rolls back correctly on validator failure")

---
🤖 PR description generated with [Claude Code](https://claude.com/claude-code) and reviewed by @<github_username>
```

Fetch `<github_username>` via `gh api user --jq '.login'`. If the call fails (no auth, no network), omit the attribution footer rather than blocking the PR.
Loading
Loading