# Changelog

What changed in each `@trymirio/mirio` release, newest first (up to 0.1.6 the package was `kibbleforms`, and its notes keep the old names). Check this when you upgrade: anything that changes how a form looks or registers is called out. Install the latest with `npm install @trymirio/mirio@latest`; `npx mirio --version` prints the one you have.

## 0.2.0 (2026-11-04)

**Kibble is now Mirio.** The package is `@trymirio/mirio` (it was `kibbleforms`), the CLI is `mirio`, and the site, docs and API moved to trymirio.com. Forms look the same, but nothing reads the old names, so a site set up with `kibbleforms` renames them once:

| Before | Now |
| --- | --- |
| `kibbleforms` and its subpaths (`kibbleforms/next`, `/vite`, `/headless`, `/client`, `/schema`, `/styles.css`, `/theme.css`, `/themes/*.css`) | `@trymirio/mirio`, `@trymirio/mirio/next` and so on |
| `npx kibbleforms init`, `npx kibble <command>` | `npx @trymirio/mirio init`, `npx mirio <command>` |
| `kibble.json`, `.kibble/secret` | `mirio.json`, `.mirio/secret` (and `.mirio/` in `.gitignore`) |
| `KIBBLE_SECRET_KEY`, `KIBBLE_API_URL`, `KIBBLE_ENV`, `KIBBLE_PRODUCTION_BRANCH`, `KIBBLE_NO_UPDATE_CHECK` | `MIRIO_SECRET_KEY`, `MIRIO_API_URL`, `MIRIO_ENV`, `MIRIO_PRODUCTION_BRANCH`, `MIRIO_NO_UPDATE_CHECK` |
| `KibbleProvider`, `useKibbleForm`, `KibbleAttribution`, `KibbleError`, `withKibble` (Next.js), `kibble()` (Vite) and the other `Kibble…` names | `MirioProvider`, `useMirioForm`, `MirioAttribution`, `MirioError`, `withMirio`, `mirio()`, `Mirio…` |
| CSS variables `--kb-*`; utilities `bg-kb-*`, `text-kb-*`, `rounded-kb` and the rest; the `kb-check` class | `--mirio-*`; `bg-mirio-*`, `text-mirio-*`, `rounded-mirio`; `mirio-check` |
| `data-kibble` on the form's root, `data-kb="…"` on its parts, `data-kb-size`, `data-kb-color-scheme` | `data-mirio-root`, `data-mirio="…"`, `data-mirio-size`, `data-mirio-color-scheme` |
| `api.kibbleforms.com` | `api.trymirio.com` |
| `X-Kibble-Test` | `X-Mirio-Test` |

The forms folder stays wherever `formsDir` in the config points. `mirio init` writes its AGENTS.md section between new markers (`<!-- mirio:start -->`), so delete the old Kibble section once it has.

**Changed for every site, whatever version it runs:**

- Webhooks are signed in `Mirio-Signature` (it was `Kibble-Signature`), with `Mirio-Delivery-Id` and the user agent `Mirio-Webhooks/1`. Update the header your receiver checks.
- The Postgres destination writes `mirio_*` columns (`mirio_id`, `mirio_status`…; they were `kibble_*`), and new tables are named `mirio_<form>`. Rename the columns of an existing table, or drop it and let Mirio create it again.
- Workspace API keys start with `mi_` and dashboard link codes with `mil_`. Keys that start with `kb_` no longer work: create a new one under Settings → API keys.

## 0.1.6 (2026-11-03)

**Turnstile checks tokens now:**

