diff --git a/src/content/docs/ai-development/agents-md.mdx b/src/content/docs/ai-development/agents-md.mdx index 61a69968..64075965 100644 --- a/src/content/docs/ai-development/agents-md.mdx +++ b/src/content/docs/ai-development/agents-md.mdx @@ -31,6 +31,11 @@ Only the root guide loads into the agent's context on every session. Detailed co keeps each session cheap while still having deep guidance available the moment it's needed. +Projects created with `fsh new` (or `dotnet new fsh`) get all of these files: `AGENTS.md`, both bridges and the +whole `.agents/` folder. Sections that only apply to the kit's own repo (branching, CI gates, the docs-repo +rule) are stripped from the scaffolded `AGENTS.md`. Pass `--no-agents` (CLI) or `--agents false` (template) to +leave all four out. + ## The `.agents/` folder ``` diff --git a/src/content/docs/changelog/index.mdx b/src/content/docs/changelog/index.mdx index cf0fb920..62e777be 100644 --- a/src/content/docs/changelog/index.mdx +++ b/src/content/docs/changelog/index.mdx @@ -1,6 +1,6 @@ --- title: Overview -lastUpdated: 2026-10-02 +lastUpdated: 2026-10-09 description: Release notes and version history for fullstackhero. sidebar: order: 1 @@ -13,6 +13,7 @@ Notable changes to the kit, newest first. ## 2026-10-09 +- **CLI & template: scaffolded projects now ship the AI guides `AGENTS.md` points to (fix).** `fsh new` and `dotnet new fsh` included `AGENTS.md` but excluded `CLAUDE.md`, `GEMINI.md` and `.agents/`, so the guide referenced files that did not exist. All four now ship together by default, the scaffolded `AGENTS.md` drops the sections that only apply to the kit's own repo, and `--no-agents` (CLI) / `--agents false` (template) leaves them all out. The internal `superpowers/` folder (specs and audits) no longer ships either. See [CLI](/docs/cli/#fsh-new) and [#1432](https://github.com/fullstackhero/dotnet-starter-kit/pull/1432). - **Identity: a failed sign-in no longer turns an open profile form into a `412` (fix).** `GET /api/v1/identity/profile` published the user's `ConcurrencyStamp` as the `ETag`, and ASP.NET Identity rotates that stamp on every write to the user row, including the `AccessFailedCount` bump of a wrong password and its reset on the next good sign-in. Anyone who typed a wrong password for the account made the user's next profile save answer `412 Precondition Failed` although nothing in the profile had changed. The `ETag` is now an HMAC-SHA256 of the fields `PUT /profile` writes (first name, last name, phone number and stored avatar URL), keyed with the user's `SecurityStamp` so a logged tag cannot be used to confirm a guessed name and phone number, and `If-Match` is compared against it. Sign-ins and token refreshes leave it alone, while a real profile change, including a new avatar, still moves it; a password change or a two-factor toggle also moves it, because they rotate the key. Because the tag follows content, a save that leaves every field as it was keeps the same tag and replaying it is accepted. Identity's own `ConcurrencyStamp` check at save time is unchanged, so a non-profile write landing inside the single request between load and save still answers `412`. No migration and no client change: keep echoing the tag from the read that seeded the form. A profile form opened before the upgrade still holds an old tag, so its first save after the deploy answers `412` once, and the dashboard's usual re-read and re-save recovers from it. See [Identity](/docs/modules/identity/#profile-concurrency) and [#1425](https://github.com/fullstackhero/dotnet-starter-kit/pull/1425). - **Authorization: `.RequirePermission(a, b)` now requires every listed permission (fix).** `RequiredPermissionAuthorizationHandler` checked only the first permission in the endpoint metadata, so a user holding `a` passed a gate that also demanded `b`. It now checks each one and succeeds only when the user holds all of them. A permission metadata entry with no permissions left (for example `.RequirePermission("")`) now denies the request; before, the handler threw `InvalidOperationException`. No kit endpoint lists more than one permission today, so nothing changes for the shipped API; your own multi-permission endpoints become stricter. See [Authorization](/docs/security/authorization/#applying-a-gate), [#1415](https://github.com/fullstackhero/dotnet-starter-kit/issues/1415) and [#1424](https://github.com/fullstackhero/dotnet-starter-kit/pull/1424). - **Mailing & Docker Compose: e-mail works out of the box, and SMTP connection security is configurable (fix).** `SmtpMailService` always connected with STARTTLS, so any server that does not offer it was refused before a single envelope was sent, and the compose stack inherited the `smtp.ethereal.email` host with empty credentials: every confirmation, password-reset and welcome e-mail failed, and a user registered by an operator could not sign in until someone confirmed the address by hand. A new **`MailOptions:Smtp:Security`** setting (MailKit `SecureSocketOptions`, by name: `None`, `Auto`, `SslOnConnect`, `StartTls`, `StartTlsWhenAvailable`) chooses the mode; it defaults to `StartTls`, so existing configuration behaves exactly as before, and an unknown name fails the options binding instead of guessing. `deploy/docker/docker-compose.yml` now reads the SMTP target from `.env` (`FSH_SMTP_HOST`, `FSH_SMTP_PORT`, `FSH_SMTP_SECURITY`, `FSH_SMTP_USERNAME`, `FSH_SMTP_PASSWORD`), defaulting to a pinned [Mailpit](https://mailpit.axllent.org) catcher (`axllent/mailpit:v1.31.3`, `Security` set to `None`) that runs only under the `mail-catcher` compose profile, which `.env.example` enables with `COMPOSE_PROFILES=mail-catcher`. With that default, e-mail is caught, not delivered. SMTP stays on the compose network and the inbox UI is published on the host loopback only, at `http://localhost:8025` (`FSH_MAILPIT_PORT`), because it holds live reset and confirmation links. For real delivery, edit `.env` only: set `FSH_SMTP_*` to your provider, set `FSH_MAIL_FROM` to a sender it accepts (the compose default is `no-reply@fsh.local`, because `appsettings.Production.json` leaves `MailOptions:From` blank), and delete the `COMPOSE_PROFILES` line. See [Mailing](/docs/building-blocks/mailing/) and [#1409](https://github.com/fullstackhero/dotnet-starter-kit/pull/1409). diff --git a/src/content/docs/cli/index.mdx b/src/content/docs/cli/index.mdx index f108f38a..995f557b 100644 --- a/src/content/docs/cli/index.mdx +++ b/src/content/docs/cli/index.mdx @@ -40,6 +40,7 @@ fsh new MyApp --non-interactive -o ./somewhere-else | `-o, --output` | Output directory (defaults to `./`) | | `--no-aspire` | Exclude the .NET Aspire AppHost project | | `--no-frontend` | Exclude the React admin + dashboard apps | +| `--no-agents` | Exclude the AI coding guides (`AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `.agents/`) | | `--skip-install` | Skip `npm install` for the React apps after scaffolding | | `--non-interactive` | Skip prompts and use defaults (name becomes required) | | `--git` | Initialize a git repository (on by default) |