Skip to content

Improve Claude Code setup#1378

Open
santir489 wants to merge 4 commits into
mainfrom
WG-improve-claude-setup
Open

Improve Claude Code setup#1378
santir489 wants to merge 4 commits into
mainfrom
WG-improve-claude-setup

Conversation

@santir489

@santir489 santir489 commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Description

This PR improves the Claude Code setup for rails_api_base by adding project-specific guidance, agents, commands, rules, and skills focused on Ruby, Rails, RSpec, PR creation, and code review workflows.

Changes include:

  • Adds Claude Code skills for Rootstrap Ruby, Rails, and RSpec conventions.
  • Adds a code-reviewer subagent to review diffs against the base branch using project conventions.
  • Adds a pr-size-checker subagent to detect large PRs and suggest logical splits.
  • Adds a create-pr command to standardize PR creation using the repository template.
  • Adds GitHub PR formatting rules to guide consistent PR descriptions.
  • Adds CLAUDE.md as the main entry point for Claude Code project context.
  • Updates the README with Claude Code setup information.

Notes

This is documentation/tooling only. It does not change application runtime behavior.

santir489 and others added 3 commits April 20, 2026 10:47
  Rootstrap's tech-guides conventions when Claude Code edits Ruby,
  Rails, or RSpec code in projects bootstrapped from this template
- pr-size-checker (agent): analyzes the current branch's diff against
  its base and recommends splitting into smaller PRs when the effective
  added lines exceed ~400, while respecting Rails-specific groupings
  (model+migration, routes+controller, factories with new models).
- github-pr-formatting (rule): single source of truth for PR creation —
  walks through filling each section of the repo's PR template (Board,
  Description, Notes, Tasks, Risk, Preview), defines the title format
  ([TICKET-ID] when applicable), and documents GitHub markdown gotchas.
- create-pr (command): workflow for opening a PR — runs the size check,
  prepares the branch, gathers commit info, and invokes
  github-pr-formatting to fill the body.
- Adds .claude/agents/code-reviewer.md, a read-only review subagent
  that preloads the ruby/rails/rspec convention skills and applies
  them to diffs against the base branch. Restricted via the `tools:`
  whitelist to read-only operations.
- Removes the Timecop guidance from rspec-conventions: this template
  uses Rails' built-in `freeze_time` / `travel_to` (configured in
  spec/rails_helper.rb), and Timecop is not in the bundle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented May 4, 2026

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

@santir489 santir489 marked this pull request as ready for review June 26, 2026 15:35
@jpascual1994 jpascual1994 requested a review from a team July 1, 2026 13:11
Comment thread CLAUDE.md

## What this repo is

Rootstrap's Rails API template — a Rails 8.1 / Ruby 4.0 boilerplate for JSON APIs. It is meant to be cloned and renamed via `bin/bootstrap.sh --name=<project>`, which `sed`s `rails_api_base` to your project name across the codebase. The template ships with two parallel surfaces:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT
Is there a way to ensure this section gets updated whenever a new project is started?
Maybe it doesn't belong here, and it fits better somewhere else, like in the Foundation checklist.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Claude Code project guidance for the rails_api_base template, including repository context, Ruby/Rails/RSpec conventions, and standardized PR creation/review workflows.

Changes:

  • Introduces CLAUDE.md as the main Claude Code entry point and documents common repo commands/architecture.
  • Adds Claude Code skills (ruby-conventions, rails-conventions, rspec-conventions) plus agents (code-reviewer, pr-size-checker) and a create-pr command/ruleset.
  • Updates the README with Claude Code setup information.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
