# Version 0.2.1

Released on 2026-08-04.

- [2026-08-04] Desktop app distribution: installers move to version-less names (`penguin-desktop-<os>-<arch>.<ext>`), are mirrored to the OSS bucket's immutable per-tag prefix alongside `SHA256SUMS.desktop`, and get a landing `/download` page — per-platform cards with the visitor's OS badged, static GitHub latest links that swap to the OSS mirror once its `latest.json` resolves client-side, a source toggle, and checksum links; nav/footer/README wired. ([details](2026-08-04-desktop-distribution-and-download-page.md))

- [2026-08-04] Tooling & CLI: standalone `install.sh` / `install.ps1` gain the forwarder's OSS-first download source selection with immutable Release-tag stamping, and `penguin update` adopts the same contract — OSS `latest.json` discovery with same-tag GitHub fallback in `auto`, strict forced modes, mirror overrides, localized failures. ([details](2026-08-04-download-source-selection.md))

- [2026-08-04] Core: compaction survives malformed summaries (fixes #170) — tolerant extraction, unusable responses retried on the standard backoff budget with a corrective note, burned attempts and tokens surfaced in stats, and one shared `RetryDetail` shape (`error_message`/`attempt`/`retry_in_ms`) across `request_end` and `compaction_end` read by both frontends. ([details](2026-08-04-compaction-retry-observability.md))

- [2026-08-04] Skills: `data-analysis` v2 — tighter data-semantics/delivery/verification constraints, and a leaner multi-run evaluation flow (Pilot results reused as the Formal Baseline, per-Candidate `runs` dispatched Case × Runs, Evaluator accepts `run` as a label). ([details](2026-08-04-data-analysis-skill-v2.md))

- [2026-08-04] Server: the last two IO hotspots closed — the 30-second scheduler tick and the schedules routes now serve from mtime-gated caches (zero steady-state file reads, hand edits still picked up; `.project_config.toml` parsed once per on-disk version across scheduler, routes and usage pricing), and `GET /messages` gains cursor pagination with tail-first web loading, Task-boundary windows, provable-continuity resync splicing and globally correct outline numbering — the no-params response stays byte-identical. ([details](2026-08-04-io-hotspots-scheduler-messages.md))

- [2026-08-04] Dependencies: `hono` bumped to ≥ 4.12.34, resolving the open Dependabot alert (GHSA-8j4g-w8fx-2239, CORS preflight ReDoS); lockfile change confined to the hono chain. ([details](2026-08-04-deps-hono-redos.md))

- [2026-08-04] Desktop app: new `packages/desktop` — an Electron shell that runs the existing server as a utilityProcess on the shared data root and its window on `http://localhost` with token-based no-login sign-in, graceful shutdown, and crash restart; desktop mode on the server (one-shot login, shutdown endpoint, unprinted random seed, `desktopMode`/`sessionVia` on /api/me), a new per-root `server.lock` single-instance guard the CLI and shell both honor, desktop-aware Web App chrome, and three-platform packaging (electron-builder over a pnpm-deploy staging tree, built by a reusable CI matrix ahead of Release creation; unsigned until the signing milestone). UI preferences (language, theme) now survive restarts: the shell reuses last launch's port when still free so the window origin — and its origin-scoped localStorage — stays stable, with `PORT=0` remaining the sole allocator. ([details](2026-08-04-desktop-app.md))

- [2026-08-04] Web App: the public fixed admin password `penguin-2026` is replaced by a random `penguin-<4 digits>` seed printed once at first start (`PENGUIN_SEED_ADMIN_PASSWORD` pins it for tests, policy-checked), and the login endpoint gains per-username exponential throttling (5 free failures, 1s doubling to 60s, `429 too_many_attempts`, reset on success, identical for unknown usernames) so the 4-digit space cannot be enumerated. ([details](2026-08-04-web-app.md))

- [2026-08-04] CLI: `penguin web` readiness-probe failures are no longer swallowed — the last error is classified (timeout / refused / reset / permission / DNS) and reported with actionable, localized guidance instead of a generic "not responding yet". ([details](2026-08-04-cli-web-probe-diagnostics.md))

- [2026-08-04] Skills: new `skill-porting` library skill — verified, schema-accurate flows for bringing skills in from Claude Code plugin marketplaces, Codex plugins, `npx skills add`/skills.sh, GitHub repos and local folders, normalizing them into penguin's skill format with a read-everything-first safety gate. ([details](2026-08-04-skill-porting-library-skill.md))

- [2026-08-04] Web App: skills become manageable from Agent settings — a Skills tab after Tools listing the installed set straight from disk, uninstall with confirmation, an Import dialog that leads with chat-driven install (URL + generated review-first prompt) and also accepts a skill zip through a new validated archive endpoint, and per-skill zip export that round-trips through that import; the agent list's tools/vault/schedules/skills icons deep-link to the matching settings tab via a new `?tab=` param, and the list rows drop the active-session badge. ([details](2026-08-04-agent-skills-and-list.md))

- [2026-08-04] Web App: Project settings gains a "New chat defaults" section — default Agent, working directory, approval mode and thinking level stored as an additive `[default_chat]` block in `.project_config.toml`, seeded into new drafts beneath route overrides and unsent drafts; the model row reads and writes the same `default_model` the models page owns through a narrow set-default endpoint, and thinking level resolves Agent-explicit → project default → `medium`. ([details](2026-08-04-project-chat-defaults.md))

- [2026-08-04] Web App: the Traces page becomes a second surface of the session sidebar — shared group/folder/mode-toggle components (the sidebar refactored onto them), workspace and agent grouping on the sidebar's own persisted preference, lazy subagent/schedule/archived folders, server-side session paging — and trace discovery plus the agents-list activity sparkline move off per-request filesystem walks onto a SQLite-derived, mtime-reconciled trace index (rebuildable cache; disk stays the source of truth). CLI sessions now follow the show-CLI-sessions preference (default hidden), titles fall back to the first user prompt, and raw session ids are gone from the page. ([details](2026-08-04-traces-page-scaling.md))

- [2026-08-04] Web App: chat refinements — the conversation outline rail appears from 5 exchanges and windows to ±20 turns around the active one (fixing its overlap onto the composer and, under browser font scaling, onto the prose column), the toolbar cost stat no longer blinks out mid-run, uploaded file attachments render as user content (right-aligned below the text like uploaded images, and inside the steering chip instead of vanishing from files-only steering), tool rows drop the stop-reason text markers entirely in favor of the status icon, and the home update hint sheds its pill for plain superscript text. ([details](2026-08-04-web-chat-refinements.md))

- [2026-08-04] Fix: ANSI color codes no longer leak into tool output — the CLI gates color on TTY/`NO_COLOR`/`TERM` with `FORCE_COLOR` override semantics matching Node, the command tool strips inherited `FORCE_COLOR`/`CLICOLOR_FORCE` from child environments so its `NO_COLOR=1` hardening wins, and the Web renders tool output through a defensive ANSI stripper covering historical Traces. ([details](2026-08-04-ansi-tool-output.md))

- [2026-08-04] Models: OpenRouter gains `qwen/qwen3.8-max` (1M context, vision, published cache-hit and cache-write prices), and the agenthub-models skill (v10) records the OpenRouter spelling — existing Projects pick it up through the models page's explicit "sync presets" action. ([details](2026-08-04-model-catalog-openrouter-qwen38-max.md))
