From e507ba9d131d1679580ee7a0649fa15003959c68 Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 21 Nov 2023 15:17:16 +0000 Subject: [PATCH 1/8] style: formatting fix via vscode --- src/solrevdev.seedfolder.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solrevdev.seedfolder.csproj b/src/solrevdev.seedfolder.csproj index 71dd073..08767f4 100644 --- a/src/solrevdev.seedfolder.csproj +++ b/src/solrevdev.seedfolder.csproj @@ -25,7 +25,7 @@ - + From 85e139ce0b4b2225ea1466accb96ad6382e9aa2a Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 21 Nov 2023 15:19:27 +0000 Subject: [PATCH 2/8] feat: nuget package upgrade --- src/solrevdev.seedfolder.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solrevdev.seedfolder.csproj b/src/solrevdev.seedfolder.csproj index 08767f4..00d27e2 100644 --- a/src/solrevdev.seedfolder.csproj +++ b/src/solrevdev.seedfolder.csproj @@ -29,7 +29,7 @@ - + From 01f2a9398b280c9e745cfa8ea6202b8760e1a5ee Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 21 Nov 2023 15:20:01 +0000 Subject: [PATCH 3/8] feat: nuget version bump to 1.2.7 --- src/solrevdev.seedfolder.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solrevdev.seedfolder.csproj b/src/solrevdev.seedfolder.csproj index 00d27e2..02a764b 100644 --- a/src/solrevdev.seedfolder.csproj +++ b/src/solrevdev.seedfolder.csproj @@ -9,7 +9,7 @@ seedfolder ./nupkg true - 1.2.6 + 1.2.7 solrevdev.seedfolder .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. From 51491c524050fb80d1665acdda63269acd86d8a0 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 22 Mar 2024 12:23:01 +0000 Subject: [PATCH 4/8] docs: make .editorconfig same as one I use in project --- .editorconfig | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.editorconfig b/.editorconfig index c7f74e0..6da0e9d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ root = true insert_final_newline = true indent_style = space indent_size = 4 -guidelines = 120 +guidelines = 140 # C# files @@ -86,7 +86,7 @@ csharp_preserve_single_line_statements = false dotnet_separate_import_directive_groups = false # IDE0005: Remove unnessecary using statements -dotnet_diagnostic.IDE0005.severity = warning +dotnet_diagnostic.IDE0005.severity = error # Expression-level preferences dotnet_style_object_initializer = true:suggestion @@ -169,10 +169,16 @@ dotnet_naming_style.end_in_async.required_suffix = Async dotnet_naming_style.end_in_async.capitalization = pascal_case dotnet_naming_style.end_in_async.word_separator = -# ---- Latest csharp features ----- # +# IDE0290 Use primary constructor +# https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12#primary-constructors +# https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/primary-constructors +# will disable this rule for now until I decide if I like it and want to use it. +# dotnet_diagnostic.IDE0290.severity = none | error | suggestion + +# IDE0290 Use primary constructor +dotnet_diagnostic.IDE0290.severity = none -# guidelines support -guidelines = 120 +# ---- Latest csharp features ----- # # CA1031: Do not catch general exception types dotnet_diagnostic.CA1031.severity = none From 259c45284d67cb8ab6b1ff2f65d9fe2c5bfa8223 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Aug 2025 10:37:46 +0100 Subject: [PATCH 5/8] feat: upgrade to .NET 8 and .NET 9 support, drop .NET 6/7 - Update target frameworks to net8.0;net9.0 - Upgrade McMaster.Extensions.CommandLineUtils to 4.1.1 - Update GitHub Actions workflow for .NET 8/9 SDK support - Update documentation and requirements in README.md - Bump version to 1.3.0 BREAKING CHANGE: Removed support for .NET 6.0 and .NET 7.0. Minimum required version is now .NET 8.0. .NET 8 provides LTS support until November 2026, while .NET 9 offers latest features with 18-month STS support. The project now targets modern .NET versions: .NET 8 (LTS until November 2026) and .NET 9 (STS with 18-month support), positioning it well for future compatibility while leveraging the latest .NET features and performance improvements. --- .editorconfig | 2 +- .github/copilot-instructions.md | 74 +++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 6 ++- .vscode/settings.json | 1 + CLAUDE.md | 62 +++++++++++++++++++++++++++ README.md | 4 ++ src/solrevdev.seedfolder.csproj | 6 +-- 7 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 CLAUDE.md diff --git a/.editorconfig b/.editorconfig index 6da0e9d..c636a36 100644 --- a/.editorconfig +++ b/.editorconfig @@ -85,7 +85,7 @@ csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = false dotnet_separate_import_directive_groups = false -# IDE0005: Remove unnessecary using statements +# IDE0005: Remove unnecessary using statements dotnet_diagnostic.IDE0005.severity = error # Expression-level preferences diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..68dda83 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,74 @@ +# AI Coding Agent Instructions for SeedFolder + +## Project Overview +This is a .NET Global Tool that creates project directories and seeds them with standard dotfiles. The entire application is contained in a single file (`src/Program.cs`) for simplicity. + +## Architecture Patterns + +### Single-File Console Application +- All logic exists in `src/Program.cs` - no complex project structure +- Uses `McMaster.Extensions.CommandLineUtils` for CLI interactions, `Figgle` for ASCII headers, `Colorful.Console` for output formatting +- Command-line parsing is handled manually in `Main()` - check for help flags before processing folder names + +### Embedded Resources Pattern +Template files in `src/Data/` are embedded as resources, not file system copies: +```xml + + +``` +Access via `Assembly.GetManifestResourceStream("solrevdev.seedfolder.Data.{filename}")` in `WriteFileAsync()` + +### Multi-Framework Targeting +Targets `net8.0;net9.0` for modern .NET compatibility. .NET 8 is LTS (supported until November 2026) and .NET 9 is STS (18-month support). Version bumps in `.csproj` trigger NuGet deployment. + +## Key Development Workflows + +### Local Testing Cycle +```bash +# Build and test locally (use build/test-local.sh script) +dotnet pack -c release -o artifacts/nupkg +dotnet tool uninstall -g solrevdev.seedfolder +dotnet tool install -g --add-source artifacts/nupkg solrevdev.seedfolder +``` + +### Version Management +- Bump `` in `src/solrevdev.seedfolder.csproj` to trigger CI/CD +- CI only runs on pushes to `master` branch (exclude commits with `***NO_CI***`, `[ci skip]`, `[skip ci]`) +- GitHub Actions automatically publishes to NuGet on master pushes + +### Running During Development +```bash +# Interactive mode +dotnet run --project src/solrevdev.seedfolder.csproj + +# With folder name argument +dotnet run --project src/solrevdev.seedfolder.csproj myfolder +``` + +## Project-Specific Conventions + +### Input Sanitization +Always use `RemoveSpaces()` and `SafeNameForFileSystem()` for folder names: +```csharp +folderName = RemoveSpaces(folderName); // Spaces → dashes +folderName = SafeNameForFileSystem(folderName); // Invalid chars → dashes +``` + +### Date Prefixing Logic +Interactive mode offers date prefixing: `YYYY-MM-DD_foldername` format using `StringBuilder` for performance. + +### Error Handling Pattern +- Check if folder exists before creation - exit with colored error message +- Use `Directory.Exists()` check, then `ConsoleColor.DarkRed` for error output +- No exceptions for user errors - graceful CLI messaging + +## File Structure Details +- `src/Data/` contains template files without leading dots (e.g., `gitignore` not `.gitignore`) +- Files are copied with proper dotfile names during `WriteFileAsync()` +- `omnisharp.json` is copied without dot prefix (special case) + +## CI/CD Integration Points +- GitHub Actions workflow in `.github/workflows/ci.yml` handles build → pack → publish +- Requires `NUGET_API_KEY` secret for automated publishing +- Uses `rohith/publish-nuget@v2.1.1` action for NuGet deployment +- Build scripts in `build/` folder provide cross-platform local testing diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb2e357..6023235 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,9 +37,11 @@ jobs: uses: actions/checkout@v4 - name: setup .net core sdk - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '8.0.x' # SDK Version to use; x will use the latest version of the 3.1 channel + dotnet-version: | + 8.0.x + 9.0.x - name: dotnet build run: dotnet build solrevdev.seedfolder.sln --configuration Release diff --git a/.vscode/settings.json b/.vscode/settings.json index 94c98dc..65ba3a1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "Figgle", "gitattributes", "locproj", + "myfolder", "nativeproj", "NOLOGO", "Nuget", diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..772be31 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,62 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a .NET Core Global Tool called `seedfolder` that creates directories and populates them with standard dotfiles. The tool is designed to quickly scaffold project folders with common configuration files. + +## Development Commands + +### Build and Test +```bash +# Build the solution +dotnet build solrevdev.seedfolder.sln --configuration Release + +# Pack for local installation +dotnet pack + +# Install locally for testing +dotnet tool install --global --add-source ./nupkg solrevdev.seedfolder + +# Uninstall after testing +dotnet tool uninstall -g solrevdev.seedfolder +``` + +### Run the Tool During Development +```bash +# Run with interactive prompts +dotnet run --project src/solrevdev.seedfolder.csproj + +# Run with folder name argument +dotnet run --project src/solrevdev.seedfolder.csproj myfolder +``` + +## Architecture + +### Single File Structure +The entire application is contained in `src/Program.cs` - a single-file console application using: +- **McMaster.Extensions.CommandLineUtils** for command-line parsing and prompts +- **Figgle** for ASCII art header generation +- **Colorful.Console** for colored console output + +### Embedded Resources +Template files are stored as embedded resources in `src/Data/` and copied to new folders: +- `dockerignore` → `.dockerignore` +- `editorconfig` → `.editorconfig` +- `gitattributes` → `.gitattributes` +- `gitignore` → `.gitignore` +- `prettierignore` → `.prettierignore` +- `prettierrc` → `.prettierrc` +- `omnisharp.json` → `omnisharp.json` + +### Key Methods +- `WriteFileAsync()` - Extracts embedded resources and writes them to the target directory +- `RemoveSpaces()` - Sanitizes folder names by replacing spaces with dashes +- `SafeNameForFileSystem()` - Removes invalid filesystem characters from folder names + +## Multi-Target Framework Support +The project targets .NET 8.0 (LTS) and 9.0 (STS) to support current and modern .NET versions. .NET 8 provides long-term support until November 2026, while .NET 9 offers the latest features with 18-month support. + +## CI/CD +GitHub Actions workflow builds, packs, and publishes to NuGet on pushes to master branch. Version is controlled by the `` property in the .csproj file. \ No newline at end of file diff --git a/README.md b/README.md index 0eb0646..b7d29e7 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,10 @@ It will also copy the following dotfiles from the `src/Data` folder over: * .prettierignore * .prettierrc +## Requirements + +This tool requires .NET 8.0 or .NET 9.0 SDK to be installed on your system. + ## Installation Locally without publishing it on NuGet diff --git a/src/solrevdev.seedfolder.csproj b/src/solrevdev.seedfolder.csproj index 02a764b..db36c7b 100644 --- a/src/solrevdev.seedfolder.csproj +++ b/src/solrevdev.seedfolder.csproj @@ -2,14 +2,14 @@ Exe - net6.0;net7.0;net8.0 + net8.0;net9.0 latest enable true seedfolder ./nupkg true - 1.2.7 + 1.3.0 solrevdev.seedfolder .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. @@ -29,7 +29,7 @@ - + From 93bf4b52ad6b829616d8d683d3761ab20399bb9e Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Aug 2025 10:45:58 +0100 Subject: [PATCH 6/8] docs: update README.md examples with framework parameters - Add --framework net8.0 and net9.0 parameters to all dotnet run examples - Examples now work correctly with multi-targeting project - Demonstrate usage of both .NET 8 and .NET 9 frameworks - Ensure users can run examples without framework selection errors - Bump version to 1.3.1 to display updated README on NuGet.org The README is embedded in NuGet packages at build time, so version bump is required for changes to be visible on NuGet.org. The version has been bumped from 1.3.0 to 1.3.1 (patch/minor bump) so the updated README.md with corrected framework examples will be displayed when the package is published to NuGet. --- README.md | 6 +++--- src/solrevdev.seedfolder.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b7d29e7..1d8102c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ For example: ```bash seedfolder -dotnet run --project src/solrevdev.seedfolder.csproj +dotnet run --project src/solrevdev.seedfolder.csproj --framework net8.0 ▲ Do you want to prefix the folder with the date? [Y/n] y ▲ What do you want the folder to be named? temp ‍▲ Creating the directory 2020-12-10_temp @@ -35,7 +35,7 @@ dotnet run --project src/solrevdev.seedfolder.csproj ▲ Done! seedfolder -dotnet run --project src/solrevdev.seedfolder.csproj +dotnet run --project src/solrevdev.seedfolder.csproj --framework net9.0 ▲ Do you want to prefix the folder with the date? [Y/n] n ▲ What do you want the folder to be named? temp ‍▲ Creating the directory temp @@ -49,7 +49,7 @@ dotnet run --project src/solrevdev.seedfolder.csproj ▲ Done! seedfolder temp -dotnet run --project src/solrevdev.seedfolder.csproj temp +dotnet run --project src/solrevdev.seedfolder.csproj --framework net8.0 temp ▲ Found 1 params to process. ‍▲ Creating the directory temp ‍▲ Copying .dockerignore to temp/.dockerignore diff --git a/src/solrevdev.seedfolder.csproj b/src/solrevdev.seedfolder.csproj index db36c7b..a90d73d 100644 --- a/src/solrevdev.seedfolder.csproj +++ b/src/solrevdev.seedfolder.csproj @@ -9,7 +9,7 @@ seedfolder ./nupkg true - 1.3.0 + 1.3.1 solrevdev.seedfolder .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. .NET Core Global Tool that creates a folder and copies dotfiles into it therefore seeding a folder. From 9fe01807808e57c1bfbdaab5eeb77e5a8d2537d8 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Aug 2025 11:08:25 +0100 Subject: [PATCH 7/8] "Claude PR Assistant workflow" --- .github/workflows/claude.yml | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 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 0000000..bc77307 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,64 @@ +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@beta + 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: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1) + # model: "claude-opus-4-1-20250805" + + # Optional: Customize the trigger phrase (default: @claude) + # trigger_phrase: "/claude" + + # Optional: Trigger when specific user is assigned to an issue + # assignee_trigger: "claude-bot" + + # Optional: Allow Claude to run specific commands + # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)" + + # Optional: Add custom instructions for Claude to customize its behavior for your project + # custom_instructions: | + # Follow our coding standards + # Ensure all new code has tests + # Use TypeScript for new files + + # Optional: Custom environment variables for Claude + # claude_env: | + # NODE_ENV: test + From 0d4ff243b22e4ffbab20c867571aed0232b59aef Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Aug 2025 11:08:26 +0100 Subject: [PATCH 8/8] "Claude Code Review workflow" --- .github/workflows/claude-code-review.yml | 78 ++++++++++++++++++++++++ 1 file changed, 78 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 0000000..a12225a --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,78 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize] + # 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@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1) + # model: "claude-opus-4-1-20250805" + + # Direct prompt for automated review (no @claude mention needed) + direct_prompt: | + Please review this pull request and provide feedback on: + - Code quality and best practices + - Potential bugs or issues + - Performance considerations + - Security concerns + - Test coverage + + Be constructive and helpful in your feedback. + + # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR + # use_sticky_comment: true + + # Optional: Customize review based on file types + # direct_prompt: | + # Review this PR focusing on: + # - For TypeScript files: Type safety and proper interface usage + # - For API endpoints: Security, input validation, and error handling + # - For React components: Performance, accessibility, and best practices + # - For tests: Coverage, edge cases, and test quality + + # Optional: Different prompts for different authors + # direct_prompt: | + # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' && + # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' || + # 'Please provide a thorough code review focusing on our coding standards and best practices.' }} + + # Optional: Add specific tools for running tests or linting + # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)" + + # Optional: Skip review for certain conditions + # if: | + # !contains(github.event.pull_request.title, '[skip-review]') && + # !contains(github.event.pull_request.title, '[WIP]') +