README.md Documents the presence and purpose of .claude/skills/* for Claude Code users.
CLAUDE.md Adds repository-wide Claude Code guidance (commands, architecture, conventions, PR workflow).
.claude/skills/ruby-conventions/SKILL.md Adds Rootstrap Ruby style guidance as an auto-activated Claude Code skill.
.claude/skills/rails-conventions/SKILL.md Adds Rootstrap Rails conventions as an auto-activated Claude Code skill.
.claude/skills/rspec-conventions/SKILL.md Adds Rootstrap RSpec conventions as an auto-activated Claude Code skill.
.claude/rules/github-pr-formatting.md Defines canonical PR body formatting rules for consistent GitHub rendering.
.claude/commands/create-pr.md Adds a standardized PR creation workflow referencing the formatting rules.
.claude/agents/pr-size-checker.md Adds an agent spec to assess PR size and propose logical splits.
.claude/agents/code-reviewer.md Adds an agent spec to review diffs against project conventions and quality checks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +37
3. **If the current branch tracks an upstream**, infer from merge base:
```bash
git merge-base HEAD main 2>/dev/null
git merge-base HEAD main 2>/dev/null
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since git merge-base prints the merge-base SHA to stdout, running it without assigning the result does not affect the later git diff $BASE...HEAD call. As far as I can tell, $BASE still remains set to main.

If the intent is to handle cases where HEAD may not be directly comparable to main, we could capture the merge base instead:

BASE=$(git merge-base HEAD main 2>/dev/null || echo "main")

Otherwise, I think the duplicate commands can just be removed.

Comment on lines +153 to +155
## Date & Time
- `Time.now` over `Time.new`; use `Date` or `Time`, not `DateTime`.
- (See also `rails-conventions` — in Rails, use `Time.zone.now`/`Time.current`.)
---
name: rails-conventions
description: Rootstrap Rails conventions. Use when writing, reviewing, or editing any Rails code — controllers, models, migrations, routes, views, mailers, initializers, locale files, or Rails config. Covers routing, ActiveRecord, migrations, i18n, time zones, mailers, assets, Bundler groups, and logging.
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Since CLAUDE.md mentions that project-level skills auto-activate based on the files being edited, maybe we could add paths: to the skill frontmatter to make that behavior explicit and deterministic.

That way, activation is driven by file glob matches rather than relying only on whether the agent considers the skill relevant from the description.

Reference: https://code.claude.com/docs/en/skills#frontmatter-reference

Example:

---
name: ruby-conventions
description: Use when writing, reviewing, or editing Ruby files.
paths: "**/*.rb,**/*.rake,**/Gemfile,**/Rakefile,**/*.gemspec"
---

Comment thread CLAUDE.md
@@ -0,0 +1,107 @@
# CLAUDE.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful to include a starter .claude/settings.json with hooks for the workflow described in CLAUDE.md?

Right now, CLAUDE.md documents steps like loading the relevant skill, running checks, and using the reviewer agent, but those seem to rely on the agent following the instructions manually. A small hooks template could make the intended workflow easier to adopt consistently across projects.

Reference: https://code.claude.com/docs/en/hooks

For example:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bundle exec rubocop",
            "timeout": 30,
            "statusMessage": "Running RuboCop..."
          }
        ]
      }
    ]
  }
}

Even if we do not want to enforce hooks by default, documenting this as an optional per-project setup could help clarify how teams can make the conventions more deterministic.

description: "Use proactively after completing code changes, or when the user asks for a code review. Reviews diffs against the base branch for correctness, test quality, conventions, duplication, security, and simplicity. Returns structured findings."
model: sonnet
maxTurns: 10
tools: Read, Grep, Glob, Bash, WebFetch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would WebFetch be needed for the code-reviewer agent?

I noticed the agent declares:

tools: Read, Grep, Glob, Bash, WebFetch

but I could not find anything in the agent instructions that requires fetching external URLs. Since this agent seems focused on reviewing the local codebase, would it be safer to keep the tool list limited to only what it needs?

For example:

tools: Read, Grep, Glob, Bash

This would reduce the available surface area while still allowing the agent to read, search, inspect, and run local review commands. Feel free to ignore this if I’m missing a use case for WebFetch here.

Comment on lines +33 to +37
3. **If the current branch tracks an upstream**, infer from merge base:
```bash
git merge-base HEAD main 2>/dev/null
git merge-base HEAD main 2>/dev/null
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since git merge-base prints the merge-base SHA to stdout, running it without assigning the result does not affect the later git diff $BASE...HEAD call. As far as I can tell, $BASE still remains set to main.

If the intent is to handle cases where HEAD may not be directly comparable to main, we could capture the merge base instead:

BASE=$(git merge-base HEAD main 2>/dev/null || echo "main")

Otherwise, I think the duplicate commands can just be removed.

### 5. Create PR

```bash
gh pr create --title "[{TICKET-ID}] {Concise description}" --body "{BODY}" --base main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: create-pr.md currently hardcodes main as the PR base branch:

gh pr create --title "..." --body "..." --base main

Since this template may be used by teams with a different default branch, such as develop or master, it might be safer to resolve the repository default branch dynamically instead of assuming main.

For example:

BASE_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null || echo "main")

gh pr create --title "..." --body "..." --base "$BASE_BRANCH"

This would keep the command aligned with each repository’s actual default branch and avoid creating PRs against the wrong base by default.

@PerezIgnacio PerezIgnacio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

- Use **Faker** for fake data; **Database Cleaner** keeps state isolated.

## Mocking / Stubbing / Doubles
- Use mocks/stubs sparingly — favor them in isolated/behavioral specs, not integration specs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, I would also add something like:

  • Avoid allow_any_instance_of, as it stubs the method on every instance of the class, decoupled from which instance is actually used, and masks real interaction bugs. Prefer stubbing/mocking the specific instance. (and an example maybe)

- Align multi-line method args after `(`, OR single-indent with `)` on its own line (avoid "double indent").
- For `case`/`if` result assignment, either align branches under the keyword or break with `kind =` on its own line.

## Syntax

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of the items in these two sections seem to be already enforced by rubocop. should we trim the list a bit to what's not covered? mostly to reduce the context and avoid having two sources of truth (which could drift)

- Refactor bad code instead of explaining it.
- Avoid superfluous comments (`counter += 1 # Increments counter by one`).
- Keep comments up to date — an outdated comment is worse than none.
- Annotations: `TODO`, `FIXME`, `OPTIMIZE`, `HACK`, `REVIEW` + `:` + description, above the relevant code. Document custom annotation keywords in the project README.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want this? I'd probably just keep TODO. Additional tags can always be added later if they are useful or a convention in the project

- `Struct.new` for trivial value objects; don't inherit from it.
- Avoid class variables (`@@var`); prefer class instance variables.
- Proper visibility (`private`/`protected`); indent modifiers at method level with blank lines.
- Prefer duck-typing over inheritance.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe "Prefer composition over inheritance. Use duck typing where appropriate." instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants