From 99070032b0cd6365a11e17b177661043fae35d74 Mon Sep 17 00:00:00 2001 From: Marcos Sevilla <31174242+marcossevilla@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:20:34 +0100 Subject: [PATCH 1/5] "Claude PR Assistant workflow" --- .github/workflows/claude.yml | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/claude.yml diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 000000000..d300267f1 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr:*)' + From f4962796be6603fe7128d94baa84fd95e9e403fd Mon Sep 17 00:00:00 2001 From: Marcos Sevilla <31174242+marcossevilla@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:20:35 +0100 Subject: [PATCH 2/5] "Claude Code Review workflow" --- .github/workflows/claude-code-review.yml | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/claude-code-review.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 000000000..b5e8cfd4d --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,44 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' + plugins: 'code-review@claude-code-plugins' + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + From 96eed98fb0d0c6271441b77d579ee3116b807243 Mon Sep 17 00:00:00 2001 From: Marcos Sevilla Date: Tue, 17 Feb 2026 14:53:01 +0100 Subject: [PATCH 3/5] docs: create CLAUDE.md and update AGENTS.md --- .github/workflows/claude-code-review.yaml | 32 ++++++++ .github/workflows/claude-code-review.yml | 44 ---------- .github/workflows/{claude.yml => claude.yaml} | 19 ++--- AGENTS.md | 81 +++++++++++++++++-- CLAUDE.md | 1 + 5 files changed, 115 insertions(+), 62 deletions(-) create mode 100644 .github/workflows/claude-code-review.yaml delete mode 100644 .github/workflows/claude-code-review.yml rename .github/workflows/{claude.yml => claude.yaml} (70%) create mode 100644 CLAUDE.md diff --git a/.github/workflows/claude-code-review.yaml b/.github/workflows/claude-code-review.yaml new file mode 100644 index 000000000..49c028eee --- /dev/null +++ b/.github/workflows/claude-code-review.yaml @@ -0,0 +1,32 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + +jobs: + claude-review: + runs-on: ubuntu-latest + permissions: + issues: read + contents: read + id-token: write + pull-requests: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: "https://github.com/anthropics/claude-code.git" + plugins: "code-review@claude-code-plugins" + prompt: "/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}" + claude_args: | + --max-turns 5 + --model claude-opus-4-6 diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml deleted file mode 100644 index b5e8cfd4d..000000000 --- a/.github/workflows/claude-code-review.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Claude Code Review - -on: - pull_request: - types: [opened, synchronize, ready_for_review, reopened] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" - -jobs: - claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run Claude Code Review - id: claude-review - uses: anthropics/claude-code-action@v1 - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' - plugins: 'code-review@claude-code-plugins' - prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options - diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yaml similarity index 70% rename from .github/workflows/claude.yml rename to .github/workflows/claude.yaml index d300267f1..85f40ae30 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yaml @@ -19,11 +19,11 @@ jobs: (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) runs-on: ubuntu-latest permissions: - contents: read - pull-requests: read issues: read - id-token: write actions: read # Required for Claude to read CI results on PRs + contents: read + id-token: write + pull-requests: read steps: - name: Checkout repository uses: actions/checkout@v4 @@ -35,16 +35,9 @@ jobs: uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - + claude_args: | + --max-turns 5 + --model claude-opus-4-6 # This is an optional setting that allows Claude to read CI results on PRs additional_permissions: | actions: read - - # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. - # prompt: 'Update the pull request description to include a summary of changes.' - - # Optional: Add claude_args to customize behavior and configuration - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options - # claude_args: '--allowed-tools Bash(gh pr:*)' - diff --git a/AGENTS.md b/AGENTS.md index 521703af4..f27c140ba 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,11 +11,82 @@ Our criteria for good code also enables us to achieve 100% test coverage. Good code has... -- as few branches as possible -- injectable dependencies -- well-named identifiers -- no sibling dependencies in the same architectural layer +- As few branches as possible +- Injectable dependencies +- Well-named identifiers +- No sibling dependencies in the same architectural layer To avoid sibling dependencies, state must either be lifted up to a common ancestor and passed down, or pushed down and subscribed to. -See CONTRIBUTING.md for development details. +See @CONTRIBUTING.md for development details. + +## Project Overview + +Very Good CLI is a Dart command-line tool by Very Good Ventures for generating scalable project templates and running developer commands. It is published on pub.dev as `very_good_cli`. + +## Common Commands + +```bash +# Install dependencies +dart pub get && cd bricks/test_optimizer && dart pub get && cd ../../ + +# Run unit tests (excludes expensive pull-request-only and e2e tests) +flutter test -x pull-request-only -x e2e + +# Run a single test file +flutter test test/src/commands/create/create_test.dart + +# Format code +dart format lib test + +# Analyze code (strict: warnings and infos are fatal) +dart analyze --fatal-infos --fatal-warnings . + +# Auto-fix lint issues +dart fix --apply + +# Activate local dev version +dart pub global activate --source path . +``` + +## Architecture + +### Command Runner Pattern + +Entry point: `bin/very_good.dart` → `VeryGoodCommandRunner` (extends `CompletionCommandRunner`). + +All commands return `Future` (exit codes from `universal_io`'s `ExitCode`). Top-level commands: `create`, `test`, `packages`, `dart`, `update`, `mcp`. + +### Create Command System + +`CreateCommand` has subcommands for each template type (flutter_app, dart_package, dart_cli, docs_site, flame_game, flutter_package, flutter_plugin). + +All subcommands extend `CreateSubCommand` and use mixins for optional features: +- `OrgName` — adds `--org-name` flag +- `MultiTemplates` — supports `--template` flag with multiple template choices +- `Publishable` — adds `--publishable` flag + +Templates use Mason for code generation. Each template has a bundle, a `Template` class, and an `onGenerateComplete` hook. Template source code lives in separate repos under `VeryGoodOpenSource/very_good_templates`. + +### CLI Abstraction Layer (`lib/src/cli/`) + +- `DartCli`, `FlutterCli`, `GitCli` — wrappers around shell commands +- `ProcessOverrides` — zone-based dependency injection for mocking `Process.run` in tests +- `TestCliRunner` — test execution logic with coverage collection + +### Testing Patterns + +- **100% test coverage required** for all PRs +- Mocking with `mocktail` +- Constructor injection for dependencies (`Logger`, `PubUpdater`, generators) +- `@visibleForTesting` used for test-only overrides (e.g., `argResultOverrides`) +- Test tags in `dart_test.yaml`: `pull-request-only` for expensive CI-only tests +- E2E tests in `e2e/` create real projects and run full workflows +- Test optimizer brick in `bricks/test_optimizer/` generates optimized test entry points + +## Code Conventions + +- Linting: `very_good_analysis` (strict Dart analysis rules) +- Dartdoc templates: `/// {@template name}...{@endtemplate}` / `/// {@macro name}` +- Commits follow [Conventional Commits](https://www.conventionalcommits.org/) (used by release-please for automated versioning) +- `lib/src/version.dart` is auto-generated — do not edit manually diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..eef4bd20c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md \ No newline at end of file From b7d1e774b5fabef4273d5374aaf4fc7820e8dde5 Mon Sep 17 00:00:00 2001 From: Marcos Sevilla Date: Tue, 17 Feb 2026 14:55:16 +0100 Subject: [PATCH 4/5] chore(cspell): add missing words --- .github/cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/cspell.json b/.github/cspell.json index bd2fd776b..b04facb7c 100644 --- a/.github/cspell.json +++ b/.github/cspell.json @@ -31,6 +31,7 @@ "gradlew", "fluttium", "clsx", + "Dartdoc", "mockingjay" ] } From abbf8232eab4301c5e65bf5063fa466cb985d81c Mon Sep 17 00:00:00 2001 From: Marcos Sevilla Date: Tue, 17 Feb 2026 14:59:00 +0100 Subject: [PATCH 5/5] chore: nits --- .github/workflows/claude.yaml | 2 +- .../{claude-code-review.yaml => claude_code_review.yaml} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{claude-code-review.yaml => claude_code_review.yaml} (97%) diff --git a/.github/workflows/claude.yaml b/.github/workflows/claude.yaml index 85f40ae30..3b0b3cb47 100644 --- a/.github/workflows/claude.yaml +++ b/.github/workflows/claude.yaml @@ -1,4 +1,4 @@ -name: Claude Code +name: claude_code on: issue_comment: diff --git a/.github/workflows/claude-code-review.yaml b/.github/workflows/claude_code_review.yaml similarity index 97% rename from .github/workflows/claude-code-review.yaml rename to .github/workflows/claude_code_review.yaml index 49c028eee..26b267c1f 100644 --- a/.github/workflows/claude-code-review.yaml +++ b/.github/workflows/claude_code_review.yaml @@ -1,4 +1,4 @@ -name: Claude Code Review +name: claude_code_review on: pull_request: