[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6RVV1HNH62866HXQ0H2KSC6":3,"skill-same:01M6RVV1HNH62866HXQ0H2KSC6":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":13,"repositoryHtmlUrl":53,"repositoryHomepageUrl":6,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":55,"install":56,"resources":68},"01M6RVV1HNH62866HXQ0H2KSC6","perl-testing",null,"Perl testing patterns using Test2::V0, Test::More, prove runner, mocking, coverage with Devel::Cover, and TDD methodology.","sakamoto-family-smile\u002Fagent_monorepo","sakamoto-family-smile","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F132812403?v=4","01M6RTAT3H8PMWX5SJ65KP3VYF","01M6RTAV321WB5RAHCWTZMX5CV",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fperl-testing\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"perl","perl testing","testing","runner","prove","cover","more","with","mocking","test2","patterns","v0","coverage","testing patterns","methodology","test","tdd","2026-11-10 10:12:30",false,"---\nname: be-init\ndescription: Initialize Backend WebFlux Plugin configuration for the current project.\nargument-hint: \"\"\nuser-invocable: true\nallowed-tools: Read, Write, Glob, Bash\n---\n\n# Initialize Backend WebFlux Plugin\n\nSet up the Backend WebFlux Plugin configuration for this project.\n\n## Instructions\n\n### Step 1: Check Existing Configuration\n\n0. `pluginRoot`: the one line of `${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot` (plugin CLAUDE.md § Configuration) — every `templates\u002F…` path in this document is `{pluginRoot}\u002Ftemplates\u002F…`. Missing → do **not** stop: initialization needs no template (only Step 2 item 9's optional checkstyle offer does — skip that offer); record that it is missing for Step 7.\n1. Check if `.claude\u002Fbackend-webflux-plugin.json` already exists in the current project directory\n2. If it exists, read the current configuration and show it to the user:\n   > \"Backend WebFlux Plugin is already configured:\"\n   > ```json\n   > { current config contents }\n   > ```\n   > \"Do you want to reconfigure? This will overwrite the existing settings.\"\n3. If the user declines, stop here\n\n### Step 2: Auto-Detect Project Settings\n\nScan the project to detect settings automatically:\n\n1. **Build tool**: Look for `build.gradle.kts` (gradle-kotlin) or `build.gradle` (gradle-groovy). A `pom.xml` with neither → **stop, write no config**: every gate row in this plugin is a Gradle task (`classes`, `checkstyleMain`, `jacocoTestReport`, `--tests`), so a Maven project would be configured \"successfully\" and fail every gate — say so and stop.\n2. **Java version**: Parse whichever build file was detected in item 1:\n   - `build.gradle.kts` (gradle-kotlin): `java.toolchain.languageVersion` or `sourceCompatibility`\n   - `build.gradle` (gradle-groovy): same keys, Groovy syntax (`sourceCompatibility = '21'` or `languageVersion = JavaLanguageVersion.of(21)`)\n   - If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.\n3. **Spring Boot version**: Parse whichever build file was detected in item 1:\n   - `build.gradle.kts` \u002F `build.gradle`: the `org.springframework.boot` entry in the plugins block\n   - If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.\n4. **Base package**: Find the first directory level under `src\u002Fmain\u002Fjava\u002F` that contains `.java` files\n5. **Data profile**: Check dependencies for `spring-boot-starter-data-r2dbc` (→ `r2dbc` present) and `mybatis-spring-boot-starter` (→ `mybatis` present; on Boot 4 it must be the `4.x` line — a `3.0.x` starter is a Boot 3 artifact, so warn in Step 3 when the versions disagree). Both present → `\"both\"`. Only one present → that profile. Neither present → default `\"both\"` (plugin default, see `docs\u002Fdecisions.md` Decision 1)\n6. **Web layer**: Check for `RouterFunction` bean definitions vs `@RestController` usage in existing source.\n   - Project is empty (no source found yet) → default `\"functional\"`, no warning needed.\n   - One style clearly dominates → that style wins, no warning needed.\n   - Both styles are present in meaningful numbers (mixed evenly) → do not silently default. Flag it in Step 3 as a warning: the existing source shows both `RouterFunction` and `@RestController` usage, and per this plugin's architecture rule a domain must never mix both styles (see `CLAUDE.md` § Web Layer) — ask the user which style to standardize on for new code rather than picking `\"functional\"` for them.\n7. **Database**: Check dependencies for `mysql-connector-j` \u002F `io.asyncer:r2dbc-mysql` (mysql, default) or `h2` (the sample's stand-in). An `io.asyncer:r2dbc-mysql` below `1.4.2` is a Boot-3 line — warn in Step 3 (the same way item 5 warns on a 3.0.x MyBatis starter); `be-crud` Step 3 stops on it. Any other vendor's driver (PostgreSQL, MariaDB, …) → **stop, write no config**: `be-crud` emits MySQL DDL and requires the MySQL drivers, so the project would be configured and then given SQL its database rejects\n8. **Migration**: Check for a `src\u002Fmain\u002Fresources\u002Fmigration\u002F` directory (manual-sql, default) or a migration-runner dependency (only if the project has explicitly opted into one). A runner changes nothing about generation — `be-crud` always writes plain SQL under `src\u002Fmain\u002Fresources\u002Fmigration\u002F` and never registers it — so warn in Step 3: a Flyway project points its runner there (`spring.flyway.locations=classpath:migration`), a Liquibase project includes each file in its changelog itself\n9. **Checkstyle**: `true` when the `checkstyle` plugin is applied in the build file. If it is applied but `config\u002Fcheckstyle\u002Fcheckstyle.xml` is missing, offer to write the file from `templates\u002Fcheckstyle-config.md` (that is the only place it is scaffolded; without it `checkstyleMain` fails on a missing config). A project that has its own file keeps it — the reviewer judges by the project's file\n10. **Coverage**: `true` only when the `jacoco` plugin is applied in the build file. Nothing in this plugin adds it, and with `coverage: true` on a project without it `be-verify`'s Coverage row fails (`jacocoTestReport` not found) and so does `Overall` — on every run. Absent → `false`, and tell the user in Step 3 how to enable it: the Gradle block in `templates\u002Fcoverage-gate.md`, then re-run `be-init`\n11. **Lombok**: Check if `lombok` is in dependencies\n12. **Gradle command**: `.\u002Fgradlew` when the wrapper exists, else `gradle` — the invocation every task-level gate row (`classes`, `checkstyleMain`, `jacocoTestReport`, `--tests`) is built on. **No build file at all** (fresh repository): `.\u002Fgradlew` — Spring Initializr ships the wrapper, and a `gradle` baked in now would run the system Gradle (absent, or a different version) against the project created next. Appending a task to the *build* command would run the full `build` every time and misattribute one failure to every row\n13. **Build command**: `{gradleCommand} build`\n14. **Test command**: `{gradleCommand} test`\n\n### Step 3: Confirm with User\n\nPresent detected values and ask the user to confirm or override:\n\n> \"Detected project settings:\"\n> ```\n> Java Version:      {detected or \"21\"}\n> Spring Boot:       {detected or \"unknown\"}\n> Build Tool:        {detected}\n> Base Package:      {detected or \"com.example\"}\n> Data Profile:      {detected or \"both\"}   (r2dbc | mybatis | both — see docs\u002Fdecisions.md)\n> Web Layer:         {detected or \"functional\"}   (functional | annotated)\n> Database:          {detected or \"mysql\"}\n> Migration:         {detected or \"manual-sql\"}\n> Checkstyle:        {detected or false}\n> Coverage:          {detected or false}   (report-only JaCoco gate — see docs\u002Fdecisions.md Decision 6)\n> Lombok:            {detected or false}\n> Architecture:      cqrs (default)\n> Work Doc Dir:      work\u002Ffeatures (default)\n> Working Language:  en (default)\n> ```\n> \"Would you like to change any of these values?\"\n\nIf the user wants changes, ask for specific values. Accept the following for architecture: `cqrs` (default).\n\nFor working language, accept: `en` (English), `ko` (Korean), `vi` (Vietnamese).\n\n#### Worked example — clean detection\n\nA project with `build.gradle.kts`, `spring-boot-starter-data-r2dbc` only, no\n`@RestController` usage, and `io.asyncer:r2dbc-mysql` in dependencies produces:\n\n> \"Detected project settings:\"\n> ```\n> Java Version:      21\n> Spring Boot:       4.0.2\n> Build Tool:        gradle-kotlin\n> Base Package:      com.example.demo\n> Data Profile:      r2dbc   (r2dbc | mybatis | both — see docs\u002Fdecisions.md)\n> Web Layer:         functional   (functional | annotated)\n> Database:          mysql\n> Migration:         manual-sql\n> Checkstyle:        true\n> Coverage:          true   (report-only JaCoco gate — see docs\u002Fdecisions.md Decision 6)\n> Lombok:            true\n> Architecture:      cqrs (default)\n> Work Doc Dir:      work\u002Ffeatures (default)\n> Working Language:  en (default)\n> ```\n> \"Would you like to change any of these values?\"\n\nThe user replies \"looks good\" → proceed to Step 4 with these values as-is.\n\n#### Worked example — edge cases\n\n**No build file present** (fresh\u002Fempty repository): every build-file-derived field\n(`javaVersion`, `springBootVersion`, `buildTool`, `buildCommand`, `testCommand`) has\nno detected value. Present the plugin defaults explicitly instead of leaving fields\nblank, and say so:\n\n> \"No `build.gradle.kts` or `build.gradle` found — this looks like a new project. Using\n> plugin defaults below; correct any that don't match your plan. Note: `be-crud` scaffolds\n> **into** an existing Spring Boot WebFlux project — it writes sources and a migration, not\n> a build file, wrapper or application class. Create the project first (Spring Initializr:\n> WebFlux + the starters for your data profile — `spring-boot-starter-data-r2dbc` +\n> `io.asyncer:r2dbc-mysql:1.4.3`, and\u002For `mybatis-spring-boot-starter:4.x` + `mysql-connector-j` —\n> plus `com.github.f4b6a3:uuid-creator`, and the test starters the generated tests compile against:\n> `spring-boot-starter-test`, `spring-boot-starter-webflux-test`, `reactor-test`, and\n> `spring-boot-starter-data-r2dbc-test` \u002F `mybatis-spring-boot-starter-test`), then run `be-crud`:\"\n> ```\n> Java Version:      21 (default, undetected)\n> Spring Boot:       4.0.2 (default, undetected)\n> Build Tool:        gradle-kotlin (default, undetected)\n> Gradle Command:    .\u002Fgradlew (Initializr ships the wrapper)\n> ...\n> ```\n\n**Mixed web-layer usage** (per Step 2 item 6): do not silently pick `\"functional\"`.\nSurface the conflict before presenting the confirmation table:\n\n> \"Note: existing source under `src\u002Fmain\u002Fjava\u002F` shows both `RouterFunction` beans\n> and `@RestController` classes in roughly equal numbers. This plugin's rule is\n> that a domain must never mix both styles (see `CLAUDE.md` § Web Layer). Which\n> style should new code use — `functional` or `annotated`?\"\n\nOnly after the user answers does `webLayer` get a value in the confirmation table;\ndo not default it in this case.\n\n### Step 4: Write Configuration\n\nWrite `.claude\u002Fbackend-webflux-plugin.json`:\n\n```json\n{\n  \"javaVersion\": \"{value}\",\n  \"springBootVersion\": \"{value}\",\n  \"buildTool\": \"{value}\",\n  \"gradleCommand\": \"{value}\",\n  \"buildCommand\": \"{value}\",\n  \"testCommand\": \"{value}\",\n  \"basePackage\": \"{value}\",\n  \"sourceDir\": \"src\u002Fmain\u002Fjava\",\n  \"testDir\": \"src\u002Ftest\u002Fjava\",\n  \"architecture\": \"{value}\",\n  \"dataProfile\": \"{value}\",\n  \"webLayer\": \"{value}\",\n  \"database\": \"{value}\",\n  \"migration\": \"{value}\",\n  \"checkstyle\": {value},\n  \"coverage\": {value},\n  \"lombokEnabled\": {value},\n  \"workDocDir\": \"{value}\",\n  \"workingLanguage\": \"{value}\"\n}\n```\n\n(No `pluginRoot` key: the plugin's install directory is read by the gate skills from\n`${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot`, which the\nSessionStart hook rewrites at every session start — a copy here would go stale on upgrade. If that\nfile is missing now, say so in Step 7.)\n\nAfter the Write tool call returns, read `.claude\u002Fbackend-webflux-plugin.json` back and\nconfirm its contents match what was just written. This is the evidence Step 7's\nsuccess message relies on — do not skip it. If the write failed or the read-back\ndoesn't match, stop and report the error instead of proceeding to Step 5.\n\n### Step 5: Set Up Work Document Directory\n\n1. If `{workDocDir}` does not exist, create it\n\n### Step 6: Add Gradle Permission\n\nCheck `.claude\u002Fsettings.json` for Bash permissions. If `{gradleCommand} *` is not in the allow list, inform the user (`.\u002Fgradlew *` for a wrapper project, `gradle *` when `gradleCommand` is `gradle` — an entry for the wrong one covers none of the gate commands):\n\n> \"To enable Gradle commands, add this to your `.claude\u002Fsettings.json` permissions.allow:\"\n> ```\n> \"Bash({gradleCommand} *)\"\n> ```\n\n### Step 7: Confirmation\n\nOnly reached if the Step 4 read-back succeeded. Display final configuration summary:\n\n> \"Backend WebFlux Plugin initialized successfully.\"\n> \"Configuration saved to `.claude\u002Fbackend-webflux-plugin.json`.\"\n> \"Data profile: {dataProfile}. Web layer: {webLayer}. See `docs\u002Fdecisions.md` if you want the rationale behind these defaults before changing them.\"\n> {When `${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot` is missing: \"The SessionStart hook has not recorded the plugin's install path — start a new session once before `be-verify`\u002F`be-review`\u002F`be-commit`.\"}\n>\n> \"Available skills:\"\n>\n> Core pipeline:\n> - `\u002Fbackend-webflux-plugin:be-plan` — Spec → backend plan.json\n> - `\u002Fbackend-webflux-plugin:be-crud` — CQRS CRUD scaffold\n> - `\u002Fbackend-webflux-plugin:be-code` — TDD feature implementation\n> - `\u002Fbackend-webflux-plugin:be-verify` — Verification gate (build + checkstyle + tests + coverage)\n> - `\u002Fbackend-webflux-plugin:be-review` — Multi-dimension code review\n> - `\u002Fbackend-webflux-plugin:be-fix` — TDD-disciplined review fix\n> - `\u002Fbackend-webflux-plugin:be-commit` — Smart commit\n>\n> Utility:\n> - `\u002Fbackend-webflux-plugin:be-build` — Build + auto-fix\n> - `\u002Fbackend-webflux-plugin:be-debug` — Systematic debugging\n> - `\u002Fbackend-webflux-plugin:be-recall` — Rules reference\n> - `\u002Fbackend-webflux-plugin:be-progress` — Progress dashboard\n>\n> Standalone audits:\n> - `\u002Fbackend-webflux-plugin:be-data` — R2DBC \u002F MyBatis data-layer audit\n> - `\u002Fbackend-webflux-plugin:be-api-review` — API contract audit\n> - `\u002Fbackend-webflux-plugin:be-clean-code` — Clean code audit\n> - `\u002Fbackend-webflux-plugin:be-logging` — Logging audit\n> - `\u002Fbackend-webflux-plugin:be-test-review` — Test quality audit\n> - `\u002Fbackend-webflux-plugin:be-security` — Security audit\n> - `\u002Fbackend-webflux-plugin:be-integrate-review` — Vendor\u002Foutbound-integration audit\n","# Initialize Backend WebFlux Plugin\n\nSet up the Backend WebFlux Plugin configuration for this project.\n\n## Instructions\n\n### Step 1: Check Existing Configuration\n\n0. `pluginRoot`: the one line of `${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot` (plugin CLAUDE.md § Configuration) — every `templates\u002F…` path in this document is `{pluginRoot}\u002Ftemplates\u002F…`. Missing → do **not** stop: initialization needs no template (only Step 2 item 9's optional checkstyle offer does — skip that offer); record that it is missing for Step 7.\n1. Check if `.claude\u002Fbackend-webflux-plugin.json` already exists in the current project directory\n2. If it exists, read the current configuration and show it to the user:\n   > \"Backend WebFlux Plugin is already configured:\"\n   > ```json\n   > { current config contents }\n   > ```\n   > \"Do you want to reconfigure? This will overwrite the existing settings.\"\n3. If the user declines, stop here\n\n### Step 2: Auto-Detect Project Settings\n\nScan the project to detect settings automatically:\n\n1. **Build tool**: Look for `build.gradle.kts` (gradle-kotlin) or `build.gradle` (gradle-groovy). A `pom.xml` with neither → **stop, write no config**: every gate row in this plugin is a Gradle task (`classes`, `checkstyleMain`, `jacocoTestReport`, `--tests`), so a Maven project would be configured \"successfully\" and fail every gate — say so and stop.\n2. **Java version**: Parse whichever build file was detected in item 1:\n   - `build.gradle.kts` (gradle-kotlin): `java.toolchain.languageVersion` or `sourceCompatibility`\n   - `build.gradle` (gradle-groovy): same keys, Groovy syntax (`sourceCompatibility = '21'` or `languageVersion = JavaLanguageVersion.of(21)`)\n   - If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.\n3. **Spring Boot version**: Parse whichever build file was detected in item 1:\n   - `build.gradle.kts` \u002F `build.gradle`: the `org.springframework.boot` entry in the plugins block\n   - If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.\n4. **Base package**: Find the first directory level under `src\u002Fmain\u002Fjava\u002F` that contains `.java` files\n5. **Data profile**: Check dependencies for `spring-boot-starter-data-r2dbc` (→ `r2dbc` present) and `mybatis-spring-boot-starter` (→ `mybatis` present; on Boot 4 it must be the `4.x` line — a `3.0.x` starter is a Boot 3 artifact, so warn in Step 3 when the versions disagree). Both present → `\"both\"`. Only one present → that profile. Neither present → default `\"both\"` (plugin default, see `docs\u002Fdecisions.md` Decision 1)\n6. **Web layer**: Check for `RouterFunction` bean definitions vs `@RestController` usage in existing source.\n   - Project is empty (no source found yet) → default `\"functional\"`, no warning needed.\n   - One style clearly dominates → that style wins, no warning needed.\n   - Both styles are present in meaningful numbers (mixed evenly) → do not silently default. Flag it in Step 3 as a warning: the existing source shows both `RouterFunction` and `@RestController` usage, and per this plugin's architecture rule a domain must never mix both styles (see `CLAUDE.md` § Web Layer) — ask the user which style to standardize on for new code rather than picking `\"functional\"` for them.\n7. **Database**: Check dependencies for `mysql-connector-j` \u002F `io.asyncer:r2dbc-mysql` (mysql, default) or `h2` (the sample's stand-in). An `io.asyncer:r2dbc-mysql` below `1.4.2` is a Boot-3 line — warn in Step 3 (the same way item 5 warns on a 3.0.x MyBatis starter); `be-crud` Step 3 stops on it. Any other vendor's driver (PostgreSQL, MariaDB, …) → **stop, write no config**: `be-crud` emits MySQL DDL and requires the MySQL drivers, so the project would be configured and then given SQL its database rejects\n8. **Migration**: Check for a `src\u002Fmain\u002Fresources\u002Fmigration\u002F` directory (manual-sql, default) or a migration-runner dependency (only if the project has explicitly opted into one). A runner changes nothing about generation — `be-crud` always writes plain SQL under `src\u002Fmain\u002Fresources\u002Fmigration\u002F` and never registers it — so warn in Step 3: a Flyway project points its runner there (`spring.flyway.locations=classpath:migration`), a Liquibase project includes each file in its changelog itself\n9. **Checkstyle**: `true` when the `checkstyle` plugin is applied in the build file. If it is applied but `config\u002Fcheckstyle\u002Fcheckstyle.xml` is missing, offer to write the file from `templates\u002Fcheckstyle-config.md` (that is the only place it is scaffolded; without it `checkstyleMain` fails on a missing config). A project that has its own file keeps it — the reviewer judges by the project's file\n10. **Coverage**: `true` only when the `jacoco` plugin is applied in the build file. Nothing in this plugin adds it, and with `coverage: true` on a project without it `be-verify`'s Coverage row fails (`jacocoTestReport` not found) and so does `Overall` — on every run. Absent → `false`, and tell the user in Step 3 how to enable it: the Gradle block in `templates\u002Fcoverage-gate.md`, then re-run `be-init`\n11. **Lombok**: Check if `lombok` is in dependencies\n12. **Gradle command**: `.\u002Fgradlew` when the wrapper exists, else `gradle` — the invocation every task-level gate row (`classes`, `checkstyleMain`, `jacocoTestReport`, `--tests`) is built on. **No build file at all** (fresh repository): `.\u002Fgradlew` — Spring Initializr ships the wrapper, and a `gradle` baked in now would run the system Gradle (absent, or a different version) against the project created next. Appending a task to the *build* command would run the full `build` every time and misattribute one failure to every row\n13. **Build command**: `{gradleCommand} build`\n14. **Test command**: `{gradleCommand} test`\n\n### Step 3: Confirm with User\n\nPresent detected values and ask the user to confirm or override:\n\n> \"Detected project settings:\"\n> ```\n> Java Version:      {detected or \"21\"}\n> Spring Boot:       {detected or \"unknown\"}\n> Build Tool:        {detected}\n> Base Package:      {detected or \"com.example\"}\n> Data Profile:      {detected or \"both\"}   (r2dbc | mybatis | both — see docs\u002Fdecisions.md)\n> Web Layer:         {detected or \"functional\"}   (functional | annotated)\n> Database:          {detected or \"mysql\"}\n> Migration:         {detected or \"manual-sql\"}\n> Checkstyle:        {detected or false}\n> Coverage:          {detected or false}   (report-only JaCoco gate — see docs\u002Fdecisions.md Decision 6)\n> Lombok:            {detected or false}\n> Architecture:      cqrs (default)\n> Work Doc Dir:      work\u002Ffeatures (default)\n> Working Language:  en (default)\n> ```\n> \"Would you like to change any of these values?\"\n\nIf the user wants changes, ask for specific values. Accept the following for architecture: `cqrs` (default).\n\nFor working language, accept: `en` (English), `ko` (Korean), `vi` (Vietnamese).\n\n#### Worked example — clean detection\n\nA project with `build.gradle.kts`, `spring-boot-starter-data-r2dbc` only, no\n`@RestController` usage, and `io.asyncer:r2dbc-mysql` in dependencies produces:\n\n> \"Detected project settings:\"\n> ```\n> Java Version:      21\n> Spring Boot:       4.0.2\n> Build Tool:        gradle-kotlin\n> Base Package:      com.example.demo\n> Data Profile:      r2dbc   (r2dbc | mybatis | both — see docs\u002Fdecisions.md)\n> Web Layer:         functional   (functional | annotated)\n> Database:          mysql\n> Migration:         manual-sql\n> Checkstyle:        true\n> Coverage:          true   (report-only JaCoco gate — see docs\u002Fdecisions.md Decision 6)\n> Lombok:            true\n> Architecture:      cqrs (default)\n> Work Doc Dir:      work\u002Ffeatures (default)\n> Working Language:  en (default)\n> ```\n> \"Would you like to change any of these values?\"\n\nThe user replies \"looks good\" → proceed to Step 4 with these values as-is.\n\n#### Worked example — edge cases\n\n**No build file present** (fresh\u002Fempty repository): every build-file-derived field\n(`javaVersion`, `springBootVersion`, `buildTool`, `buildCommand`, `testCommand`) has\nno detected value. Present the plugin defaults explicitly instead of leaving fields\nblank, and say so:\n\n> \"No `build.gradle.kts` or `build.gradle` found — this looks like a new project. Using\n> plugin defaults below; correct any that don't match your plan. Note: `be-crud` scaffolds\n> **into** an existing Spring Boot WebFlux project — it writes sources and a migration, not\n> a build file, wrapper or application class. Create the project first (Spring Initializr:\n> WebFlux + the starters for your data profile — `spring-boot-starter-data-r2dbc` +\n> `io.asyncer:r2dbc-mysql:1.4.3`, and\u002For `mybatis-spring-boot-starter:4.x` + `mysql-connector-j` —\n> plus `com.github.f4b6a3:uuid-creator`, and the test starters the generated tests compile against:\n> `spring-boot-starter-test`, `spring-boot-starter-webflux-test`, `reactor-test`, and\n> `spring-boot-starter-data-r2dbc-test` \u002F `mybatis-spring-boot-starter-test`), then run `be-crud`:\"\n> ```\n> Java Version:      21 (default, undetected)\n> Spring Boot:       4.0.2 (default, undetected)\n> Build Tool:        gradle-kotlin (default, undetected)\n> Gradle Command:    .\u002Fgradlew (Initializr ships the wrapper)\n> ...\n> ```\n\n**Mixed web-layer usage** (per Step 2 item 6): do not silently pick `\"functional\"`.\nSurface the conflict before presenting the confirmation table:\n\n> \"Note: existing source under `src\u002Fmain\u002Fjava\u002F` shows both `RouterFunction` beans\n> and `@RestController` classes in roughly equal numbers. This plugin's rule is\n> that a domain must never mix both styles (see `CLAUDE.md` § Web Layer). Which\n> style should new code use — `functional` or `annotated`?\"\n\nOnly after the user answers does `webLayer` get a value in the confirmation table;\ndo not default it in this case.\n\n### Step 4: Write Configuration\n\nWrite `.claude\u002Fbackend-webflux-plugin.json`:\n\n```json\n{\n  \"javaVersion\": \"{value}\",\n  \"springBootVersion\": \"{value}\",\n  \"buildTool\": \"{value}\",\n  \"gradleCommand\": \"{value}\",\n  \"buildCommand\": \"{value}\",\n  \"testCommand\": \"{value}\",\n  \"basePackage\": \"{value}\",\n  \"sourceDir\": \"src\u002Fmain\u002Fjava\",\n  \"testDir\": \"src\u002Ftest\u002Fjava\",\n  \"architecture\": \"{value}\",\n  \"dataProfile\": \"{value}\",\n  \"webLayer\": \"{value}\",\n  \"database\": \"{value}\",\n  \"migration\": \"{value}\",\n  \"checkstyle\": {value},\n  \"coverage\": {value},\n  \"lombokEnabled\": {value},\n  \"workDocDir\": \"{value}\",\n  \"workingLanguage\": \"{value}\"\n}\n```\n\n(No `pluginRoot` key: the plugin's install directory is read by the gate skills from\n`${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot`, which the\nSessionStart hook rewrites at every session start — a copy here would go stale on upgrade. If that\nfile is missing now, say so in Step 7.)\n\nAfter the Write tool call returns, read `.claude\u002Fbackend-webflux-plugin.json` back and\nconfirm its contents match what was just written. This is the evidence Step 7's\nsuccess message relies on — do not skip it. If the write failed or the read-back\ndoesn't match, stop and report the error instead of proceeding to Step 5.\n\n### Step 5: Set Up Work Document Directory\n\n1. If `{workDocDir}` does not exist, create it\n\n### Step 6: Add Gradle Permission\n\nCheck `.claude\u002Fsettings.json` for Bash permissions. If `{gradleCommand} *` is not in the allow list, inform the user (`.\u002Fgradlew *` for a wrapper project, `gradle *` when `gradleCommand` is `gradle` — an entry for the wrong one covers none of the gate commands):\n\n> \"To enable Gradle commands, add this to your `.claude\u002Fsettings.json` permissions.allow:\"\n> ```\n> \"Bash({gradleCommand} *)\"\n> ```\n\n### Step 7: Confirmation\n\nOnly reached if the Step 4 read-back succeeded. Display final configuration summary:\n\n> \"Backend WebFlux Plugin initialized successfully.\"\n> \"Configuration saved to `.claude\u002Fbackend-webflux-plugin.json`.\"\n> \"Data profile: {dataProfile}. Web layer: {webLayer}. See `docs\u002Fdecisions.md` if you want the rationale behind these defaults before changing them.\"\n> {When `${CLAUDE_CONFIG_DIR:-$HOME\u002F.claude}\u002Fplugins\u002Fdata\u002Fbackend-webflux-plugin\u002FpluginRoot` is missing: \"The SessionStart hook has not recorded the plugin's install path — start a new session once before `be-verify`\u002F`be-review`\u002F`be-commit`.\"}\n>\n> \"Available skills:\"\n>\n> Core pipeline:\n> - `\u002Fbackend-webflux-plugin:be-plan` — Spec → backend plan.json\n> - `\u002Fbackend-webflux-plugin:be-crud` — CQRS CRUD scaffold\n> - `\u002Fbackend-webflux-plugin:be-code` — TDD feature implementation\n> - `\u002Fbackend-webflux-plugin:be-verify` — Verification gate (build + checkstyle + tests + coverage)\n> - `\u002Fbackend-webflux-plugin:be-review` — Multi-dimension code review\n> - `\u002Fbackend-webflux-plugin:be-fix` — TDD-disciplined review fix\n> - `\u002Fbackend-webflux-plugin:be-commit` — Smart commit\n>\n> Utility:\n> - `\u002Fbackend-webflux-plugin:be-build` — Build + auto-fix\n> - `\u002Fbackend-webflux-plugin:be-debug` — Systematic debugging\n> - `\u002Fbackend-webflux-plugin:be-recall` — Rules reference\n> - `\u002Fbackend-webflux-plugin:be-progress` — Progress dashboard\n>\n> Standalone audits:\n> - `\u002Fbackend-webflux-plugin:be-data` — R2DBC \u002F MyBatis data-layer audit\n> - `\u002Fbackend-webflux-plugin:be-api-review` — API contract audit\n> - `\u002Fbackend-webflux-plugin:be-clean-code` — Clean code audit\n> - `\u002Fbackend-webflux-plugin:be-logging` — Logging audit\n> - `\u002Fbackend-webflux-plugin:be-test-review` — Test quality audit\n> - `\u002Fbackend-webflux-plugin:be-security` — Security audit\n> - `\u002Fbackend-webflux-plugin:be-integrate-review` — Vendor\u002Foutbound-integration audit\n",{"name":45,"description":46,"allowed-tools":47,"argument-hint":48,"user-invocable":49},"be-init","Initialize Backend WebFlux Plugin configuration for the current project.","Read, Write, Glob, Bash","",true,"main","99f07e592261c66756a2927d0440fc5fef950507",".claude\u002Fskills\u002Fecc\u002Fperl-testing","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile","2026-11-08 20:29:14",{"source":8,"skillName":45,"commands":57,"prompt":67,"zipAvailable":49},[58,61,64],{"tool":59,"command":60},"npx","npx skills add sakamoto-family-smile\u002Fagent_monorepo --skill be-init",{"tool":62,"command":63},"bunx","bunx skills add sakamoto-family-smile\u002Fagent_monorepo --skill be-init",{"tool":65,"command":66},"pnpm","pnpm dlx skills add sakamoto-family-smile\u002Fagent_monorepo --skill be-init","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fperl-testing\u002FSKILL.md",[],[70,102,110,130,153,180],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":82,"publishedAt":40},"01M6RW50THEFSKK42YNR8XFZA1","remotion-video-creation","Best practices for Remotion - Video creation in React. 29 domain-specific rules covering 3D, animations, audio, captions, charts, transitions, and more.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fremotion-video-creation\u002FSKILL.md",[76,79],{"categoryNo":77,"categoryName":78,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":80,"categoryName":81,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体",[83,84,85,86,87,88,89,90,91,92,93,94,29,95,96,97,98,99,100,101],"Video","remotion video","remotion video creation","creation","Remotion","Charts","Captions","Audio","3D","Composition","Animation","best practices","animations","domain-specific","domain","three","Rules","Lottie","for",{"skillNo":103,"name":104,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":107,"publishedAt":40},"01M6VCJ23NPECPSZJKGY691F75","hotcook-recipes","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fhotcook-agent\u002Fdata\u002Fskills\u002Fhotcook-recipes\u002FSKILL.md",[],[108,109],"hotcook recipes","recipes",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":124,"publishedAt":40},"01M6VCHHE00X5XHSDRD1KH1BW2","code-helper","Code review and assistance skill","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fagent-system-2\u002Fskills\u002Fcode-helper\u002Fskill.md",[116,119],{"categoryNo":117,"categoryName":118,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":120,"categoryName":121,"taxonomyType":122,"taxonomyTypeDesc":123},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[125,126,127,128,129],"code helper","helper","code","code review","review",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":142,"publishedAt":40},"01M6VCH3Q31A20H6SQ1H0J7JB2","research-assistant","Web research assistant skill using Brave Search MCP","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fagent-system-1\u002Fskills\u002Fresearch-assistant\u002Fskill.md",[136,139],{"categoryNo":137,"categoryName":138,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":140,"categoryName":141,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[143,144,145,146,147,148,149,150,151,152],"research assistant","research","assistant","MCP","web","search","brave search","web research","brave","web research assistant",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":163,"publishedAt":40},"01M6VCGZZGPNVJSCZ1JTMNZAHY","x-api","X\u002FTwitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fx-api\u002FSKILL.md",[159,162],{"categoryNo":160,"categoryName":161,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":120,"categoryName":121,"taxonomyType":122,"taxonomyTypeDesc":123},[164,165,30,166,167,168,101,169,170,171,172,173,33,174,175,176,177,178,148,179],"x api","api","when","limits","rate","threads","reading","native","posting","platform","api integration","twitter","use","auth","analytics","OAuth",{"skillNo":181,"name":182,"nameZh":6,"description":183,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":184,"categories":185,"keywords":187,"publishedAt":40},"01M6VCGVX6DGB1FKTA53QBBCQB","workspace-surface-audit","Audit the active repo, MCP servers, plugins, connectors, env surfaces, and harness setup, then recommend the highest-value ECC-native skills, hooks, agents, and operator workflows. Use when the user wants help setting up Claude Code or understanding what capabilities are actually available in their environment.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fworkspace-surface-audit\u002FSKILL.md",[186],{"categoryNo":140,"categoryName":141,"taxonomyType":20,"taxonomyTypeDesc":21},[188,189,190,191,146,192,193,127,194,195,196,197,176,198,199,200,201,171,202,166],"workspace surface audit","workspace","audit","hooks","workflows","connectors","capabilities","harness","repo","environment","up","harness setup","active","env","value"]