Conversation
The weekly mutation baseline (#591) flagged 220 surviving mutants in src/streaming/mqttBridge.ts — the largest single contributor. The existing tests asserted topic suffixes and a few fields but never the full published payloads, so emptying any string literal or flipping a guard survived undetected. Add mutation-coverage suites that pin the exact contents the bridge emits: the full HA discovery config set (deep-equal over all 19 homeassistant/* topics), per-side publishState payloads, the connect-option/LWT/clientId wiring, the testConnection TLS matrix, and the error-path warn messages. No source changes. Scoped Stryker: 220 -> 32 surviving on this file (61.6% baseline file score -> 92.18%). The remaining 32 are equivalent mutants (slugify's own empty-string fallback, JSON.stringify dropping undefined, safePublish's connected-guard, setTimeout timing values, info-level console.log strings).
## Why The weekly mutation baseline (#591) flagged **220 surviving mutants** in `src/streaming/mqttBridge.ts` — the single largest contributor across all shards. The existing tests asserted topic *suffixes* and a handful of fields, but never the *full published payloads*, so emptying any string literal or flipping a guard survived undetected. ## What Add mutation-coverage test suites to `src/streaming/tests/mqttBridge.test.ts` that pin the exact contents the bridge emits. **No source changes.** - **HA discovery** — a single deep-equality assertion over the full 19-topic `homeassistant/*` config set (climate L/R, water-level, ambient temp/humidity, pump rpm/loop/stall/clog ×2, biometrics hr/br/hrv ×2). Kills the bulk of the StringLiteral/ArrayDeclaration survivors (`manufacturer`, `model`, `payload_available`, config topics, `identifiers`, templates, `modes`, temp bounds). - **publishState** — exact payloads for device-status, water-level, per-side climate (`isPowered → 'heat'/'off'`), biometrics, pump rpm/loop_temp scaling, stall/clog. - **connect options + lifecycle** — clientId prefix, LWT offline-retained will, `end(false)` on shutdown, already-connected no-op guard, client-error + subscribe-error warns. - **testConnection** — TLS `rejectUnauthorized` option matrix. - **resolveConfig** — DB-read-throw warn message, DB-true `haDiscovery` source (kills the `?? → &&` operator mutant the existing `false`-valued test couldn't separate). Every asserted constant is written independently of the source, so any literal/operator mutation in `mqttBridge.ts` now fails a test. ## Result Scoped Stryker run on `mqttBridge.ts`: **220 → 32 surviving** (file score **61.6% → 92.18%**, +18 kills in the second batch). The remaining 32 are equivalent mutants — masked by `slugify`'s own empty-string fallback, `JSON.stringify` dropping `undefined`, `safePublish`'s connected-guard, `setTimeout` timing values, and info-level `console.log` strings. ## Test plan - `pnpm exec vitest run src/streaming/tests/mqttBridge.test.ts` → **98 passed**. - `pnpm exec stryker run --mutate src/streaming/mqttBridge.ts` → 32 survived, 400 killed, 92.18%. - `eslint src/streaming/tests/mqttBridge.test.ts` → clean. Refs #591 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive test coverage for MQTT bridge functionality, including Home Assistant discovery payloads, device state publishing, connection lifecycle management, error handling, and TLS configuration scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update worktree-june-6-stryker ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/worktree-june-6-stryker/scripts/install \ | sudo bash -s -- --branch worktree-june-6-stryker ``` 🎯 **Pin to this exact build** ([run 27075004539](https://github.com/sleepypod/core/actions/runs/27075004539) · `02da363`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/02da363a31477a8e6cb10101a3831a60fd7ea6a8/scripts/install \ | sudo bash -s -- \ --branch worktree-june-6-stryker \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27075004539/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27075004539/artifacts/7458281344) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
… P2) (#637) ## Summary Adds **Autopilot** — a reactive WHEN/IF/THEN rules engine that sits beside the scheduler and responds to live pod signals, plus the full builder UI from the design bundle. Merged to `dev` now with the nav entry **hidden** so the half-wired signal catalog isn't user-facing until P2 lands the biometric/ambient/enum signal sources (sleepypod-core-69). ### Server - `automations.*` tRPC router — CRUD, `setEnabled`/`setDryRun`, `runs` (audit log), `status` (live state), kill-switch get/set, `nights`, `backtest`. Writes hot-reload the running engine (mirrors `schedules.ts` → JobManager). - Real-history backtest (`src/automation/backtest.ts`) — pure replay over recorded series (movement, ambient, vitals, water) for a chosen past night, reusing the engine's own `WindowStore`/`evaluateCondition`/`evaluateExpr` so the preview matches real behavior. Edge + policy modes. - Global kill-switch — persisted `autopilotEnabled` setting (migration 0014, additive `ALTER TABLE`) that short-circuits engine ticks and is restored at boot. ### Builder - `builderModel.ts` — bidirectional mapper between the friendly WHEN/IF/THEN UI and the engine AST ("lower 2°F" → `setTemperature(current − 2)`; "ambient + 3" → `setTemperature(ambient + 3)`). Round-trip unit-tested. ### UI - `/autopilot` desktop console (full-bleed, like `/debug`): automations list as plain-English sentences, two-pane rule editor with live sentence preview + live backtest, diagnostics panel (per-rule state, run-log, kill-switch, dry-run). - Compact Autopilot panel inside the `/debug` console (kept — this is the dogfooding entry point while nav is hidden). - **BottomNav entry removed** — `/autopilot` is deep-link-only until P2. ### Safety Engine is inert with zero rules (fresh DB no-ops each tick). Even an enabled rule today can only act on the live-wired signals (per-side temp/level, water.low); biometric/ambient/enum read `undefined`→skip by design. Every action is gated by manual-override hold, dry-run, and the kill-switch. ### Deferred to P2 (sleepypod-core-69) Engine handles numeric signals only, so the builder catalog is the numeric/backtestable subset. Enum/bool signals (sleep stage, occupancy) wait on their source wiring. ## Test plan - `pnpm tsc` clean, `pnpm lint` clean, `pnpm next build` clean. - Vitest: 1922 pass (+22 new); round-trip builder mapper, backtest replay, engine tick/safety covered. - Manual: deploy to pod 192.168.1.88; confirm BottomNav shows no Autopilot tab; confirm `/debug` Autopilot panel renders live engine state; deep-link `/autopilot` loads the builder. Closes sleepypod-core-66 (P0+P1). P2 tracked in sleepypod-core-69. <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update worktree-diy-autopilot ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/worktree-diy-autopilot/scripts/install \ | sudo bash -s -- --branch worktree-diy-autopilot ``` 🎯 **Pin to this exact build** ([run 27108297477](https://github.com/sleepypod/core/actions/runs/27108297477) · `c48a38d`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/c48a38d28dbffffa14c1db146261e44cf7775675/scripts/install \ | sudo bash -s -- \ --branch worktree-diy-autopilot \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27108297477/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27108297477/artifacts/7469107386) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features * **Autopilot Console**: Introduced a reactive automation engine allowing users to create, manage, and test automation rules with a structured WHEN/IF/THEN interface. * **Rule Backtesting**: Added interactive backtest preview showing how automation rules would behave against historical sensor data. * **Automation Monitoring**: Added status panel displaying active rules, execution history, fires-today counts, and recent run audit logs. * **Safety Controls**: Implemented global kill-switch, dry-run mode for testing, cooldown gating, and anti-thrash protections. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
…encies (#638) This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@formatjs/intl-localematcher](https://redirect.github.com/formatjs/formatjs) | [`0.8.9` → `0.8.10`](https://renovatebot.com/diffs/npm/@formatjs%2fintl-localematcher/0.8.9/0.8.10) |  |  | | [@tanstack/react-query](https://tanstack.com/query) ([source](https://redirect.github.com/TanStack/query/tree/HEAD/packages/react-query)) | [`5.100.14` → `5.101.0`](https://renovatebot.com/diffs/npm/@tanstack%2freact-query/5.100.14/5.101.0) |  |  | | [@types/react](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)) | [`19.2.15` → `19.2.16`](https://renovatebot.com/diffs/npm/@types%2freact/19.2.15/19.2.16) |  |  | | [@vitest/coverage-v8](https://vitest.dev/guide/coverage) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8)) | [`4.1.7` → `4.1.8`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-v8/4.1.7/4.1.8) |  |  | | [@xyflow/react](https://reactflow.dev) ([source](https://redirect.github.com/xyflow/xyflow/tree/HEAD/packages/react)) | [`12.10.2` → `12.11.0`](https://renovatebot.com/diffs/npm/@xyflow%2freact/12.10.2/12.11.0) |  |  | | [eslint-config-next](https://nextjs.org/docs/app/api-reference/config/eslint) ([source](https://redirect.github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next)) | [`16.2.6` → `16.2.7`](https://renovatebot.com/diffs/npm/eslint-config-next/16.2.6/16.2.7) |  |  | | [next](https://nextjs.org) ([source](https://redirect.github.com/vercel/next.js)) | [`16.2.6` → `16.2.7`](https://renovatebot.com/diffs/npm/next/16.2.6/16.2.7) |  |  | | [react](https://react.dev/) ([source](https://redirect.github.com/facebook/react/tree/HEAD/packages/react)) | [`19.2.6` → `19.2.7`](https://renovatebot.com/diffs/npm/react/19.2.6/19.2.7) |  |  | | [react-dom](https://react.dev/) ([source](https://redirect.github.com/facebook/react/tree/HEAD/packages/react-dom)) | [`19.2.6` → `19.2.7`](https://renovatebot.com/diffs/npm/react-dom/19.2.6/19.2.7) |  |  | | [shadcn](https://redirect.github.com/shadcn-ui/ui) ([source](https://redirect.github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn)) | [`4.8.2` → `4.10.0`](https://renovatebot.com/diffs/npm/shadcn/4.8.2/4.10.0) |  |  | | [tsx](https://tsx.hirok.io) ([source](https://redirect.github.com/privatenumber/tsx)) | [`4.22.3` → `4.22.4`](https://renovatebot.com/diffs/npm/tsx/4.22.3/4.22.4) |  |  | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | [`8.60.0` → `8.60.1`](https://renovatebot.com/diffs/npm/typescript-eslint/8.60.0/8.60.1) |  |  | | [vitest](https://vitest.dev) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`4.1.7` → `4.1.8`](https://renovatebot.com/diffs/npm/vitest/4.1.7/4.1.8) |  |  | --- ### Release Notes <details> <summary>formatjs/formatjs (@​formatjs/intl-localematcher)</summary> ### [`v0.8.10`](https://redirect.github.com/formatjs/formatjs/releases/tag/%40formatjs/intl-localematcher%400.8.10): @​formatjs/intl-localematcher: 0.8.10 [Compare Source](https://redirect.github.com/formatjs/formatjs/compare/@formatjs/intl-localematcher@0.8.9...@formatjs/intl-localematcher@0.8.10) #### 0.8.10 (2026-06-03) #### What's Changed - build: dispatch release workflow for npm publishing by [@​longlho](https://redirect.github.com/longlho) in [#​6677](https://redirect.github.com/formatjs/formatjs/pull/6677) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260521.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6679](https://redirect.github.com/formatjs/formatjs/pull/6679) - chore(deps): update dependency vite to v8.0.14 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6680](https://redirect.github.com/formatjs/formatjs/pull/6680) - chore(deps): update dependency ts-jest to v29.4.11 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6682](https://redirect.github.com/formatjs/formatjs/pull/6682) - chore(deps): update dependency webpack to v5.107.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6683](https://redirect.github.com/formatjs/formatjs/pull/6683) - chore(deps): update pnpm to v11.2.2 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6685](https://redirect.github.com/formatjs/formatjs/pull/6685) - chore(deps): update rust crate serde\_json to v1.0.150 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6686](https://redirect.github.com/formatjs/formatjs/pull/6686) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260522.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6687](https://redirect.github.com/formatjs/formatjs/pull/6687) - chore: keep gazelle idempotent by [@​longlho](https://redirect.github.com/longlho) in [#​6689](https://redirect.github.com/formatjs/formatjs/pull/6689) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260523.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6690](https://redirect.github.com/formatjs/formatjs/pull/6690) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260524.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6691](https://redirect.github.com/formatjs/formatjs/pull/6691) - chore(deps): update pnpm to v11.3.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6692](https://redirect.github.com/formatjs/formatjs/pull/6692) - chore(deps): update codescythe to 0.6.1 by [@​longlho](https://redirect.github.com/longlho) in [#​6693](https://redirect.github.com/formatjs/formatjs/pull/6693) - fix(formatjs\_cli): support id interpolation hash algorithms by [@​longlho](https://redirect.github.com/longlho) in [#​6695](https://redirect.github.com/formatjs/formatjs/pull/6695) - chore(deps): update babel monorepo to v7.29.7 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6696](https://redirect.github.com/formatjs/formatjs/pull/6696) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260526.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6697](https://redirect.github.com/formatjs/formatjs/pull/6697) - chore(deps): update dependency oxc-transform to ^0.133.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6699](https://redirect.github.com/formatjs/formatjs/pull/6699) - chore(deps): update dependency webpack to v5.107.2 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6698](https://redirect.github.com/formatjs/formatjs/pull/6698) - chore(deps): update dependency oxfmt to ^0.52.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6702](https://redirect.github.com/formatjs/formatjs/pull/6702) - chore(deps): update dependency oxlint to v1.67.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6703](https://redirect.github.com/formatjs/formatjs/pull/6703) - chore(deps): update typescript-eslint monorepo to v8.60.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6704](https://redirect.github.com/formatjs/formatjs/pull/6704) - fix(deps): update dependency oxc-parser to ^0.133.0 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6705](https://redirect.github.com/formatjs/formatjs/pull/6705) - fix(formatjs\_cli): speed up skipped message diagnostics by [@​longlho](https://redirect.github.com/longlho) in [#​6709](https://redirect.github.com/formatjs/formatjs/pull/6709) - fix(deps): update rust crate oxc\_data\_structures to 0.133 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6713](https://redirect.github.com/formatjs/formatjs/pull/6713) - fix(deps): update rust OXC crates to 0.133 by [@​longlho](https://redirect.github.com/longlho) in [#​6714](https://redirect.github.com/formatjs/formatjs/pull/6714) - build: verify generated package manifests from bazel deps by [@​longlho](https://redirect.github.com/longlho) in [#​6701](https://redirect.github.com/formatjs/formatjs/pull/6701) - build: generate package manifests by [@​longlho](https://redirect.github.com/longlho) in [#​6718](https://redirect.github.com/formatjs/formatjs/pull/6718) - chore(deps): update dependency [@​rescripts/cli](https://redirect.github.com/rescripts/cli) to v0.0.16 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6716](https://redirect.github.com/formatjs/formatjs/pull/6716) - chore(deps): update dependency react-scripts to v5.0.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6719](https://redirect.github.com/formatjs/formatjs/pull/6719) - build: align release-please with generated package manifests by [@​longlho](https://redirect.github.com/longlho) in [#​6720](https://redirect.github.com/formatjs/formatjs/pull/6720) - chore(deps): update dependency [@​rescripts/rescript-env](https://redirect.github.com/rescripts/rescript-env) to v0.0.14 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6717](https://redirect.github.com/formatjs/formatjs/pull/6717) - chore(deps): update dependency [@​typescript/native-preview](https://redirect.github.com/typescript/native-preview) to v7.0.0-dev.20260527.1 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6724](https://redirect.github.com/formatjs/formatjs/pull/6724) - build: add bazel release-please workspace plugin by [@​longlho](https://redirect.github.com/longlho) in [#​6723](https://redirect.github.com/formatjs/formatjs/pull/6723) - chore(deps): update dependency rolldown to v1.0.3 by [@​renovate](https://redirect.github.com/renovate)\[bot] in [#​6725](https://redirect.github.com/formatjs/formatjs/pull/6725) **Full Changelog**: <https://github.com/formatjs/formatjs/compare/@formatjs/intl-localematcher@0.8.9...@​formatjs/intl-localematcher@0.8.10> ##### Dependencies - The following workspace dependencies were updated - dependencies - [@​formatjs/fast-memoize](https://redirect.github.com/formatjs/fast-memoize) bumped to 3.1.6 </details> <details> <summary>TanStack/query (@​tanstack/react-query)</summary> ### [`v5.101.0`](https://redirect.github.com/TanStack/query/blob/HEAD/packages/react-query/CHANGELOG.md#51010) [Compare Source](https://redirect.github.com/TanStack/query/compare/@tanstack/react-query@5.100.14...@tanstack/react-query@5.101.0) ##### Patch Changes - Updated dependencies \[]: - [@​tanstack/query-core](https://redirect.github.com/tanstack/query-core)@​5.101.0 </details> <details> <summary>vitest-dev/vitest (@​vitest/coverage-v8)</summary> ### [`v4.1.8`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.8) [Compare Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8) ##### 🐞 Bug Fixes - **browser**: - Disable client `cdp` API when `allowWrite/allowExec: false` \[backport to v4] - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) and **Codex** in [#​10450](https://redirect.github.com/vitest-dev/vitest/issues/10450) [<samp>(e4067)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/e4067b3b1) - Remove orphaned Playwright route when same module is mocked via multiple ids \[backport to v4] - by [@​toxik](https://redirect.github.com/toxik) and [@​Zelys-DFKH](https://redirect.github.com/Zelys-DFKH) in [#​10474](https://redirect.github.com/vitest-dev/vitest/issues/10474) [<samp>(675b4)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/675b4343f) ##### [View changes on GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8) </details> <details> <summary>xyflow/xyflow (@​xyflow/react)</summary> ### [`v12.11.0`](https://redirect.github.com/xyflow/xyflow/blob/HEAD/packages/react/CHANGELOG.md#12110) [Compare Source](https://redirect.github.com/xyflow/xyflow/compare/@xyflow/react@12.10.2...@xyflow/react@12.11.0) ##### Minor Changes - [#​5677](https://redirect.github.com/xyflow/xyflow/pull/5677) [`e6661de`](https://redirect.github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62) - Add `autoPanOnSelection` to auto-pan when user drags a selection close to the edge of the viewport. ##### Patch Changes - [#​5791](https://redirect.github.com/xyflow/xyflow/pull/5791) [`732c8eb`](https://redirect.github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c) - Adds a type error when `handleId` is used without `handleType` in `useNodeConnections` - [#​5793](https://redirect.github.com/xyflow/xyflow/pull/5793) [`c5c853d`](https://redirect.github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb) - Dev Warnings now use library-specific messaging with the correct documentation links. - [#​5776](https://redirect.github.com/xyflow/xyflow/pull/5776) [`0441e9f`](https://redirect.github.com/xyflow/xyflow/commit/0441e9f9471380b5ba057fc0a6a8cbdc6ff5ed7b) - Export `NodeHandle` type - [#​5755](https://redirect.github.com/xyflow/xyflow/pull/5755) [`88737f9`](https://redirect.github.com/xyflow/xyflow/commit/88737f9713f3a6f99c6448e02b6518c7aeedae28) - Add `@types/react` and `@types/react-dom` as optional peer dependencies to prevent issues with pnpm strict mode (`hoist: false`) - [#​5105](https://redirect.github.com/xyflow/xyflow/pull/5105) [`076ad38`](https://redirect.github.com/xyflow/xyflow/commit/076ad3893725f654641f7b8c39e7a4e7935eb702) - Fix type for event passed to onNodeDrag - [#​5784](https://redirect.github.com/xyflow/xyflow/pull/5784) [`7055140`](https://redirect.github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472) - Fix node resizing possible beyond absolute extents - [#​5769](https://redirect.github.com/xyflow/xyflow/pull/5769) [`ad4d547`](https://redirect.github.com/xyflow/xyflow/commit/ad4d547724a1c2debf8eb7c6e117aabbfd601934) - Use `useEffect` for StoreUpdater to restore previous behaviour - Updated dependencies \[[`732c8eb`](https://redirect.github.com/xyflow/xyflow/commit/732c8eb8d5ff86ab1c057588724221e9b3b8553c), [`c5c853d`](https://redirect.github.com/xyflow/xyflow/commit/c5c853d4a2f537caaea725ab9e7bd480e24b86fb), [`e6661de`](https://redirect.github.com/xyflow/xyflow/commit/e6661de531212f9a209dba17dd63fbbd4ee16f62), [`737194d`](https://redirect.github.com/xyflow/xyflow/commit/737194d571894dd84ce7cbab02f2a4d0b779d018), [`40660cd`](https://redirect.github.com/xyflow/xyflow/commit/40660cdb054fb1a110799a3ad7cecbf51371727f), [`4806e7c`](https://redirect.github.com/xyflow/xyflow/commit/4806e7cde6d69cd7570098ecca86523666b80175), [`7055140`](https://redirect.github.com/xyflow/xyflow/commit/7055140e66e4aebb08ce512bdff34add7e115472)]: - [@​xyflow/system](https://redirect.github.com/xyflow/system)@​0.0.77 </details> <details> <summary>vercel/next.js (eslint-config-next)</summary> ### [`v16.2.7`](https://redirect.github.com/vercel/next.js/compare/v16.2.6...411c455dcdec630b9e2e83d24e27b0f9e05927b6) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.6...v16.2.7) </details> <details> <summary>vercel/next.js (next)</summary> ### [`v16.2.7`](https://redirect.github.com/vercel/next.js/compare/v16.2.6...411c455dcdec630b9e2e83d24e27b0f9e05927b6) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.6...v16.2.7) </details> <details> <summary>facebook/react (react)</summary> ### [`v19.2.7`](https://redirect.github.com/facebook/react/compare/v19.2.6...6117d7cca4906492c51fe6a03381e35adfd86e7d) [Compare Source](https://redirect.github.com/facebook/react/compare/v19.2.6...v19.2.7) </details> <details> <summary>facebook/react (react-dom)</summary> ### [`v19.2.7`](https://redirect.github.com/facebook/react/compare/v19.2.6...6117d7cca4906492c51fe6a03381e35adfd86e7d) [Compare Source](https://redirect.github.com/facebook/react/compare/v19.2.6...v19.2.7) </details> <details> <summary>shadcn-ui/ui (shadcn)</summary> ### [`v4.10.0`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#4100) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.9.0...shadcn@4.10.0) ##### Minor Changes - [#​10842](https://redirect.github.com/shadcn-ui/ui/pull/10842) [`7c63c467361dee9e20631b2999040912439b35d4`](https://redirect.github.com/shadcn-ui/ui/commit/7c63c467361dee9e20631b2999040912439b35d4) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - add support for GitHub registries ### [`v4.9.0`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#490) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.8.3...shadcn@4.9.0) ##### Minor Changes - [#​10834](https://redirect.github.com/shadcn-ui/ui/pull/10834) [`8e2d2d1439f54260aa0c51747261c220334ec641`](https://redirect.github.com/shadcn-ui/ui/commit/8e2d2d1439f54260aa0c51747261c220334ec641) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - add npx shadcn eject ### [`v4.8.3`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#483) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.8.2...shadcn@4.8.3) ##### Patch Changes - [#​10659](https://redirect.github.com/shadcn-ui/ui/pull/10659) [`07900769d91b09def00e68179bcb7a821f59b954`](https://redirect.github.com/shadcn-ui/ui/commit/07900769d91b09def00e68179bcb7a821f59b954) Thanks [@​raashish1601](https://redirect.github.com/raashish1601)! - update template handling - [#​10495](https://redirect.github.com/shadcn-ui/ui/pull/10495) [`360e8a19c3ee13ac78b656027462007c8bdaa6d5`](https://redirect.github.com/shadcn-ui/ui/commit/360e8a19c3ee13ac78b656027462007c8bdaa6d5) Thanks [@​artemxknpv](https://redirect.github.com/artemxknpv)! - Preserve quotes in className literals when applying RTL transforms. </details> <details> <summary>privatenumber/tsx (tsx)</summary> ### [`v4.22.4`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.22.4) [Compare Source](https://redirect.github.com/privatenumber/tsx/compare/v4.22.3...v4.22.4) ##### Bug Fixes - resolve CommonJS directory requires inside dependencies ([#​803](https://redirect.github.com/privatenumber/tsx/issues/803)) ([1ce8463](https://redirect.github.com/privatenumber/tsx/commit/1ce846335b7c445a3328c7d27f06424949356d97)) *** This release is also available on: - [npm package (@​latest dist-tag)](https://www.npmjs.com/package/tsx/v/4.22.4) </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.60.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8601-2026-06-01) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.60.0...v8.60.1) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.60.1) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjIwOS40IiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsImZpeC1wYXRjaCIsIm5vbi1tYWpvciJdfQ==--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/all-minor-patch ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/all-minor-patch/scripts/install \ | sudo bash -s -- --branch renovate/all-minor-patch ``` 🎯 **Pin to this exact build** ([run 27120913376](https://github.com/sleepypod/core/actions/runs/27120913376) · `a46cb7c`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/a46cb7c93262bad79ee16d21d071c56b9b9eead6/scripts/install \ | sudo bash -s -- \ --branch renovate/all-minor-patch \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27120913376/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27120913376/artifacts/7473360526) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…+ runaway durations (#639) ## Why Pod 88 (Pod 5 J55) field debug 2026-06-10: `sleep_records` degenerated — one overnight presence span fragmented into dozens of <15min sessions with **66-109 bogus bed-exits**, and durations ran away to **2736/2850min (45-47h)**. Raw vitals/movement/bed_temp streams were intact, so this was a detection bug, not data loss. Root cause in `modules/sleep-detector/main.py` `_update()`: raw per-sample `capSense` presence drove `_exit_count` and session/interval transitions directly. At 2 Hz a single noisy dropout (sub-second) immediately counted a bed-exit and split the session; the constant flapping back to present kept resetting `_last_present_ts`, so `ts - _last_present_ts >= ABSENCE_TIMEOUT_S` never fired and sessions never closed. ## What - **Debounce / hysteresis** (`PRESENCE_DEBOUNCE_S = 30s`): a present↔absent flip is only committed after the differing raw state persists for the dwell window. Brief dropouts are cancelled — they no longer increment `times_exited_bed` or split the session. `_apply_debounce()` records the true transition timestamp so interval edges and the session entry time stay accurate. Dwell `< ABSENCE_TIMEOUT_S` so a real exit still closes the session. - **Runaway cap** (`MAX_SESSION_S = 16h`): belt-and-suspenders force-close so no `sleep_record` can persist a multi-day `sleep_duration_seconds`. ## Test plan `modules/sleep-detector/test_main.py` — `TestPresenceDebounce`: - `test_brief_dropout_does_not_increment_exit_or_split_session` — 50 sub-debounce dropouts across one span → exactly **1 record, 1 exit**. - `test_sustained_absence_counts_single_exit` — a genuine sustained absence → 1 exit. - `test_runaway_session_is_capped` — presence past `MAX_SESSION_S` → no row exceeds the cap. ``` uv run --with pytest pytest -q test_main.py # 23 passed ``` ## Follow-up (manual, pod 88) Existing garbage rows (`sleep_records` ~id 300-316) predate this fix and live in the pod's `biometrics.db`; they need a one-time cleanup over SSH (not done here to avoid mutating live data unprompted): ```sql -- inspect first SELECT id, sleep_duration_seconds/60 AS min, times_exited_bed FROM sleep_records WHERE id BETWEEN 300 AND 316; -- then delete the fragments/runaways DELETE FROM sleep_records WHERE sleep_duration_seconds > 16*3600 OR times_exited_bed > 20; ``` Separate minor (not addressed): pod clock is UTC, so nightly dates label as the next UTC day. Closes sleepypod-core-71. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Presence debouncing with 30-second dwell time applied to bed occupancy detection * Session duration capped at maximum 16 hours with automatic closure of long-running sessions * Session timestamps now aligned to actual state transition times * **Tests** * Added comprehensive test coverage for presence debounce behavior and session duration limits <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/sleep-detector-presence-debounce ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/sleep-detector-presence-debounce/scripts/install \ | sudo bash -s -- --branch fix/sleep-detector-presence-debounce ``` 🎯 **Pin to this exact build** ([run 27320090177](https://github.com/sleepypod/core/actions/runs/27320090177) · `332570f`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/332570fed0a82a1c1f9172125e7b69c4f1eb536b/scripts/install \ | sudo bash -s -- \ --branch fix/sleep-detector-presence-debounce \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27320090177/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27320090177/artifacts/7553491736) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
## Why The weekly mutation run ([run 26679315747](https://github.com/sleepypod/core/actions/runs/26679315747)) raises Node.js 20 deprecation annotations on two jobs — `summarize` and `record-baseline`: > Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: `actions/github-script@v7`. Actions will be forced to run with Node.js 24 by default starting June 16th, 2026. Node.js 20 will be removed from the runner on September 16th, 2026. `actions/github-script@v7` is the only action in the repo still pinned to a Node 20 release; every other action (`checkout@v6`, `setup-node@v6`, `download-artifact@v8`, `upload-artifact@v7`) is already on a Node 24 major. ## What Bump all three `actions/github-script@v7` usages in `.github/workflows/mutation.yml` to `@v9` (Node 24): - `Comment on PR` step (PR-labeled runs) - `Update pinned tracking issue` step (`summarize` job) - `Compute aggregated row` step (`record-baseline` job) ### Why v9 is safe for these scripts v9's breaking changes are limited to: - `require('@actions/github')` no longer works in-script - `getOctokit` is now an injected parameter (can't be `const`/`let` redeclared) None of the three scripts touch either — they only use `require('fs')`/`require('path')` (Node built-ins) plus the standard `github.rest.*`, `context`, and `core` globals, all unchanged in v9. ## Test plan - [x] `git diff` confirms the only change is `v7` → `v9` on the three `uses:` lines; indentation and YAML structure unchanged. - [x] Confirmed 3 `@v9` / 0 `@v7` remaining in the workflow. - [ ] After merge, the next scheduled (or manually dispatched) mutation run should no longer emit the Node.js 20 deprecation annotation on the `summarize` and `record-baseline` jobs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update ci/mutation-github-script-node24 ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/ci/mutation-github-script-node24/scripts/install \ | sudo bash -s -- --branch ci/mutation-github-script-node24 ``` 🎯 **Pin to this exact build** ([run 26691633977](https://github.com/sleepypod/core/actions/runs/26691633977) · `a15deda`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/a15deda978d696b460ff96539ffe49dc577aabc2/scripts/install \ | sudo bash -s -- \ --branch ci/mutation-github-script-node24 \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/26691633977/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/26691633977/artifacts/7310401530) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…d assertions (#626) ## Why `src/streaming/mqttBridge.ts` is the single largest source of surviving mutants in the weekly mutation run — **220 surviving** ([issue #591](#591), [run 26679315747](https://github.com/sleepypod/core/actions/runs/26679315747)), roughly 8.5% of the repo's 2580 survivors. The existing discovery test only asserts that *some* `homeassistant/...` topic is published and pins a couple of fields; it never checks the config payload bodies. As a result every `StringLiteral` / `ObjectLiteral` / `ArrayDeclaration` / `ConditionalExpression` / `EqualityOperator` mutant inside the HA discovery builders (`haDevice`, `climate`, `sensor`, and the binary-sensor literals) and their call sites survives. ## What Add a `mqttBridge — HA discovery payload content` describe block that drives the bridge with a fixed `MQTT_DEVICE_ID` + topic prefix (so every payload is deterministic), captures all published `homeassistant/...` config messages, and `toEqual`-asserts the **complete** payload for each entity: - left/right `climate` - `water_level`, `ambient_temperature`, `ambient_humidity` sensors - per-side `pump_*_rpm` / `pump_*_loop_temp` sensors - per-side `pump_*_stall` / `pump_*_clog` binary sensors - per-side `heart_rate` / `breathing_rate` / `hrv` biometric sensors - the shared `device` identity block on every config A full `toEqual` on each payload fails when any string, template, unit, device-class, mode list, or the `side === 'left'` label conditional is mutated — which is exactly what kills the surviving mutants. Scope is deliberately this one file (the biggest cluster) for a focused PR; the remaining survivors across other files are left for follow-ups. ## Test plan - [x] `npx vitest run src/streaming/tests/mqttBridge.test.ts` → **87 passed** (was 76; +11 new). - [x] Empirically verified the assertions kill mutants: mutating `payload_available: 'online'` → `''` in the `climate` builder fails exactly the two climate payload tests; source restored after. - [x] `npx eslint src/streaming/tests/mqttBridge.test.ts` clean. - [x] `npx tsc --noEmit` clean (exit 0, 0 errors). - [ ] Confirm mutation-score lift on the `streaming` shard on the next labeled / scheduled mutation run. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update test/mutation-mqtt-discovery ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/test/mutation-mqtt-discovery/scripts/install \ | sudo bash -s -- --branch test/mutation-mqtt-discovery ``` 🎯 **Pin to this exact build** ([run 26691824606](https://github.com/sleepypod/core/actions/runs/26691824606) · `ba39c3d`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/ba39c3d5ee088484bc93d025db9ab6b5726d48fd/scripts/install \ | sudo bash -s -- \ --branch test/mutation-mqtt-discovery \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/26691824606/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/26691824606/artifacts/7310460917) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…#636) ## Why Field report (and reproduced live on a pod): a side **"gets set to 83 when it's supposed to be off."** Root cause: the hardware has **no true off state**. Powering a side down parks it at heat **level 0** (neutral). `responseParser` synthesizes the temperature straight from the level via `levelToFahrenheit(0)` = `Math.round(82.5)` = **83**. Because `current/targetTemperature` were derived from the level rather than a real sensor, every consumer of `/device/status` — TempScreen, HomeKit, MQTT, automations — saw a target of **83°F** on a side the firmware reports as off (`targetLevel: 0`). Verified live against the pod at `.88` before the fix: ``` $ curl http://192.168.1.88:3000/api/device/status left: targetLevel: 0 → targetTemperature: 83 ❌ right: targetLevel: 0 → targetTemperature: 83 ❌ ``` ## What Fix at the **source** so the phantom can't reach any consumer: `parseDeviceStatus` now reports `null` for a level-0 side instead of `levelToFahrenheit(0)`. Level 0 already means "off" everywhere else in the codebase (`targetLevel !== 0` = powered), so this just makes the temperature honest about it. `SideStatus.current/targetTemperature` become `number | null`; consumers updated to handle null: - **`responseParser.ts`** — `tempForLevel(level)` → `null` when `level === 0` (both sides, current + target) - **`device.getStatus`** — output schema fields nullable; `convertTemp` passes `null` through - **HomeKit** (`thermostat.ts`, `sideController.ts`) — fall back to neutral, since HomeKit characteristics require a number - **`automation/signals.ts`** — an off side leaves the temp signal **absent**, so rules don't fire against a phantom neutral - **`SideSelector`** — prop widened (the UI was already null-safe via `?? 80`, and gates display on `targetLevel !== 0`) Also folded in (same bug surface, found via review/verification): - **`health.thermal`** — reports `null` for an off side rather than passing through the stored 83 - **`ThermalTrendChart`** — guards an all-null `temps` window (now reachable for an off side) so `Math.min(...[])` can't hand the Y-axis an `Infinity` domain - **`health.ts`** — corrected a misleading `MIN_FLOW_RPM` comment (it's a conservative dead-pump floor, independent of the configurable `pump_stall_rpm_threshold`, default 500) ## Test plan - `npx tsc --noEmit` clean; full affected suites green (parser, device, homekit, mqtt, automation, streaming, diagnostics, health). - New regressions: `responseParser` asserts **null** at level 0 (was `83`); `device.getStatus` asserts an off side passes `null` end-to-end; `health.thermal` and `ThermalTrendChart` guard tests. - **Manual (post-deploy on `.88`):** `curl http://192.168.1.88:3000/api/device/status` shows `targetTemperature: null` for the off sides, with `targetLevel: 0` unchanged. TempScreen/HomeKit show the side as **off** rather than 83°F. <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update feat/thermal-debug-view ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/thermal-debug-view/scripts/install \ | sudo bash -s -- --branch feat/thermal-debug-view ``` 🎯 **Pin to this exact build** ([run 27321593892](https://github.com/sleepypod/core/actions/runs/27321593892) · `847bbf2`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/847bbf29d265e8dc91d516a0f218131af5f3d63e/scripts/install \ | sudo bash -s -- \ --branch feat/thermal-debug-view \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27321593892/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27321593892/artifacts/7554027923) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added thermal trend chart component for visualizing temperature trends over time * Added thermal diagnostics endpoint providing comprehensive system status including pump performance and temperature readings * **Bug Fixes** * Fixed temperature reporting for inactive states to correctly return null instead of phantom readings * **Tests** * Added test coverage for thermal trending and diagnostics functionality with edge cases <!-- end of auto-generated comment: release notes by coderabbit.ai -->
… assertions (#641) ## Why Issue #591 (weekly mutation baseline): `src/db/schema.ts` is the top surviving file at **208 surviving mutants**. The existing `migrations.test.ts` runs *pre-generated SQL* under `src/db/migrations/`, so it never exercises the drizzle schema objects — mutating a column name to `""`, flipping a `.default(false)` to `true`, or emptying an index array (`}, t => []`) leaves the static SQL untouched and nothing fails. ## What Add `src/db/tests/schema.test.ts` that reads the schema objects directly via `getTableConfig` and pins, per table: - table name, - the full ordered column list with `notNull` + a default descriptor (literal value / `sql` expression / `$defaultFn` / none), - every index (name, unique flag, columns), - plus the exact set of exported tables. One `toEqual` per table kills the StringLiteral (table/column/default/index names), BooleanLiteral (default flips), and ArrayDeclaration (`→ []`) mutators together. No source changes — the schema is correct as-is. Mirrors the test-only approach of #626/#635. ## Test plan - [x] `npx vitest run src/db/tests/schema.test.ts` → 12/12 pass. - [x] Applied representative mutations (string default → `""`, `.default(false)` → `true`, index array → `[]`) and confirmed the test **fails** under each, then reverted — mutants genuinely killed, not merely covered. - [x] Pre-existing `retention.test.ts` failures confirmed unrelated (fail on clean tree via stash). <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update test/db-schema-mutants ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/test/db-schema-mutants/scripts/install \ | sudo bash -s -- --branch test/db-schema-mutants ``` 🎯 **Pin to this exact build** ([run 27480566648](https://github.com/sleepypod/core/actions/runs/27480566648) · `d96aa1d`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/d96aa1dbbe021526ab64d3ceecbbe76dfce3418d/scripts/install \ | sudo bash -s -- \ --branch test/db-schema-mutants \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27480566648/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27480566648/artifacts/7614941911) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
## Why
In the Autopilot rule editor, the dry-run notice was tucked at the
bottom of the left-hand form column, below the THEN card — easy to miss,
and far from the preview/backtest the user is actually reading while in
dry-run.
Per the Autopilot.html design handoff, the notice should sit above the
right column's cards so it caps the live preview and reads as context
for "here's what this rule *would* do."
## What
Move the `rule.mode === 'dryrun'` notice from the bottom of the left
form column to the top of the right column, above SentencePreview and
the BacktestPanel card. No styling or logic change — same condition,
same markup, new position.
## Test plan
- `tsc` clean
- `eslint src/components/Autopilot/RuleEditor.tsx` clean
- Manual: open a rule editor, toggle Dry-run — notice now appears at the
top of the right pane above the "Reads as" card; toggle to Active —
notice disappears.
<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
Hello fellow agent / curious human! Anything between the
sleepypod:install-start and sleepypod:install-end markers
gets overwritten on the next CI run. Want to change what's
here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>
Pick the snippet that matches your pod. **Already-installed pods can't
use the curl bootstraps below** — sleepypod's egress firewall DROPs
github.com, and the script that knows how to unblock WAN is the very
file curl is trying to fetch. Use `sp-update` instead; it's on disk and
opens WAN as its first step.
🔄 **Already on a sleepypod** (most common — review a PR on a running
pod):
```bash
sudo sp-update feat/autopilot-design
```
🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/autopilot-design/scripts/install \
| sudo bash -s -- --branch feat/autopilot-design
```
🎯 **Pin to this exact build** ([run
27516922675](https://github.com/sleepypod/core/actions/runs/27516922675)
· `fcf0a90`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fcf0a906b5e54285c4c594de6d29de08770316b5/scripts/install \
| sudo bash -s -- \
--branch feat/autopilot-design \
--artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27516922675/sleepypod-core.zip'
```
🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27516922675/artifacts/7626634849)
· self-destructs in 30 days 💥
</details>
<!-- sleepypod:install-end -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Code formatting and layout adjustments with no functional changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Why
The Automations right pane shows the capacitive presence matrix
(bed-pressure zones) only as a **live** view — the raw ~2 Hz `capSense2`
frames are never persisted, so the spatial zone replay and `cap.*`
backtest can't reach past nights. This is the foundation for lifting the
night/date selector to pane scope and adding a standalone "Last Night"
historical view (follow-up PRs).
## What
Add a downsampling writer that aggregates the live capacitive stream
into **one row per side per ~5s window** in a new `cap_sense_frames`
table, pruned to **~48h** (the bulkiest sensor stream — only the last
night or two is ever replayed).
- New `cap_sense_frames` table (`zones` head/torso/legs means, scalar
`max/mean/spread`, modal `peakZone`, `frameCount`).
- `streaming/capFramePersistence.ts`: ts-keyed windowing (correct under
stream catch-up), best-effort writes (a DB failure never disrupts the
live stream), throttled 48h prune.
- Wired into the `piezoStream` broadcast loop alongside the existing
live snapshot; windows reset on RAW-file switch.
- Extracted `reduceCap` + new `zoneTriple` into dependency-free
`automation/capReduce.ts` to avoid a `piezoStream ↔ signals.biometrics`
import cycle.
Scalar (Pod 3) sensors persist `zones: null` — no spatial resolution to
replay, but `cap.*` scalars still backtest.
## Scope / non-goals
This PR only **writes** the frames. Reading them into the backtest
series and the UI (pane-level night picker, standalone history view) are
follow-up PRs.
## Test plan
- `vitest run src/automation/tests/capReduce.test.ts
src/streaming/tests/capFramePersistence.test.ts` — new unit coverage for
`zoneTriple` and the window state machine (accumulate within window,
rollover past the 5s boundary, scalar→null zones, per-side independence,
reset).
- `vitest run src/automation/tests/signals.biometrics.test.ts
src/streaming/tests/piezoStream.test.ts src/lib/tests/occupancy.test.ts`
— existing suites green after the `reduceCap` extraction.
- `tsc` clean; `eslint` clean on changed files.
- `pnpm db:biometrics:generate` → migration `0010_fixed_silvermane.sql`.
Manual: on a pod, confirm `cap_sense_frames` accrues ~1 row/side/5s
while occupied and that rows older than 48h are pruned.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added historical storage and analysis of capacitive presence sensor
readings with spatial zone tracking
* Automatic data retention and cleanup for storage optimization
* **Refactor**
* Reorganized internal sensor data processing utilities
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- sleepypod:install-start -->
<!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block.
Hello fellow agent / curious human! Anything between the
sleepypod:install-start and sleepypod:install-end markers
gets overwritten on the next CI run. Want to change what's
here? Edit .github/workflows/build.yml instead. 💤 -->
<details open>
<summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary>
Pick the snippet that matches your pod. **Already-installed pods can't
use the curl bootstraps below** — sleepypod's egress firewall DROPs
github.com, and the script that knows how to unblock WAN is the very
file curl is trying to fetch. Use `sp-update` instead; it's on disk and
opens WAN as its first step.
🔄 **Already on a sleepypod** (most common — review a PR on a running
pod):
```bash
sudo sp-update feat/persist-cap-frames
```
🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every
push:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/persist-cap-frames/scripts/install \
| sudo bash -s -- --branch feat/persist-cap-frames
```
🎯 **Pin to this exact build** ([run
27516162063](https://github.com/sleepypod/core/actions/runs/27516162063)
· `34b060c`) — fresh-pod path, locked to one CI artifact for
reproducible review:
```bash
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/34b060c475e873eebcd6765f33607daae66029ae/scripts/install \
| sudo bash -s -- \
--branch feat/persist-cap-frames \
--artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27516162063/sleepypod-core.zip'
```
🧊 Artifact:
[`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27516162063/artifacts/7626417573)
· self-destructs in 30 days 💥
</details>
<!-- sleepypod:install-end -->
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`25.9.1` → `25.9.3`](https://renovatebot.com/diffs/npm/@types%2fnode/25.9.1/25.9.3) |  |  | | [@types/react](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)) | [`19.2.16` → `19.2.17`](https://renovatebot.com/diffs/npm/@types%2freact/19.2.16/19.2.17) |  |  | | [bonjour-service](https://redirect.github.com/onlxltd/bonjour-service) | [`1.4.0` → `1.4.1`](https://renovatebot.com/diffs/npm/bonjour-service/1.4.0/1.4.1) |  |  | | [eslint-config-next](https://nextjs.org/docs/app/api-reference/config/eslint) ([source](https://redirect.github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next)) | [`16.2.7` → `16.2.9`](https://renovatebot.com/diffs/npm/eslint-config-next/16.2.7/16.2.9) |  |  | | [next](https://nextjs.org) ([source](https://redirect.github.com/vercel/next.js)) | [`16.2.7` → `16.2.9`](https://renovatebot.com/diffs/npm/next/16.2.7/16.2.9) |  |  | | [pnpm](https://pnpm.io) ([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm)) | [`10.34.1` → `10.34.3`](https://renovatebot.com/diffs/npm/pnpm/10.34.1/10.34.3) |  |  | | [semantic-release](https://redirect.github.com/semantic-release/semantic-release) | [`25.0.3` → `25.0.5`](https://renovatebot.com/diffs/npm/semantic-release/25.0.3/25.0.5) |  |  | | [shadcn](https://redirect.github.com/shadcn-ui/ui) ([source](https://redirect.github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn)) | [`4.10.0` → `4.11.0`](https://renovatebot.com/diffs/npm/shadcn/4.10.0/4.11.0) |  |  | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | [`8.60.1` → `8.61.0`](https://renovatebot.com/diffs/npm/typescript-eslint/8.60.1/8.61.0) |  |  | --- ### Release Notes <details> <summary>onlxltd/bonjour-service (bonjour-service)</summary> ### [`v1.4.1`](https://redirect.github.com/onlxltd/bonjour-service/releases/tag/1.4.1) [Compare Source](https://redirect.github.com/onlxltd/bonjour-service/compare/1.4.0...1.4.1) #### What's Changed - Fix for imports by [@​mdidon](https://redirect.github.com/mdidon) in [#​80](https://redirect.github.com/onlxltd/bonjour-service/pull/80) - Addressed [#​79](https://redirect.github.com/onlxltd/bonjour-service/issues/79) raised by [@​andersk](https://redirect.github.com/andersk) **Full Changelog**: <onlxltd/bonjour-service@1.4.0...1.4.1> </details> <details> <summary>vercel/next.js (eslint-config-next)</summary> ### [`v16.2.9`](https://redirect.github.com/vercel/next.js/compare/v16.2.8...v16.2.9) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.8...v16.2.9) ### [`v16.2.8`](https://redirect.github.com/vercel/next.js/compare/v16.2.7...v16.2.8) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.7...v16.2.8) </details> <details> <summary>vercel/next.js (next)</summary> ### [`v16.2.9`](https://redirect.github.com/vercel/next.js/compare/v16.2.8...v16.2.9) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.8...v16.2.9) ### [`v16.2.8`](https://redirect.github.com/vercel/next.js/compare/v16.2.7...v16.2.8) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.7...v16.2.8) </details> <details> <summary>pnpm/pnpm (pnpm)</summary> ### [`v10.34.3`](https://redirect.github.com/pnpm/pnpm/compare/v10.34.2...v10.34.3) [Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v10.34.2...v10.34.3) ### [`v10.34.2`](https://redirect.github.com/pnpm/pnpm/compare/v10.34.1...v10.34.2) [Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v10.34.1...v10.34.2) </details> <details> <summary>semantic-release/semantic-release (semantic-release)</summary> ### [`v25.0.5`](https://redirect.github.com/semantic-release/semantic-release/releases/tag/v25.0.5) [Compare Source](https://redirect.github.com/semantic-release/semantic-release/compare/v25.0.4...v25.0.5) ##### Bug Fixes - **revert:** next ([#​4200](https://redirect.github.com/semantic-release/semantic-release/issues/4200)) ([db8ffaa](https://redirect.github.com/semantic-release/semantic-release/commit/db8ffaad90139532f30c0fcd955cf52ffdc1a267)) ### [`v25.0.4`](https://redirect.github.com/semantic-release/semantic-release/releases/tag/v25.0.4) [Compare Source](https://redirect.github.com/semantic-release/semantic-release/compare/v25.0.3...v25.0.4) ##### Bug Fixes - **code-quality:** add missing comma in context object for consistency ([493d6cd](https://redirect.github.com/semantic-release/semantic-release/commit/493d6cdaa1ed697427acea596d0d25eb53b462a2)) </details> <details> <summary>shadcn-ui/ui (shadcn)</summary> ### [`v4.11.0`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#4110) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.10.0...shadcn@4.11.0) ##### Minor Changes - [#​10886](https://redirect.github.com/shadcn-ui/ui/pull/10886) [`05eb2b968bdc769ad78df9628dc2260e1dec903c`](https://redirect.github.com/shadcn-ui/ui/commit/05eb2b968bdc769ad78df9628dc2260e1dec903c) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - improve search command ##### Patch Changes - [#​10851](https://redirect.github.com/shadcn-ui/ui/pull/10851) [`7dfd933102fdb881f8abd24fc1ef11a669682b94`](https://redirect.github.com/shadcn-ui/ui/commit/7dfd933102fdb881f8abd24fc1ef11a669682b94) Thanks [@​harshithasompura](https://redirect.github.com/harshithasompura)! - move msw to devDependencies </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.61.0`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8610-2026-06-08) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.60.1...v8.61.0) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.61.0) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTkuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIxOS4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsImZpeC1wYXRjaCIsIm5vbi1tYWpvciJdfQ==--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/all-minor-patch ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/all-minor-patch/scripts/install \ | sudo bash -s -- --branch renovate/all-minor-patch ``` 🎯 **Pin to this exact build** ([run 27521087530](https://github.com/sleepypod/core/actions/runs/27521087530) · `46384d7`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/46384d797a73a6dd7c27bdfb2e75b1ce6f1ff79a/scripts/install \ | sudo bash -s -- \ --branch renovate/all-minor-patch \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27521087530/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27521087530/artifacts/7628085280) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…642) ## Why Two UX problems in the Autopilot/Automations builder: 1. The edge-triggered **backtest chart** became unreadable at high event density (e.g. 7 fires + 70 suppressed). Every fired and suppressed sample drew a full-height vertical line across the plot, hatching a "curtain" that buried the actual traces. 2. The builder's **number inputs** were +/- steppers only — you couldn't click in and type a value. The minute fields also crammed the unit into the value ("5m") inside the box. ## What All changes are scoped to the **edge-triggered** path of `Chart` and the shared `NumberField`. Continuous-policy mode renders identically to before (guarded by `policy ?`), and the `simulate`/server backtest logic and the summary Stat cards are untouched. ### Backtest chart (`BacktestPanel.tsx`) - **Removed** all per-sample full-height vertical lines (both suppressed and fired); suppressed no longer marks the main plot at all, fires remain as dots on the avg curve. - **Cooldown bands**: consecutive suppressed indices collapse into a single low-opacity grey rect per run (padded half a sample-step each side) instead of N marks. - **Event rail**: new ~14px dark rounded lane beneath the plot carries all event density — one grey tick per suppressed sample, one heavier red tick per fire on top. Time-axis labels moved below the rail; viewBox height recomputed from the new geometry. - **Hierarchy fix**: windowed-avg is now the brightest/heaviest trace (white `#fafafa`, 2px); raw movement dropped to a 1px hairline at 0.5 opacity behind it. - **Red does one job**: faint red fire-zone tint above the threshold, threshold dashed line softened to 0.6 opacity, saturated red reserved for fires (curve dots + rail ticks). - **Legend** updated to match: white avg swatch, suppressed shown as a vertical tick, new translucent "cooldown" block. ### Number inputs (`primitives.tsx`, `RuleEditor.tsx`) - `NumberField` center is now a typeable `<input>` (click in and type) alongside the +/- buttons, via a draft string that commits only when it parses. - The unit renders **outside** the box (matching the existing number-then-unit pattern); minute fields now read `[5] minutes` instead of `5m`. Applies to every builder field (threshold, comparison value, delta, clamp min/max, window, revert, cooldown). ## Test plan - `eslint` + `tsc --noEmit` clean on all three files. - Deployed to Pod 5 (`192.168.1.88`); `sleepypod.service` active, app serving. - Manual: open the Automations builder backtest panel on a high-density night and confirm the plot stays clean with events on the rail; click into each number field and type a value; confirm continuous-policy mode chart is visually unchanged. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes **New Features** - Backtest chart now features edge mode with a dedicated event rail to better visualize event density - Cooldown bands now display suppressed event information more clearly - Number input fields now support direct text entry **Style** - Time durations now display as "minutes" for improved clarity - Updated chart legend to reflect new visualization elements <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update feat/automation-builder-ui ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/automation-builder-ui/scripts/install \ | sudo bash -s -- --branch feat/automation-builder-ui ``` 🎯 **Pin to this exact build** ([run 27520854239](https://github.com/sleepypod/core/actions/runs/27520854239) · `5cb380c`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/5cb380c75f60169ba951bafe9ce647d5c3067a65/scripts/install \ | sudo bash -s -- \ --branch feat/automation-builder-ui \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27520854239/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27520854239/artifacts/7628004076) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…lling past target) (#640) ## Summary The biometrics archive pruner (`modules/biometrics-archiver/sleepypod-biometrics-pruner`) has never pruned on a pod with a large archive. It exits before deleting anything, so `/persistent/biometrics-archive` grows unbounded and `/persistent` fills past the 80% target. ### Root cause ```bash oldest=$(find ... -printf '%T@ %p\n' | sort -n | head -1 | awk '{print $2}') ``` Under `set -euo pipefail`, `head -1` closes the pipe after the first line. With a large archive (thousands of files) `sort` is still writing, gets `SIGPIPE` → `sort: write failed: 'standard output': Broken pipe`, the pipeline returns 141, and `set -e` aborts the whole script. Net effect: `pruned=0` every run, service shows `status=2/INVALIDARGUMENT`. ### Fix Replace `sort -n | head -1 | awk '{print $2}'` with `sort -n | awk 'NR==1{print $2}'`. `awk` reads the whole stream (prints only line 1) so `sort` never gets SIGPIPE. ## Evidence (Pod 5 / .88, eight-pod) - `/persistent` at **84%** (target <80%); `/persistent/biometrics-archive` = **9.4 GB**, 3,789 `*.RAW.gz`. - `journalctl -u sleepypod-biometrics-pruner`: `sort: write failed: 'standard output': Broken pipe` → `status=2/INVALIDARGUMENT` every 15 min. ## Test plan - [x] Repro under `set -o pipefail`: `seq 1 100000 | sort -n | head -1 | awk '{print $1}'` exits **141**; `sort -n | awk 'NR==1{print $1}'` exits **0**. - [x] `bash -n` clean. - [ ] Deploy to .88, run `systemctl start sleepypod-biometrics-pruner`, confirm it prunes oldest `.RAW.gz` until `/persistent` < 80% and logs `pruned=N`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed a premature-pruning failure in the biometrics archive pruner caused by pipeline breakage under strict error handling. The script now reliably identifies and prunes the oldest eligible files, preventing it from aborting early and helping keep archive size properly managed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/biometrics-pruner-sigpipe ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/biometrics-pruner-sigpipe/scripts/install \ | sudo bash -s -- --branch fix/biometrics-pruner-sigpipe ``` 🎯 **Pin to this exact build** ([run 27520832687](https://github.com/sleepypod/core/actions/runs/27520832687) · `412c906`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/412c90698d429015f8b045f8173d4f337ed66477/scripts/install \ | sudo bash -s -- \ --branch fix/biometrics-pruner-sigpipe \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27520832687/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27520832687/artifacts/7627998221) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…lay (#648) ## Why #645 added the `cap_sense_frames` persistence layer (downsampled ~5s-windowed capacitive presence frames) but **nothing read it**. The table was write-only: `recordCapFrame` (via `piezoStream`) inserts and the pruner deletes, but no `SELECT` exists anywhere. Every pod was paying the write + storage + prune cost of what the schema calls "the bulkiest sensor stream" with zero consumers — and the schema's own stated purpose was unrealized: > windowed row per side (~5s) so the **spatial zone replay and cap.\* backtest** can reach recent nights Neither consumer existed. The three `{side}.cap.*` signals were still flagged `liveOnly: true` (a flag nothing actually reads), and `CapZoneViz` only rendered the live stream. ## What Wire both read paths the persistence layer was built for: **Backtest (`cap.*`)** - `loadSeries` now pulls `{side}.cap.max/mean/spread` from `cap_sense_frames` over the night window, mirroring the existing per-signal series blocks. - The three cap signals drop the now-false `liveOnly` flag — they are back-testable. - `cap.peakZone` deliberately stays out of the engine catalog: it's a spatial zone index, not a scalar signal (consistent with #645's design choice). **Spatial zone replay** - New `automations.capZoneReplay` query: returns the per-window `[head, torso, legs]` loads + `peakZone` for a chosen night, stride-downsampled to a `maxFrames` budget (default 300) so a full night stays a light payload. Skips Pod-3 scalar frames (null `zones`). - `CapZoneViz` gains a **Live / Replay** toggle (shown only when a backtest night is available). Replay scrubs — or auto-plays — through the recorded zone snapshots beside the backtest, with a stable per-night normalization. - Added a `Pause` icon. ## Test plan - `automations.test.ts` (new): covers `capZoneReplay` night resolution, the spatial-frame select, stride downsampling (25 rows → maxFrames 10 → 9 frames, first preserved), null-zones coercion, and the no-history `ok:false` path. - `npx tsc` clean; ESLint clean on all touched files. - `vitest run` for automation + streaming suites: 138 pass. - Manual: open a rule using a Bed pressure signal in the editor → backtest chart now plots the cap series; toggle Replay → scrub/play the night's zones. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update feat/cap-frame-readers ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/feat/cap-frame-readers/scripts/install \ | sudo bash -s -- --branch feat/cap-frame-readers ``` 🎯 **Pin to this exact build** ([run 27524905607](https://github.com/sleepypod/core/actions/runs/27524905607) · `4843f01`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/4843f01247a65a858d4e6bb221426da5777692fb/scripts/install \ | sudo bash -s -- \ --branch feat/cap-frame-readers \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27524905607/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27524905607/artifacts/7629394448) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added a Live/Replay view for capacitive zone visualization, including play/pause controls and timeline scrubbing for historical nights. * Wired the rule editor’s capacitive zone visualization to backtest context (selected side and night), so it aligns with the active backtest window. * Extended backtest-capable capacitive signals for cap max/mean/spread. * **Style** * Added a Pause icon for replay playback controls. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
> ℹ️ **Note**
>
> This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Update | Change |
|---|---|---|
| [node](https://nodejs.org)
([source](https://redirect.github.com/nodejs/node)) | major | `22` →
`24` |
---
### Release Notes
<details>
<summary>nodejs/node (node)</summary>
###
[`v24.16.0`](https://redirect.github.com/nodejs/node/releases/tag/v24.16.0):
2026-05-21, Version 24.16.0 'Krypton' (LTS), @​aduh95
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.15.0...v24.16.0)
##### Notable Changes
-
\[[`b267f6bca3`](https://redirect.github.com/nodejs/node/commit/b267f6bca3)]
- **(SEMVER-MINOR)** **crypto**: implement `randomUUIDv7()` (nabeel378)
[#​62553](https://redirect.github.com/nodejs/node/pull/62553)
-
\[[`ec2451b9cd`](https://redirect.github.com/nodejs/node/commit/ec2451b9cd)]
- **(SEMVER-MINOR)** **debugger**: add edit-free runtime expression
probes to `node inspect` (Joyee Cheung)
[#​62713](https://redirect.github.com/nodejs/node/pull/62713)
-
\[[`9705f628d9`](https://redirect.github.com/nodejs/node/commit/9705f628d9)]
- **(SEMVER-MINOR)** **fs**: add signal option to `fs.stat()` (Mert Can
Altin)
[#​57775](https://redirect.github.com/nodejs/node/pull/57775)
-
\[[`40ccfdecf9`](https://redirect.github.com/nodejs/node/commit/40ccfdecf9)]
- **(SEMVER-MINOR)** **fs**: expose `frsize` field in `statfs` (Jinho
Jang)
[#​62277](https://redirect.github.com/nodejs/node/pull/62277)
-
\[[`d7188af5c9`](https://redirect.github.com/nodejs/node/commit/d7188af5c9)]
- **(SEMVER-MINOR)** **http**: harden `ClientRequest` options merge
(Matteo Collina)
[#​63082](https://redirect.github.com/nodejs/node/pull/63082)
-
\[[`aa1d8a9afc`](https://redirect.github.com/nodejs/node/commit/aa1d8a9afc)]
- **(SEMVER-MINOR)** **http**: add `req.signal` to `IncomingMessage`
(Akshat)
[#​62541](https://redirect.github.com/nodejs/node/pull/62541)
-
\[[`6f37f7e240`](https://redirect.github.com/nodejs/node/commit/6f37f7e240)]
- **(SEMVER-MINOR)** **stream**: propagate destruction in `duplexPair`
(Ahmed Elhor)
[#​61098](https://redirect.github.com/nodejs/node/pull/61098)
-
\[[`d14029be7f`](https://redirect.github.com/nodejs/node/commit/d14029be7f)]
- **(SEMVER-MINOR)** **test\_runner**: support test order randomization
(Pietro Marchini)
[#​61747](https://redirect.github.com/nodejs/node/pull/61747)
-
\[[`d142c584cd`](https://redirect.github.com/nodejs/node/commit/d142c584cd)]
- **(SEMVER-MINOR)** **test\_runner**: align mock timeout api (sangwook)
[#​62820](https://redirect.github.com/nodejs/node/pull/62820)
-
\[[`01a9552585`](https://redirect.github.com/nodejs/node/commit/01a9552585)]
- **(SEMVER-MINOR)** **test\_runner**: add mock-timers support for
`AbortSignal.timeout` (DeveloperViraj)
[#​60751](https://redirect.github.com/nodejs/node/pull/60751)
-
\[[`00705a459a`](https://redirect.github.com/nodejs/node/commit/00705a459a)]
- **(SEMVER-MINOR)** **util**: colorize text with hex colors (Guilherme
Araújo)
[#​61556](https://redirect.github.com/nodejs/node/pull/61556)
##### Commits
-
\[[`dd72df060d`](https://redirect.github.com/nodejs/node/commit/dd72df060d)]
- **assert,util**: fix stale nested cycle memo entries (Ruben
Bridgewater)
[#​62509](https://redirect.github.com/nodejs/node/pull/62509)
-
\[[`add94f4bc3`](https://redirect.github.com/nodejs/node/commit/add94f4bc3)]
- **build**: track PDL files as inputs in inspector GN build (Robo)
[#​62888](https://redirect.github.com/nodejs/node/pull/62888)
-
\[[`1b1eb9e334`](https://redirect.github.com/nodejs/node/commit/1b1eb9e334)]
- **build**: remove redundant -fuse-linker-plugin from GCC LTO flags
(Daniel Lando)
[#​62667](https://redirect.github.com/nodejs/node/pull/62667)
-
\[[`8752b604ec`](https://redirect.github.com/nodejs/node/commit/8752b604ec)]
- **crypto**: deduplicate and canonicalize CryptoKey usages (Filip
Skokan)
[#​62902](https://redirect.github.com/nodejs/node/pull/62902)
-
\[[`341947e7fd`](https://redirect.github.com/nodejs/node/commit/341947e7fd)]
- **crypto**: reject unintended raw key format string input (Filip
Skokan)
[#​62974](https://redirect.github.com/nodejs/node/pull/62974)
-
\[[`28a78747fc`](https://redirect.github.com/nodejs/node/commit/28a78747fc)]
- **crypto**: remove Argon2 KDF derivation from its job setup (Filip
Skokan)
[#​62863](https://redirect.github.com/nodejs/node/pull/62863)
-
\[[`16e8c2b54d`](https://redirect.github.com/nodejs/node/commit/16e8c2b54d)]
- **crypto**: fix unsigned conversion of 4-byte RSA publicExponent
(DeepView Autofix)
[#​62839](https://redirect.github.com/nodejs/node/pull/62839)
-
\[[`eeae754a87`](https://redirect.github.com/nodejs/node/commit/eeae754a87)]
- **crypto**: reject inherited key type names (Jonathan Lopes)
[#​62875](https://redirect.github.com/nodejs/node/pull/62875)
-
\[[`9dd5540325`](https://redirect.github.com/nodejs/node/commit/9dd5540325)]
- **crypto**: add memory tracking for secureContext openssl objects
(Mert Can Altin)
[#​59051](https://redirect.github.com/nodejs/node/pull/59051)
-
\[[`b267f6bca3`](https://redirect.github.com/nodejs/node/commit/b267f6bca3)]
- **(SEMVER-MINOR)** **crypto**: implement randomUUIDv7() (nabeel378)
[#​62553](https://redirect.github.com/nodejs/node/pull/62553)
-
\[[`7597d204c1`](https://redirect.github.com/nodejs/node/commit/7597d204c1)]
- **crypto**: add support for
[`Ed25519`](https://redirect.github.com/nodejs/node/commit/Ed25519)
context parameter (Filip Skokan)
[#​62474](https://redirect.github.com/nodejs/node/pull/62474)
-
\[[`4bf85845da`](https://redirect.github.com/nodejs/node/commit/4bf85845da)]
- **debugger**: move ProbeInspectorSession and helpers to separate files
(Joyee Cheung)
[#​63013](https://redirect.github.com/nodejs/node/pull/63013)
-
\[[`ec2451b9cd`](https://redirect.github.com/nodejs/node/commit/ec2451b9cd)]
- **(SEMVER-MINOR)** **debugger**: add edit-free runtime expression
probes to `node inspect` (Joyee Cheung)
[#​62713](https://redirect.github.com/nodejs/node/pull/62713)
-
\[[`83e98f77b7`](https://redirect.github.com/nodejs/node/commit/83e98f77b7)]
- **deps**: update corepack to 0.35.0 (Node.js GitHub Bot)
[#​63375](https://redirect.github.com/nodejs/node/pull/63375)
-
\[[`ec8c6b939a`](https://redirect.github.com/nodejs/node/commit/ec8c6b939a)]
- **deps**: V8: cherry-pick
[`657d8de`](https://redirect.github.com/nodejs/node/commit/657d8de27427)
(Guy Bedford)
[#​62784](https://redirect.github.com/nodejs/node/pull/62784)
-
\[[`722c0c3274`](https://redirect.github.com/nodejs/node/commit/722c0c3274)]
- **deps**: update nghttp3 to 1.14.0 (Node.js GitHub Bot)
[#​61187](https://redirect.github.com/nodejs/node/pull/61187)
-
\[[`5304db93d3`](https://redirect.github.com/nodejs/node/commit/5304db93d3)]
- **deps**: update nghttp3 to 1.13.1 (Node.js GitHub Bot)
[#​60046](https://redirect.github.com/nodejs/node/pull/60046)
-
\[[`e073b3811d`](https://redirect.github.com/nodejs/node/commit/e073b3811d)]
- **deps**: update nghttp3 to 1.11.0 (James M Snell)
[#​59249](https://redirect.github.com/nodejs/node/pull/59249)
-
\[[`1d00313fb2`](https://redirect.github.com/nodejs/node/commit/1d00313fb2)]
- **deps**: update ngtcp2 to 1.14.0 (James M Snell)
[#​59249](https://redirect.github.com/nodejs/node/pull/59249)
-
\[[`8b3a4fc18f`](https://redirect.github.com/nodejs/node/commit/8b3a4fc18f)]
- **deps**: update amaro to 1.1.9 (Node.js GitHub Bot)
[#​63090](https://redirect.github.com/nodejs/node/pull/63090)
-
\[[`62fe0cfcd1`](https://redirect.github.com/nodejs/node/commit/62fe0cfcd1)]
- **deps**: update llhttp to 9.4.1 (Node.js GitHub Bot)
[#​63045](https://redirect.github.com/nodejs/node/pull/63045)
-
\[[`137e09c8e9`](https://redirect.github.com/nodejs/node/commit/137e09c8e9)]
- **deps**: update corepack to 0.34.7 (Node.js GitHub Bot)
[#​62810](https://redirect.github.com/nodejs/node/pull/62810)
-
\[[`14a4cb8fbc`](https://redirect.github.com/nodejs/node/commit/14a4cb8fbc)]
- **deps**: update timezone to 2026b (Node.js GitHub Bot)
[#​62962](https://redirect.github.com/nodejs/node/pull/62962)
-
\[[`3e1036583a`](https://redirect.github.com/nodejs/node/commit/3e1036583a)]
- **deps**: upgrade npm to 11.13.0 (npm team)
[#​62898](https://redirect.github.com/nodejs/node/pull/62898)
-
\[[`01dfe5961c`](https://redirect.github.com/nodejs/node/commit/01dfe5961c)]
- **deps**: cherry-pick
[libuv/libuv@`439a54b`](https://redirect.github.com/libuv/libuv/commit/439a54b)
(skooch)
[#​62881](https://redirect.github.com/nodejs/node/pull/62881)
-
\[[`6cd368b10c`](https://redirect.github.com/nodejs/node/commit/6cd368b10c)]
- **deps**: update sqlite to 3.53.0 (Node.js GitHub Bot)
[#​62699](https://redirect.github.com/nodejs/node/pull/62699)
-
\[[`f218a4f553`](https://redirect.github.com/nodejs/node/commit/f218a4f553)]
- **deps**: update nbytes to 0.1.4 (Node.js GitHub Bot)
[#​62698](https://redirect.github.com/nodejs/node/pull/62698)
-
\[[`b47688524a`](https://redirect.github.com/nodejs/node/commit/b47688524a)]
- **deps**: update archs files for openssl-3.5.6 (Node.js GitHub Bot)
[#​62629](https://redirect.github.com/nodejs/node/pull/62629)
-
\[[`d202e2d343`](https://redirect.github.com/nodejs/node/commit/d202e2d343)]
- **deps**: upgrade openssl sources to openssl-3.5.6 (Node.js GitHub
Bot) [#​62629](https://redirect.github.com/nodejs/node/pull/62629)
-
\[[`2faba66341`](https://redirect.github.com/nodejs/node/commit/2faba66341)]
- **deps**: update minimatch to 10.2.5 (Node.js GitHub Bot)
[#​62594](https://redirect.github.com/nodejs/node/pull/62594)
-
\[[`fa46c90c5d`](https://redirect.github.com/nodejs/node/commit/fa46c90c5d)]
- **deps**: update googletest to
[`d72f9c8`](https://redirect.github.com/nodejs/node/commit/d72f9c8aea6817cdf1ca0ac10887f328de7f3da2)
(Node.js GitHub Bot)
[#​62593](https://redirect.github.com/nodejs/node/pull/62593)
-
\[[`099ded5713`](https://redirect.github.com/nodejs/node/commit/099ded5713)]
- **deps**: update simdjson to 4.6.1 (Node.js GitHub Bot)
[#​62592](https://redirect.github.com/nodejs/node/pull/62592)
-
\[[`7ce95afe96`](https://redirect.github.com/nodejs/node/commit/7ce95afe96)]
- **deps**: libuv: cherry-pick
[`aabb765`](https://redirect.github.com/nodejs/node/commit/aabb7651de)
(Santiago Gimeno)
[#​62561](https://redirect.github.com/nodejs/node/pull/62561)
-
\[[`57ef845623`](https://redirect.github.com/nodejs/node/commit/57ef845623)]
- **deps**: update icu to 78.3 (Node.js GitHub Bot)
[#​62324](https://redirect.github.com/nodejs/node/pull/62324)
-
\[[`493ac40e12`](https://redirect.github.com/nodejs/node/commit/493ac40e12)]
- **deps**: update libuv to 1.52.1 (Node.js GitHub Bot)
[#​61829](https://redirect.github.com/nodejs/node/pull/61829)
-
\[[`b39508b368`](https://redirect.github.com/nodejs/node/commit/b39508b368)]
- **deps**: update undici to 7.25.0 (Node.js GitHub Bot)
[#​63011](https://redirect.github.com/nodejs/node/pull/63011)
-
\[[`cb67a925e9`](https://redirect.github.com/nodejs/node/commit/cb67a925e9)]
- **deps**: use npm undici\@​seven tag in `update-undici.sh`
(Matteo Collina)
[#​62739](https://redirect.github.com/nodejs/node/pull/62739)
-
\[[`aa1e0bc28b`](https://redirect.github.com/nodejs/node/commit/aa1e0bc28b)]
- **doc**: fix typos and inconsistencies in crypto.md and webcrypto.md
(Filip Skokan)
[#​62828](https://redirect.github.com/nodejs/node/pull/62828)
-
\[[`f2a1735ed9`](https://redirect.github.com/nodejs/node/commit/f2a1735ed9)]
- **doc**: fix duplicate word "to to" in util.styleText (Daijiro Wachi)
[#​62917](https://redirect.github.com/nodejs/node/pull/62917)
-
\[[`b6378e215c`](https://redirect.github.com/nodejs/node/commit/b6378e215c)]
- **doc**: fix node-config-schema (Сковорода Никита Андреевич)
[#​61596](https://redirect.github.com/nodejs/node/pull/61596)
-
\[[`233894a9ce`](https://redirect.github.com/nodejs/node/commit/233894a9ce)]
- **doc**: fix the TypeScript Execute (tsx) project link (David
Thornton)
[#​63093](https://redirect.github.com/nodejs/node/pull/63093)
-
\[[`5d97919f8f`](https://redirect.github.com/nodejs/node/commit/5d97919f8f)]
- **doc**: correct diagnostics\_channel built-in channel names (Bryan
English)
[#​62995](https://redirect.github.com/nodejs/node/pull/62995)
-
\[[`2a9ccc927e`](https://redirect.github.com/nodejs/node/commit/2a9ccc927e)]
- **doc**: use mjs/cjs blocks for callbackify null reason example
(Daijiro Wachi)
[#​62884](https://redirect.github.com/nodejs/node/pull/62884)
-
\[[`ef413b5358`](https://redirect.github.com/nodejs/node/commit/ef413b5358)]
- **doc**: fix typo in test.md (Rich Trott)
[#​62960](https://redirect.github.com/nodejs/node/pull/62960)
-
\[[`76f21c5070`](https://redirect.github.com/nodejs/node/commit/76f21c5070)]
- **doc**: correct typo in PR contribution instructions (Mike McCready)
[#​62738](https://redirect.github.com/nodejs/node/pull/62738)
-
\[[`ca02af1f7d`](https://redirect.github.com/nodejs/node/commit/ca02af1f7d)]
- **doc**: fix duplicate word "of of" in postMessageToThread (Daijiro
Wachi)
[#​62917](https://redirect.github.com/nodejs/node/pull/62917)
-
\[[`46c99ed526`](https://redirect.github.com/nodejs/node/commit/46c99ed526)]
- **doc**: fix duplicate word "for for" in compile cache (Daijiro Wachi)
[#​62917](https://redirect.github.com/nodejs/node/pull/62917)
-
\[[`1a60851734`](https://redirect.github.com/nodejs/node/commit/1a60851734)]
- **doc**: fix typo in dns.lookup options description (Daijiro Wachi)
[#​62882](https://redirect.github.com/nodejs/node/pull/62882)
-
\[[`169b5ea2ed`](https://redirect.github.com/nodejs/node/commit/169b5ea2ed)]
- **doc**: fix Argon2 parameter bounds (Tobias Nießen)
[#​62868](https://redirect.github.com/nodejs/node/pull/62868)
-
\[[`9a3a190f4e`](https://redirect.github.com/nodejs/node/commit/9a3a190f4e)]
- **doc**: clarify diffieHellman.generateKeys recomputes same key (Kit
Dallege)
[#​62205](https://redirect.github.com/nodejs/node/pull/62205)
-
\[[`0fba9e87d6`](https://redirect.github.com/nodejs/node/commit/0fba9e87d6)]
- **doc**: remove Ayase-252 and meixg from triagger team (Antoine du
Hamel)
[#​62841](https://redirect.github.com/nodejs/node/pull/62841)
-
\[[`9c700f3446`](https://redirect.github.com/nodejs/node/commit/9c700f3446)]
- **doc**: clarify dns.lookup() callback signature when all is true
(eungi)
[#​62800](https://redirect.github.com/nodejs/node/pull/62800)
-
\[[`6b7280bc17`](https://redirect.github.com/nodejs/node/commit/6b7280bc17)]
- **doc**: add experimental modules lifetime policy (Paolo Insogna)
[#​62753](https://redirect.github.com/nodejs/node/pull/62753)
-
\[[`ce47ea31c9`](https://redirect.github.com/nodejs/node/commit/ce47ea31c9)]
- **doc**: clarify process.\_debugProcess() in Permission Model (Fahad
Khan)
[#​62537](https://redirect.github.com/nodejs/node/pull/62537)
-
\[[`ba01633757`](https://redirect.github.com/nodejs/node/commit/ba01633757)]
- **doc**: fix typo in devcontainer guide (Rohan Santhosh Kumar)
[#​62687](https://redirect.github.com/nodejs/node/pull/62687)
-
\[[`70b4d5839b`](https://redirect.github.com/nodejs/node/commit/70b4d5839b)]
- **doc**: clarify Backport-PR-URL metadata added automatically (Mike
McCready)
[#​62668](https://redirect.github.com/nodejs/node/pull/62668)
-
\[[`8126d1c3eb`](https://redirect.github.com/nodejs/node/commit/8126d1c3eb)]
- **doc**: update WPT test runner README.md (Filip Skokan)
[#​62680](https://redirect.github.com/nodejs/node/pull/62680)
-
\[[`978afea4b5`](https://redirect.github.com/nodejs/node/commit/978afea4b5)]
- **doc**: fix spelling in release announcement guidance (Rohan Santhosh
Kumar)
[#​62663](https://redirect.github.com/nodejs/node/pull/62663)
-
\[[`1684ab8ff8`](https://redirect.github.com/nodejs/node/commit/1684ab8ff8)]
- **doc**: note non-monotonic clock in crypto.randomUUIDv7 (nabeel378)
[#​62600](https://redirect.github.com/nodejs/node/pull/62600)
-
\[[`86d4f07930`](https://redirect.github.com/nodejs/node/commit/86d4f07930)]
- **doc**: update bug bounty program (Rafael Gonzaga)
[#​62590](https://redirect.github.com/nodejs/node/pull/62590)
-
\[[`736ed8a08f`](https://redirect.github.com/nodejs/node/commit/736ed8a08f)]
- **doc**: document TransformStream transformer.cancel option (Tom
Pereira)
[#​62566](https://redirect.github.com/nodejs/node/pull/62566)
-
\[[`938af9be01`](https://redirect.github.com/nodejs/node/commit/938af9be01)]
- **doc**: mention test runner retry attemp is zero based (Moshe Atlow)
[#​62504](https://redirect.github.com/nodejs/node/pull/62504)
-
\[[`94433e450f`](https://redirect.github.com/nodejs/node/commit/94433e450f)]
- **doc,src,test**: fix dead inspector help URL (semimikoh)
[#​62745](https://redirect.github.com/nodejs/node/pull/62745)
-
\[[`ddf1f01659`](https://redirect.github.com/nodejs/node/commit/ddf1f01659)]
- **esm**: add `ERR_REQUIRE_ESM_RACE_CONDITION` (Antoine du Hamel)
[#​62462](https://redirect.github.com/nodejs/node/pull/62462)
-
\[[`4a506acd16`](https://redirect.github.com/nodejs/node/commit/4a506acd16)]
- **fs**: add followSymlinks option to glob (Matteo Collina)
[#​62695](https://redirect.github.com/nodejs/node/pull/62695)
-
\[[`f4ea495f9b`](https://redirect.github.com/nodejs/node/commit/f4ea495f9b)]
- **fs**: restore fs patchability in ESM loader (Joyee Cheung)
[#​62835](https://redirect.github.com/nodejs/node/pull/62835)
-
\[[`63c111cd60`](https://redirect.github.com/nodejs/node/commit/63c111cd60)]
- **fs**: validate position argument before length === 0 early return
(Edy Silva)
[#​62674](https://redirect.github.com/nodejs/node/pull/62674)
-
\[[`9705f628d9`](https://redirect.github.com/nodejs/node/commit/9705f628d9)]
- **(SEMVER-MINOR)** **fs**: add signal option to fs.stat() (Mert Can
Altin)
[#​57775](https://redirect.github.com/nodejs/node/pull/57775)
-
\[[`40ccfdecf9`](https://redirect.github.com/nodejs/node/commit/40ccfdecf9)]
- **(SEMVER-MINOR)** **fs**: expose frsize field in statfs (Jinho Jang)
[#​62277](https://redirect.github.com/nodejs/node/pull/62277)
-
\[[`717476a24e`](https://redirect.github.com/nodejs/node/commit/717476a24e)]
- **http**: emit 'drain' on OutgoingMessage only after buffers drain
(Robert Nagy)
[#​62936](https://redirect.github.com/nodejs/node/pull/62936)
-
\[[`d7188af5c9`](https://redirect.github.com/nodejs/node/commit/d7188af5c9)]
- **(SEMVER-MINOR)** **http**: harden ClientRequest options merge
(Matteo Collina)
[#​63082](https://redirect.github.com/nodejs/node/pull/63082)
-
\[[`64f15c274a`](https://redirect.github.com/nodejs/node/commit/64f15c274a)]
- **http**: fix leaked error listener on sync HTTP req create + destroy
(Tim Perry)
[#​62872](https://redirect.github.com/nodejs/node/pull/62872)
-
\[[`5c4798d799`](https://redirect.github.com/nodejs/node/commit/5c4798d799)]
- **http**: fix no\_proxy leading-dot suffix matching (Daijiro Wachi)
[#​62333](https://redirect.github.com/nodejs/node/pull/62333)
-
\[[`9f3bc70ae5`](https://redirect.github.com/nodejs/node/commit/9f3bc70ae5)]
- **http**: cleanup pipeline queue (Robert Nagy)
[#​62534](https://redirect.github.com/nodejs/node/pull/62534)
-
\[[`aa1d8a9afc`](https://redirect.github.com/nodejs/node/commit/aa1d8a9afc)]
- **(SEMVER-MINOR)** **http**: add req.signal to IncomingMessage
(Akshat)
[#​62541](https://redirect.github.com/nodejs/node/pull/62541)
-
\[[`900dc758ff`](https://redirect.github.com/nodejs/node/commit/900dc758ff)]
- **http2**: expose writable stream state on compat response (T)
[#​63003](https://redirect.github.com/nodejs/node/pull/63003)
-
\[[`b3bfe35912`](https://redirect.github.com/nodejs/node/commit/b3bfe35912)]
- **inspector**: coerce key and value to string in webstorage events
(Ali Hassan)
[#​62616](https://redirect.github.com/nodejs/node/pull/62616)
-
\[[`3dc3fb6ad8`](https://redirect.github.com/nodejs/node/commit/3dc3fb6ad8)]
- **inspector**: return errors when CDP protocol event emission fails
(Ryuhei Shima)
[#​62162](https://redirect.github.com/nodejs/node/pull/62162)
-
\[[`4f3f21bd7c`](https://redirect.github.com/nodejs/node/commit/4f3f21bd7c)]
- **inspector**: auto collect webstorage data (Ryuhei Shima)
[#​62145](https://redirect.github.com/nodejs/node/pull/62145)
-
\[[`36cc04189d`](https://redirect.github.com/nodejs/node/commit/36cc04189d)]
- **inspector**: initial support storage inspection (Ryuhei Shima)
[#​61139](https://redirect.github.com/nodejs/node/pull/61139)
-
\[[`1718bc3b9b`](https://redirect.github.com/nodejs/node/commit/1718bc3b9b)]
- **inspector**: fix absolute URLs in network http (bugyaluwang)
[#​62955](https://redirect.github.com/nodejs/node/pull/62955)
-
\[[`97e32c7a74`](https://redirect.github.com/nodejs/node/commit/97e32c7a74)]
- **lib**: avoid quadratic shift() in startup snapshot callback (Daijiro
Wachi)
[#​62914](https://redirect.github.com/nodejs/node/pull/62914)
-
\[[`25d2e999de`](https://redirect.github.com/nodejs/node/commit/25d2e999de)]
- **lib**: harden kKeyOps lookup with null prototype (Filip Skokan)
[#​62877](https://redirect.github.com/nodejs/node/pull/62877)
-
\[[`37d3913c8f`](https://redirect.github.com/nodejs/node/commit/37d3913c8f)]
- **lib**: short-circuit WebIDL BufferSource SAB check (Filip Skokan)
[#​62833](https://redirect.github.com/nodejs/node/pull/62833)
-
\[[`430c69d25f`](https://redirect.github.com/nodejs/node/commit/430c69d25f)]
- **lib**: use js-only implementation of `isDataView()` (René)
[#​62780](https://redirect.github.com/nodejs/node/pull/62780)
-
\[[`3ba0add6a0`](https://redirect.github.com/nodejs/node/commit/3ba0add6a0)]
- **lib**: fix lint in internal/webstreams/util.js (Filip Skokan)
[#​62806](https://redirect.github.com/nodejs/node/pull/62806)
-
\[[`9b95c41398`](https://redirect.github.com/nodejs/node/commit/9b95c41398)]
- **lib**: fix sequence argument handling in Blob constructor (Ms2ger)
[#​62179](https://redirect.github.com/nodejs/node/pull/62179)
-
\[[`314dacdbee`](https://redirect.github.com/nodejs/node/commit/314dacdbee)]
- **lib**: improve Web Cryptography key validation ordering (Filip
Skokan)
[#​62749](https://redirect.github.com/nodejs/node/pull/62749)
-
\[[`3d18162430`](https://redirect.github.com/nodejs/node/commit/3d18162430)]
- **lib**: reject SharedArrayBuffer in web APIs per spec (Ali Hassan)
[#​62632](https://redirect.github.com/nodejs/node/pull/62632)
-
\[[`ada3ce879d`](https://redirect.github.com/nodejs/node/commit/ada3ce879d)]
- **lib**: defer AbortSignal.any() following (sangwook)
[#​62367](https://redirect.github.com/nodejs/node/pull/62367)
-
\[[`b2981ec7eb`](https://redirect.github.com/nodejs/node/commit/b2981ec7eb)]
- **meta**: bump actions/download-artifact from 8.0.0 to 8.0.1
(dependabot\[bot])
[#​62549](https://redirect.github.com/nodejs/node/pull/62549)
-
\[[`7cd20667b5`](https://redirect.github.com/nodejs/node/commit/7cd20667b5)]
- **meta**: bump github/codeql-action from 4.35.1 to 4.35.3
(dependabot\[bot])
[#​63074](https://redirect.github.com/nodejs/node/pull/63074)
-
\[[`91a07cfe9f`](https://redirect.github.com/nodejs/node/commit/91a07cfe9f)]
- **meta**: bump Mozilla-Actions/sccache-action from 0.0.9 to 0.0.10
(dependabot\[bot])
[#​63073](https://redirect.github.com/nodejs/node/pull/63073)
-
\[[`09e17fe47c`](https://redirect.github.com/nodejs/node/commit/09e17fe47c)]
- **meta**: add automation policy (Chengzhong Wu)
[#​62871](https://redirect.github.com/nodejs/node/pull/62871)
-
\[[`59e7fb7986`](https://redirect.github.com/nodejs/node/commit/59e7fb7986)]
- **meta**: move VoltrexKeyva to emeritus (Matteo Collina)
[#​62895](https://redirect.github.com/nodejs/node/pull/62895)
-
\[[`1e2915cfa6`](https://redirect.github.com/nodejs/node/commit/1e2915cfa6)]
- **meta**: bump peter-evans/create-pull-request from 8.1.0 to 8.1.1
(dependabot\[bot])
[#​62845](https://redirect.github.com/nodejs/node/pull/62845)
-
\[[`0253c6e2be`](https://redirect.github.com/nodejs/node/commit/0253c6e2be)]
- **meta**: bump step-security/harden-runner from 2.16.1 to 2.19.0
(dependabot\[bot])
[#​62844](https://redirect.github.com/nodejs/node/pull/62844)
-
\[[`f503675b86`](https://redirect.github.com/nodejs/node/commit/f503675b86)]
- **meta**: bump actions/setup-node from 6.3.0 to 6.4.0
(dependabot\[bot])
[#​62842](https://redirect.github.com/nodejs/node/pull/62842)
-
\[[`5e14e4d26e`](https://redirect.github.com/nodejs/node/commit/5e14e4d26e)]
- **meta**: broaden stale bot (Aviv Keller)
[#​62658](https://redirect.github.com/nodejs/node/pull/62658)
-
\[[`795db76f87`](https://redirect.github.com/nodejs/node/commit/795db76f87)]
- **meta**: pass release version to release worker (flakey5)
[#​62777](https://redirect.github.com/nodejs/node/pull/62777)
-
\[[`ef384fe39f`](https://redirect.github.com/nodejs/node/commit/ef384fe39f)]
- **meta**: add QUIC to CODEOWNERS (Tim Perry)
[#​62652](https://redirect.github.com/nodejs/node/pull/62652)
-
\[[`67e0ac568d`](https://redirect.github.com/nodejs/node/commit/67e0ac568d)]
- **meta**: move Michael to emeritus (Michael Dawson)
[#​62536](https://redirect.github.com/nodejs/node/pull/62536)
-
\[[`5dad616393`](https://redirect.github.com/nodejs/node/commit/5dad616393)]
- **meta**: populate apt list for slim runner in update-openssl workflow
(René)
[#​62628](https://redirect.github.com/nodejs/node/pull/62628)
-
\[[`a869d25d8a`](https://redirect.github.com/nodejs/node/commit/a869d25d8a)]
- **meta**: bump step-security/harden-runner from 2.15.0 to 2.16.1
(dependabot\[bot])
[#​62550](https://redirect.github.com/nodejs/node/pull/62550)
-
\[[`769efc0403`](https://redirect.github.com/nodejs/node/commit/769efc0403)]
- **meta**: bump actions/setup-node from 6.2.0 to 6.3.0
(dependabot\[bot])
[#​62548](https://redirect.github.com/nodejs/node/pull/62548)
-
\[[`73fcc2b055`](https://redirect.github.com/nodejs/node/commit/73fcc2b055)]
- **meta**: bump github/codeql-action from 4.32.4 to 4.35.1
(dependabot\[bot])
[#​62547](https://redirect.github.com/nodejs/node/pull/62547)
-
\[[`6c001246fe`](https://redirect.github.com/nodejs/node/commit/6c001246fe)]
- **meta**: bump codecov/codecov-action from 5.5.2 to 6.0.0
(dependabot\[bot])
[#​62545](https://redirect.github.com/nodejs/node/pull/62545)
-
\[[`5ee40d6a03`](https://redirect.github.com/nodejs/node/commit/5ee40d6a03)]
- **meta**: bump actions/cache from 5.0.3 to 5.0.4 (dependabot\[bot])
[#​62543](https://redirect.github.com/nodejs/node/pull/62543)
-
\[[`ca16ad8a05`](https://redirect.github.com/nodejs/node/commit/ca16ad8a05)]
- **meta**: require DCO signoff in commit message guidelines (James M
Snell)
[#​62510](https://redirect.github.com/nodejs/node/pull/62510)
-
\[[`db9497fc41`](https://redirect.github.com/nodejs/node/commit/db9497fc41)]
- **meta**: expand memory leak DoS criteria to all DoS (Joyee Cheung)
[#​62505](https://redirect.github.com/nodejs/node/pull/62505)
-
\[[`13b7d08b8d`](https://redirect.github.com/nodejs/node/commit/13b7d08b8d)]
- **module**: remove duplicated checks from `_resolveFilename` (Antoine
du Hamel)
[#​62729](https://redirect.github.com/nodejs/node/pull/62729)
-
\[[`6b53efb53a`](https://redirect.github.com/nodejs/node/commit/6b53efb53a)]
- **module,win**: fix long subpath import (Stefan Stojanovic)
[#​62101](https://redirect.github.com/nodejs/node/pull/62101)
-
\[[`841dfbf6fc`](https://redirect.github.com/nodejs/node/commit/841dfbf6fc)]
- **node-api**: update libuv ABI stability note (Chengzhong Wu)
[#​62789](https://redirect.github.com/nodejs/node/pull/62789)
-
\[[`01090f2aa1`](https://redirect.github.com/nodejs/node/commit/01090f2aa1)]
- **node-api**: add napi\_create\_external\_sharedarraybuffer (Ben
Noordhuis)
[#​62623](https://redirect.github.com/nodejs/node/pull/62623)
-
\[[`87443b4355`](https://redirect.github.com/nodejs/node/commit/87443b4355)]
- **node-api**: execute tsfn finalizer after queue drains when aborted
(Kevin Eady)
[#​61956](https://redirect.github.com/nodejs/node/pull/61956)
-
\[[`e95570c054`](https://redirect.github.com/nodejs/node/commit/e95570c054)]
- **process**: handle rejections only when needed (Gürgün Dayıoğlu)
[#​62919](https://redirect.github.com/nodejs/node/pull/62919)
-
\[[`37d49f3219`](https://redirect.github.com/nodejs/node/commit/37d49f3219)]
- **process**: optimize asyncHandledRejections by using FixedQueue
(Gürgün Dayıoğlu)
[#​60854](https://redirect.github.com/nodejs/node/pull/60854)
-
\[[`f697c55e38`](https://redirect.github.com/nodejs/node/commit/f697c55e38)]
- **quic**: add QuicEndpoint.listening & QuicStream.destroy() and tests
(Tim Perry)
[#​62648](https://redirect.github.com/nodejs/node/pull/62648)
-
\[[`c128942b69`](https://redirect.github.com/nodejs/node/commit/c128942b69)]
- **quic**: fixup token verification to handle zero expiration (James M
Snell)
[#​62620](https://redirect.github.com/nodejs/node/pull/62620)
-
\[[`abb881ec92`](https://redirect.github.com/nodejs/node/commit/abb881ec92)]
- **quic**: support multiple ALPN negotiation (James M Snell)
[#​62620](https://redirect.github.com/nodejs/node/pull/62620)
-
\[[`476926c2ad`](https://redirect.github.com/nodejs/node/commit/476926c2ad)]
- **quic**: apply multiple TLS context improvements and SNI support
(James M Snell)
[#​62620](https://redirect.github.com/nodejs/node/pull/62620)
-
\[[`76d9c24b95`](https://redirect.github.com/nodejs/node/commit/76d9c24b95)]
- **quic**: implement rapidhash for hashing improvements (James M Snell)
[#​62620](https://redirect.github.com/nodejs/node/pull/62620)
-
\[[`08726cd43d`](https://redirect.github.com/nodejs/node/commit/08726cd43d)]
- **quic**: move quic behind compile time flag (Matteo Collina)
[#​61444](https://redirect.github.com/nodejs/node/pull/61444)
-
\[[`ea4f19aaa7`](https://redirect.github.com/nodejs/node/commit/ea4f19aaa7)]
- **quic**: use arena allocation for packets (James M Snell)
[#​62589](https://redirect.github.com/nodejs/node/pull/62589)
-
\[[`21e9239e2a`](https://redirect.github.com/nodejs/node/commit/21e9239e2a)]
- **quic**: fixup linting/formatting issues (James M Snell)
[#​62387](https://redirect.github.com/nodejs/node/pull/62387)
-
\[[`edeed4303b`](https://redirect.github.com/nodejs/node/commit/edeed4303b)]
- **quic**: update http3 impl details (James M Snell)
[#​62387](https://redirect.github.com/nodejs/node/pull/62387)
-
\[[`7f3a85e6aa`](https://redirect.github.com/nodejs/node/commit/7f3a85e6aa)]
- **quic**: fix a handful of bugs and missing functionality (James M
Snell)
[#​62387](https://redirect.github.com/nodejs/node/pull/62387)
-
\[[`45c1ebddf8`](https://redirect.github.com/nodejs/node/commit/45c1ebddf8)]
- **quic**: copy options.certs buffer instead of detaching (Chengzhong
Wu) [#​61403](https://redirect.github.com/nodejs/node/pull/61403)
-
\[[`a31a8ee680`](https://redirect.github.com/nodejs/node/commit/a31a8ee680)]
- **quic**: reduce boilerplate and other minor cleanups (James M Snell)
[#​59342](https://redirect.github.com/nodejs/node/pull/59342)
-
\[[`3be70ff43a`](https://redirect.github.com/nodejs/node/commit/3be70ff43a)]
- **quic**: multiple fixups and updates (James M Snell)
[#​59342](https://redirect.github.com/nodejs/node/pull/59342)
-
\[[`b91a93444c`](https://redirect.github.com/nodejs/node/commit/b91a93444c)]
- **quic**: update more of the quic to the new compile guard (James M
Snell)
[#​59342](https://redirect.github.com/nodejs/node/pull/59342)
-
\[[`ca0080c164`](https://redirect.github.com/nodejs/node/commit/ca0080c164)]
- **quic**: few additional small comment edits in cid.h (James M Snell)
[#​59342](https://redirect.github.com/nodejs/node/pull/59342)
-
\[[`6553202d83`](https://redirect.github.com/nodejs/node/commit/6553202d83)]
- **quic**: fixup NO\_ERROR macro conflict on windows (James M Snell)
[#​59381](https://redirect.github.com/nodejs/node/pull/59381)
-
\[[`6df1508ac2`](https://redirect.github.com/nodejs/node/commit/6df1508ac2)]
- **quic**: fixup windows coverage compile error (James M Snell)
[#​59381](https://redirect.github.com/nodejs/node/pull/59381)
-
\[[`b2b0bf8b04`](https://redirect.github.com/nodejs/node/commit/b2b0bf8b04)]
- **quic**: update the guard to check openssl version (James M Snell)
[#​59249](https://redirect.github.com/nodejs/node/pull/59249)
-
\[[`5556b154bd`](https://redirect.github.com/nodejs/node/commit/5556b154bd)]
- **quic**: start re-enabling quic with openssl 3.5 (James M Snell)
[#​59249](https://redirect.github.com/nodejs/node/pull/59249)
-
\[[`2ca42c8263`](https://redirect.github.com/nodejs/node/commit/2ca42c8263)]
- **repl**: keep reference count for `process.on('newListener')` (Anna
Henningsen)
[#​61895](https://redirect.github.com/nodejs/node/pull/61895)
-
\[[`2f37f9177f`](https://redirect.github.com/nodejs/node/commit/2f37f9177f)]
- **sqlite**: use OneByte for ASCII text and internalize col names (Ali
Hassan)
[#​61954](https://redirect.github.com/nodejs/node/pull/61954)
-
\[[`3c96ae1b2f`](https://redirect.github.com/nodejs/node/commit/3c96ae1b2f)]
- **sqlite**: add serialize() and deserialize() (Ali Hassan)
[#​62579](https://redirect.github.com/nodejs/node/pull/62579)
-
\[[`be4d2f3a4c`](https://redirect.github.com/nodejs/node/commit/be4d2f3a4c)]
- **sqlite**: enable Percentile extension (Jurj Andrei George)
[#​61295](https://redirect.github.com/nodejs/node/pull/61295)
-
\[[`dafed453b2`](https://redirect.github.com/nodejs/node/commit/dafed453b2)]
- **src**: clean up experimental flag variables (Antoine du Hamel)
[#​62759](https://redirect.github.com/nodejs/node/pull/62759)
-
\[[`dca1e6aeea`](https://redirect.github.com/nodejs/node/commit/dca1e6aeea)]
- **src**: expose help texts into node-config-schema.json (Pietro
Marchini)
[#​58680](https://redirect.github.com/nodejs/node/pull/58680)
-
\[[`28c4f44eb1`](https://redirect.github.com/nodejs/node/commit/28c4f44eb1)]
- **src**: add permission support to config file (Marco Ippolito)
[#​60746](https://redirect.github.com/nodejs/node/pull/60746)
-
\[[`f49175b220`](https://redirect.github.com/nodejs/node/commit/f49175b220)]
- **src**: fix small compile warning in quic/streams.cc (James M Snell)
[#​60118](https://redirect.github.com/nodejs/node/pull/60118)
-
\[[`c9d4a446d8`](https://redirect.github.com/nodejs/node/commit/c9d4a446d8)]
- **src**: cleanup quic TransportParams class (James M Snell)
[#​59884](https://redirect.github.com/nodejs/node/pull/59884)
-
\[[`99bb02fd9e`](https://redirect.github.com/nodejs/node/commit/99bb02fd9e)]
- **src**: swap dotenv and config file parsing order (Marco Ippolito)
[#​63035](https://redirect.github.com/nodejs/node/pull/63035)
-
\[[`ecb4d49b7b`](https://redirect.github.com/nodejs/node/commit/ecb4d49b7b)]
- **src**: add missing \<cstdlib> for abort() declaration (Charles Kerr)
[#​63001](https://redirect.github.com/nodejs/node/pull/63001)
-
\[[`b6219b6362`](https://redirect.github.com/nodejs/node/commit/b6219b6362)]
- **src**: fix crash in GetErrorSource() for invalid using syntax
(semimikoh)
[#​62770](https://redirect.github.com/nodejs/node/pull/62770)
-
\[[`b5ca5ad4c5`](https://redirect.github.com/nodejs/node/commit/b5ca5ad4c5)]
- **src**: simplify `TCPWrap::Connect` signature (Anna Henningsen)
[#​62929](https://redirect.github.com/nodejs/node/pull/62929)
-
\[[`ef7ffce7cf`](https://redirect.github.com/nodejs/node/commit/ef7ffce7cf)]
- **src**: use DCHECK in AsyncWrap::MakeCallback instead emiting a
warning (Gerhard Stöbich)
[#​62795](https://redirect.github.com/nodejs/node/pull/62795)
-
\[[`cd9890a5ab`](https://redirect.github.com/nodejs/node/commit/cd9890a5ab)]
- **src**: fix MaybeStackBuffer char\_traits deprecation warning
(om-ghante)
[#​62507](https://redirect.github.com/nodejs/node/pull/62507)
-
\[[`c70ff44aee`](https://redirect.github.com/nodejs/node/commit/c70ff44aee)]
- **src**: use context-free V8 message column getters (René)
[#​62778](https://redirect.github.com/nodejs/node/pull/62778)
-
\[[`06c405f1d7`](https://redirect.github.com/nodejs/node/commit/06c405f1d7)]
- **src**: coerce `spawnSync` args to string once (Antoine du Hamel)
[#​62633](https://redirect.github.com/nodejs/node/pull/62633)
-
\[[`6151999ad6`](https://redirect.github.com/nodejs/node/commit/6151999ad6)]
- **src**: use stack allocation for small string encoding (Ali Hassan)
[#​62431](https://redirect.github.com/nodejs/node/pull/62431)
-
\[[`a71a4ac7a3`](https://redirect.github.com/nodejs/node/commit/a71a4ac7a3)]
- **src**: add contextify interceptor debug logs (Chengzhong Wu)
[#​62460](https://redirect.github.com/nodejs/node/pull/62460)
-
\[[`ad9a2909c2`](https://redirect.github.com/nodejs/node/commit/ad9a2909c2)]
- **src**: workaround AIX libc++ std::filesystem bug (Richard Lau)
[#​62788](https://redirect.github.com/nodejs/node/pull/62788)
-
\[[`7792f1ae47`](https://redirect.github.com/nodejs/node/commit/7792f1ae47)]
- **stream**: copyedit `webstreams/adapter.js` (Antoine du Hamel)
[#​63034](https://redirect.github.com/nodejs/node/pull/63034)
-
\[[`1397d8ce5c`](https://redirect.github.com/nodejs/node/commit/1397d8ce5c)]
- **stream**: remove duplicated utility (Antoine du Hamel)
[#​63031](https://redirect.github.com/nodejs/node/pull/63031)
-
\[[`ff86b1d64f`](https://redirect.github.com/nodejs/node/commit/ff86b1d64f)]
- **stream**: simplify `setPromiseHandled` utility (Antoine du Hamel)
[#​63032](https://redirect.github.com/nodejs/node/pull/63032)
-
\[[`24a078149a`](https://redirect.github.com/nodejs/node/commit/24a078149a)]
- **stream**: validate ReadableStream.from iterator objects (Daeyeon
Jeong)
[#​62911](https://redirect.github.com/nodejs/node/pull/62911)
-
\[[`cfb1fa9680`](https://redirect.github.com/nodejs/node/commit/cfb1fa9680)]
- **stream**: reject duplicate nested transferables (Daeyeon Jeong)
[#​62831](https://redirect.github.com/nodejs/node/pull/62831)
-
\[[`d0c913758a`](https://redirect.github.com/nodejs/node/commit/d0c913758a)]
- **stream**: ensuring cross-destruction in \_duplexify to prevent leaks
(Daijiro Wachi)
[#​62824](https://redirect.github.com/nodejs/node/pull/62824)
-
\[[`978f5c15d7`](https://redirect.github.com/nodejs/node/commit/978f5c15d7)]
- **stream**: simplify `readableStreamFromIterable` (Antoine du Hamel)
[#​62651](https://redirect.github.com/nodejs/node/pull/62651)
-
\[[`3527646ba5`](https://redirect.github.com/nodejs/node/commit/3527646ba5)]
- **stream**: fix nested compose error propagation (Matteo Collina)
[#​62556](https://redirect.github.com/nodejs/node/pull/62556)
-
\[[`dfb9edef4f`](https://redirect.github.com/nodejs/node/commit/dfb9edef4f)]
- **stream**: allow shared array buffer sources in writable webstream
adapter (René)
[#​62163](https://redirect.github.com/nodejs/node/pull/62163)
-
\[[`f00cdab627`](https://redirect.github.com/nodejs/node/commit/f00cdab627)]
- **stream**: simplify `createPromiseCallback` (Antoine du Hamel)
[#​62650](https://redirect.github.com/nodejs/node/pull/62650)
-
\[[`3ed783535f`](https://redirect.github.com/nodejs/node/commit/3ed783535f)]
- **stream**: fix writev unhandled rejection in fromWeb (sangwook)
[#​62297](https://redirect.github.com/nodejs/node/pull/62297)
-
\[[`29b196694c`](https://redirect.github.com/nodejs/node/commit/29b196694c)]
- **stream**: noop pause/resume on destroyed streams (Robert Nagy)
[#​62557](https://redirect.github.com/nodejs/node/pull/62557)
-
\[[`d73dbb9fc8`](https://redirect.github.com/nodejs/node/commit/d73dbb9fc8)]
- **stream**: refactor duplexify to be less suceptible to prototype
pollution (Antoine du Hamel)
[#​62559](https://redirect.github.com/nodejs/node/pull/62559)
-
\[[`6f37f7e240`](https://redirect.github.com/nodejs/node/commit/6f37f7e240)]
- **(SEMVER-MINOR)** **stream**: propagate destruction in duplexPair
(Ahmed Elhor)
[#​61098](https://redirect.github.com/nodejs/node/pull/61098)
-
\[[`b8816580e9`](https://redirect.github.com/nodejs/node/commit/b8816580e9)]
- **test**: generate `localstorage.db` in a temp dir (Chengzhong Wu)
[#​62660](https://redirect.github.com/nodejs/node/pull/62660)
-
\[[`31a863fd29`](https://redirect.github.com/nodejs/node/commit/31a863fd29)]
- **test**: update WPT for url to
[`258f285`](https://redirect.github.com/nodejs/node/commit/258f285de0)
(Node.js GitHub Bot)
[#​63087](https://redirect.github.com/nodejs/node/pull/63087)
-
\[[`d0d19bd8e3`](https://redirect.github.com/nodejs/node/commit/d0d19bd8e3)]
- **test**: update WPT for streams to
[`f8f26a3`](https://redirect.github.com/nodejs/node/commit/f8f26a372f)
(Node.js GitHub Bot)
[#​62864](https://redirect.github.com/nodejs/node/pull/62864)
-
\[[`f50ac5bc78`](https://redirect.github.com/nodejs/node/commit/f50ac5bc78)]
- **test**: improve config-file permission test coverage (Rafael
Gonzaga)
[#​60929](https://redirect.github.com/nodejs/node/pull/60929)
-
\[[`a0f90000f4`](https://redirect.github.com/nodejs/node/commit/a0f90000f4)]
- **test**: export isRiscv64 from common module (Jamie Magee)
[#​62609](https://redirect.github.com/nodejs/node/pull/62609)
-
\[[`da4dd8646f`](https://redirect.github.com/nodejs/node/commit/da4dd8646f)]
- **test**: normalize known inspector crash as completion (Joyee Cheung)
[#​62851](https://redirect.github.com/nodejs/node/pull/62851)
-
\[[`b7fdd94a4c`](https://redirect.github.com/nodejs/node/commit/b7fdd94a4c)]
- **test**: account for RFC 7919 FFDHE negotiation in OpenSSL 4.0 (Filip
Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`375a993aaf`](https://redirect.github.com/nodejs/node/commit/375a993aaf)]
- **test**: skip tls-deprecated secp256k1 on OpenSSL 4.0 (Filip Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`698d8287d1`](https://redirect.github.com/nodejs/node/commit/698d8287d1)]
- **test**: use an always invalid cipher and cover OpenSSL 4.0
behaviours (Filip Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`036bc6f300`](https://redirect.github.com/nodejs/node/commit/036bc6f300)]
- **test**: use valid DER OCSP responses (Filip Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`3aa9938da8`](https://redirect.github.com/nodejs/node/commit/3aa9938da8)]
- **test**: skip test-tls-error-stack when engines are unsupported
(Filip Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`947f1ae246`](https://redirect.github.com/nodejs/node/commit/947f1ae246)]
- **test**: accept renamed OpenSSL 4.0 error code and reason (Filip
Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`afdd355622`](https://redirect.github.com/nodejs/node/commit/afdd355622)]
- **test**: update test/addons/openssl-binding for OpenSSL 4.0 (Filip
Skokan)
[#​62805](https://redirect.github.com/nodejs/node/pull/62805)
-
\[[`8637524a99`](https://redirect.github.com/nodejs/node/commit/8637524a99)]
- **test**: mark test-snapshot-reproducible flaky (Filip Skokan)
[#​62808](https://redirect.github.com/nodejs/node/pull/62808)
-
\[[`c22d34134b`](https://redirect.github.com/nodejs/node/commit/c22d34134b)]
- **test**: check contextify contextual store behavior in strict mode
(René)
[#​62571](https://redirect.github.com/nodejs/node/pull/62571)
-
\[[`0b4e0d3c94`](https://redirect.github.com/nodejs/node/commit/0b4e0d3c94)]
- **test**: update tls junk data error expectations (Filip Skokan)
[#​62629](https://redirect.github.com/nodejs/node/pull/62629)
-
\[[`85d83c2cdb`](https://redirect.github.com/nodejs/node/commit/85d83c2cdb)]
- **test**: ensure WPT report is in out/wpt (Filip Skokan)
[#​62637](https://redirect.github.com/nodejs/node/pull/62637)
-
\[[`9e21711c60`](https://redirect.github.com/nodejs/node/commit/9e21711c60)]
- **test**: improve WPT runner summary (Filip Skokan)
[#​62636](https://redirect.github.com/nodejs/node/pull/62636)
-
\[[`e04e2c9ac1`](https://redirect.github.com/nodejs/node/commit/e04e2c9ac1)]
- **test**: skip url WPT subtests instead of modifying test script
(Filip Skokan)
[#​62635](https://redirect.github.com/nodejs/node/pull/62635)
-
\[[`7b1211f88c`](https://redirect.github.com/nodejs/node/commit/7b1211f88c)]
- **test**: capture negative utimes mtime at call time (Yuya Inoue)
[#​62490](https://redirect.github.com/nodejs/node/pull/62490)
-
\[[`f1a6e9fcc7`](https://redirect.github.com/nodejs/node/commit/f1a6e9fcc7)]
- **test**: allow skipping individual WPT subtests (Filip Skokan)
[#​62517](https://redirect.github.com/nodejs/node/pull/62517)
-
\[[`23f927542e`](https://redirect.github.com/nodejs/node/commit/23f927542e)]
- **test**: use on-disk fixture for test-npm-install (Joyee Cheung)
[#​62584](https://redirect.github.com/nodejs/node/pull/62584)
-
\[[`4739c45879`](https://redirect.github.com/nodejs/node/commit/4739c45879)]
- **test**: update WPT for url to
[`7a3645b`](https://redirect.github.com/nodejs/node/commit/7a3645b79a)
(Node.js GitHub Bot)
[#​62591](https://redirect.github.com/nodejs/node/pull/62591)
-
\[[`f68189b839`](https://redirect.github.com/nodejs/node/commit/f68189b839)]
- **test\_runner**: add `testId` to test events (Moshe Atlow)
[#​62772](https://redirect.github.com/nodejs/node/pull/62772)
-
\[[`5c2770446e`](https://redirect.github.com/nodejs/node/commit/5c2770446e)]
- **test\_runner**: publish to TracingChannel for OTel instrumentation
(Moshe Atlow)
[#​62502](https://redirect.github.com/nodejs/node/pull/62502)
-
\[[`d14029be7f`](https://redirect.github.com/nodejs/node/commit/d14029be7f)]
- **(SEMVER-MINOR)** **test\_runner**: support test order randomization
(Pietro Marchini)
[#​61747](https://redirect.github.com/nodejs/node/pull/61747)
-
\[[`3f74a58979`](https://redirect.github.com/nodejs/node/commit/3f74a58979)]
- **test\_runner**: update node-config-schema (Pietro Marchini)
[#​58680](https://redirect.github.com/nodejs/node/pull/58680)
-
\[[`60c83f6199`](https://redirect.github.com/nodejs/node/commit/60c83f6199)]
- **test\_runner**: fix failing suite hooks when marked with `todo`
(Moshe Atlow)
[#​63097](https://redirect.github.com/nodejs/node/pull/63097)
-
\[[`d142c584cd`](https://redirect.github.com/nodejs/node/commit/d142c584cd)]
- **(SEMVER-MINOR)** **test\_runner**: align mock timeout api (sangwook)
[#​62820](https://redirect.github.com/nodejs/node/pull/62820)
-
\[[`3e72065ed6`](https://redirect.github.com/nodejs/node/commit/3e72065ed6)]
- **test\_runner**: fix suite rerun edge case (Moshe Atlow)
[#​62860](https://redirect.github.com/nodejs/node/pull/62860)
-
\[[`01a9552585`](https://redirect.github.com/nodejs/node/commit/01a9552585)]
- **(SEMVER-MINOR)** **test\_runner**: add mock-timers support for
AbortSignal.timeout (DeveloperViraj)
[#​60751](https://redirect.github.com/nodejs/node/pull/60751)
-
\[[`dd43efffa6`](https://redirect.github.com/nodejs/node/commit/dd43efffa6)]
- **test\_runner**: add passed, attempt, and diagnostic to SuiteContext
(Moshe Atlow)
[#​62504](https://redirect.github.com/nodejs/node/pull/62504)
-
\[[`a12dc445cc`](https://redirect.github.com/nodejs/node/commit/a12dc445cc)]
- **tools**: add a check for clean git tree after tests (Antoine du
Hamel)
[#​62661](https://redirect.github.com/nodejs/node/pull/62661)
-
\[[`5b49178375`](https://redirect.github.com/nodejs/node/commit/5b49178375)]
- **tools**: use LTS Node.js in notify-on-push workflow (Nenad Spasenic)
[#​63084](https://redirect.github.com/nodejs/node/pull/63084)
-
\[[`5a93bde5bb`](https://redirect.github.com/nodejs/node/commit/5a93bde5bb)]
- **tools**: update gr2m/create-or-update-pull-request-action to v1.10.1
(Mike McCready)
[#​63065](https://redirect.github.com/nodejs/node/pull/63065)
-
\[[`b133019d19`](https://redirect.github.com/nodejs/node/commit/b133019d19)]
- **tools**: simplify `update-undici.sh` (Antoine du Hamel)
[#​63044](https://redirect.github.com/nodejs/node/pull/63044)
-
\[[`04d3538074`](https://redirect.github.com/nodejs/node/commit/04d3538074)]
- **tools**: do not run `test-linux` on unrelated tools changes (Antoine
du Hamel)
[#​63037](https://redirect.github.com/nodejs/node/pull/63037)
-
\[[`4d396ac4a5`](https://redirect.github.com/nodejs/node/commit/4d396ac4a5)]
- **tools**: bump the eslint group in /tools/eslint with 4 updates
(dependabot\[bot])
[#​62848](https://redirect.github.com/nodejs/node/pull/62848)
-
\[[`9354bf40e7`](https://redirect.github.com/nodejs/node/commit/9354bf40e7)]
- **tools**: update gyp-next to 0.22.1 (Node.js GitHub Bot)
[#​62961](https://redirect.github.com/nodejs/node/pull/62961)
-
\[[`c23db1ca85`](https://redirect.github.com/nodejs/node/commit/c23db1ca85)]
- **tools**: fix commit linter for semver-major release proposals
(Antoine du Hamel)
[#​62993](https://redirect.github.com/nodejs/node/pull/62993)
-
\[[`6e097ee3f1`](https://redirect.github.com/nodejs/node/commit/6e097ee3f1)]
- **tools**: consolidate and simplify .editorconfig deps section
(Daijiro Wachi)
[#​62887](https://redirect.github.com/nodejs/node/pull/62887)
-
\[[`a47ea6d6ea`](https://redirect.github.com/nodejs/node/commit/a47ea6d6ea)]
- **tools**: set bot as author of tools-deps-update PRs (Antoine du
Hamel)
[#​62856](https://redirect.github.com/nodejs/node/pull/62856)
-
\[[`00e86f0471`](https://redirect.github.com/nodejs/node/commit/00e86f0471)]
- **tools**: bump brace-expansion from 5.0.4 to 5.0.5 in /tools/eslint
(dependabot\[bot])
[#​62458](https://redirect.github.com/nodejs/node/pull/62458)
-
\[[`cd7e262e75`](https://redirect.github.com/nodejs/node/commit/cd7e262e75)]
- **tools**: bump brace-expansion in /tools/clang-format
(dependabot\[bot])
[#​62467](https://redirect.github.com/nodejs/node/pull/62467)
-
\[[`bfc1319bc8`](https://redirect.github.com/nodejs/node/commit/bfc1319bc8)]
- **tools**: exclude
[@​node-core/doc-kit](https://redirect.github.com/node-core/doc-kit)
from dependabot cooldown (Levi Zim)
[#​62775](https://redirect.github.com/nodejs/node/pull/62775)
-
\[[`a932fbd10b`](https://redirect.github.com/nodejs/node/commit/a932fbd10b)]
- **tools**: re-enable undici WPTs in daily wpt.fyi job (Filip Skokan)
[#​62677](https://redirect.github.com/nodejs/node/pull/62677)
-
\[[`f7bd9e3055`](https://redirect.github.com/nodejs/node/commit/f7bd9e3055)]
- **tools**: update gyp-next to 0.22.0 (Node.js GitHub Bot)
[#​62697](https://redirect.github.com/nodejs/node/pull/62697)
-
\[[`c400d46d87`](https://redirect.github.com/nodejs/node/commit/c400d46d87)]
- **tools**: improve backport review script (Antoine du Hamel)
[#​62573](https://redirect.github.com/nodejs/node/pull/62573)
-
\[[`be23b75814`](https://redirect.github.com/nodejs/node/commit/be23b75814)]
- **tools**: improve output for unexpected passes in WTP tests (Antoine
du Hamel)
[#​62587](https://redirect.github.com/nodejs/node/pull/62587)
-
\[[`609c013ece`](https://redirect.github.com/nodejs/node/commit/609c013ece)]
- **tools**: revert OpenSSL update workflow to ubuntu-latest (Richard
Lau) [#​62627](https://redirect.github.com/nodejs/node/pull/62627)
-
\[[`81bac1ebfd`](https://redirect.github.com/nodejs/node/commit/81bac1ebfd)]
- **tools**: bump the eslint group in /tools/eslint with 2 updates
(dependabot\[bot])
[#​62552](https://redirect.github.com/nodejs/node/pull/62552)
-
\[[`1fee26522d`](https://redirect.github.com/nodejs/node/commit/1fee26522d)]
- **tools**: allow triagers to queue a PR for CI until it's reviewed
(Antoine du Hamel)
[#​62524](https://redirect.github.com/nodejs/node/pull/62524)
-
\[[`332088f929`](https://redirect.github.com/nodejs/node/commit/332088f929)]
- **tools**: do not run `commit-lint` on release proposals (Antoine du
Hamel)
[#​62523](https://redirect.github.com/nodejs/node/pull/62523)
-
\[[`9a25fc8a4d`](https://redirect.github.com/nodejs/node/commit/9a25fc8a4d)]
- **url**: process crash via malformed UNC hostname in pathToFileURL()
(Nicola Del Gobbo)
[#​62574](https://redirect.github.com/nodejs/node/pull/62574)
-
\[[`7bd08ff60a`](https://redirect.github.com/nodejs/node/commit/7bd08ff60a)]
- **url**: optimize URLSearchParams set/delete duplicate handling
(Gürgün Dayıoğlu)
[#​62266](https://redirect.github.com/nodejs/node/pull/62266)
-
\[[`2d636388fa`](https://redirect.github.com/nodejs/node/commit/2d636388fa)]
- **url**: align default argument handling for URLPattern with webidl
(Filip Skokan)
[#​62719](https://redirect.github.com/nodejs/node/pull/62719)
-
\[[`00705a459a`](https://redirect.github.com/nodejs/node/commit/00705a459a)]
- **(SEMVER-MINOR)** **util**: colorize text with hex colors (Guilherme
Araújo)
[#​61556](https://redirect.github.com/nodejs/node/pull/61556)
-
\[[`0e2adb3e45`](https://redirect.github.com/nodejs/node/commit/0e2adb3e45)]
- **watch**: track worker entry files in watch mode (SudhansuBandha)
[#​62368](https://redirect.github.com/nodejs/node/pull/62368)
-
\[[`c58fe38211`](https://redirect.github.com/nodejs/node/commit/c58fe38211)]
- **watch**: fix --env-file-if-exists crashing on linux if the file is
missing (Efe)
[#​61870](https://redirect.github.com/nodejs/node/pull/61870)
###
[`v24.15.0`](https://redirect.github.com/nodejs/node/compare/v24.14.1...v24.15.0)
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.14.1...v24.15.0)
###
[`v24.14.1`](https://redirect.github.com/nodejs/node/compare/v24.14.0...v24.14.1)
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.14.0...v24.14.1)
###
[`v24.14.0`](https://redirect.github.com/nodejs/node/compare/v24.13.1...v24.14.0)
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.13.1...v24.14.0)
###
[`v24.13.1`](https://redirect.github.com/nodejs/node/compare/v24.13.0...v24.13.1)
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.13.0...v24.13.1)
###
[`v24.13.0`](https://redirect.github.com/nodejs/node/releases/tag/v24.13.0):
2026-01-13, Version 24.13.0 'Krypton' (LTS), @​marco-ippolito
[Compare
Source](https://redirect.github.com/nodejs/node/compare/v24.12.0...v24.13.0)
This is a security release.
##### Notable Changes
lib:
- (CVE-2025-59465) add TLSSocket default error handler (RafaelGSS)
[nodejs-private/node-private#797](https://redirect.github.com/nodejs-private/node-private/pull/797)
- (CVE-2025-55132) disable futimes when permission model is enabled
(RafaelGSS)
[nodejs-private/node-private#748](https://redirect.github.com/nodejs-private/node-private/pull/748)
lib,permission:
- (CVE-2025-55130) require full read and write to symlink APIs
(RafaelGSS)
[nodejs-private/node-private#760](https://redirect.github.com/nodejs-private/node-private/pull/760)
src:
- (CVE-2025-59466) rethrow stack overflow exceptions in async\_hooks
(Matteo Collina)
[nodejs-private/node-private#773](https://redirect.github.com/nodejs-private/node-private/pull/773)
src,lib:
- (CVE-2025-55131) refactor unsafe buffer creation to remove zero-fill
toggle (Сковорода Никита Андреевич)
[nodejs-private/node-private#759](https://redirect.github.com/nodejs-private/node-private/pull/759)
tls:
- (CVE-2026-21637) route callback exceptions through error handlers
(Matteo Collina)
[nodejs-private/node-private#796](https://redirect.github.com/nodejs-private/node-private/pull/796)
##### Commits
-
\[[`2092785d01`](https://redirect.github.com/nodejs/node/commit/2092785d01)]
- **deps**: update c-ares to v1.34.6 (Node.js GitHub Bot)
[#​60997](https://redirect.github.com/nodejs/node/pull/60997)
-
\[[`3e58b7f2af`](https://redirect.github.com/nodejs/node/commit/3e58b7f2af)]
- **deps**: update undici to 7.18.2 (Node.js GitHub Bot)
[#​61283](https://redirect.github.com/nodejs/node/pull/61283)
-
\[[`4ba536a5a6`](https://redirect.github.com/nodejs/node/commit/4ba536a5a6)]
- **(CVE-2025-59465)** **lib**: add TLSSocket default error handler
(RafaelGSS)
[nodejs-private/node-private#797](https://redirect.github.com/nodejs-private/node-private/pull/797)
-
\[[`89adaa21fd`](https://redirect.github.com/nodejs/node/commit/89adaa21fd)]
- **(CVE-2025-55132)** **lib**: disable futimes when permission model is
enabled (RafaelGSS)
[nodejs-private/node-private#748](https://redirect.github.com/nodejs-private/node-private/pull/748)
-
\[[`7302b4dae1`](https://redirect.github.com/nodejs/node/commit/7302b4dae1)]
- **(CVE-2025-55130)** **lib,permission**: require full read and write
to symlink APIs (RafaelGSS)
[nodejs-private/node-private#760](https://redirect.github.com/nodejs-private/node-private/pull/760)
- \[[`ac030753c4`](https://redi
> ✂ **Note**
>
> PR body was truncated to here.
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- "before 6am on monday"
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/sleepypod/core).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsIm1ham9yIl19-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Why PR #416 bumped `.node-version` `22` → `24`, but that file only drives **dev/CI** (`actions/setup-node` reads `node-version-file: '.node-version'`). The **pod runtime** version is pinned independently in `scripts/install` (`NODE_WANTED` / `NODE_FULL`), so fresh pods would still install Node 22 — leaving dev/CI and production out of lockstep. ## What Bump the pod's Node pin to `24.16.0` (current v24 LTS, 'Krypton') so freshly-installed pods match the toolchain. ## Safety `better-sqlite3` (the only native dep) ships **N-API prebuilds** (`prebuilds/linux-<arch>/node.napi.node`) and is `pnpm install`-ed **on the pod**, not bundled from CI. N-API is ABI-stable across Node majors, so the 22 → 24 move carries no native-module ABI risk. The install script's existing SHA-256 verification covers the new tarball. The `CURRENT_NODE_MAJOR -lt NODE_WANTED` guard means pods already on Node ≥ 24 are left untouched; pods on 22 get upgraded on next install run. ## Test plan - `bash -n scripts/install` — syntax clean ✅ - Verified `https://nodejs.org/dist/v24.16.0/node-v24.16.0-linux-arm64.tar.gz` returns HTTP 200 ✅ - Manual: run installer on a clean pod, confirm `node -v` reports v24.16.0 and the app's better-sqlite3 module loads <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update chore/install-node-24 ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/chore/install-node-24/scripts/install \ | sudo bash -s -- --branch chore/install-node-24 ``` 🎯 **Pin to this exact build** ([run 27525355981](https://github.com/sleepypod/core/actions/runs/27525355981) · `f1338bb`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/f1338bb773b7c850ef61950cc71f7de5df5fddb9/scripts/install \ | sudo bash -s -- \ --branch chore/install-node-24 \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27525355981/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27525355981/artifacts/7629546769) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://redirect.github.com/microsoft/TypeScript)) | [`^5.9.3` → `^6.0.0`](https://renovatebot.com/diffs/npm/typescript/5.9.3/6.0.3) |  |  | --- ### Release Notes <details> <summary>microsoft/TypeScript (typescript)</summary> ### [`v6.0.3`](https://redirect.github.com/microsoft/TypeScript/compare/v6.0.2...050880ce59e30b356b686bd3144efe24f875ebc8) [Compare Source](https://redirect.github.com/microsoft/TypeScript/compare/v6.0.2...v6.0.3) ### [`v6.0.2`](https://redirect.github.com/microsoft/TypeScript/compare/v5.9.3...607a22a90d1a5a1b507ce01bb8cd7ec020f954e7) [Compare Source](https://redirect.github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.2) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDIuNyIsInVwZGF0ZWRJblZlciI6IjQzLjIxOS4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsIm1ham9yIl19--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/typescript-6.x ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/typescript-6.x/scripts/install \ | sudo bash -s -- --branch renovate/typescript-6.x ``` 🎯 **Pin to this exact build** ([run 27526054951](https://github.com/sleepypod/core/actions/runs/27526054951) · `3003ac9`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/3003ac964101578340465f6d642934110c9f35b1/scripts/install \ | sudo bash -s -- \ --branch renovate/typescript-6.x \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27526054951/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27526054951/artifacts/7629783757) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jonathan Ng <jon@jonathanng.com>
## Problem The `piezoStream` streaming tests flaked intermittently in CI (e.g. blocked #650 and #315), each run failing a *different* test in `src/streaming/tests/piezoStream.test.ts` with `waitFor`/`waitUntil` timeouts and a trailing `Hook timed out in 10000ms`. They always passed in isolation, which masked the cause as "slow CI." ## Root cause Two compounding bugs: 1. **Permanent frame loss from a connect race.** The file-tailing loop broadcasts live frames *only to currently-connected clients* (no backfill) and advances its read offset to EOF on the first 10ms tick. Tests that wrote the RAW file **before** connecting raced that first tick — under CPU contention the loop consumed the whole file before the client socket attached, so those frames were lost for good. Confirmed empirically: even with a 20s wait timeout the frames never arrived (`messages=[]`), proving permanent loss rather than slow delivery. 2. **Teardown hang cascade.** `WebSocketServer.close()` only fires its callback once every client has disconnected. When a test bailed before `client.close()` (because of #1), the still-open socket kept `shutdownPiezoStreamServer()` from ever resolving → the `afterEach` hook burned its full 10s timeout and reported a second failure. ## Fix - **Tests:** append RAW data only *after* the client connects, matching production (firmware appends to the RAW file while clients stream). This is the deterministic pattern a few tests already used (`subscribe filter`, `partial trailing record`). A comment on the `startAndPort` helper documents the ordering so it isn't "tidied" back. - **Production (`shutdownPiezoStreamServer`):** terminate live client sockets before `server.close()` so shutdown always completes — a real robustness bug, not test-only. ## Test plan - `pnpm run tsc` — clean - `eslint` on both changed files — clean - Full suite: `pnpm test run` → 109 files / 2124 passed, 1 skipped - **Repro harness:** saturate all cores (`yes > /dev/null` ×2·ncpu) and run the piezo file repeatedly: - Before: failed within ~2 runs (different test each time, `messages=[]` + 10s hook timeout) - After: **6/6 green** under the same saturation; 3/3 in isolation <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/piezo-stream-test-flake ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/piezo-stream-test-flake/scripts/install \ | sudo bash -s -- --branch fix/piezo-stream-test-flake ``` 🎯 **Pin to this exact build** ([run 27527119653](https://github.com/sleepypod/core/actions/runs/27527119653) · `1ace69b`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/1ace69bbd3bbf7232c2f6341b09052534dacd5fc/scripts/install \ | sudo bash -s -- \ --branch fix/piezo-stream-test-flake \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27527119653/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27527119653/artifacts/7630170313) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Bug Fixes** * Fixed server shutdown hang issue when WebSocket clients remain connected during shutdown process. * **Tests** * Updated streaming protocol tests to eliminate race conditions in data handling scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What Adds mutation-killing tests for `src/server/routers/system.ts`, the single largest cluster of surviving mutants in the weekly mutation-testing baseline (#591 — 167 surviving in that file). ## Why The existing suite asserted **outcomes** (parsed return values, error wrapping) but never the **exact commands** the router shells out. As a result every `StringLiteral` / `ArrayDeclaration` / `ObjectLiteral` mutant on the `df` / `du` / `iptables` / `journalctl` / `systemctl` / `nmcli` invocations survived — you could swap `'iptables'` for `''`, drop the `{ timeout }` option, or empty out an argv array and no test noticed. A handful of `Regex` / `ConditionalExpression` / `ArithmeticOperator` mutants also survived because single-space test fixtures never exercised them. ## How A `recordExec` helper captures every `execFile` call (binary, argv, options object) so tests can assert the literal commands, plus targeted edge-case fixtures: - **internetStatus** — `iptables -L OUTPUT -n`; anchored `^DROP\b` matching (a mid-line `DROP` and `DROPLET` must **not** read as blocked) - **setInternetAccess** — the complete ordered iptables flush + LAN-only ruleset for both block and unblock paths, and that rules are persisted from `iptables-save` - **wifiStatus / getLogSources / getLogs / getDiskUsage / getStorageBreakdown** — exact argv + `timeout`/`maxBuffer` option objects, service display names - **edge fixtures** — multi-whitespace `df` output (so `/\s+/` vs `/\s/` actually matters), zero-total `usedPercent` guard (no `Infinity`), the `lines + 1` pagination boundary (`>` vs `>=`), and the `"Unknown error"` / log-message branches ## Result `system.ts` mutation score **~52% → 94.5%** (167 → 17 survivors; the remainder are equivalent mutants — optional chaining on always-defined values, a no-op `nextCursor = null`, `/\s/` on a `[0]` access). Verified with `npx stryker run --mutate 'src/server/routers/system.ts'`. **No production code changed** — tests only. `pnpm vitest run` (51 pass), `tsc --noEmit`, and `eslint` all green. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update test/system-router-mutants-591 ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/test/system-router-mutants-591/scripts/install \ | sudo bash -s -- --branch test/system-router-mutants-591 ``` 🎯 **Pin to this exact build** ([run 27884384868](https://github.com/sleepypod/core/actions/runs/27884384868) · `6c639a1`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/6c639a17e3c173ab0c9cc36e929b24e3102f7a83/scripts/install \ | sudo bash -s -- \ --branch test/system-router-mutants-591 \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27884384868/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27884384868/artifacts/7769047411) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Expanded test coverage for system router endpoints, including validation of command execution, error handling, and edge cases across system operations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@base-ui/react](https://base-ui.com) ([source](https://redirect.github.com/mui/base-ui/tree/HEAD/packages/react)) | [`1.5.0` → `1.6.0`](https://renovatebot.com/diffs/npm/@base-ui%2freact/1.5.0/1.6.0) |  |  | | [@tailwindcss/postcss](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)) | [`4.3.0` → `4.3.1`](https://renovatebot.com/diffs/npm/@tailwindcss%2fpostcss/4.3.0/4.3.1) |  |  | | [@trpc/client](https://trpc.io) ([source](https://redirect.github.com/trpc/trpc/tree/HEAD/packages/client)) | [`11.17.0` → `11.18.0`](https://renovatebot.com/diffs/npm/@trpc%2fclient/11.17.0/11.18.0) |  |  | | [@trpc/next](https://trpc.io) ([source](https://redirect.github.com/trpc/trpc/tree/HEAD/packages/next)) | [`11.17.0` → `11.18.0`](https://renovatebot.com/diffs/npm/@trpc%2fnext/11.17.0/11.18.0) |  |  | | [@trpc/react-query](https://trpc.io) ([source](https://redirect.github.com/trpc/trpc/tree/HEAD/packages/react)) | [`11.17.0` → `11.18.0`](https://renovatebot.com/diffs/npm/@trpc%2freact-query/11.17.0/11.18.0) |  |  | | [@trpc/server](https://trpc.io) ([source](https://redirect.github.com/trpc/trpc/tree/HEAD/packages/server)) | [`11.17.0` → `11.18.0`](https://renovatebot.com/diffs/npm/@trpc%2fserver/11.17.0/11.18.0) |  |  | | [@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`25.9.3` → `25.9.4`](https://renovatebot.com/diffs/npm/@types%2fnode/25.9.3/25.9.4) |  |  | | [@vitest/coverage-v8](https://vitest.dev/guide/coverage) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8)) | [`4.1.8` → `4.1.9`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-v8/4.1.8/4.1.9) |  |  | | [better-sqlite3](https://redirect.github.com/WiseLibs/better-sqlite3) | [`12.10.0` → `12.11.1`](https://renovatebot.com/diffs/npm/better-sqlite3/12.10.0/12.11.1) |  |  | | [lucide-react](https://lucide.dev) ([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react)) | [`1.17.0` → `1.21.0`](https://renovatebot.com/diffs/npm/lucide-react/1.17.0/1.21.0) |  |  | | [pnpm](https://pnpm.io) ([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm)) | [`10.34.3` → `10.34.4`](https://renovatebot.com/diffs/npm/pnpm/10.34.3/10.34.4) |  |  | | [tailwindcss](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)) | [`4.3.0` → `4.3.1`](https://renovatebot.com/diffs/npm/tailwindcss/4.3.0/4.3.1) |  |  | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | [`8.61.0` → `8.61.1`](https://renovatebot.com/diffs/npm/typescript-eslint/8.61.0/8.61.1) |  |  | | [vitest](https://vitest.dev) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`4.1.8` → `4.1.9`](https://renovatebot.com/diffs/npm/vitest/4.1.8/4.1.9) |  |  | --- ### Release Notes <details> <summary>mui/base-ui (@​base-ui/react)</summary> ### [`v1.6.0`](https://redirect.github.com/mui/base-ui/blob/HEAD/CHANGELOG.md#v160) [Compare Source](https://redirect.github.com/mui/base-ui/compare/v1.5.0...v1.6.0) *Jun 18, 2026* ##### General changes - Correct inaccurate prop JSDoc ([#​5036](https://redirect.github.com/mui/base-ui/issues/5036)) by [@​atomiks](https://redirect.github.com/atomiks) - Update the hook value when store/arguments change ([#​4866](https://redirect.github.com/mui/base-ui/issues/4866)) by [@​chuganzy](https://redirect.github.com/chuganzy) - Restore viewport morphing after reopen for kept-mounted popups ([#​5010](https://redirect.github.com/mui/base-ui/issues/5010)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix pseudo-element bounds in dev mode ([#​5000](https://redirect.github.com/mui/base-ui/issues/5000)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Accordion - Fix trigger behavior bugs ([#​4833](https://redirect.github.com/mui/base-ui/issues/4833)) by [@​atomiks](https://redirect.github.com/atomiks) - Remove region role from `Accordion.Root` ([#​4961](https://redirect.github.com/mui/base-ui/issues/4961)) by [@​chuganzy](https://redirect.github.com/chuganzy) - Align keyboard navigation with APG ([#​4965](https://redirect.github.com/mui/base-ui/issues/4965)) by [@​chuganzy](https://redirect.github.com/chuganzy) ##### Alert Dialog - Fix programmatic focus return ([#​4849](https://redirect.github.com/mui/base-ui/issues/4849)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Autocomplete - Keep ArrowLeft/ArrowRight on the input caret in grid mode ([#​4948](https://redirect.github.com/mui/base-ui/issues/4948)) by [@​spokodev](https://redirect.github.com/spokodev) - Document `open` requirement for the `inline` prop ([#​5069](https://redirect.github.com/mui/base-ui/issues/5069)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Avatar - Fix image status edge cases ([#​4835](https://redirect.github.com/mui/base-ui/issues/4835)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Checkbox - Fix parent group cancellation and indeterminate state ([#​4941](https://redirect.github.com/mui/base-ui/issues/4941)) by [@​atomiks](https://redirect.github.com/atomiks) - Ignore `data-focused` Field attribute when disabled ([#​4998](https://redirect.github.com/mui/base-ui/issues/4998)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix extra `validate` fn calls ([#​4911](https://redirect.github.com/mui/base-ui/issues/4911)) by [@​mj12albert](https://redirect.github.com/mj12albert) ##### Checkbox Group - Fix parent group cancellation and indeterminate state ([#​4941](https://redirect.github.com/mui/base-ui/issues/4941)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix parent checkbox with custom `validate` fn ([#​4912](https://redirect.github.com/mui/base-ui/issues/4912)) by [@​mj12albert](https://redirect.github.com/mj12albert) - Fix validation with multiple required checkboxes ([#​4958](https://redirect.github.com/mui/base-ui/issues/4958)) by [@​atomiks](https://redirect.github.com/atomiks) - Forward group ids ([#​4997](https://redirect.github.com/mui/base-ui/issues/4997)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Collapsible - Fix trigger and panel state bugs ([#​4848](https://redirect.github.com/mui/base-ui/issues/4848)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Combobox - Fix chip context error ([#​4877](https://redirect.github.com/mui/base-ui/issues/4877)) by [@​lyzno1](https://redirect.github.com/lyzno1) - Keep ArrowLeft/ArrowRight on the input caret in grid mode ([#​4948](https://redirect.github.com/mui/base-ui/issues/4948)) by [@​spokodev](https://redirect.github.com/spokodev) - Avoid re-rendering every item on each keystroke ([#​4964](https://redirect.github.com/mui/base-ui/issues/4964)) by [@​flaviendelangle](https://redirect.github.com/flaviendelangle) - Fix autofill and selected state edge cases ([#​4972](https://redirect.github.com/mui/base-ui/issues/4972)) by [@​atomiks](https://redirect.github.com/atomiks) - Document `open` requirement for the `inline` prop ([#​5069](https://redirect.github.com/mui/base-ui/issues/5069)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Dialog - Fix confirmation return focus ([#​5024](https://redirect.github.com/mui/base-ui/issues/5024)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix programmatic focus return ([#​4849](https://redirect.github.com/mui/base-ui/issues/4849)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix positioning and viewport edge cases ([#​4925](https://redirect.github.com/mui/base-ui/issues/4925)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix non-modal focus-out close and tabindex management ([#​5030](https://redirect.github.com/mui/base-ui/issues/5030)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Drawer - Fix confirmation return focus ([#​5024](https://redirect.github.com/mui/base-ui/issues/5024)) by [@​atomiks](https://redirect.github.com/atomiks) - Improve swipe dismiss drag performance ([#​4867](https://redirect.github.com/mui/base-ui/issues/4867)) by [@​atomiks](https://redirect.github.com/atomiks) - Drive swipe gestures natively to stop per-frame re-rasterization ([#​4980](https://redirect.github.com/mui/base-ui/issues/4980)) by [@​atomiks](https://redirect.github.com/atomiks) - Add virtual keyboard provider ([#​4353](https://redirect.github.com/mui/base-ui/issues/4353)) by [@​atomiks](https://redirect.github.com/atomiks) - Commit swipe on primary-button release ([#​5057](https://redirect.github.com/mui/base-ui/issues/5057)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Field - Fix form validation bugs ([#​4873](https://redirect.github.com/mui/base-ui/issues/4873)) by [@​atomiks](https://redirect.github.com/atomiks) - Reflect disabled `Field.Item` state in `Field.Label` ([#​4916](https://redirect.github.com/mui/base-ui/issues/4916)) by [@​chuganzy](https://redirect.github.com/chuganzy) - Reflect disabled `Field.Item` state in `Field.Description` ([#​4960](https://redirect.github.com/mui/base-ui/issues/4960)) by [@​chuganzy](https://redirect.github.com/chuganzy) - Fix valueMissing revalidation ([#​4995](https://redirect.github.com/mui/base-ui/issues/4995)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix validation bugs ([#​4894](https://redirect.github.com/mui/base-ui/issues/4894)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Fieldset - Fix disabled fieldset form bugs ([#​4890](https://redirect.github.com/mui/base-ui/issues/4890)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Form - Fix form validation bugs ([#​4873](https://redirect.github.com/mui/base-ui/issues/4873)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Menu - Fix submenu trigger interactions ([#​4892](https://redirect.github.com/mui/base-ui/issues/4892)) by [@​atomiks](https://redirect.github.com/atomiks) - Open submenus on hover after a plain delay ([#​4990](https://redirect.github.com/mui/base-ui/issues/4990)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix controlled hover leave close ([#​4893](https://redirect.github.com/mui/base-ui/issues/4893)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix positioning and viewport edge cases ([#​4925](https://redirect.github.com/mui/base-ui/issues/4925)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Menubar - Fix vertical menu focus behavior ([#​4922](https://redirect.github.com/mui/base-ui/issues/4922)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Meter - Sync value text with indicator ([#​4904](https://redirect.github.com/mui/base-ui/issues/4904)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Navigation Menu - Preserve exit transition when controlled ([#​4855](https://redirect.github.com/mui/base-ui/issues/4855)) by [@​mattrothenberg](https://redirect.github.com/mattrothenberg) - Fix interaction, value, and styling-hook bugs ([#​4942](https://redirect.github.com/mui/base-ui/issues/4942)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Number Field - Handle unreadable clipboard paste ([#​4876](https://redirect.github.com/mui/base-ui/issues/4876)) by [@​lyzno1](https://redirect.github.com/lyzno1) - Fix committed values and keyboard stepping ([#​4905](https://redirect.github.com/mui/base-ui/issues/4905)) by [@​atomiks](https://redirect.github.com/atomiks) - Respect Intl rounding options on blur ([#​4804](https://redirect.github.com/mui/base-ui/issues/4804)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix formatter locale cache ([#​4999](https://redirect.github.com/mui/base-ui/issues/4999)) by [@​atomiks](https://redirect.github.com/atomiks) - Preserve numeric precision while keeping default display formatting ([#​5040](https://redirect.github.com/mui/base-ui/issues/5040)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix input and scrub edge cases ([#​5046](https://redirect.github.com/mui/base-ui/issues/5046)) by [@​atomiks](https://redirect.github.com/atomiks) ##### OTP Field - 🚨 **Breaking change:** Unmark preview<br /> the namespace export is renamed `OTPFieldPreview` → `OTPField` and should be imported as: `{ OTPField } from '@​base-ui/react/otp-field'` ([#​5029](https://redirect.github.com/mui/base-ui/issues/5029)) by [@​atomiks](https://redirect.github.com/atomiks) - Avoid password manager bubbles after first input ([#​4868](https://redirect.github.com/mui/base-ui/issues/4868)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Popover - Fix controlled hover leave close ([#​4893](https://redirect.github.com/mui/base-ui/issues/4893)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix programmatic focus return ([#​4849](https://redirect.github.com/mui/base-ui/issues/4849)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix positioning and viewport edge cases ([#​4925](https://redirect.github.com/mui/base-ui/issues/4925)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix non-modal focus-out close and tabindex management ([#​5030](https://redirect.github.com/mui/base-ui/issues/5030)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Preview Card - Fix controlled hover leave close ([#​4893](https://redirect.github.com/mui/base-ui/issues/4893)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix positioning and viewport edge cases ([#​4925](https://redirect.github.com/mui/base-ui/issues/4925)) by [@​atomiks](https://redirect.github.com/atomiks) - Keep inline preview anchored while open ([#​4836](https://redirect.github.com/mui/base-ui/issues/4836)) by [@​atomiks](https://redirect.github.com/atomiks) - Close when active trigger unmounts ([#​4886](https://redirect.github.com/mui/base-ui/issues/4886)) by [@​michaldudak](https://redirect.github.com/michaldudak) ##### Radio Group - Forward group ids ([#​4997](https://redirect.github.com/mui/base-ui/issues/4997)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix selection on space key press ([#​4930](https://redirect.github.com/mui/base-ui/issues/4930)) by [@​chuganzy](https://redirect.github.com/chuganzy) - Fix disabled selected form submission ([#​4926](https://redirect.github.com/mui/base-ui/issues/4926)) by [@​atomiks](https://redirect.github.com/atomiks) - Honor canceled value changes ([#​4996](https://redirect.github.com/mui/base-ui/issues/4996)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Scroll Area - Fix overflow and scrolling state ([#​4936](https://redirect.github.com/mui/base-ui/issues/4936)) by [@​atomiks](https://redirect.github.com/atomiks) - Add scrolling state to Thumb ([#​4982](https://redirect.github.com/mui/base-ui/issues/4982)) by [@​aarongarciah](https://redirect.github.com/aarongarciah) ##### Select - Fix autofill and selected state edge cases ([#​4934](https://redirect.github.com/mui/base-ui/issues/4934)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix dirty state not clearing in multiple mode ([#​4971](https://redirect.github.com/mui/base-ui/issues/4971)) by [@​atomiks](https://redirect.github.com/atomiks) - Skip disabled items in typeahead and fix multiple-mode serialization ([#​5025](https://redirect.github.com/mui/base-ui/issues/5025)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Slider - Fix extra `validate` fn calls ([#​4911](https://redirect.github.com/mui/base-ui/issues/4911)) by [@​mj12albert](https://redirect.github.com/mj12albert) - Fix interaction edge cases ([#​4937](https://redirect.github.com/mui/base-ui/issues/4937)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix touchend listener accumulation leak ([#​5070](https://redirect.github.com/mui/base-ui/issues/5070)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Switch - Fix extra `validate` fn calls ([#​4911](https://redirect.github.com/mui/base-ui/issues/4911)) by [@​mj12albert](https://redirect.github.com/mj12albert) ##### Tabs - Fix state edge cases ([#​4935](https://redirect.github.com/mui/base-ui/issues/4935)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix suspended panel activation ([#​4903](https://redirect.github.com/mui/base-ui/issues/4903)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Toast - Fix timer and limit edge cases ([#​4933](https://redirect.github.com/mui/base-ui/issues/4933)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Toggle - Fix grouped cancelation and JSDoc ([#​4940](https://redirect.github.com/mui/base-ui/issues/4940)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Toggle Group - Fix grouped cancelation and JSDoc ([#​4940](https://redirect.github.com/mui/base-ui/issues/4940)) by [@​atomiks](https://redirect.github.com/atomiks) - Remove invalid `aria-orientation` from `role="group"` element ([#​4628](https://redirect.github.com/mui/base-ui/issues/4628)) by [@​sernstberger](https://redirect.github.com/sernstberger) - Fix disabled state and roving focus bugs ([#​4968](https://redirect.github.com/mui/base-ui/issues/4968)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Toolbar - Do not forward `disabled` to default toolbar button ([#​4967](https://redirect.github.com/mui/base-ui/issues/4967)) by [@​mj12albert](https://redirect.github.com/mj12albert) - Fix disabled state and roving focus bugs ([#​4968](https://redirect.github.com/mui/base-ui/issues/4968)) by [@​atomiks](https://redirect.github.com/atomiks) ##### Tooltip - Fix positioning and viewport edge cases ([#​4925](https://redirect.github.com/mui/base-ui/issues/4925)) by [@​atomiks](https://redirect.github.com/atomiks) - Fix provider delay group lifecycle ([#​4887](https://redirect.github.com/mui/base-ui/issues/4887)) by [@​michaldudak](https://redirect.github.com/michaldudak) - Reset preventUnmountOnClose on reopen ([#​4885](https://redirect.github.com/mui/base-ui/issues/4885)) by [@​michaldudak](https://redirect.github.com/michaldudak) - Close when active trigger unmounts ([#​4886](https://redirect.github.com/mui/base-ui/issues/4886)) by [@​michaldudak](https://redirect.github.com/michaldudak) All contributors of this release in alphabetical order: [@​aarongarciah](https://redirect.github.com/aarongarciah), [@​atomiks](https://redirect.github.com/atomiks), [@​chuganzy](https://redirect.github.com/chuganzy), [@​flaviendelangle](https://redirect.github.com/flaviendelangle), [@​lyzno1](https://redirect.github.com/lyzno1), [@​mattrothenberg](https://redirect.github.com/mattrothenberg), [@​michaldudak](https://redirect.github.com/michaldudak), [@​mj12albert](https://redirect.github.com/mj12albert), [@​sernstberger](https://redirect.github.com/sernstberger), [@​spokodev](https://redirect.github.com/spokodev) </details> <details> <summary>tailwindlabs/tailwindcss (@​tailwindcss/postcss)</summary> ### [`v4.3.1`](https://redirect.github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#431---2026-06-12) [Compare Source](https://redirect.github.com/tailwindlabs/tailwindcss/compare/v4.3.0...v4.3.1) ##### Added - Add `--silent` option to suppress output in `@tailwindcss/cli` ([#​20100](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100)) ##### Fixed - Remove deprecation warnings by using `Module#registerHooks` instead of `Module#register` on Node 26+ ([#​20028](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028)) - Canonicalization: don't crash when plugin utilities throw for unsupported values ([#​20052](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052)) - Allow `@apply` to be used with CSS mixins ([#​19427](https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427)) - Ensure `not-*` correctly negates `@container` queries, including `style(…)` queries ([#​20059](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059)) - Ensure `drop-shadow-*` color utilities work with custom shadow values containing `calc(…)` ([#​20080](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080)) - Fix 'Sourcemap is likely to be incorrect' warnings when using `@tailwindcss/vite` ([#​20103](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103)) - Ensure `@tailwindcss/webpack` can be installed in Rspack projects without requiring `webpack` as a peer dependency ([#​20027](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027)) - Canonicalization: don't suggest invalid `calc(…)` expressions (e.g. `px-[calc(1rem+0px)]` → `px-[calc(1rem+0)]`) ([#​20127](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127)) - Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. `left-[99999px]` → `left-[99999px]`, not `left-24999.75`) ([#​20130](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130)) - Ensure `@tailwindcss/cli` in `--watch` mode recovers when a tracked dependency is deleted and restored ([#​20137](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137)) - Ensure standalone `@tailwindcss/cli` binaries are ignored when scanning for class candidates ([#​20139](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139)) - Ensure class candidates are extracted from Twig `addClass(…)` and `removeClass(…)` calls ([#​20198](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198)) - Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes ([#​19588](https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588)) - Allow `@variant` to be used inside `addBase` ([#​19480](https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480)) - Ensure `@source` globs with symlinks are preserved ([#​20203](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203)) - Ensure later `@source` rules can re-include files excluded by earlier `@source not` rules ([#​20203](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203)) - Upgrade: don't migrate empty class rules to invalid `@utility` rules ([#​20205](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205)) - Ensure transitions between `inset-shadow-none` and other inset shadows work correctly ([#​20208](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208)) - Ensure explicitly referenced `@source` directories are scanned even when ignored by git ([#​20214](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214)) - Ensure `@source` globs ending in `**/*` preserve dynamic path segments to avoid scanning too many files ([#​20217](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217)) - Canonicalization: don't fold `calc(…)` divisions when the result would require high precision (e.g. `w-[calc(100%/3.5)]` → `w-[calc(100%/3.5)]`, not `w-[28.571428571428573%]`) ([#​20221](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221)) - Serve ESM type declarations to ESM importers of `@tailwindcss/postcss` ([#​20228](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228)) ##### Changed - Generate `0` instead of `calc(var(--spacing) * 0)` for spacing utilities like `m-0` and `left-0` ([#​20196](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196)) - Generate `var(--spacing)` instead of `calc(var(--spacing) * 1)` for spacing utilities like `m-1` and `left-1` ([#​20196](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196)) </details> <details> <summary>trpc/trpc (@​trpc/client)</summary> ### [`v11.18.0`](https://redirect.github.com/trpc/trpc/releases/tag/v11.18.0) [Compare Source](https://redirect.github.com/trpc/trpc/compare/v11.17.0...v11.18.0) ##### What's Changed - fix(ci): restore tests package version and pin Bun by [@​KATT](https://redirect.github.com/KATT) in [#​7393](https://redirect.github.com/trpc/trpc/pull/7393) - fix(tanstack-react-query): add prefix support for mutation options by [@​tmkx](https://redirect.github.com/tmkx) in [#​7370](https://redirect.github.com/trpc/trpc/pull/7370) - chore: fix duplicate "the" in unstable-core JSDoc comment by [@​dfedoryshchev](https://redirect.github.com/dfedoryshchev) in [#​7366](https://redirect.github.com/trpc/trpc/pull/7366) - feat(openapi): Add server url support by [@​Nick-Lucas](https://redirect.github.com/Nick-Lucas) in [#​7411](https://redirect.github.com/trpc/trpc/pull/7411) ##### New Contributors - [@​dfedoryshchev](https://redirect.github.com/dfedoryshchev) made their first contribution in [#​7366](https://redirect.github.com/trpc/trpc/pull/7366) **Full Changelog**: <trpc/trpc@v11.17.0...v11.18.0> </details> <details> <summary>vitest-dev/vitest (@​vitest/coverage-v8)</summary> ### [`v4.1.9`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.9) [Compare Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9) ##### 🐞 Bug Fixes - Fix `importOriginal` with optimizer and query import \[backport to v4] - by **Hiroshi Ogawa**, **David Harris**, **Codex**and **Vladimir** in [#​10546](https://redirect.github.com/vitest-dev/vitest/issues/10546) [<samp>(a5180)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/a5180190c) - **browser**: - Wait for orchestrator readiness before resolving browser sessions \[backport to v4] - by **Vladimir** and **Séamus O'Connor** in [#​10555](https://redirect.github.com/vitest-dev/vitest/issues/10555) [<samp>(7fb29)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7fb29651a) - Wait for iframe tester readiness before preparing \[backport to v4] - by **Vladimir** and **Séamus O'Connor** in [#​10497](https://redirect.github.com/vitest-dev/vitest/issues/10497) and [#​10556](https://redirect.github.com/vitest-dev/vitest/issues/10556) [<samp>(fbc62)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/fbc626c40) - **mocker**: - Hoist vi.mock() for vite-plus/test imports \[backport to v4] - by **Hiroshi Ogawa**, **LongYinan**, **Claude Opus 4.8** and **Vladimir** in [#​10548](https://redirect.github.com/vitest-dev/vitest/issues/10548) [<samp>(2c955)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/2c9559c02) - **pool**: - Prevent test run hang on worker crash \[backport to v4] - by **Ari Perkkiö** and **Jattioui Ismail** in [#​10543](https://redirect.github.com/vitest-dev/vitest/issues/10543) and [#​10564](https://redirect.github.com/vitest-dev/vitest/issues/10564) [<samp>(934b0)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/934b0f587) ##### [View changes on GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9) </details> <details> <summary>WiseLibs/better-sqlite3 (better-sqlite3)</summary> ### [`v12.11.1`](https://redirect.github.com/WiseLibs/better-sqlite3/releases/tag/v12.11.1) [Compare Source](https://redirect.github.com/WiseLibs/better-sqlite3/compare/v12.10.1...v12.11.1) #### What's Changed - Fix Electron v42 build errors on Windows by [@​m4heshd](https://redirect.github.com/m4heshd) in [#​1488](https://redirect.github.com/WiseLibs/better-sqlite3/pull/1488) **Full Changelog**: <WiseLibs/better-sqlite3@v12.11.0...v12.11.1> ### [`v12.10.1`](https://redirect.github.com/WiseLibs/better-sqlite3/releases/tag/v12.10.1) [Compare Source](https://redirect.github.com/WiseLibs/better-sqlite3/compare/v12.10.0...v12.10.1) #### What's Changed - Bump the github-actions group across 1 directory with 4 updates by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​1451](https://redirect.github.com/WiseLibs/better-sqlite3/pull/1451) - Fix V8 external API usage for Electron 42 by [@​tstone-1](https://redirect.github.com/tstone-1) in [#​1475](https://redirect.github.com/WiseLibs/better-sqlite3/pull/1475) **Full Changelog**: <WiseLibs/better-sqlite3@v12.10.0...v12.10.1> </details> <details> <summary>lucide-icons/lucide (lucide-react)</summary> ### [`v1.21.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.21.0): Version 1.21.0 [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.20.0...1.21.0) #### What's Changed - ci(release.yml): Remove new-version in release flow by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4478](https://redirect.github.com/lucide-icons/lucide/pull/4478) - ci(release.yml): Fix workflow and remove `version` scripts in package scripts by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4479](https://redirect.github.com/lucide-icons/lucide/pull/4479) - fix(docs): rename navigation category label by [@​Hsiii](https://redirect.github.com/Hsiii) in [#​4483](https://redirect.github.com/lucide-icons/lucide/pull/4483) - feat(icons): added `broken-bone` icon by [@​Patolord](https://redirect.github.com/Patolord) in [#​4131](https://redirect.github.com/lucide-icons/lucide/pull/4131) #### New Contributors - [@​Hsiii](https://redirect.github.com/Hsiii) made their first contribution in [#​4483](https://redirect.github.com/lucide-icons/lucide/pull/4483) - [@​Patolord](https://redirect.github.com/Patolord) made their first contribution in [#​4131](https://redirect.github.com/lucide-icons/lucide/pull/4131) **Full Changelog**: <lucide-icons/lucide@1.20.0...1.21.0> ### [`v1.20.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.20.0): Version 1.20.0 [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.19.0...1.20.0) #### What's Changed - fix(icons): decreased size of arrows inside `square-arrow-*` icons by [@​jguddas](https://redirect.github.com/jguddas) in [#​3926](https://redirect.github.com/lucide-icons/lucide/pull/3926) - chore(tags): Add tags to `search-` icons by [@​jamiemlaw](https://redirect.github.com/jamiemlaw) in [#​4099](https://redirect.github.com/lucide-icons/lucide/pull/4099) - feat(icons): added `save-check` icon by [@​Konixy](https://redirect.github.com/Konixy) in [#​3120](https://redirect.github.com/lucide-icons/lucide/pull/3120) - feat(icons): added `tag-plus` and `tag-x` icons by [@​adam-kov](https://redirect.github.com/adam-kov) in [#​3980](https://redirect.github.com/lucide-icons/lucide/pull/3980) - feat(icons): added `banknote-check` icon by [@​mfjramirezf](https://redirect.github.com/mfjramirezf) in [#​3956](https://redirect.github.com/lucide-icons/lucide/pull/3956) - feat(icons): added `clock-arrow-in` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2403](https://redirect.github.com/lucide-icons/lucide/pull/2403) - feat(icons): added `summary` icon by [@​jpjacobpadilla](https://redirect.github.com/jpjacobpadilla) in [#​3114](https://redirect.github.com/lucide-icons/lucide/pull/3114) - feat(icons): added `user-round-arrow-in` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2283](https://redirect.github.com/lucide-icons/lucide/pull/2283) - feat(icons): added `clock-arrow-out` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2404](https://redirect.github.com/lucide-icons/lucide/pull/2404) - docs(docs): fix broken Svelte package source link in README by [@​SRKrukowski](https://redirect.github.com/SRKrukowski) in [#​4468](https://redirect.github.com/lucide-icons/lucide/pull/4468) - chore(deps-dev): bump [@​angular/compiler](https://redirect.github.com/angular/compiler) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4474](https://redirect.github.com/lucide-icons/lucide/pull/4474) - chore(deps-dev): bump [@​angular/core](https://redirect.github.com/angular/core) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4470](https://redirect.github.com/lucide-icons/lucide/pull/4470) - chore(deps-dev): bump vitest from 4.0.12 to 4.1.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4429](https://redirect.github.com/lucide-icons/lucide/pull/4429) - chore(deps-dev): bump markdown-it from 14.1.1 to 14.2.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4475](https://redirect.github.com/lucide-icons/lucide/pull/4475) - chore(deps-dev): bump [@​angular/common](https://redirect.github.com/angular/common) from 21.2.5 to 21.2.17 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​4471](https://redirect.github.com/lucide-icons/lucide/pull/4471) - feat(icons): added `pencil-sparkles` icon by [@​jennieboops](https://redirect.github.com/jennieboops) in [#​4445](https://redirect.github.com/lucide-icons/lucide/pull/4445) #### New Contributors - [@​Konixy](https://redirect.github.com/Konixy) made their first contribution in [#​3120](https://redirect.github.com/lucide-icons/lucide/pull/3120) - [@​adam-kov](https://redirect.github.com/adam-kov) made their first contribution in [#​3980](https://redirect.github.com/lucide-icons/lucide/pull/3980) - [@​mfjramirezf](https://redirect.github.com/mfjramirezf) made their first contribution in [#​3956](https://redirect.github.com/lucide-icons/lucide/pull/3956) - [@​SRKrukowski](https://redirect.github.com/SRKrukowski) made their first contribution in [#​4468](https://redirect.github.com/lucide-icons/lucide/pull/4468) - [@​jennieboops](https://redirect.github.com/jennieboops) made their first contribution in [#​4445](https://redirect.github.com/lucide-icons/lucide/pull/4445) **Full Changelog**: <lucide-icons/lucide@1.19.0...1.20.0> ### [`v1.19.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.19.0): Version 1.19.0 [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.18.0...1.19.0) #### What's Changed - chore(deps): upgrade pnpm to version 11.6.0 by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4458](https://redirect.github.com/lucide-icons/lucide/pull/4458) - feat(icons): added `star-*` icons by [@​RajnishKMehta](https://redirect.github.com/RajnishKMehta) in [#​3918](https://redirect.github.com/lucide-icons/lucide/pull/3918) - chore(suggest-tags): Update metadata suggestion script by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4462](https://redirect.github.com/lucide-icons/lucide/pull/4462) - feat(icons): added `save-pen` icon by [@​vaporvee](https://redirect.github.com/vaporvee) in [#​4179](https://redirect.github.com/lucide-icons/lucide/pull/4179) - feat(icons): added `wrench-off` icon by [@​nilsjonsson](https://redirect.github.com/nilsjonsson) in [#​4434](https://redirect.github.com/lucide-icons/lucide/pull/4434) - feat(icons): added `ad` icon by [@​jamiemlaw](https://redirect.github.com/jamiemlaw) in [#​4323](https://redirect.github.com/lucide-icons/lucide/pull/4323) - feat(icons): added `eye-dashed` icon by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4415](https://redirect.github.com/lucide-icons/lucide/pull/4415) - feat(icons): added `save-plus` icon by [@​jwlinqx](https://redirect.github.com/jwlinqx) in [#​4448](https://redirect.github.com/lucide-icons/lucide/pull/4448) - feat(icons): added `list-sort-descending` icon by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4457](https://redirect.github.com/lucide-icons/lucide/pull/4457) - fix(lucide-react-native): Fix provider exports by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4463](https://redirect.github.com/lucide-icons/lucide/pull/4463) - fix(site): reserve space for icon detail drawer by [@​vyctorbrzezowski](https://redirect.github.com/vyctorbrzezowski) in [#​4344](https://redirect.github.com/lucide-icons/lucide/pull/4344) - fix(icons): changed `wallet-cards` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​3888](https://redirect.github.com/lucide-icons/lucide/pull/3888) - feat(site): Improve search and add sorting options by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4453](https://redirect.github.com/lucide-icons/lucide/pull/4453) - feat(icons): added `podium` icon by [@​jguddas](https://redirect.github.com/jguddas) in [#​2124](https://redirect.github.com/lucide-icons/lucide/pull/2124) #### New Contributors - [@​vaporvee](https://redirect.github.com/vaporvee) made their first contribution in [#​4179](https://redirect.github.com/lucide-icons/lucide/pull/4179) - [@​nilsjonsson](https://redirect.github.com/nilsjonsson) made their first contribution in [#​4434](https://redirect.github.com/lucide-icons/lucide/pull/4434) - [@​jwlinqx](https://redirect.github.com/jwlinqx) made their first contribution in [#​4448](https://redirect.github.com/lucide-icons/lucide/pull/4448) - [@​vyctorbrzezowski](https://redirect.github.com/vyctorbrzezowski) made their first contribution in [#​4344](https://redirect.github.com/lucide-icons/lucide/pull/4344) **Full Changelog**: <lucide-icons/lucide@1.18.0...1.19.0> ### [`v1.18.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.18.0): Version 1.18.0 [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.17.0...1.18.0) #### What's Changed - chore(site): Remove survey from site by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4417](https://redirect.github.com/lucide-icons/lucide/pull/4417) - feat(icons): added `play-off` icon by [@​Ahmed-Dghaies](https://redirect.github.com/Ahmed-Dghaies) in [#​4412](https://redirect.github.com/lucide-icons/lucide/pull/4412) - fix(metadata): add missing use-cases prop on play-off.json by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4423](https://redirect.github.com/lucide-icons/lucide/pull/4423) - fix(docs): force hide #bb-banner, if html.has-bb-banner is missing by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4422](https://redirect.github.com/lucide-icons/lucide/pull/4422) - fix(docs): Remove `@next` from installation instructions for`@lucide/svelte` by [@​alecglassford](https://redirect.github.com/alecglassford) in [#​4432](https://redirect.github.com/lucide-icons/lucide/pull/4432) - feat(packages/angular): add support for Angular v22 and onwards by [@​karsa-mistmere](https://redirect.github.com/karsa-mistmere) in [#​4450](https://redirect.github.com/lucide-icons/lucide/pull/4450) - fix(ci): add check to skip release if latest tag was created today by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4085](https://redirect.github.com/lucide-icons/lucide/pull/4085) - feat(icons): added `webcam-off` icon by [@​jordan-burnett](https://redirect.github.com/jordan-burnett) in [#​4242](https://redirect.github.com/lucide-icons/lucide/pull/4242) #### New Contributors - [@​alecglassford](https://redirect.github.com/alecglassford) made their first contribution in [#​4432](https://redirect.github.com/lucide-icons/lucide/pull/4432) - [@​jordan-burnett](https://redirect.github.com/jordan-burnett) made their first contribution in [#​4242](https://redirect.github.com/lucide-icons/lucide/pull/4242) **Full Changelog**: <lucide-icons/lucide@1.17.0...1.18.0> </details> <details> <summary>pnpm/pnpm (pnpm)</summary> ### [`v10.34.4`](https://redirect.github.com/pnpm/pnpm/compare/v10.34.3...v10.34.4) [Compare Source](https://redirect.github.com/pnpm/pnpm/compare/v10.34.3...v10.34.4) </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.61.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8611-2026-06-15) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.61.0...v8.61.1) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.61.1) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMzUuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIzNS4wIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsImZpeC1wYXRjaCIsIm5vbi1tYWpvciJdfQ==--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/all-minor-patch ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/all-minor-patch/scripts/install \ | sudo bash -s -- --branch renovate/all-minor-patch ``` 🎯 **Pin to this exact build** ([run 27973841616](https://github.com/sleepypod/core/actions/runs/27973841616) · `6f84753`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/6f84753a8a8fb583e4704a7f070f73a9fd7c5374/scripts/install \ | sudo bash -s -- \ --branch renovate/all-minor-patch \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/27973841616/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/27973841616/artifacts/7800955542) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…655) This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@tanstack/react-query](https://tanstack.com/query) ([source](https://redirect.github.com/TanStack/query/tree/HEAD/packages/react-query)) | [`5.101.0` → `5.101.1`](https://renovatebot.com/diffs/npm/@tanstack%2freact-query/5.101.0/5.101.1) |  |  | | [@xyflow/react](https://reactflow.dev) ([source](https://redirect.github.com/xyflow/xyflow/tree/HEAD/packages/react)) | [`12.11.0` → `12.11.1`](https://renovatebot.com/diffs/npm/@xyflow%2freact/12.11.0/12.11.1) |  |  | | [bonjour-service](https://redirect.github.com/onlxltd/bonjour-service) | [`1.4.1` → `1.4.2`](https://renovatebot.com/diffs/npm/bonjour-service/1.4.1/1.4.2) |  |  | | [globals](https://redirect.github.com/sindresorhus/globals) | [`17.6.0` → `17.7.0`](https://renovatebot.com/diffs/npm/globals/17.6.0/17.7.0) |  |  | | [recharts](https://redirect.github.com/recharts/recharts) | [`3.8.1` → `3.9.0`](https://renovatebot.com/diffs/npm/recharts/3.8.1/3.9.0) |  |  | | [shadcn](https://redirect.github.com/shadcn-ui/ui) ([source](https://redirect.github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn)) | [`4.11.0` → `4.12.0`](https://renovatebot.com/diffs/npm/shadcn/4.11.0/4.12.0) |  |  | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | [`8.61.1` → `8.62.0`](https://renovatebot.com/diffs/npm/typescript-eslint/8.61.1/8.62.0) |  |  | --- ### Release Notes <details> <summary>TanStack/query (@​tanstack/react-query)</summary> ### [`v5.101.1`](https://redirect.github.com/TanStack/query/blob/HEAD/packages/react-query/CHANGELOG.md#51011) [Compare Source](https://redirect.github.com/TanStack/query/compare/@tanstack/react-query@5.101.0...@tanstack/react-query@5.101.1) ##### Patch Changes - Updated dependencies \[[`9eff92e`](https://redirect.github.com/TanStack/query/commit/9eff92ed86e284ec0125b3a3539d028688235bd1)]: - [@​tanstack/query-core](https://redirect.github.com/tanstack/query-core)@​5.101.1 </details> <details> <summary>xyflow/xyflow (@​xyflow/react)</summary> ### [`v12.11.1`](https://redirect.github.com/xyflow/xyflow/blob/HEAD/packages/react/CHANGELOG.md#12111) [Compare Source](https://redirect.github.com/xyflow/xyflow/compare/@xyflow/react@12.11.0...@xyflow/react@12.11.1) ##### Patch Changes - [#​5815](https://redirect.github.com/xyflow/xyflow/pull/5815) [`87da45c`](https://redirect.github.com/xyflow/xyflow/commit/87da45cdf55aaf4549120a60165598675993783d) - Fix `FinalConnectionState` type so it preserves the discriminated union. - [#​5823](https://redirect.github.com/xyflow/xyflow/pull/5823) [`a6afc91`](https://redirect.github.com/xyflow/xyflow/commit/a6afc91160e0a0e172b03d82c43972222f9ae740) - Update attribution link - [#​5824](https://redirect.github.com/xyflow/xyflow/pull/5824) [`6b1dac5`](https://redirect.github.com/xyflow/xyflow/commit/6b1dac50ff1b837688c362ede5dcc8a57ac97444) - Do not fire on pane click when connection ends on pane - [#​5818](https://redirect.github.com/xyflow/xyflow/pull/5818) [`4ddc2d8`](https://redirect.github.com/xyflow/xyflow/commit/4ddc2d8420c39ca2e16bbce0e2265601a63a332f) - Provide the shared handle config (`connectOnClick`, `noPanClassName`, `rfId`) through context instead of subscribing to the store in every `Handle`, so a store update no longer runs a selector once per handle - [#​5817](https://redirect.github.com/xyflow/xyflow/pull/5817) [`8df250b`](https://redirect.github.com/xyflow/xyflow/commit/8df250b095d0c8a6c82c9155d22250b94b295e76) - Reduce per-handle work on store updates by returning a shared connection state while no connection is in progress. - [#​5822](https://redirect.github.com/xyflow/xyflow/pull/5822) [`a6249de`](https://redirect.github.com/xyflow/xyflow/commit/a6249de56c5181edbbe205058a2e5eb593dc278b) - Return stable reference for edge position when connected node gets deleted - Updated dependencies \[[`ceb8604`](https://redirect.github.com/xyflow/xyflow/commit/ceb8604047f97e6c9028fed17bb10186a7ca9e8b), [`87da45c`](https://redirect.github.com/xyflow/xyflow/commit/87da45cdf55aaf4549120a60165598675993783d)]: - [@​xyflow/system](https://redirect.github.com/xyflow/system)@​0.0.78 </details> <details> <summary>onlxltd/bonjour-service (bonjour-service)</summary> ### [`v1.4.2`](https://redirect.github.com/onlxltd/bonjour-service/releases/tag/1.4.2) [Compare Source](https://redirect.github.com/onlxltd/bonjour-service/compare/1.4.1...1.4.2) #### What's Changed - Bump tar from 7.5.15 to 7.5.16 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​81](https://redirect.github.com/onlxltd/bonjour-service/pull/81) - Bump undici from 6.25.0 to 6.27.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​82](https://redirect.github.com/onlxltd/bonjour-service/pull/82) - Bump js-yaml from 4.1.1 to 4.2.0 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​83](https://redirect.github.com/onlxltd/bonjour-service/pull/83) **Full Changelog**: <onlxltd/bonjour-service@1.4.1...1.4.2> </details> <details> <summary>sindresorhus/globals (globals)</summary> ### [`v17.7.0`](https://redirect.github.com/sindresorhus/globals/compare/v17.6.0...a19670cc86c1218e915657c55ea02ba3e7623834) [Compare Source](https://redirect.github.com/sindresorhus/globals/compare/v17.6.0...v17.7.0) </details> <details> <summary>recharts/recharts (recharts)</summary> ### [`v3.9.0`](https://redirect.github.com/recharts/recharts/releases/tag/v3.9.0) [Compare Source](https://redirect.github.com/recharts/recharts/compare/v3.8.1...v3.9.0) #### What's Changed ##### Animations 3.9 comes with new animations! There are several bug fixes and what's best, all animations are now fully customizable. See the animations guide on <https://recharts.github.io/en-US/guide/animations/> - Animation guide by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7179](https://redirect.github.com/recharts/recharts/pull/7179) - Animation tests by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7255](https://redirect.github.com/recharts/recharts/pull/7255) - New animation props by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7215](https://redirect.github.com/recharts/recharts/pull/7215) - test: cover legacy animation length changes by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7283](https://redirect.github.com/recharts/recharts/pull/7283) - test: add sparse animation path tests for Line component by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7295](https://redirect.github.com/recharts/recharts/pull/7295) - Export and document interpolate function by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7293](https://redirect.github.com/recharts/recharts/pull/7293) - test: enhance line animation tests for ComposedChart and responsive by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7289](https://redirect.github.com/recharts/recharts/pull/7289) - Manual animations on website by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7483](https://redirect.github.com/recharts/recharts/pull/7483) - Add new example where chart animates by scroll by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7484](https://redirect.github.com/recharts/recharts/pull/7484) - fix: preserve single-value line dash gaps during animation by [@​puneetdixit200](https://redirect.github.com/puneetdixit200) in [#​7405](https://redirect.github.com/recharts/recharts/pull/7405) - Add animate-by-scroll example and update docs by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7487](https://redirect.github.com/recharts/recharts/pull/7487) - Add custom fillOpacity on hover website example by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7489](https://redirect.github.com/recharts/recharts/pull/7489) - honorable mention to [@​robjampar](https://redirect.github.com/robjampar) for PR [#​6973](https://redirect.github.com/recharts/recharts/pull/6973) which ended up declined but it introduced the starting idea for the new animation props ##### New features other than animations - Expose and document chart layout hooks and layout types in public API by [@​Copilot](https://redirect.github.com/Copilot) in [#​7265](https://redirect.github.com/recharts/recharts/pull/7265) - feat: allow HTML attributes passthrough on ResponsiveContainer by [@​techcodie](https://redirect.github.com/techcodie) in [#​7168](https://redirect.github.com/recharts/recharts/pull/7168) - feat: add nodeInset and nodeGap properties to Treemap for better la… by [@​MaximSrour](https://redirect.github.com/MaximSrour) in [#​7044](https://redirect.github.com/recharts/recharts/pull/7044) - feat(PieChart): add dataKey to Legend payload by [@​Harikrushn9118](https://redirect.github.com/Harikrushn9118) in [#​7137](https://redirect.github.com/recharts/recharts/pull/7137) ##### Bugfixes - fix: preserve valid falsy custom names (0, "") in tooltips by [@​vamsi2246](https://redirect.github.com/vamsi2246) in [#​7175](https://redirect.github.com/recharts/recharts/pull/7175) - fix(ResponsiveContainer): Fix erroneous console warning on init by [@​andypoorman](https://redirect.github.com/andypoorman) in [#​7174](https://redirect.github.com/recharts/recharts/pull/7174) - fix(DataUtils): improve isPercent validation to exclude invalid formats by [@​vamsi2246](https://redirect.github.com/vamsi2246) in [#​7178](https://redirect.github.com/recharts/recharts/pull/7178) - fix(BarChart): render stacked bars when all values are 0 ([#​6235](https://redirect.github.com/recharts/recharts/issues/6235)) by [@​andypoorman](https://redirect.github.com/andypoorman) in [#​7199](https://redirect.github.com/recharts/recharts/pull/7199) - fix(Sankey): prevent NaN node positions when link values sum to zero by [@​Mridul012](https://redirect.github.com/Mridul012) in [#​7185](https://redirect.github.com/recharts/recharts/pull/7185) - fix(Funnel): prevent NaN coordinate layout crash when all values are zero by [@​Mridul012](https://redirect.github.com/Mridul012) in [#​7184](https://redirect.github.com/recharts/recharts/pull/7184) - fixes an issue where XAxis and YAxis padding were ignored by the clipping mask when allowDataOverflow={true} was used alongside a restricted domain by [@​emiedonmokumo](https://redirect.github.com/emiedonmokumo) in [#​7232](https://redirect.github.com/recharts/recharts/pull/7232) - fix: use originalDataIndex for tooltip dispatch in Bar by [@​mayrang](https://redirect.github.com/mayrang) in [#​7273](https://redirect.github.com/recharts/recharts/pull/7273) - fix: resolve TypeScript 6 deprecation errors in tsconfig files by [@​shreedharbhat98](https://redirect.github.com/shreedharbhat98) in [#​7285](https://redirect.github.com/recharts/recharts/pull/7285) - fix(bar): use Math.round instead of bitwise truncation for bar positioning by [@​EduardF1](https://redirect.github.com/EduardF1) in [#​7297](https://redirect.github.com/recharts/recharts/pull/7297) - fix(types): propagate Tooltip types in chart helper contexts by [@​mixelburg](https://redirect.github.com/mixelburg) in [#​7125](https://redirect.github.com/recharts/recharts/pull/7125) - fix(Legend): prevent overlap with chart on container resize by [@​maroKanatani](https://redirect.github.com/maroKanatani) in [#​7201](https://redirect.github.com/recharts/recharts/pull/7201) - test(YAxis): failing repro for [#​7362](https://redirect.github.com/recharts/recharts/issues/7362) — function domain doesn't render ticks on empty/all-null data by [@​nlenepveu](https://redirect.github.com/nlenepveu) in [#​7384](https://redirect.github.com/recharts/recharts/pull/7384) ##### Tree-shaking We now have focused tree-shaking tests that allow us to observe exactly which components end up in the final bundle and why. I have also removed some unnecessary loops and you should see the final bundle size decrease somewhat as a result. There are also two new examples on the website, showing real bundle size: - <https://recharts.github.io/recharts/canary/www/en-US/examples/BundleSizeTreemap/> - <https://recharts.github.io/recharts/canary/www/en-US/examples/BundleSizeSunburst/> * Improve bundle tracing and tree-shaking for Shape defaults by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7348](https://redirect.github.com/recharts/recharts/pull/7348) * Refactor Shape props to reduce bundle sizes by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7349](https://redirect.github.com/recharts/recharts/pull/7349) * Types: switch Shape from spread to separate prop object by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7351](https://redirect.github.com/recharts/recharts/pull/7351) ##### Documentation updates - docs: clarify valid types for axis tick prop by [@​Harikrushn9118](https://redirect.github.com/Harikrushn9118) in [#​7191](https://redirect.github.com/recharts/recharts/pull/7191) - style: update layout gaps and add new navigation links by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7412](https://redirect.github.com/recharts/recharts/pull/7412) - www: show deployed commit hash in footer across production and staging builds by [@​Copilot](https://redirect.github.com/Copilot) in [#​7258](https://redirect.github.com/recharts/recharts/pull/7258) - Replace old bundle-viz with two new chart examples by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7390](https://redirect.github.com/recharts/recharts/pull/7390) - Remove our custom storybook plugins by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7382](https://redirect.github.com/recharts/recharts/pull/7382) - feat: add PolarAngleAxis component storybook story by [@​whatfontisthis](https://redirect.github.com/whatfontisthis) in [#​7243](https://redirect.github.com/recharts/recharts/pull/7243) - feat: add LabelList component Storybook story by [@​whatfontisthis](https://redirect.github.com/whatfontisthis) in [#​7244](https://redirect.github.com/recharts/recharts/pull/7244) - docs: add Windows install workaround to DEVELOPING.md by [@​harsh-05](https://redirect.github.com/harsh-05) in [#​7324](https://redirect.github.com/recharts/recharts/pull/7324) - docs: add [@​since](https://redirect.github.com/since) 3.9 annotation to hooks by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7326](https://redirect.github.com/recharts/recharts/pull/7326) - Add [@​since](https://redirect.github.com/since) annotation to useChartLayout by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7360](https://redirect.github.com/recharts/recharts/pull/7360) - Add since annotation to useActiveTooltipDataPoints by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7338](https://redirect.github.com/recharts/recharts/pull/7338) - devops: upload test results to Flakiness.io by [@​aslushnikov](https://redirect.github.com/aslushnikov) in [#​7359](https://redirect.github.com/recharts/recharts/pull/7359) - Omnidoc: add API examples support and enhance example discovery by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7342](https://redirect.github.com/recharts/recharts/pull/7342) - Dedup website examples by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7340](https://redirect.github.com/recharts/recharts/pull/7340) - Remove Area.baseLine type by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7317](https://redirect.github.com/recharts/recharts/pull/7317) - docs: add session storage support for controls state by [@​PavelVanecek](https://redirect.github.com/PavelVanecek) in [#​7279](https://redirect.github.com/recharts/recharts/pull/7279) - fix(Scatter): use HTTPS in JSDoc links by [@​Parth10P](https://redirect.github.com/Parth10P) in [#​7192](https://redirect.github.com/recharts/recharts/pull/7192) - Update copyright year to 2026 by [@​ojhawkins](https://redirect.github.com/ojhawkins) in [#​7288](https://redirect.github.com/recharts/recharts/pull/7288) - Fix Legend props not appearing in omnidoc website by [@​Copilot](https://redirect.github.com/Copilot) in [#​7203](https://redirect.github.com/recharts/recharts/pull/7203) - docs: add Deno to install instructions by [@​bartlomieju](https://redirect.github.com/bartlomieju) in [#​7473](https://redirect.github.com/recharts/recharts/pull/7473) #### New Contributors - [@​MaximSrour](https://redirect.github.com/MaximSrour) made their first contribution in [#​7044](https://redirect.github.com/recharts/recharts/pull/7044) - [@​vamsi2246](https://redirect.github.com/vamsi2246) made their first contribution in [#​7175](https://redirect.github.com/recharts/recharts/pull/7175) - [@​andypoorman](https://redirect.github.com/andypoorman) made their first contribution in [#​7174](https://redirect.github.com/recharts/recharts/pull/7174) - [@​Mridul012](https://redirect.github.com/Mridul012) made their first contribution in [#​7185](https://redirect.github.com/recharts/recharts/pull/7185) - [@​emiedonmokumo](https://redirect.github.com/emiedonmokumo) made their first contribution in [#​7232](https://redirect.github.com/recharts/recharts/pull/7232) - [@​mayrang](https://redirect.github.com/mayrang) made their first contribution in [#​7273](https://redirect.github.com/recharts/recharts/pull/7273) - [@​legions-developer](https://redirect.github.com/legions-developer) made their first contribution in [#​7280](https://redirect.github.com/recharts/recharts/pull/7280) - [@​ojhawkins](https://redirect.github.com/ojhawkins) made their first contribution in [#​7288](https://redirect.github.com/recharts/recharts/pull/7288) - [@​EduardF1](https://redirect.github.com/EduardF1) made their first contribution in [#​7297](https://redirect.github.com/recharts/recharts/pull/7297) - [@​harsh-05](https://redirect.github.com/harsh-05) made their first contribution in [#​7324](https://redirect.github.com/recharts/recharts/pull/7324) - [@​aslushnikov](https://redirect.github.com/aslushnikov) made their first contribution in [#​7359](https://redirect.github.com/recharts/recharts/pull/7359) - [@​maroKanatani](https://redirect.github.com/maroKanatani) made their first contribution in [#​7201](https://redirect.github.com/recharts/recharts/pull/7201) - [@​techcodie](https://redirect.github.com/techcodie) made their first contribution in [#​7168](https://redirect.github.com/recharts/recharts/pull/7168) - [@​whatfontisthis](https://redirect.github.com/whatfontisthis) made their first contribution in [#​7243](https://redirect.github.com/recharts/recharts/pull/7243) - [@​nlenepveu](https://redirect.github.com/nlenepveu) made their first contribution in [#​7384](https://redirect.github.com/recharts/recharts/pull/7384) - [@​bartlomieju](https://redirect.github.com/bartlomieju) made their first contribution in [#​7473](https://redirect.github.com/recharts/recharts/pull/7473) - [@​puneetdixit200](https://redirect.github.com/puneetdixit200) made their first contribution in [#​7405](https://redirect.github.com/recharts/recharts/pull/7405) **Full Changelog**: <recharts/recharts@v3.8.1...v3.9.0-canary.0> </details> <details> <summary>shadcn-ui/ui (shadcn)</summary> ### [`v4.12.0`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#4120) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.11.1...shadcn@4.12.0) ##### Minor Changes - [#​11022](https://redirect.github.com/shadcn-ui/ui/pull/11022) [`18fcf0f766857a7249cc0daac3c1609610edd158`](https://redirect.github.com/shadcn-ui/ui/commit/18fcf0f766857a7249cc0daac3c1609610edd158) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - add scroll-fade and shimmer utilities ### [`v4.11.1`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#4111) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.11.0...shadcn@4.11.1) ##### Patch Changes - [#​10905](https://redirect.github.com/shadcn-ui/ui/pull/10905) [`9197676b3d09b77f51b17b63e5978db29e498ca4`](https://redirect.github.com/shadcn-ui/ui/commit/9197676b3d09b77f51b17b63e5978db29e498ca4) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - replace node-fetch with native fetch - [#​10967](https://redirect.github.com/shadcn-ui/ui/pull/10967) [`365d53b590a6ddb79c1487a9dbeabcde5f4ac37f`](https://redirect.github.com/shadcn-ui/ui/commit/365d53b590a6ddb79c1487a9dbeabcde5f4ac37f) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - Preserve existing dependency specifiers in package.json when running `shadcn add`. </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.62.0`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8620-2026-06-22) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.61.1...v8.62.0) ##### 🚀 Features - remove redundant package.json "files" ([#​12444](https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12444)) ##### ❤️ Thank You - Kirk Waiblinger [@​kirkwaiblinger](https://redirect.github.com/kirkwaiblinger) See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.62.0) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsImZpeC1wYXRjaCIsIm5vbi1tYWpvciJdfQ==--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/all-minor-patch ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/all-minor-patch/scripts/install \ | sudo bash -s -- --branch renovate/all-minor-patch ``` 🎯 **Pin to this exact build** ([run 28416699862](https://github.com/sleepypod/core/actions/runs/28416699862) · `04149a0`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/04149a027f56722bd36f4798aab268a4a61b44b7/scripts/install \ | sudo bash -s -- \ --branch renovate/all-minor-patch \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/28416699862/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/28416699862/artifacts/7969733819) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
44 verified findings (1 critical, 3 high, 16 medium, 24 low) across server/API, hardware/streaming, Python device modules, scheduler/ automation/HomeKit, DB/migrations, and frontend. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Self-contained work plan (4 batches, 44 items) with locations, concrete changes, and verification steps, for execution in a fresh session. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The hand-edited when for 0003_sensor_calibration (1773714000000) was greater than 0004's and 0005's, so drizzle's migrator skipped them on incremental upgrades past 0003 — missing tables then made 0009 fail and the pod could not boot. Set it strictly between 0002 and 0004. Adds a journal monotonicity guard and an incremental-upgrade regression test (migrate to 0003, then run the full migrator, assert 0004+ tables exist). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drift compared DB schedule rows against schedulerJobCount minus only PRIME/REBOOT, so LED-brightness, away-mode, run-once, and calibration jobs made every health poll flag drift and rebuild the whole scheduler (~7s). Count only schedule-backed job types (temperature/power_on/power_off/alarm) on the scheduler side instead. Also fixes the test db mock: drizzle tables all have constructor name SQLiteTable, so the per-table detection silently returned the temp array for power/alarm queries, hiding the phantom drift in existing tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…read timeout When a DAC response timed out, the losing readMessage() stayed subscribed and later consumed the NEXT command's response, shifting every subsequent command/response pair; connectDac's early-return blocked recovery. Reads now take an AbortSignal and settle when the timeout fires, and each send first discards any stale buffered responses (commands are strictly sequential, so anything buffered at send time is stale by definition). Same fix applied to the dev/test SocketClient path: its single pendingRead slot already cancelled on timeout, but the late response sat in the queue and misaligned the next command — now discarded before each send. Covers review items 1.3 and 3.5. Adds regression tests for dropped and late-buffered responses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ndow A record with a far-future ts landed in bed_temp/freezer_temp, and because the downsample cursors seed from MAX(timestamp) at startup, every subsequent write was blocked forever — surviving restarts. Add sanitize_ts (mirroring sleep-detector's, plus an upper bound of now+60s) and clamp the DB-seeded cursors to now so an already-poisoned DB self-heals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…port test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The latch was set on every HomeKit toggle and never cleared, so external power changes (scheduler off, auto-off, pump stall guard) were shadowed forever: isEffectivelyPowered reported stale ON and setTargetTemperature could re-heat a bed the scheduler had turned off. Clear the latch once a status update confirms the intended state; keep it while the write is still propagating (status lags a poll interval). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signal 1 zeroed movement for BOTH beds whenever EITHER pump had RPM>0, and
the pump-off guard period was likewise global, so the idle side's real
movement was discarded for entire pump runtimes. RPM gating and the guard
period are now tracked per side; cross-side mechanical coupling remains
covered by Signal 2 (correlated ref-anomaly).
Also fixes a latent guard bug: _pump_off_at initialized to 0.0 gated
everything for the first PUMP_GUARD_S after process start when
time.monotonic() has a near-zero origin — now -inf ('never turned off').
Not validated against recorded pod data (none available in this repo);
covered with unit tests instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… stalls After the first WS frame, a sticky ref permanently set refetchInterval:false, so a dying WS server froze temps, pump-stall, alarm, and water-level status with no fallback. WS is now trusted only while the socket is connected AND a frame arrived within 15s; otherwise HTTP polls at 7s. While WS is live, HTTP idles at 60s instead of off — each idle poll re-evaluates freshness, so a silently-stalled (half-open) socket self-heals within one cycle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
During snooze nothing is vibrating, so handleStop built its targets from leftAlarmActive/rightAlarmActive (both false), fired no clearAlarm mutation, and the alarm resumed at the end of the snooze. When no side is actively vibrating, targets now come from the snoozed sides (backend clearAlarm already cancels the pending snooze timer). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ms it The visible device status is WS-preferred, so HTTP refetch()/invalidate() after mutations never updated the UI, and clearing the dial's local target in onSettled snapped it back to the stale value for ~2s before the next frame. New useOptimisticValue hook: preview() for in-progress drags, commit() holds the value until the server reports it (6s fallback), discard() on mutation error. Applied to the TempScreen dial, ±1 buttons, power toggle, and PowerButton — whose doc comment promised an optimistic toggle it never had. Covers review items 3.8, 3.9, and 4.20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Sense2
Review items:
- 4.7 piezo-processor: tolerate truncated int32 buffers (len % 4 != 0 killed
the module via np.frombuffer ValueError)
- 4.9 piezo-processor: HRTracker re-seeds after a sustained streak of
uncorrectable readings instead of freezing on a stale median; single
outliers still stay out of history. Also fix FrzHealthPumpState's pump-off
guard falsely asserting for the first 5s when time.monotonic() starts near
zero (same sentinel bug as sleep-detector's gate; made its tests flaky on
fast runs)
- 4.8 calibration: drop non-dict trigger JSON instead of crash-looping the
calibrator on .get()
- 4.10 calibration: scan the final quiet window in CapCalibrator
(off-by-one vs CapSense2Calibrator)
- 4.11 calibration: write_trigger_atomic gets pid+counter uniquifier (the old
with_suffix('.tmp') collapsed all writers to one tmp path) and fsyncs file
+ directory around the rename
Also includes the pre-existing verified working-tree change to
CapSense2Calibrator: accept 6-value capSense2 frames (Pod 4/5 firmware
without the REF pair), mirroring sleep-detector's extractor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 4.3 normalizeFrame: optional-chain nested frzHealth/frzTherm wire fields so a firmware build omitting a branch degrades to zeros instead of throwing in the WS message handler - 4.4 clamp snooze setTimeout delays to the 32-bit ms ceiling (larger values wrap and restart the alarm immediately) - 4.5 mqttBridge.testConnection resolves tlsInsecure via resolveConfig's db-then-env precedence instead of env only - 4.6 piezoStream seek: chunked async reads + periodic parse yields replace the up-to-64MB readSync that blocked the event loop for all clients Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 4.12 timeOfDay triggers fire on the first tick at-or-after the slot within a 10-minute grace window instead of exact-minute equality (a >60s tick gap silently skipped the slot). Fired-state is now keyed by local calendar date from the tz-aware clock — the old weekday key also blocked the same slot every following week for the life of the process. - 4.13 scheduleRunOnceSession cancels the session's existing jobs before scheduling: an in-process restore passes a filtered set-point list whose indices shift, so stale ids could double-fire set points. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 4.14 delete 0002_nappy_warpath.sql — orphaned byte-identical duplicate of 0003_previous_phil_sheldon.sql, absent from the journal - 4.15 reconstruct missing meta/0007_snapshot.json (0006 schema + 0007's MQTT columns, id taken from 0008's prevId); drizzle-kit check passes and generate produces no diff - 4.16 new biometrics migration 0011: plain timestamp indexes on vitals, movement, and vitals_quality so retention pruning can seek instead of full-scanning the pod's largest tables - 4.17 prune vitals_quality on the same cutoff as vitals — vitals_id is a logical, unenforced reference and no module pruned the table, so quality rows orphaned forever (a real FK would need a table rebuild and PRAGMA foreign_keys in every writer; documented in the schema instead) - 4.18 install --restore removes live -wal/-shm sidecars after copying the .db so SQLite can't replay post-backup transactions over the restore Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 4.2 triggerUpdate branch validation also rejects '..', '//', leading/trailing '/', leading '-', and '.lock' (git-ref-safe; the character class alone allowed traversal and option injection) - 4.21 DeviceSettingsForm resets from server data only when the values actually change — every refetch produced a new object identity and stomped fields mid-edit - 4.22 diagnostics pump-stall tile: armed = green (flag was inverted) - 4.23 CapZoneViz: reduce instead of spreading a long replay's flattened zones into Math.max (RangeError past the argument limit) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 4.24 untrack + gitignore biometrics.dev.db-shm/-wal (transient per-machine WAL state; the .db fixture itself stays tracked) - 4.25 fill in CLAUDE.md Build & Test, Architecture Overview, and Conventions sections - 4.26 Dependabot triage tracked as ygg task core-3 - 4.19 decision noted in the fix plan: keep the pump-stall opt-in safety reset as-is (power-cutting feature; safe default wins) - mark all Batch 4 checkboxes; lint cleanups from the batch Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 2026-07-01 review docs The 2026-07-01 repo-wide review is fully remediated (47/47 items); its docs are retired from docs/ and remain in git history. The new plan covers the 1 Major + 4 Minor findings left from the 2026-07-03 adversarial Codex review, self-contained since .reviews/ is gitignored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fix RAW file selection so the streamer skips `SEQNO.RAW` and, if the top-level `/persistent` scan finds nothing usable, falls back to `/persistent/biometrics`. Pod evidence: - `sleepypod.service` had no `RAW_DATA_DIR` override in its environment, so the app used its default path. - `/persistent` contained `SEQNO.RAW` and the `biometrics/` directory; `/persistent/biometrics` contained the real capture file `00D0660E.RAW`. - `journalctl -u sleepypod.service` showed `[sensorStream] Switched to RAW file: SEQNO.RAW`, followed by CBOR resync errors, which explained why only `DEV` appeared in the Sensors tab. Implementation: - keep the existing one-directory scan behavior - skip only `SEQNO.RAW` - if the scan of `/persistent` finds nothing, retry in `/persistent/biometrics` - add a regression test for the fallback path and `SEQNO.RAW` exclusion <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved RAW file detection so streaming attaches to the newest valid capture instead of a placeholder file. * Added fallback discovery for devices that store captures in a nested biometrics folder, reducing resync errors and failed attachments. * **Tests** * Added coverage for RAW selection behavior across top-level and fallback locations, including handling of placeholder files and empty directories. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Jonathan Ng <jon@jonathanng.com>
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@eslint/css](https://redirect.github.com/eslint/css) | [`1.3.0` → `1.4.0`](https://renovatebot.com/diffs/npm/@eslint%2fcss/1.3.0/1.4.0) |  |  | | [@tailwindcss/postcss](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)) | [`4.3.1` → `4.3.2`](https://renovatebot.com/diffs/npm/@tailwindcss%2fpostcss/4.3.1/4.3.2) |  |  | | [@tanstack/react-query](https://tanstack.com/query) ([source](https://redirect.github.com/TanStack/query/tree/HEAD/packages/react-query)) | [`5.101.1` → `5.101.2`](https://renovatebot.com/diffs/npm/@tanstack%2freact-query/5.101.1/5.101.2) |  |  | | [eslint-config-next](https://nextjs.org/docs/app/api-reference/config/eslint) ([source](https://redirect.github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next)) | [`16.2.9` → `16.2.10`](https://renovatebot.com/diffs/npm/eslint-config-next/16.2.9/16.2.10) |  |  | | [lucide-react](https://lucide.dev) ([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react)) | [`1.21.0` → `1.23.0`](https://renovatebot.com/diffs/npm/lucide-react/1.21.0/1.23.0) |  |  | | [next](https://nextjs.org) ([source](https://redirect.github.com/vercel/next.js)) | [`16.2.9` → `16.2.10`](https://renovatebot.com/diffs/npm/next/16.2.9/16.2.10) |  |  | | [recharts](https://redirect.github.com/recharts/recharts) | [`3.9.0` → `3.9.1`](https://renovatebot.com/diffs/npm/recharts/3.9.0/3.9.1) |  |  | | [shadcn](https://redirect.github.com/shadcn-ui/ui) ([source](https://redirect.github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn)) | [`4.12.0` → `4.13.0`](https://renovatebot.com/diffs/npm/shadcn/4.12.0/4.13.0) |  |  | | [tailwindcss](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)) | [`4.3.1` → `4.3.2`](https://renovatebot.com/diffs/npm/tailwindcss/4.3.1/4.3.2) |  |  | | [tsx](https://tsx.hirok.io) ([source](https://redirect.github.com/privatenumber/tsx)) | [`4.22.4` → `4.23.0`](https://renovatebot.com/diffs/npm/tsx/4.22.4/4.23.0) |  |  | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | [`8.62.0` → `8.62.1`](https://renovatebot.com/diffs/npm/typescript-eslint/8.62.0/8.62.1) |  |  | --- ### Release Notes <details> <summary>eslint/css (@​eslint/css)</summary> ### [`v1.4.0`](https://redirect.github.com/eslint/css/blob/HEAD/CHANGELOG.md#140-2026-07-01) [Compare Source](https://redirect.github.com/eslint/css/compare/e447a05a298047a2340da00e5abd415707c2c3c5...8d7c2c553db62e3bce71ecfaa8665ecfeeeda334) ##### Features - add suggestions to prefer-logical-properties ([#​474](https://redirect.github.com/eslint/css/issues/474)) ([045277e](https://redirect.github.com/eslint/css/commit/045277e498d6dcd486f514c1632f40ad6cb7aa4a)) ##### Bug Fixes - check for preludes in `[@import](https://redirect.github.com/import)` ([#​470](https://redirect.github.com/eslint/css/issues/470)) ([cc8791d](https://redirect.github.com/eslint/css/commit/cc8791dcb277473fc7a49487c02155c5b049645e)) - false negative when font used as identifier ([#​471](https://redirect.github.com/eslint/css/issues/471)) ([f248a32](https://redirect.github.com/eslint/css/commit/f248a32d5d99dbdf3ebdf5da6838a4c3c174bc86)) - reporting font-size unit with percentage in line-height ([#​466](https://redirect.github.com/eslint/css/issues/466)) ([bae9097](https://redirect.github.com/eslint/css/commit/bae9097c0a355b1eb85ad6dcc2737f29f22b3a90)) - type compatibility issue between CSS v1 and ESLint v9 ([#​473](https://redirect.github.com/eslint/css/issues/473)) ([3cb31a5](https://redirect.github.com/eslint/css/commit/3cb31a5f94a121706ab5150f95f09f2023826797)) - update baseline data ([6726b1f](https://redirect.github.com/eslint/css/commit/6726b1f9facf5f178e3035a87e415d45b3511541)) - update baseline data ([#​469](https://redirect.github.com/eslint/css/issues/469)) ([99ba37f](https://redirect.github.com/eslint/css/commit/99ba37f373e76d5c86fd34319e6c7c833e2a5110)) - update baseline data ([#​475](https://redirect.github.com/eslint/css/issues/475)) ([7dbbb9d](https://redirect.github.com/eslint/css/commit/7dbbb9d27c7f17db021bbc5124c51a96c6e3ca10)) - update baseline data ([#​482](https://redirect.github.com/eslint/css/issues/482)) ([cd52c73](https://redirect.github.com/eslint/css/commit/cd52c7305a0f85f9d0811b83e19a9082307e13cd)) - update dependency [@​eslint/plugin-kit](https://redirect.github.com/eslint/plugin-kit) to ^0.7.2 ([#​463](https://redirect.github.com/eslint/css/issues/463)) ([1678418](https://redirect.github.com/eslint/css/commit/167841821aeb4a9ba1f632b0d756dd1d3bd2ed5c)) </details> <details> <summary>tailwindlabs/tailwindcss (@​tailwindcss/postcss)</summary> ### [`v4.3.2`](https://redirect.github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#432---2026-06-26) [Compare Source](https://redirect.github.com/tailwindlabs/tailwindcss/compare/v4.3.1...v4.3.2) ##### Fixed - Support bare spacing values for `auto-rows-*` and `auto-cols-*` utilities (e.g. `auto-rows-12` and `auto-cols-16`) ([#​20229](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229)) - Prevent `@tailwindcss/cli` in `--watch` mode from crashing on Windows when `@source` points to a directory that doesn't exist ([#​20242](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242)) - Prevent `@tailwindcss/vite` from crashing in Deno v2.8.x when `context.parentURL` is not a valid URL ([#​20245](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245)) - Ensure `@tailwindcss/cli` in `--watch` mode rebuilds when the input CSS file changes in an ignored directory ([#​20246](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246)) - Allow `@variant` rules used in `addBase(…)` to use custom variants defined later ([#​20247](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247)) - Prevent `@tailwindcss/vite` from crashing during HMR when scanned files or directories are deleted ([#​20259](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259)) - Generate `font-size` instead of `color` declarations for `text-[--spacing(…)]` ([#​20260](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260)) - Prevent `@source` patterns from scanning unrelated sibling files and folders ([#​20263](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263)) - Extract class candidates adjacent to Template Toolkit delimiters like `%]…[%` in `.tt`, `.tt2`, and `.tx` files ([#​20269](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269)) - Extract class candidates from conditional Maud syntax like `p.text-black[condition]` ([#​20269](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269)) - Prevent `@position-try` rules from triggering unknown at-rule warnings when optimizing CSS ([#​20277](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277)) - Support class suggestions for named opacity modifiers from `--opacity` theme values ([#​20287](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287)) - Prevent type errors in `@tailwindcss/postcss` when used with newer PostCSS patch releases ([#​20289](https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289)) </details> <details> <summary>TanStack/query (@​tanstack/react-query)</summary> ### [`v5.101.2`](https://redirect.github.com/TanStack/query/blob/HEAD/packages/react-query/CHANGELOG.md#51012) [Compare Source](https://redirect.github.com/TanStack/query/compare/@tanstack/react-query@5.101.1...@tanstack/react-query@5.101.2) ##### Patch Changes - Updated dependencies \[]: - [@​tanstack/query-core](https://redirect.github.com/tanstack/query-core)@​5.101.2 </details> <details> <summary>vercel/next.js (eslint-config-next)</summary> ### [`v16.2.10`](https://redirect.github.com/vercel/next.js/compare/v16.2.9...v16.2.10) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.9...v16.2.10) </details> <details> <summary>lucide-icons/lucide (lucide-react)</summary> ### [`v1.23.0`](https://redirect.github.com/lucide-icons/lucide/releases/tag/1.23.0): Version 1.23.0 [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.22.0...1.23.0) #### What's Changed - fix(docs): prevent scrollbar layout shift on icons page by [@​g30r93g](https://redirect.github.com/g30r93g) in [#​4500](https://redirect.github.com/lucide-icons/lucide/pull/4500) - chore(docs): Remove certificates banner by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4504](https://redirect.github.com/lucide-icons/lucide/pull/4504) - ci(repo-journal.yml): GH copilot repo summary by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4505](https://redirect.github.com/lucide-icons/lucide/pull/4505) - ci(repo-journal.yml): Small fix in the workflow by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4508](https://redirect.github.com/lucide-icons/lucide/pull/4508) - ci(repo-journal.yml): Switch to token by [@​ericfennis](https://redirect.github.com/ericfennis) in [#​4509](https://redirect.github.com/lucide-icons/lucide/pull/4509) - feat(icons): added `paper-bag` icon by [@​dkast](https://redirect.github.com/dkast) in [#​4023](https://redirect.github.com/lucide-icons/lucide/pull/4023) #### New Contributors - [@​g30r93g](https://redirect.github.com/g30r93g) made their first contribution in [#​4500](https://redirect.github.com/lucide-icons/lucide/pull/4500) - [@​dkast](https://redirect.github.com/dkast) made their first contribution in [#​4023](https://redirect.github.com/lucide-icons/lucide/pull/4023) **Full Changelog**: <lucide-icons/lucide@1.22.0...1.23.0> ### [`v1.22.0`](https://redirect.github.com/lucide-icons/lucide/compare/1.21.0...1.22.0) [Compare Source](https://redirect.github.com/lucide-icons/lucide/compare/1.21.0...1.22.0) </details> <details> <summary>vercel/next.js (next)</summary> ### [`v16.2.10`](https://redirect.github.com/vercel/next.js/compare/v16.2.9...v16.2.10) [Compare Source](https://redirect.github.com/vercel/next.js/compare/v16.2.9...v16.2.10) </details> <details> <summary>recharts/recharts (recharts)</summary> ### [`v3.9.1`](https://redirect.github.com/recharts/recharts/releases/tag/v3.9.1) [Compare Source](https://redirect.github.com/recharts/recharts/compare/v3.9.0...v3.9.1) #### What's Changed - perf: optimize ScatterChart hover by reducing re-renders from O(n) to O(1) by [@​roy7](https://redirect.github.com/roy7) in [#​7133](https://redirect.github.com/recharts/recharts/pull/7133) - fix(YAxis): render explicit ticks when a non-literal domain can't resolve on empty data ([#​7362](https://redirect.github.com/recharts/recharts/issues/7362)) by [@​nlenepveu](https://redirect.github.com/nlenepveu) in [#​7393](https://redirect.github.com/recharts/recharts/pull/7393) - fix: avoid Sankey nodes overlapping skipped-depth links by [@​pupuking723](https://redirect.github.com/pupuking723) in [#​7471](https://redirect.github.com/recharts/recharts/pull/7471) - Add stacked bar chart with horizontal threshold line example by [@​nijuse](https://redirect.github.com/nijuse) in [#​7495](https://redirect.github.com/recharts/recharts/pull/7495) - fix(DefaultLegendContent): omit empty value from legend icon aria-label by [@​greymoth-jp](https://redirect.github.com/greymoth-jp) in [#​7501](https://redirect.github.com/recharts/recharts/pull/7501) - chore(deps): bump immer from 10.2.0 to 11.1.8 by [@​dependabot](https://redirect.github.com/dependabot)\[bot] in [#​7452](https://redirect.github.com/recharts/recharts/pull/7452) - fix(getNiceTickValues): remove trailing duplicate tick when allowDecimals=false by [@​JSap0914](https://redirect.github.com/JSap0914) in [#​7482](https://redirect.github.com/recharts/recharts/pull/7482) - Fix/per graphical item formatter prop by [@​shreedharbhat98](https://redirect.github.com/shreedharbhat98) in [#​7287](https://redirect.github.com/recharts/recharts/pull/7287) #### New Contributors - [@​pupuking723](https://redirect.github.com/pupuking723) made their first contribution in [#​7471](https://redirect.github.com/recharts/recharts/pull/7471) - [@​nijuse](https://redirect.github.com/nijuse) made their first contribution in [#​7495](https://redirect.github.com/recharts/recharts/pull/7495) - [@​greymoth-jp](https://redirect.github.com/greymoth-jp) made their first contribution in [#​7501](https://redirect.github.com/recharts/recharts/pull/7501) - [@​JSap0914](https://redirect.github.com/JSap0914) made their first contribution in [#​7482](https://redirect.github.com/recharts/recharts/pull/7482) **Full Changelog**: <recharts/recharts@v3.9.0...v3.9.1> </details> <details> <summary>shadcn-ui/ui (shadcn)</summary> ### [`v4.13.0`](https://redirect.github.com/shadcn-ui/ui/blob/HEAD/packages/shadcn/CHANGELOG.md#4130) [Compare Source](https://redirect.github.com/shadcn-ui/ui/compare/shadcn@4.12.0...shadcn@4.13.0) ##### Minor Changes - [#​11082](https://redirect.github.com/shadcn-ui/ui/pull/11082) [`f3e7de11752b087b1c4bf61f4035a866f3a4f9ed`](https://redirect.github.com/shadcn-ui/ui/commit/f3e7de11752b087b1c4bf61f4035a866f3a4f9ed) Thanks [@​shadcn](https://redirect.github.com/shadcn)! - base-ui is now default </details> <details> <summary>privatenumber/tsx (tsx)</summary> ### [`v4.23.0`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.0) [Compare Source](https://redirect.github.com/privatenumber/tsx/compare/v4.22.5...v4.23.0) ##### Bug Fixes - avoid redundant filesystem probes during module resolution ([257bbbb](https://redirect.github.com/privatenumber/tsx/commit/257bbbb7eb2784cad6a3bb7a2d9c9747d28d96ec)), closes [privatenumber/tsx#809](https://redirect.github.com/privatenumber/tsx/issues/809) ##### Features - add multi-scenario startup benchmark suite ([c178197](https://redirect.github.com/privatenumber/tsx/commit/c178197b104d055fd3431f7448982f3156394d12)), closes [privatenumber/tsx#809](https://redirect.github.com/privatenumber/tsx/issues/809) [#​809](https://redirect.github.com/privatenumber/tsx/issues/809) [hi#signal](https://redirect.github.com/hi/issues/signal) [privatenumber/tsx#145](https://redirect.github.com/privatenumber/tsx/issues/145) [#​809](https://redirect.github.com/privatenumber/tsx/issues/809) *** This release is also available on: - [npm package (@​latest dist-tag)](https://www.npmjs.com/package/tsx/v/4.23.0) ### [`v4.22.5`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.22.5) [Compare Source](https://redirect.github.com/privatenumber/tsx/compare/v4.22.4...v4.22.5) ##### Bug Fixes - isolate hook state per async module.register() registration ([a305f36](https://redirect.github.com/privatenumber/tsx/commit/a305f365f0cbcc31a44549dcbb0e63dc2883e96d)) *** This release is also available on: - [npm package (@​latest dist-tag)](https://www.npmjs.com/package/tsx/v/4.22.5) </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.62.1`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8621-2026-06-29) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.62.0...v8.62.1) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.62.1) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/sleepypod/core). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI0Mi4yIiwidGFyZ2V0QnJhbmNoIjoiZGV2IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsImZpeC1wYXRjaCIsIm5vbi1tYWpvciJdfQ==--> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update renovate/all-minor-patch ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/renovate/all-minor-patch/scripts/install \ | sudo bash -s -- --branch renovate/all-minor-patch ``` 🎯 **Pin to this exact build** ([run 28830928213](https://github.com/sleepypod/core/actions/runs/28830928213) · `c266978`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/c266978a460403455fefd313a12b20f9e084ab37/scripts/install \ | sudo bash -s -- \ --branch renovate/all-minor-patch \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/28830928213/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/28830928213/artifacts/8124378585) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…all pods (#662) ## Problem Field report (trinity): the log viewer fails with ``` Failed to read logs: Command failed: journalctl -u sleepypod.service -n 201 --no-pager --output short-iso --show-cursor No journal files were opened due to insufficient permissions. ``` `system.getLogs` shells out to `journalctl` from the next-server, which runs as `User=sleepypod`. The installer only granted `SupplementaryGroups=dac`, and journal files are readable only by `adm` / `systemd-journal` / `wheel` — so on pods where the journal directory isn't world-readable, journalctl opens zero files and every log read fails. ## Fix Build the unit's supplementary-groups list dynamically in `scripts/install`: `dac` plus `systemd-journal` (falling back to `adm` where `systemd-journal` doesn't exist), keeping the existing getent guard so systemd never sees a nonexistent group. The installer rewrites the unit on every run, so existing pods pick this up on their next `sp-update`. ## Test plan - [x] `bash -n scripts/install` passes - [x] Simulated the group-line rendering under `set -euo pipefail` for all three cases (dac+journal, dac only, neither) — emits `SupplementaryGroups=dac systemd-journal`, `SupplementaryGroups=dac`, and omits the line respectively - [ ] On an affected pod: run installer, `systemctl show sleepypod -p SupplementaryGroups` shows `systemd-journal`, and `/debug` log viewer loads entries ## Immediate workaround for affected pods ```bash sudo mkdir -p /etc/systemd/system/sleepypod.service.d printf '[Service]\nSupplementaryGroups=systemd-journal\n' | sudo tee /etc/systemd/system/sleepypod.service.d/journal.conf sudo systemctl daemon-reload && sudo systemctl restart sleepypod ``` <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/install-journal-group ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/install-journal-group/scripts/install \ | sudo bash -s -- --branch fix/install-journal-group ``` 🎯 **Pin to this exact build** ([run 28831409722](https://github.com/sleepypod/core/actions/runs/28831409722) · `e47243b`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/e47243b63fefe6f3afd0849b45bfe56280ea8561/scripts/install \ | sudo bash -s -- \ --branch fix/install-journal-group \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/28831409722/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/28831409722/artifacts/8124541929) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…nded stops (#663) ## Problem Field report (Pod 4, 2026-07-11): `stall_left`/`stall_right` alerts fired daily on both sides within seconds of each other, always with `rpm = 0`; the two most recent ended in `power_off`, leaving the bed guard-blocked. The pumps are healthy — 3,477 of 5,881 flow readings in the last 7 days show normal running RPM, and the daily prime ran fine at ~3,000 RPM *after* the trip. Every alert lines up with a **firmware-commanded pump stop**, not a stall: - Jul 7 + Jul 8 alerts both at exactly **12:10:21 UTC** — the end of the scheduled daily prime (flow data shows the prime running 12:01:02 → 12:10:33). - Jul 11 alerts at 08:48:39/49 — exactly **28,800s (the 8h session duration) after the 00:48:02 power-on**, with sides tripping in the same order they powered on. ## Root cause `runStallGuard` derived `expectedActive` solely from `device_state`, which mirrors firmware through the `durationExpired` heuristic (`targetLevel === 0 && heatingDuration === 0`, else `currentLevel !== 0`). After the firmware ends a session, `currentLevel` stays non-zero while the water equalizes, so the mirror reports the side as powered for minutes while the pump correctly reads 0 RPM. With frzHealth frames arriving ~every 10s (not the 60s cadence ADR 0022 assumed) and `dwellSamples = 2`, the guard tripped ~20s after every natural session end. ## Fix `DeviceStateSync` now suppresses stall counting when the stop is explainable by lag-free firmware-side signals (`isExpectedPumpStop`): 1. **`pump.duty === 0`** — firmware isn't driving the pump. A genuinely stalled pump under closed-loop control shows duty > 0 while RPM reads 0, so real stalls are unaffected. Falls back cleanly when the frame omits `duty`. 2. **Priming active, or ended within 120s** — the prime cycle spins both pumps regardless of side power and stops them at the end. 3. **Firmware `targetLevel === 0`** — commanded neutral, pump stop expected even while `device_state` lags. 4. **Session countdown (`heatTime`) within 90s of its natural end**, projected forward from the last poll. Gated on `heatingDuration > 0` so firmware variants that report no countdown during an active session keep the previous behavior. A zero-RPM frame mid-session with the pump still driven reaches the guard as `expectedActive = true` exactly as before. `pumpStallGuard.ts` itself is unchanged. Also documents the failure mode as an addendum in ADR 0022. ## Test plan - `vitest run src/hardware/tests/` — 71 tests pass, including a new suite (`deviceStateSync.stallSuppression.test.ts`) covering: duty=0 suppression, duty>0 non-suppression, missing-duty fallback, priming + post-prime grace expiry, firmware-neutral-while-DB-powered (the field-observed case), session-end grace, countdown projection across a stalled status stream, indefinite-session (heatingDuration=0) non-suppression, and mid-session zero-RPM still tripping. - `tsc --noEmit` and `eslint` clean. - Manual verification once merged: on the affected pod, re-enable stall protection, let an 8h session expire and the 12:01 daily prime complete — no `pump_alerts` rows should appear; then verify a real stall still trips by unplugging a pump mid-session. Refs: ygg `sleepypod-core-1`, ADR 0022. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/pump-stall-false-trip ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/pump-stall-false-trip/scripts/install \ | sudo bash -s -- --branch fix/pump-stall-false-trip ``` 🎯 **Pin to this exact build** ([run 29172327550](https://github.com/sleepypod/core/actions/runs/29172327550) · `a45903d`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/a45903d711b0ca342330e04b0a493fd4ddba8e21/scripts/install \ | sudo bash -s -- \ --branch fix/pump-stall-false-trip \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/29172327550/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/29172327550/artifacts/8253876739) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Reduced false pump-stall alerts when pumps stop normally due to firmware commands, priming completion, neutral settings, or session end. * Continued detecting genuine mid-session zero-RPM stalls while the pump is still expected to run. * Improved handling of pump status and session timing to prevent premature alerts. * **Documentation** * Added an architecture decision record addendum explaining stall-detection behavior and safeguards. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…665) ## Summary Works this week's top entry on the mutation hit list (#591): `src/streaming/piezoStream.ts`, 151 surviving mutants — the largest single contributor after last week's mqttBridge pass (#635). - **~30 new tests + tightened assertions in existing ones**, targeting the survivor list extracted from run 29145443368's `mutation-report-streaming` artifact: - `readRawRecord`: direct byte-level tests — every seq/data CBOR encoding width (inline/1/2/4/8-byte), the 23-byte inline boundary, per-byte key corruption, exact error messages, `data: null` for placeholders, exact `nextOffset`. - `findIndexEntry`: boundary-exact binary-search assertions (kills the `<`/`<=` and loop-condition mutants). - `decodeSensorFrames`: primitive/null inner values must not abort the batch. - Seek: full-window replay is not silently truncated (64 MB cap regression), window boundary is inclusive at exactly +30s, replay stops for good at the first out-of-window frame, `incomplete`/`droppedFrames` absent on clean replays, distinct error messages for no-file vs no-frames, numeric-string and `Infinity` timestamps rejected. - Tail loop: split-record delivery is exactly-once with a seekable index offset (leftover-buffer offset accounting), resync warnings carry exact byte counts, resync from a malformed record that itself starts with `0xa2`, Pod 3 scalar capSense snapshot, non-frzHealth frames don't reach server listeners. - Lifecycle: shutdown actually closes the listening port, connect/disconnect/drop-count log lines asserted (field-debugging surface per docs/DEBUGGING.md). - **One minimal source change**: `readRawRecord`, `findIndexEntry`, `int32BufferToArray`, `decodeSensorFrames` added to the existing `__test__` export so the parser can be tested without a WS server per assertion. - **New `/mutation-hitlist` skill** (`.claude/skills/mutation-hitlist/`): packages the weekly workflow — issue lookup, artifact download, `survivors.py` extraction, killing-test playbook by mutator type, known equivalent-mutant categories, CI-based verification. Expected remaining survivors are the documented equivalent classes: module-level initializer mutants (false survivors under the vitest runner's module cache), timing/perf-only values (poll intervals, yield cadence, read-chunk sizes), and double-guarded checks. The `mutation-test` label on this PR triggers the scoped CI run for exact numbers. ## Test plan - [x] `pnpm exec vitest run src/streaming/tests/piezoStream.test.ts` — 91 passed, 0 failed - [x] eslint clean on both changed files - [x] `mutation-test` label applied → CI mutation run on this PR posts the before/after summary - [ ] Compare PR mutation summary against the 151-survivor baseline; comment results on #591 <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update test/piezostream-mutants-591 ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/test/piezostream-mutants-591/scripts/install \ | sudo bash -s -- --branch test/piezostream-mutants-591 ``` 🎯 **Pin to this exact build** ([run 29174117551](https://github.com/sleepypod/core/actions/runs/29174117551) · `3081292`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/3081292a8fc9bb6ae3c496199798d784208a39a2/scripts/install \ | sudo bash -s -- \ --branch test/piezostream-mutants-591 \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/29174117551/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/29174117551/artifacts/8254351375) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
…ressure (#660) ## Why `sp-bundle-logs` already captures the RAW *routing* (where frames land, where each reader looks, tmpfs state), but two live field reports needed signals it didn't collect: 1. **"Only DEV shows in the Sensors tab"** (#608) — caused by the streamer tailing `SEQNO.RAW` (the 16-byte counter) instead of a real capture. The tell is in `sleepypod.service`'s log: `[sensorStream] Switched to RAW file: SEQNO.RAW` followed by `Resync:` spam. Not previously in the bundle. 2. **"Pod stopped working, `/persistent` full, update fails with No space left on device"** — a stalled biometrics pruner letting the gzip archive grow unbounded. The bundle recorded the pruner's journal but not the archive size vs. disk free, so the smoking gun wasn't obvious. ## Change Two probes appended to the existing `raw/` section: - `raw/ws-3001.txt` + `raw/sensorstream-log.txt` — is the streamer WS server up, and what did it last attach to (+ any resync spam). - `raw/archive-size.txt` — `du -sh` of the cold archive, gz file count, and `df -h /persistent` side by side. No new dependencies; all best-effort under the existing `capture` helper. Pruner/archiver journals continue to come from the `journals/` section. ## Test plan - `bash -n` clean. - Nested-quote `bash -c` snippets smoke-tested locally (archive-size probe emits count + df; sensorStream grep is a no-op on a non-pod). - On-pod: run `sp-bundle-logs`, confirm `raw/ws-3001.txt`, `raw/sensorstream-log.txt`, and `raw/archive-size.txt` are populated. <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update chore/sp-bundle-logs-streamer-retention ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/chore/sp-bundle-logs-streamer-retention/scripts/install \ | sudo bash -s -- --branch chore/sp-bundle-logs-streamer-retention ``` 🎯 **Pin to this exact build** ([run 28831420964](https://github.com/sleepypod/core/actions/runs/28831420964) · `71859db`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/71859db98d8fdfd0f64cdf49f8a00b089fe418c0/scripts/install \ | sudo bash -s -- \ --branch chore/sp-bundle-logs-streamer-retention \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/28831420964/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/28831420964/artifacts/8124547044) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added more diagnostic and storage details to the bundled logs, including network, service journal, disk usage, and archive size information. * **Bug Fixes** * Improved service setup so it only uses available system groups, reducing startup failures on systems where expected groups are missing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
#659) ## Why A pod owner (trinity) reported their pod stopped working — `/persistent` was full, and `sp-update` failed with: ``` cp: error copying '/persistent/sleepypod-data/sleepypod.db' to '…sleepypod.db.bak…': No space left on device ``` Their `/persistent/biometrics-archive` had grown to ~13 GB of 15 GB. The gzip archiver had been running fine, but the **pruner never deleted anything** — the archive grew unbounded. ## Root cause `sleepypod-biometrics-pruner` used two GNU-only constructs: - `df --output=pcent /persistent` — read current disk usage - `find … -printf '%T@ %p\n'` — pick the oldest archive Pods can ship **busybox** coreutils/findutils (the install script already accounts for this — see the `sha256sum` → `shasum` busybox fallback, and every other disk check uses the portable `df -m … | awk` form). On busybox: - `df --output=pcent` is rejected → empty stdout → `used_pct` defaults to `0` → `0 ≤ 80` → loop breaks immediately → **nothing is ever pruned**. - `find -printf` isn't supported either, so even past the df check no file would be selected. Result: archiver keeps adding gzips, pruner silently no-ops, disk fills, pod dies. (A separate `head -1` SIGPIPE stall was already fixed on `dev`; this is the remaining latent failure mode.) ## Change - `df -P /persistent | awk 'NR==2 {gsub(/%/,"",$5); print $5}'` — POSIX capacity %, works on busybox **and** GNU. - `ls -1tr "$ARCHIVE_DIR"/*.RAW.gz | awk 'NR==1'` — busybox-safe oldest-by-mtime, keeping the pipefail-safe `awk NR==1` (not `head -1`) that the prior fix established. - Factored the read into a `disk_used_pct()` helper used in both the loop and the final log line. No behavior change on GNU pods; fixes the silent stall on busybox pods. ## Test plan - `bash -n` clean. - `df -P … | awk` parse verified against a real mount (`used_pct=26`). - `ls -1tr | awk NR==1` verified to select the oldest of three files by mtime, and to return empty (no crash under `set -euo pipefail`) on an empty archive dir. - Manual on-pod verification pending: install on a busybox pod with a >80%-full `/persistent` and confirm `pruner: pruned=N used_pct=<target>` in `journalctl -u sleepypod-biometrics-pruner`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved archive cleanup on devices with limited shell tools, making it more reliable across environments. * Fixed disk usage reporting so the final status message is more consistent and less likely to fail when system output is empty. * Updated selection of the oldest archived file to work more broadly while preserving the same cleanup behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- sleepypod:install-start --> <!-- 🛑 AUTO-GENERATED — sleepypod-bot owns this block. Hello fellow agent / curious human! Anything between the sleepypod:install-start and sleepypod:install-end markers gets overwritten on the next CI run. Want to change what's here? Edit .github/workflows/build.yml instead. 💤 --> <details open> <summary>🛏️ <strong>Beam this PR onto a sleepypod</strong> ✨</summary> Pick the snippet that matches your pod. **Already-installed pods can't use the curl bootstraps below** — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use `sp-update` instead; it's on disk and opens WAN as its first step. 🔄 **Already on a sleepypod** (most common — review a PR on a running pod): ```bash sudo sp-update fix/biometrics-pruner-busybox ``` 🚀 **Fresh pod / first install** — bootstraps from GitHub, rebuilds every push: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/fix/biometrics-pruner-busybox/scripts/install \ | sudo bash -s -- --branch fix/biometrics-pruner-busybox ``` 🎯 **Pin to this exact build** ([run 28749897785](https://github.com/sleepypod/core/actions/runs/28749897785) · `83dae7e`) — fresh-pod path, locked to one CI artifact for reproducible review: ```bash curl -fsSL https://raw.githubusercontent.com/sleepypod/core/83dae7ec58bbe72d1c6a2f18506f6599d80d8042/scripts/install \ | sudo bash -s -- \ --branch fix/biometrics-pruner-busybox \ --artifact-url 'https://nightly.link/sleepypod/core/actions/runs/28749897785/sleepypod-core.zip' ``` 🧊 Artifact: [`sleepypod-core`](https://github.com/sleepypod/core/actions/runs/28749897785/artifacts/8094350378) · self-destructs in 30 days 💥 </details> <!-- sleepypod:install-end -->
# Conflicts: # src/streaming/tests/mqttBridge.test.ts
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
🎉 This PR is included in version 2.5.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Release summary
50 commits from
dev. Highlights:Fixes
power_offstall alerts on a healthy Pod 4. Pump duty is now authoritative when present; priming, firmware target level, and a bounded session-end countdown cover pods that omit it./persistentfill past target.Features
Chores
Test plan
dev(lint, typecheck, unit tests, build) — every commit landed through a PR with its own checks.sp-update, verify.git-infoshows the new commit; confirm biometrics writing,/debugconsole clean, and nopump_alertsrows after a session-duration expiry and a scheduled prime.Merge with a merge commit (not squash) — preserves semver commit messages for the release tooling.
🤖 Generated with Claude Code
🛏️ Beam this PR onto a sleepypod ✨
Pick the snippet that matches your pod. Already-installed pods can't use the curl bootstraps below — sleepypod's egress firewall DROPs github.com, and the script that knows how to unblock WAN is the very file curl is trying to fetch. Use
sp-updateinstead; it's on disk and opens WAN as its first step.🔄 Already on a sleepypod (most common — review a PR on a running pod):
🚀 Fresh pod / first install — bootstraps from GitHub, rebuilds every push:
curl -fsSL https://raw.githubusercontent.com/sleepypod/core/dev/scripts/install \ | sudo bash -s -- --branch dev🎯 Pin to this exact build (run 29174365542 ·
a3d885f) — fresh-pod path, locked to one CI artifact for reproducible review:🧊 Artifact:
sleepypod-core· self-destructs in 30 days 💥