- `kibble turnstile set <secret key>` gives Kibble your Turnstile widget's secret key. It reads the site key from `settings.turnstileSiteKey` in your schema files (`--site-key` when forms use more than one), Kibble checks the secret key with Cloudflare and stores it encrypted, and it's never printed back. `kibble turnstile` lists which forms are checked; `kibble turnstile remove` deletes the key. See [Turnstile](/docs/spam.md#turnstile).
- Before, Kibble rendered the widget but checked no tokens. If a form already sets `turnstileSiteKey`, registering it now warns until you run `kibble turnstile set`; from then on, responses with a missing or invalid token go to spam. Nothing changes in how forms look.

**Setup:**

- The AGENTS.md section `kibble init` writes now connects Slack with "Add to Slack" (`npx kibble destinations add slack --form <slug>` prints a link for a person), like the docs, instead of asking for a webhook URL.

## 0.1.5 (2026-10-27)

**How forms look** (styled components; restyle with `classNames` if you prefer the old spacing):

- Single and multiple choice options sit closer together: 4px apart instead of 8px.
- The "Optional" mark next to a label is lighter (70% of the muted color), so it reads as a note rather than part of the label, also when labels are gray.
- Multi-step forms no longer show "Your answers are saved as you go." under the buttons. Progress is still saved after each step; pass `<MultiStep notice="…" />` to show a line of your own.
- Checkboxes and radio buttons are drawn by Kibble instead of the browser, so they follow your theme: unchecked, the field background with the border color (no more gray browser fill in dark mode); checked, the primary color with the check or dot in the primary text color. The box is centered on the first line of its label at every size. They're styled by the `kb-check` class in `theme.css` and `styles.css`; in Windows high-contrast mode they fall back to the browser's own.

## 0.1.4 (2026-10-27)

**Where responses come from:**

- Responses now say which page on your site led to the form (`meta.referrer`, a path like `/pricing`), the first page of the visit (`meta.landingPage`) and the other site the visit came from (`meta.entryReferrer`, an origin), and campaign tags from the landing page when the form's page has none. Optionally, add `<KibbleAttribution />` to your root layout to record the pages before the form. Other sites are recorded as their origin only, never a path or query. Off with `createClient({ attribution: false })`. See [Attribution and hidden fields](/docs/attribution.md).
- Hidden fields and `prefill.query` read the visit's landing page when the form's page doesn't have the parameter.
- `meta.pageUrl` is now the page's origin and path: no query string (prefill links can carry answers there; campaign tags stay in `utm`) and no `#fragment`. Kibble trims it the same way for older versions.
- To follow in-site navigation, the client wraps `history.pushState` and `replaceState` (calling the originals) and listens for `popstate`. `createClient({ attribution: false })` leaves history alone.

- The thank-you card has a smaller, filled check mark (the primary color, with the check in its text color), a medium-weight title, and less space between its title and message.

**CLI:**

- `kibble destinations add slack --form <slug>` without a URL prints an "Add to Slack" link for a person to pick the channel, and waits for it (`--no-wait`, `--json`).
- `kibble status` and `kibble sync` say when a newer kibbleforms is out, at most once a day (`KIBBLE_NO_UPDATE_CHECK=1` turns it off).

**Kibble (no upgrade needed):** "Add to Slack" in the dashboard; webhooks and databases must be public addresses; spreadsheet formulas in CSV exports are neutralized; Slack and email notifications say where each response came from; Insights shows the pages that led to the form.

## 0.1.3 (2026-10-27)

**Changes how forms look:**

- Labels mark optional fields with a small, muted "Optional" and leave required fields unmarked (before: a red `*` on required fields). Screen readers hear "Optional" with the label; required controls still carry `aria-required`. To get asterisks back: `requiredIndicator={<span aria-hidden className="ml-0.5 text-kb-error">*</span>}` and `optionalIndicator={null}` on `Form` or `KibbleProvider`. See [Label](/docs/components/label-help-error.md).
- More room between a label and its control: `--kb-gap` is 0.5rem at `sm` and `md`, 0.625rem at `lg` (was 0.25, 0.375 and 0.5rem).
- A required `consent` checkbox follows `requiredIndicator` (no mark by default).

**CLI:**

- GitLab, CircleCI, Buildkite, Jenkins, Bitbucket Pipelines, Azure Pipelines and Travis are read by branch: production on `KIBBLE_PRODUCTION_BRANCH`, else the provider's default branch, else `main`; other branches and pull/merge requests register as preview. Before, they registered production on every branch.
- `init` at a monorepo root lists every app below it, Next.js and Astro before plain Vite, and asks you to pick the site.

**Docs:** a scroll offset for the success card under a fixed header ([Success](/docs/components/success.md)).

## 0.1.2 (2026-10-27)

- Inputs, selects and buttons keep the size's control height (`sm` inputs were 39px instead of 36px, buttons 37px).
- Render, Railway and any other build server that sets `CI` register forms as production. In 0.1.1 they registered as development.
- `init` only stops at a real repo root (no `package.json`, a workspace file, or no React), so a React site with a Vite storybook folder sets up normally; `--force` skips the check.
- `domains add` names the www twin from the hostname, and none for a wildcard, `localhost` or an IP.

## 0.1.1 (2026-10-27)

- A build with no deploy host (a local `next build`) registers forms as development, not production.
- The success card takes focus and scrolls into view when it replaces the form.
- `init` stops at a monorepo root before using a link code, matches the install hint to your package manager, maps shadcn colors only when the site has shadcn's variables, and writes an AGENTS.md section that matches the site (live or sandbox, the styles it set up).
- The shadcn theme files fall back to Kibble's colors when a variable is missing.
- `kibble --version` prints the package's version.

## 0.1.0 (2026-10-26)

First release: the `Form` components and headless hooks, the typed schema, the client, and the `kibble` CLI (`init`, `sync`, `push`, `test`, `status`, `claim`, `domains`, `destinations`, `review`, `submissions`, `env`).
