# Changelog

## 0.4.0 (2026-10-10)

- **Deferred tool tier** (ceulen pattern): the `skill_manage` tool now register `exposure: "deferred"` — not declared to the model until `tool_search` loads them (they stay callable via `ctx.executeTool`/codemode). The package now force-activates `tool_search` in `session_start` when it defers tools (pi only auto-activates discovery for MCP servers). Unit tests pin the exposure flags and the activation branches.

## 0.3.7 (2026-09-30)

- Removed the unused `SelfSkillsSettings` type import. Verified against Pi SDK 0.99.2.

## 0.3.6 (2026-09-28)

- **Fix: `file` paths are normalized (path.posix.normalize) before the
  SKILL.md-refusal and containment checks** in writeAction, deleteAction,
  and both batch write/delete ops. Alias forms (`./SKILL.md`,
  `sub/../SKILL.md`) previously fell past the basename refusal into the
  generic relpath error (and containment saw raw input); they are now
  refused with the same SKILL.md-specific message as the bare name.
- Tests: alias-form refusal suite (`SKILL.md` / `./SKILL.md` /
  `sub/../SKILL.md` for write and delete, skill unchanged after).

## 0.3.5 (2026-09-24)

- **Fix: in-queue create re-checks the discovered-name clash** — parity with
  the pre-queue check. Two parallel `create`s of the same name into different
  roots (different targets, so the target-exists check alone never fires)
  both passed the pre-queue discovery snapshot and silently double-created;
  the in-queue `discoverSkills` re-check now refuses the second with the
  `already discovered` error. Test races two promises without monkeypatching
  (mutation-queue registration is serialized, so the first write lands before
  the second's re-check runs).

## 0.3.4 (2026-09-22)

- **Fix: batch commit re-verifies the disk hash in-queue** — `operations[]`
  planned against an in-memory overlay but committed whatever was there at
  write time, so an external write landing between plan-time validation and
  commit was silently clobbered. The commit loop now re-hashes each existing
  SKILL.md patch target inside the mutation queue (mirroring `patchAction`'s
  authoritative check) and fails that op cleanly — including the
  target-vanished case. With nothing written yet, the failure reports `Batch
  failed before any write` instead of a misleading partial-application notice.
- **Docs truth**: README `read` row corrected — reading with `file=` records
  THAT bundled file, not SKILL.md, and does not unlock patch/write/delete
  (they gate on the SKILL.md read state); the `operations` row now states the
  commit-time partial-application caveat instead of claiming any-failure
  atomicity. The `selfskills` doc-skill lists `write`/`delete` in its
  description (0.2.0 features) and its writable-roots list includes project
  `.agents/skills` + local package roots.

## 0.3.3 (2026-09-21)

- **Cleanup: removed the unused `listDeletedSnapshots` import** from
  `extensions/index.ts` (only `latestDeletedSnapshot` is used).

## 0.3.2 (2026-09-20)

- **Fix: binary-safe backups (single-file AND batch paths)** — `write`, single-file `delete`, and batch `operations` snapshotted the current file via a UTF-8 string read, corrupting backups of binary bundled assets (unrestorable mangled bytes). `snapshot()`/`contentHash()` now accept `Buffer`; existing content is read and backed up without encoding on every path, and single-file restore round-trips bytes. SKILL.md paths keep text behavior (validation unchanged).

## 0.3.1

- **Fix: deletion-snapshot ordering** — `snapshotDir` re-evaluated its millisecond stamp inside the collision loop, so a mid-loop tick could emit `T2-2` while bare `T2` stayed free; the next snapshot claimed `T2`, sorting **before** `T2-2`. Consequences: cap-pruning could delete the *newest* snapshot and `latestDeletedSnapshot`/restore could resolve a stale one (seen live as a CI test flake). The stamp is now evaluated once per call — names are strictly monotonic with creation order.

## 0.3.0

- **`create` root placement**: new optional `root` param places a new skill in any writable root (path shown by `list`) — e.g. a project's `.agents/skills` — instead of only `~/.pi/agent/skills`/skillsDir. Previously the only way to get a project-local new skill was raw `write`, bypassing validation + backups (observed live in session 01a08bcc). Relative roots anchor to the session cwd; root matching canonicalizes both sides (macOS /var↔/private/var aliasing can't cause a refusal); the cwd-level `.agents/skills` is listed and creatable even when it doesn't exist yet (bootstrap), and create mkdir -p's the target.
- `list` now shows the writable roots (`user`/`project`/`project-agents`/`skillsDir`/`package`) so `root=` values are discoverable.
- Docs truth: `LIST_NOTE` and the tool description now state that project `.agents/skills` roots are patchable (true since 0.2.0 `patchProjectAgents`) and where `create` lands; the discipline block tells the model to use `root=` instead of bypassing with raw write/sed.
- **Guard fix**: the user-level `~/.agents/skills` can never become a writable project root — even when the session cwd is `$HOME` (non-git), whose boundary would otherwise swallow it. Closes a 0.2.x hole where a trusted `$HOME` cwd made an existing `~/.agents/skills` patchable, and keeps the new bootstrap root from inheriting the same edge.

## 0.2.0

- **Bundled-file writes**: `write` action creates/overwrites `references/`, `scripts/`, etc. under an existing skill's directory — extend a reference by topic instead of forking a sibling skill. SKILL.md stays patch-only; overwrites are backed up.
- **Delete**: bundled files (backup + restorable, empty parent dirs pruned) and whole skills (full-file snapshot to `backups/<skill>/__deleted__/`, restorable — recreates the skill from its snapshot).
- **Batch atomicity**: `operations[]` runs multiple patch/write/delete ops against an in-memory overlay, validates every resulting SKILL.md with the real SDK loader, then commits together — any failure writes nothing.
- **Read-hash precondition**: patches refuse with "hash mismatch" if the file changed on disk since it was read (other session/user/tool) — re-read and retry instead of clobbering.
- Restore extended: per-bundled-file restore (`file=` param), deleted-skill recreation, v0.1 flat SKILL.md backups still restorable.
- Backup layout v2: `backups/<skill>/<relpath>/<stamp.ms>-<sha256[:10]>.md`.

## 0.1.0

- Initial release: `skill_manage` tool with `list`/`read`/`patch`/`create`/`restore` actions.
- Writable-root allowlist (`<agentDir>/skills`, trusted `<cwd>/.pi/skills`, `skillsDir` override, local package skills); package/node_modules skills read-only.
- Patch gates: read-before-patch, unique-match, real SDK validation, backup + atomic write via `withFileMutationQueue`.
- Content-addressed backups with per-skill cap pruning and restore.
- `selfskills` doc-skill + per-turn standing-rules injection (`selfskills.inject`).
- `/selfskills` status command.
