# Changelog

# Changelog

All notable changes to Benson are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.16.1] - 2026-09-27

### Fixed

- Docs-site deploy no longer exports `DOCKER_DEFAULT_PLATFORM`. That variable
  is a buildx platform list (`linux/amd64,linux/arm64`), and `docker compose
  pull` rejects a list. The runner pulls its own platform from the image
  manifest.

### Site impact

Nothing. This release only changes the release workflow.

## [0.16.0] - 2026-09-27

### Removed

- **MCP server.** `benson mcp` is gone. `benson init` writes
  `.claude/skills/benson/SKILL.md` and no longer writes `CLAUDE.md` or
  `.mcp.json`. Agents read the documentation site for the installed version.

### Fixed

- A version tag deploys the docs site after the image push. The crate
  publishes from the same rust image CI uses.

### Site impact

Add `.claude/skills/benson/SKILL.md` to an existing site. Stop invoking `benson mcp`. Delete a leftover `.mcp.json`.

## [0.15.0] - 2026-09-27

### Added

- **Redirect fragments.** A `[[redirects]]` `to` may include one `#fragment`,
  such as `/#our-firm`. A request query is placed before that fragment
  (`/our-firm?x=1` → `Location: /?x=1#our-firm`).
- **Mermaid diagrams.** A `mermaid` fence renders as a diagram in browser HTML,
  including listing summaries. Markdown and JSON keep the fence. Mermaid 12.0.0
  is served at `/js/mermaid.min.js`, and `base.html` loads it only when the page
  contains a diagram.

### Site impact

Nothing is required for an existing site to keep working. To render Mermaid diagrams, add the conditional `/js/mermaid.min.js` hook to `base.html`. A site created with `benson init` already has the hook.

## [0.14.0] - 2026-09-26

### Added

- **Site redirects.** `[[redirects]]` in `config.toml` maps a request path to
  another path. `status` defaults to 301; 301, 302, 307, and 308 are allowed.
  A matching GET or HEAD is answered before auth and the file cache, and the
  request query is kept on `Location`. MCP tools `add_redirect` and
  `remove_redirect` edit the table; `update_site` reports whether it is
  configured.
- **Resource usage log.** `benson serve` writes an INFO `resource usage` line
  at startup and every five minutes with `rss_mb`, `cpu_user_ms`, and
  `cpu_system_ms`.

### Changed

- Release images build for `DOCKER_DEFAULT_PLATFORM` (default `linux/amd64`)
  on the docker runner. CI and the release crate publish run on the rust
  runner.

### Site impact

Nothing is required. `[[redirects]]` and the resource-usage log are opt-in.

## [0.13.0] - 2026-09-16

### Fixed

- Posts with `

` keep the preview in the full page body and insert
  `<span id="continue-reading"></span>` at the split. Listings still use only
  the excerpt. Posts without the marker are unchanged.

### Site impact

Nothing to edit. The continue-reading marker is engine behavior.

## [0.12.1] - 2026-08-19

### Fixed

- Release workflow crates job no longer runs `apt-get install nodejs`.
  That step was leftover from the `rust:1.96` Debian container; the
  Alpine `build-home` runner has no `apt-get` and already supports JS
  actions, matching `ci.yml`.

### Site impact

Nothing. This release only changes the release workflow.

## [0.12.0] - 2026-08-19

### Changed

- **BREAKING: environment overlays use the `config` crate's `BENSON_` / `__`
  convention.** `load_config` reads `config.toml` then overlays any
  `SiteConfig` field from the environment. Nested keys use `__`
  (`BENSON_SERVER__BIND_ADDR`). The SMTP password and `--no-auth`
  confirmation stay as raw env reads.
  - **Migration:** rename `BIND_ADDR` → `BENSON_SERVER__BIND_ADDR`,
    `CACHE_DIR` → `BENSON_SERVER__CACHE_DIR`, and
    `BENSON__FORMS__NOTIFY` → `BENSON_FORMS__NOTIFY`. Empty
    `BENSON_FORMS__NOTIFY=` still clears the recipient list.

### Site impact

Rename `BIND_ADDR` to `BENSON_SERVER__BIND_ADDR`, `CACHE_DIR` to `BENSON_SERVER__CACHE_DIR`, and `BENSON__FORMS__NOTIFY` to `BENSON_FORMS__NOTIFY`. An empty `BENSON_FORMS__NOTIFY=` still clears the recipient list.

### Added

- Gitea Actions CI runs `cargo fmt`, `clippy`, `test`, and `build` as
  separate steps on `build-home`, triggered on every pull request update
  (no cargo-make, no sccache, no `main`/`develop` push allowlist).

## [0.10.0] - unreleased

### Changed

- **BREAKING: sections are now declared with a `section = true` front-matter flag
  instead of the `_index.*` filename convention.** A directory index
  (`index.md` / `index.toml`) is a **bundle page** by default (it absorbs its
  sibling `.md` files as co-located content) and becomes a **section** (lists its
  child pages, does not absorb siblings) only when its front matter sets
  `section = true`. The `_index.md` / `_index.toml` filenames are no longer
  recognized.
  - **Migration:** rename each `_index.md` → `index.md` (or `_index.toml` →
    `index.toml`) and add `section = true` to its front matter.

### Site impact

Rename each `_index.md` to `index.md` (or `_index.toml` to `index.toml`) and add `section = true` to its front matter.

### Added

- **Hidden sections hide their whole subtree.** Setting `hidden = true` on a
  section marks every descendant page and nested subsection as unlisted —
  excluded from `sitemap.xml`, `llms.txt`, and section listings — so you can
  carve out private "sub-sites." Pages remain reachable by direct URL (this is
  unlisted, not access control; use `[[auth.rules]]` to restrict access).
- **Section body rendering.** A section's own index body (the markdown after the
  front matter of its `index.md`, or the co-located `index.md` of an
  `index.toml` section) is rendered to HTML and passed to the browser template as
  `content`, so a section template can show intro copy above the child listing.
- **Parent-section context on pages.** A page rendered inside a section now
  receives its parent section's `section_title`, `section_description`, and
  `section_url` in the template context, so page templates can show breadcrumbs
  or a "back to section" link.
- **`--version` / `-V` CLI flag**, and the version now appears in `benson --help`.
- **MCP:** `new_page` and `edit_page` accept a `section` flag; `edit_page` also
  accepts `hidden`. `update_site` advertises the section and hidden-section
  features and no longer references the legacy `_index.*` convention.

### Fixed

- A hidden section now lists its own child pages on its own index page. Previously
  hidden-subtree propagation marked every child private and `render_section`
  filtered them all out, leaving a private sub-site's index empty.
- A section directory whose name contains an underscore no longer orphans its
  standalone child pages (the child-to-section key is now normalized through
  `derive_url`, matching the `_`→`-` transform used for the section's URL).

[0.16.1]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.16.1
[0.16.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.16.0
[0.15.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.15.0
[0.14.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.14.0
[0.13.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.13.0
[0.12.1]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.12.1
[0.12.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.12.0
[0.10.0]: https://gitea.galiath.net/Greg-Hewett/benson/releases/tag/v0.10.0

