# Changelog

All notable changes to this project are documented in this file. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
project follows the `0.y.z` convention used by its author: `PATCH` for
compatible fixes, `MINOR` for features or breaking changes.

## 0.11.1 - 2026-11-01

### Fixed

- Deliver the profile through `before_agent_start` again on every Pi version,
  returning the complete prompt instead of prepending to the request through
  `context_with_system` (no longer registered). Another extension returning
  `systemPrompt` makes Pi replace the whole system message after every hook, so
  the request-local prepend never reached the provider; the complete prompt is
  what Pi projects last, and it chains, so the managed block appears exactly
  once when another extension builds on `event.systemPrompt`, before or after
  this one. A later extension returning an independent full replacement can
  still discard it, and the read-only check warns then. While a profile is
  active the request carries a complete prompt: the 0.11.0 native section-delta
  benefit is given up, adding tools during a run rebuilds the system header, and
  prompt snippets and guidelines of a tool activated mid-run are absent until
  the next run. With no profile, Pi keeps its own prompt and deltas.
- The missing-profile warning now reports an observation: "the selected profile
  was not found in this request. Another extension may have replaced the
  complete system prompt." The unverified-format variant is unchanged.

## 0.11.0 - 2026-10-31

### Fixed

- On Pi 1.4+, prepend the frozen profile through the request-local system
  transcript instead of returning a complete prompt. Adding tools no longer
  forces the extra header reconstruction caused by this extension. Native
  sections and updates remain intact; this does not guarantee provider cache
  hits. Pi 0.85.1 keeps its legacy path and minimum support is unchanged.

### Changed

- On the modern path, another extension returning a complete `systemPrompt`
  can remove the profile in either load order, even when it only appends text.
  This is a coexistence incompatibility. A missing frozen block now produces
  a warning once per run and `not in payload` in the footer. Unrecognized
  formats report `payload unverified`; payloads are never rewritten to repair
  another extension's override.

## 0.10.0 - 2026-10-17

### Removed

- The control statement that opened every managed block (the "System
  instructions" heading, the priority claim and the note on inheritance) is no
  longer written. The block now holds the markers and the profile bodies only.
- `profiles.<id>.controlText`, `/sp control-text` and the "Change the control
  statement" menu entry, which only chose between keeping and dropping that
  text. An existing `controlText` key in `config.json` is ignored; remove it to
  keep the file valid against the schema.

## 0.9.1 - 2026-10-01

### Fixed

- The guided menu had no entry for the control statement, so the value could
  only be changed by remembering `/sp control-text`. The menu now offers
  "Change the control statement", which opens the same `full`/`none` picker and
  writes to the active profile's own config.

## 0.9.0 - 2026-10-01

### Added

- `profiles.<id>.controlText` in `config.json` chooses whether the managed
  block keeps its opening control statement. `full` (the default) keeps it and
  `none` writes the profile bodies only, with the block markers and their order
  unchanged. Only the selected profile's metadata is read, so the value is never
  inherited from an `extends` parent.
- `/sp control-text` sets that key for the active profile: without arguments it
  shows a `full`/`none` picker that marks the current value, and
  `/sp control-text full|none` writes it directly without a picker. Both write to
  the profile's own config, apply on the next turn without `/sp reload`, and
  leave the other keys and metadata in place.

## 0.8.0 - 2026-09-22

### Added

- A "Manage model bindings" submenu in the guided menu groups adding, listing
  and removing bindings, with a way back to the main menu. The list shows every
  binding of both configs as `scope:id — profile ← rules`, with priority when it
  is not the default.

### Changed

- "Bind a profile to a model" and "Remove a model binding" now live inside the
  "Manage model bindings" submenu.

## 0.7.0 - 2026-09-22

### Added

- "Remove a model binding" in the guided menu, listing every binding of both
  configs with its scope, profile and rules.
- `/sp bind` warns when the session selection is `manual` or `off` (bindings
  apply only in auto mode) and when the new binding does not match the active
  model.

### Changed

- `(any provider)` in the bind picker now opens one list with every model,
  labelled `provider · id`, so a single model of any provider can be chosen;
  its `(any model)` entry still creates `*/*`. Before, the step ended
  immediately with `*/*` and no model could be picked.
- `/sp unbind <binding-id>` without `--scope` searches the project config first
  and then the global one, instead of the global config only.

## 0.6.0 - 2026-09-19

### Added

- `/sp config` shows a config file and its diagnostics, and `/sp set` and
  `/sp unset` change `subagents`, `inheritGlobalBindings` and `selection`
  without editing the file. The interactive menu gained "Show configuration" and
  "Change a setting".

## 0.5.0 - 2026-09-18

### Added

- The `subagents` config key (`off`, `bindings`, `inherit`) controls whether the
  profile applies inside a subagent.

### Changed

- A background subagent no longer receives the `defaultProfile`. With the default
  `bindings` policy, only an explicit binding that matches the child's model
  applies.

## 0.4.1 - 2026-09-18

### Added

- The interactive bind menu can target every model of a provider (`provider/*`)
  or any model of any provider (`*/*`).

### Changed

- Profile and model pickers use a searchable list capped at ten rows. Pi's
  extension selector renders every option, so the model catalog pushed the
  dialog off the screen.
- Interactive `/sp bind` asks for a provider and then a model, and shows the
  active model and the profile's existing bindings.
- Generated binding ids use `any` for a wildcard segment (`base-deepseek-any`,
  `base-any-any`).

## 0.3.1 - 2026-09-18

### Changed

- The managed block no longer names the active profile, its scope or the
  inherited base. Layers are emitted as plain text without headings, so the
  block carries no identifier for the active profile.

## 0.3.0 - 2026-09-18

### Changed

- The managed block now declares the profile the primary system instructions and
  requires them to be followed over any conflicting instruction.
- The block no longer names the extension, and its begin and end markers are
  neutral.

### Removed

- The caveat that the ordering was not a guarantee of obedience.

## 0.2.0 - 2026-09-18

### Added

- The `/sp` picker and `/sp list` now show the folder each profile lives in.

### Removed

- The managed block no longer states that it is not an administrative override of
  provider-side restrictions.

## 0.1.0 - 2026-09-18

### Added

- Markdown system prompt profiles read from the global Pi config directory and,
  when the project is trusted, from the project.
- A single active profile per session with optional `extends` inheritance.
- Deterministic auto-selection through provider/model bindings and defaults.
- The `/sp` command with `list`, `use`, `auto`, `off`, `status`, `why`,
  `preview`, `bind`, `unbind`, `reload`, `validate`, `new`, `edit` and
  `default`, plus a guided menu when it runs without arguments.
- Non-interactive flags `--sp-profile`, `--sp-auto` and `--sp-off`.
- Session-scoped selection persisted as a custom session entry.
- A versioned JSON schema and an examples folder.
- A documentation site built with Astro and Starlight, published on GitHub Pages.
