Skip to content

Releases: jvgomg/podkit

podkit 0.6.0

Choose a tag to compare

@github-actions github-actions released this 23 Mar 01:15
5188193

podkit v0.6.0

The biggest release since video sync landed — new commands, a reworked sync engine, a pile of bug fixes, and quality of life improvements that make podkit feel more solid day-to-day.

If you're upgrading from 0.5.x, everything is backwards-compatible. No config changes needed.

podkit doctor

This release introduces podkit doctor — the start of making podkit useful beyond just syncing content. The idea is simple: podkit already knows your iPod inside and out, so it should be able to diagnose and fix problems too.

The first check tackles something every iPod user has run into at some point: corrupted album artwork. Wrong covers, glitched images, artwork from a completely different album showing up — the iPod's artwork database is fragile and it doesn't take much to break it. podkit doctor detects integrity issues and rebuilds the artwork from your source collection automatically. See the artwork repair guide for the full walkthrough.

The second check finds orphan files — tracks sitting on the iPod that aren't referenced by the database, quietly eating up space. --verbose breaks them down by directory and extension; --format csv exports the full list for inspection.

More checks are coming. The goal is for podkit doctor to be a swiss army knife for iPod maintenance — useful even if you don't use podkit for syncing.

Highlights

podkit device scan — Discover connected iPods without guessing mount paths. Shows volume name, UUID, size, and mount status. Especially useful for finding the volume UUID needed to configure multi-device or Docker setups.

Graceful shutdown — Ctrl+C during sync now finishes the current operation and saves all completed work to the iPod database before exiting (code 130). Previously, Ctrl+C killed the process immediately, potentially leaving orphaned files and unsaved progress. A second Ctrl+C force-quits if you really need out. The database is also saved every 50 tracks during sync, so even a crash or force-quit loses minimal work.

Unified sync pipeline — Music and video sync now run through the same engine (SyncDifferSyncPlannerSyncExecutor). This means video sync gets all the reliability features music had — self-healing upgrades, error categorization with configurable retries, and consistent progress reporting. The ContentTypeHandler pattern makes it straightforward to add new content types down the road.

Under the Hood

  • Dual progress bars — sync output now shows both overall progress and per-file progress simultaneously, so you can see how far along a large sync is at a glance.
  • Album artwork cache cuts redundant artwork extractions by ~10x — one extraction per album instead of per track. The podkit doctor repair routine shares the same cache.
  • Full USB ejectpodkit device eject now fully detaches the USB device, not just unmounts the volume. On macOS, the iPod disappears from Disk Utility; on Linux, the USB device is powered off.
  • Incremental saves during video sync — the database saves every 10 completed video transfers, reducing data loss from interruptions during long video syncs.
  • The daemon forwards SIGINT to the sync child process on SIGTERM, so Docker's 10-second shutdown window is actually used for graceful draining instead of a hard kill.
  • Docker image layers optimized with COPY --chmod=755 instead of separate RUN chmod steps.

Bug Fixes

  • --delete flag was removing tracks of the wrong content type — syncing music could delete videos and vice versa
  • Episode/season number 0 was treated as unset (|| vs ??), causing S01E00 episodes to be deleted and re-added every sync
  • Track removal left audio/video files on disk — track.remove() now deletes the file by default
  • Duplicate source tracks caused an infinite metadata update loop — the diff engine now deduplicates, first match wins
  • Video sync overall progress counter was incrementing on every transcode sub-tick instead of once per video
  • podkit doctor orphan detection now skips macOS ._ resource fork files that were inflating the count
  • Graceful shutdown fixes: video sync interruptions could silently skip the database save; "Force quit" appeared immediately on first Ctrl+C via bun run; Ctrl+C during read-only phases now exits instantly

Full changelog

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.6.0

Minor Changes

  • 4dd7b44 Thanks @jvgomg! - Add podkit device scan command to discover connected iPod devices. Shows each iPod's volume name, UUID, size, and mount status — useful for finding the volume UUID needed to configure multi-device setups, especially in Docker.

  • d19d6e3 Thanks @jvgomg! - Add podkit doctor command for running diagnostic checks on an iPod, and podkit device reset-artwork for wiping artwork and clearing sync tags. podkit doctor runs all checks and reports problems; podkit doctor --repair artwork-integrity -c <collection> repairs by check ID using the source collection. @podkit/core exports resetArtworkDatabase and rebuildArtworkDatabase primitives, and a diagnostic framework in the diagnostics/ module built on a DiagnosticCheck interface (check + repair pattern). Includes a binary ArtworkDB parser and integrity checker.

  • b698a07 Thanks @jvgomg! - Add dual progress bars to sync output showing both overall and per-file progress simultaneously. Video sync now displays total file count alongside per-file transcode percentage and speed, so users can see how far along a large sync is. Music sync uses the same layout for consistency.

  • 2873f14 Thanks @jvgomg! - Add graceful shutdown handling for sync and doctor commands

    Pressing Ctrl+C during podkit sync now triggers a graceful shutdown: the current operation finishes, all completed tracks are saved to the iPod database, and the process exits cleanly with code 130. Previously, Ctrl+C killed the process immediately, potentially leaving orphaned files and unsaved work.

    • Sync: first Ctrl+C drains the current operation and saves; second Ctrl+C force-quits
    • Doctor: repair operations save partial progress on interrupt
    • Incremental saves: the database is now saved every 50 completed tracks during sync, reducing data loss from force-quits or crashes
    • New podkit doctor check: detects orphaned files on the iPod (files not referenced by the database) with optional cleanup via --repair orphan-files
  • 7624265 Thanks @jvgomg! - Unify sync pipeline with ContentTypeHandler pattern

    • Add generic ContentTypeHandler<TSource, TDevice> interface for media-type-specific sync logic
    • Add MusicHandler and VideoHandler implementations
    • Add UnifiedDiffer, UnifiedPlanner, and UnifiedExecutor generic pipeline components
    • Add shared error categorization and retry logic (error-handling.ts)
    • Add handler registry for looking up handlers by type string
    • Video sync now routes through the unified pipeline in the CLI
    • Video executor supports self-healing upgrades (preset-change, metadata-correction)
    • Video executor categorizes errors and supports configurable per-category retries
    • Fix album artwork cache incorrectly sharing artwork between tracks with and without artwork
    • Generic CollectionAdapter<TItem, TFilter> interface replaces separate music/video adapter contracts

Patch Changes

  • 67d1357 Thanks @jvgomg! - Fix --delete flag removing video tracks when syncing music (and vice versa). The delete flag now only considers tracks of the content type being synced.

  • 120a7b1 Thanks @jvgomg! - Improve podkit doctor orphan file reporting. Orphan detection now skips macOS ._ resource fork files that were inflating the count. Add --verbose output showing orphan breakdown by directory, file extension, and the 10 largest files. Add --format csv to export the full orphan file list for inspection.

  • 3f56a1b Thanks @jvgomg! - Fix video sync deleting and re-adding episodes with episode number 0 (e.g., S01E00)

    The || operator treated episode/season number 0 as falsy, converting it to undefined. This broke diff key matching for episode 0, causing every sync to delete and re-add the video. Changed to ?? (nullish coalescing) which only converts null/undefined, preserving 0 as a valid value.

  • 3db2bbb Thanks [@jvgomg](https://github.com...

Read more

podkit 0.5.1

Choose a tag to compare

@github-actions github-actions released this 19 Mar 21:57
f598bd9

podkit v0.5.1

A quick patch release with two bug fixes that improve reliability on NAS setups and Subsonic connections.

Bug Fixes

iPod detection on Synology NAS and NVMe systems — The Linux device manager was tripping over non-standard partition names. On Synology, block devices look like usb1p2 instead of the usual sda1, and on NVMe drives you get nvme0n1p2. The old regex for stripping partition suffixes would mangle these names (turning usb1p2 into usb1p instead of usb1), which meant podkit couldn't find the USB identity of the device and silently failed to detect the iPod. The fix properly handles both partition naming conventions — so if you're running podkit on a Synology NAS in daemon mode, your iPod should now be detected automatically.

Subsonic connections no longer hang indefinitely — When a Subsonic server was unreachable (DNS failure, connection refused, server down), the adapter would just... wait. Forever. Now it retries 3 times with exponential backoff (1s, 2s, 4s), then fails with a clear error message that includes the server URL and what went wrong. If you're running in Docker, the error even suggests checking DNS, network mode, and firewall settings — the usual suspects for container networking issues. Non-connection errors like 401 or 403 fail immediately without retrying.


Full auto-generated changelog

Releases

podkit@0.5.1

Patch Changes

@podkit/core@0.5.1

Patch Changes

  • 2e7ba81 Thanks @jvgomg! - Fix iPod detection on Synology NAS and NVMe-based systems where block device names use non-standard partition suffixes

  • e1b0fbc Thanks @jvgomg! - Fix Subsonic connection failures hanging indefinitely instead of failing with a clear error message

@podkit/daemon@0.2.1

Patch Changes

@podkit/docker@0.2.1

Patch Changes

  • Updated dependencies []:
    • podkit@0.5.1
    • @podkit/daemon@0.2.1

Changelog

Patch Changes

Checksums (SHA256)

ddbcc85c17c4f28d327c76434f0fd988fa05c7ae9eed53b6f92a72f0ed4c5ffd  podkit-daemon-linux-arm64.tar.gz
26118b44a31c3fd042b77b570d57a5ebf2846c6b889f44fa2779df30e24e5b54  podkit-daemon-linux-x64.tar.gz
64695dc0ecafc73e89753d459826dabf82bcc33314debd77a4d233392eb20da9  podkit-darwin-arm64.tar.gz
a434215b7ebc966bd24b57d1ae3e01b455382c72868a38e2740b988253ca7eaf  podkit-darwin-x64.tar.gz
217558cb3a0f921bb2cc33fd237c27de285b186ec165510ac71361324608ae76  podkit-linux-arm64.tar.gz
f60b11d48fee874830c4170d0d1de4cfb804912e9b1db4d347c6f72f1e443111  podkit-linux-x64.tar.gz

podkit 0.5.0

Choose a tag to compare

@github-actions github-actions released this 19 Mar 18:19
b16ee0d

podkit v0.5.0

podkit 0.5.0 brings Docker daemon mode, a config migration system, smarter shell completions, a new --force-metadata flag, and more reliable iPod ejecting. Since we're still pre-v1, some of these are technically breaking (the config version field), but nothing should require you to change how you use podkit today.

Highlights

Daemon mode for Docker — podkit can now run as a long-running service that polls for iPod devices and auto-syncs them when plugged in. Perfect for NAS setups where you want hands-free syncing. Supports Apprise notifications (ntfy, Slack, Discord, Telegram) so you know when a sync completes. See the daemon mode guide.

Config migration system — Config files now have a version field, and podkit migrate walks you through upgrading when the format changes. Supports --dry-run to preview changes, automatic backups, and interactive migrations that can prompt for decisions. If you're running an older config, podkit will tell you exactly what to do. See the migration docs.

Shell completions for option values — Tab completion now goes beyond just subcommands and flags. Options like --quality, --type, --encoding, and --format complete their known values (e.g., max, high, medium, low). Even --device and --collection complete with names from your config file. Works in both zsh and bash — see the CLI reference.

--force-metadata flag — Rewrite metadata on all synced tracks without re-transcoding or re-transferring audio files. Useful when you've updated tags in your source library and want to push those changes to your iPod quickly.

Under the Hood

Eject reliability on macOS — If you've ever had macOS refuse to eject your iPod because Finder or Spotlight was holding a reference, this one's for you. podkit now uses diskutil eject (proper removable-media handling), flushes filesystem buffers first, and automatically retries up to 3 times when the device is busy. On Linux, busy errors from udisksctl are now surfaced properly so the retry logic can kick in.

Docker and daemon are now versioned packages@podkit/docker and @podkit/daemon ship as proper versioned packages with changelogs, OCI image labels, and a /usr/local/share/podkit-versions.json manifest for inspecting component versions inside the container.

Quality of Life

  • Docker image published as multi-arch (linux/amd64 + linux/arm64) to ghcr.io/jvgomg/podkit
  • Daemon supports configurable poll intervals (PODKIT_POLL_INTERVAL) and graceful shutdown
  • File-based health check at /tmp/podkit-daemon-health for Docker healthcheck integration

Full auto-generated changelog

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.5.0

Minor Changes

  • 6b90ef7 Thanks @jvgomg! - Add config migration system with podkit migrate command

    Config files now have a version field. Running any command with an outdated config shows a clear error directing you to run podkit migrate. The migrate command detects your config version, shows what will change, backs up your original file, and applies updates. Supports --dry-run to preview changes and interactive migrations that can prompt for decisions. Configs without a version field are treated as version 0 and can be migrated with podkit migrate.

  • 0019607 Thanks @jvgomg! - Add --force-metadata flag to rewrite metadata on all synced tracks without re-transcoding or re-transferring files

  • 4edadde Thanks @jvgomg! - Add tab completion for option values and dynamic config names

    Options like --quality, --type, --encoding, and --format now offer their known values when pressing tab (e.g. max, high, medium, low). The --device and --collection flags complete with names from your config file. Works in both zsh and bash.

Patch Changes

  • 8dddd29 Thanks @jvgomg! - Improve iPod eject reliability with automatic retry and filesystem sync

    • Use diskutil eject instead of diskutil unmount on macOS for proper removable-media handling (unmounts + detaches the disk)
    • Flush filesystem buffers before ejecting to ensure all writes are persisted
    • Automatically retry eject up to 3 times when the device is temporarily busy (common on macOS when Finder/Spotlight holds a reference)
    • Show progress output during retry so you know what's happening
    • On Linux, return busy errors from udisksctl immediately so the retry wrapper can handle them instead of silently falling through
  • Updated dependencies [8dddd29, 0019607]:

    • @podkit/core@0.5.0

@podkit/core@0.5.0

Minor Changes

  • 0019607 Thanks @jvgomg! - Add --force-metadata flag to rewrite metadata on all synced tracks without re-transcoding or re-transferring files

Patch Changes

  • 8dddd29 Thanks @jvgomg! - Improve iPod eject reliability with automatic retry and filesystem sync
    • Use diskutil eject instead of diskutil unmount on macOS for proper removable-media handling (unmounts + detaches the disk)
    • Flush filesystem buffers before ejecting to ensure all writes are persisted
    • Automatically retry eject up to 3 times when the device is temporarily busy (common on macOS when Finder/Spotlight holds a reference)
    • Show progress output during retry so you know what's happening
    • On Linux, return busy errors from udisksctl immediately so the retry wrapper can handle them instead of silently falling through

@podkit/daemon@0.2.0

Minor Changes

  • 0aed896 Thanks @jvgomg! - Initial release of @podkit/docker and @podkit/daemon as versioned packages.

    @podkit/daemon is a long-running service that polls for iPod devices and automatically syncs them. It detects when an iPod is plugged in, mounts it, runs a full podkit sync, and ejects it — hands-free. Designed for always-on setups like NAS devices running Docker. Supports configurable poll intervals (PODKIT_POLL_INTERVAL) and Apprise notifications (PODKIT_APPRISE_URL). Handles graceful shutdown, waiting for any in-progress sync to complete before exiting.

    @podkit/docker is the Docker distribution of podkit, published as a multi-arch image (linux/amd64, linux/arm64) to ghcr.io/jvgomg/podkit. Bundles the CLI and daemon binaries in an Alpine-based image following LinuxServer.io conventions (PUID/PGID, /config volume). Supports two modes: CLI (default, run sync on demand) and daemon (opt-in, auto-detect and sync iPods on plug-in). Component versions are inspectable via OCI image labels and /usr/local/share/podkit-versions.json.

@podkit/docker@0.2.0

Minor Changes

  • 0aed896 Thanks @jvgomg! - Initial release of @podkit/docker and @podkit/daemon as versioned packages.

    @podkit/daemon is a long-running service that polls for iPod devices and automatically syncs them. It detects when an iPod is plugged in, mounts it, runs a full podkit sync, and ejects it — hands-free. Designed for always-on setups like NAS devices running Docker. Supports configurable poll intervals (PODKIT_POLL_INTERVAL) and Apprise notifications (PODKIT_APPRISE_URL). Handles graceful shutdown, waiting for any in-progress sync to complete before exiting.

    @podkit/docker is the Docker distribution of podkit, published as a multi-arch image (linux/amd64, linux/arm64) to ghcr.io/jvgomg/podkit. Bundles the CLI and daemon binaries in an Alpine-based image following LinuxServer.io conventions (PUID/PGID, /config volume). Supports two modes: CLI (default, run sync on demand) and daemon (opt-in, auto-detect and sync iPods on plug-in). Component versions are inspectable via OCI image labels and /usr/local/share/podkit-versions.json.

Patch Changes


Changelog

Minor Changes

  • [`6b90ef...
Read more

podkit 0.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Mar 00:22
9a31a00

podkit 0.4.0

This is a big one. podkit 0.4.0 brings Linux support, Docker distribution, environment-variable-driven configuration, shell completions, and a major overhaul of video metadata handling. It also fixes a critical bug where Homebrew and standalone binary installations were completely non-functional for iPod operations. As a pre-v1 project, this release includes some minor breaking changes to config defaults.

Highlights

  • Linux device managementpodkit mount, podkit eject, and podkit device add now work on Debian, Ubuntu, Alpine, and other Linux distributions. Uses udisksctl for unprivileged operation (with mount/umount fallback), lsblk for device enumeration, and reads USB identity from /sys for iPod auto-detection. iFlash adapter detection works too. Docs

  • Docker image — Official image at ghcr.io/jvgomg/podkit for linux/amd64 and linux/arm64. Based on Alpine with FFmpeg pre-installed, PUID/PGID support, and Docker Compose examples. This release also adds musl-compatible standalone binaries to release assets. Docs

  • Environment variable config — Define collections and devices entirely via env vars — no config file required. Set PODKIT_MUSIC_PATH=/music and go. Supports named collections, Subsonic sources, video collections, and per-device overrides. Docs

  • Shell completions — Tab completion for all commands, subcommands, and options via podkit completions install. Supports zsh and bash, with a --alias dev mode for local development. Generated automatically from the CLI structure, so new commands just work. Docs

  • Video metadata overhaul — The filename parser now handles anime fansub naming conventions ([Group]_Show_Name_EP_(codec)_[CRC].ext), prefers folder-based series titles for richer metadata, strips scene release cruft from episode titles, and detects language and edition tags. A new configurable showLanguage transform reformats language markers in series titles (e.g., (JPN)(Japanese)). Changing language preferences triggers metadata-only updates, not file re-transfers. Show language docs

Under the Hood

  • The big one nobody noticed — The compiled CLI binary (Homebrew installs, standalone downloads) was completely broken for any command that actually talked to an iPod. The native .node addon that bridges to libgpod wasn't being bundled into the single-file binary, so every iPod database operation silently failed. This went undetected because development uses bun run (which resolves the addon from node_modules), not the compiled binary. The fix embeds the addon directly in the binary and fully statically links all native dependencies — including on Linux, where builds now use musl/Alpine for universal compatibility across distros.

  • Video episode titles — Episodes without an explicit title in the filename (e.g., Show - S01E01.mkv) were showing the series name as the episode title on iPod, so you'd see "My Show" repeated for every episode instead of something useful. They now display as S01E01, and episodes with titles show as S01E01 - Episode Title.

Quality of Life

  • volumeUuid is now optional in device config — UUID validation still protects against syncing to the wrong iPod when configured, but you no longer need it for simple setups
  • --dry-run output now shows showLanguage transform info so you can preview how language tags will be reformatted before syncing

Full changelog

Releases

podkit@0.4.0

Minor Changes

  • 8c121ff Thanks @jvgomg! - Add shell completion support with podkit completions command. Tab completion for all commands, subcommands, and options is generated automatically from the CLI structure. Supports zsh and bash via podkit completions install for guided setup, including a dev mode (--alias) that creates a shorthand function with completions for local development workflows.

  • #37 424e0e9 Thanks @jvgomg! - Add official Docker image for running podkit in containers. The image is based on Alpine Linux and supports both linux/amd64 and linux/arm64 architectures. Published to GitHub Container Registry on each release.

    Also adds musl-compatible Linux binaries to release assets for users on Alpine and other musl-based distributions.

  • #38 50e529c Thanks @jvgomg! - Add environment variable support for defining collections and devices without a config file. Set PODKIT_MUSIC_PATH=/music to configure a music collection entirely via env vars — no config file needed. Supports named collections (PODKIT_MUSIC_MAIN_PATH), Subsonic sources (PODKIT_MUSIC_TYPE=subsonic), and video collections (PODKIT_VIDEO_PATH). Device volumeUuid is now optional, and UUID validation protects against syncing to the wrong iPod when configured.

  • #38 50e529c Thanks @jvgomg! - Add Linux device manager support for mount, eject, and device detection. podkit now supports podkit mount, podkit eject, and podkit device add on Debian, Ubuntu, Alpine, and other Linux distributions. Uses lsblk for device enumeration, udisksctl for unprivileged mount/eject (with fallback to mount/umount), and USB identity from /sys for iPod auto-detection. iFlash adapter detection works on Linux via block size and capacity signals.

  • #38 50e529c Thanks @jvgomg! - Improve video filename parsing and add show language transform for video sync

    Filename parsing improvements:

    • Add anime fansub filename pattern support ([Group]_Show_Name_EP_(codec)_[CRC].ext)
    • Prefer folder-based series titles over filename-only parsing for richer metadata
    • Strip scene release cruft (quality tags, codecs, release groups) from episode titles
    • Detect language and edition tags from filenames and folder paths
    • Add language and edition optional fields to CollectionVideo

    Show language transform:

    • Add configurable showLanguage transform that reformats language markers in video series titles (e.g., (JPN)(Japanese))
    • Enabled by default with abbreviated format — configure via config file, per-device overrides, or PODKIT_SHOW_LANGUAGE* env vars
    • Changing language display preferences causes metadata-only updates, not file re-transfers (dual-key matching in video differ)

    CLI:

    • Add showLanguage config support (boolean shorthand or [showLanguage] table with format and expand options)
    • Add per-device showLanguage overrides
    • Show transform info in --dry-run output
    • Add @podkit/libgpod-node as explicit dependency for reliable native binding resolution in worktrees

Patch Changes

  • #38 50e529c Thanks @jvgomg! - Fix native libgpod binding not loading in compiled CLI binary. The Homebrew and standalone binary distributions were completely broken for any command that touched the iPod database. The .node addon is now embedded directly in the single-file binary, and all native dependencies are fully statically linked — including on Linux, where builds now use musl/Alpine for universal compatibility across all distros (Debian, Ubuntu, RHEL, Fedora, Arch, Alpine, etc.).

  • Updated dependencies [50e529c, 21ab79a, 50e529c]:

    • @podkit/core@0.4.0

@podkit/core@0.4.0

Minor Changes

  • #38 50e529c Thanks @jvgomg! - Add Linux device manager support for mount, eject, and device detection. podkit now supports podkit mount, podkit eject, and podkit device add on Debian, Ubuntu, Alpine, and other Linux distributions. Uses lsblk for device enumeration, udisksctl for unprivileged mount/eject (with fallback to mount/umount), and USB identity from /sys for iPod auto-detection. iFlash adapter detection works on Linux via block size and capacity signals.

  • #38 50e529c Thanks @jvgomg! - Improve video filename parsing and add show language transform for video sync

    Filename parsing improvements:

    • Add anime fansub filename pattern support ([Group]_Show_Name_EP_(codec)_[CRC].ext)
    • Prefer folder-based series titles over filename-only parsing for richer metadata
    • Strip scene release cruft (qua...
Read more

podkit 0.3.0

Choose a tag to compare

@github-actions github-actions released this 17 Mar 17:19
80f1320

podkit v0.3.0

This is a big release! podkit now keeps your iPod in sync much more intelligently — it detects when your source files have improved and upgrades tracks automatically, handles volume normalization, understands compilation albums, and can even spot when your album artwork has changed.

There are a few breaking changes to the CLI and config format (details below). We're still pre-v1, so we're taking this opportunity to clean up the interface while the project is young. Migration is straightforward — see the breaking changes section for exactly what to update.

Highlights

  • Self-healing sync — podkit now detects when a source file has improved (format upgrade, higher quality, new artwork, corrected metadata) and upgrades the track on your iPod in place, preserving play counts, ratings, and playlist membership. No more removing and re-adding tracks to get better quality. Read more →

  • Sound Check — Volume normalization is here. podkit reads ReplayGain and iTunNORM tags from your source files (and Subsonic servers via OpenSubsonic) and writes Sound Check values to the iPod database, so tracks play back at consistent volumes. Verbose mode shows a breakdown of tag formats found in your collection. Read more →

  • Device-aware quality presets — Quality presets have been redesigned into four tiers: max, high, medium, low. The max preset automatically picks lossless ALAC on devices that support it and falls back to high-quality AAC on others. If you change your preset, podkit detects the mismatch and re-transcodes on the next sync. Read more →

  • Artwork change detection — Use --check-artwork to detect when album art has changed in your source collection and update it on your iPod without re-transferring audio. Artwork fingerprints are built up progressively during normal syncs, so there's nothing extra to set up. Read more →

  • Compilation albums — Compilation metadata from FLAC, MP3, M4A files and Subsonic servers is now written to the iPod database correctly, so compilation albums show up under "Compilations" where they belong. Read more →

Breaking Changes

CLI: Named flags replace positional arguments — All device names, collection names, and sync types now use named flags. This makes commands more readable and consistent. CLI reference →

- podkit sync music -c main
+ podkit sync -t music -c main

- podkit device add myipod /Volumes/IPOD
+ podkit device add -d myipod --path /Volumes/IPOD

- podkit device info myipod
+ podkit device info -d myipod

Config: ftintitle renamed to cleanArtists — The [transforms.ftintitle] config section is now a top-level cleanArtists key. Supports a simple cleanArtists = true or a table with options. Clean Artists docs →

- [transforms.ftintitle]
- enabled = true
+ cleanArtists = true

Config: Quality presets redesigned — Presets are now max, high, medium, low (default: high). A new encoding option replaces the old CBR preset variants, and lossyQuality has been removed. Quality presets docs →

Under the Hood

  • The curious case of the backwards encoder — Turns out macOS's AudioToolbox AAC encoder uses a quality scale where 0 is best and 14 is worst. Our mapping had it the wrong way around, which meant the "high" VBR preset was quietly producing ~44 kbps audio instead of ~256 kbps. If you've been on macOS and wondering why your transcodes sounded a bit rough — mystery solved. This release fixes the mapping using empirically-measured bitrate targets, so presets now sound the way they should.

  • Sync tags — podkit now embeds small metadata tags in the iPod track's comment field recording exactly what transcode settings produced each file. This eliminates false re-transcoding caused by natural VBR bitrate variance — previously, a track encoded at 248 kbps targeting 256 kbps might get re-transcoded unnecessarily. You can retrofit tags onto existing tracks with --force-sync-tags. Sync tags reference →

  • Subsonic prefetch pipeline — Syncing from Subsonic/Navidrome is now faster. Previously, each track was downloaded then transcoded sequentially, leaving the network idle during CPU work. The sync executor now pipelines downloads ahead of transcoding so network I/O overlaps with FFmpeg encoding.

  • replaceTrackFile() in libgpod-node — A new native binding that replaces a track's audio file while preserving the database entry. This is the foundation that makes self-healing sync possible — the old file is deleted, libgpod generates a fresh device path with the correct extension, and the iPod firmware uses the right decoder.

Quality of Life

  • unmount now works as an alias for eject
  • --no-tips flag (and tips config option) to suppress contextual tips
  • Mount command tries diskutil mount before falling back to sudo, with better error messages explaining what's happening
  • device clear confirmation prompt now shows the [y/N] hint
  • Transcoding progress no longer wraps on narrow terminals
  • Video sync time estimates are now ~20x more accurate

Full changelog

Releases

@podkit/libgpod-node@0.1.0

Minor Changes

  • e4485a1 Thanks @jvgomg! - Add self-healing sync for changed and upgraded source files. Sync now detects when a source file has improved — format upgrade (MP3 replaced with FLAC), quality upgrade (higher bitrate), artwork added, Sound Check values changed, or metadata corrected — and upgrades the iPod track in place, preserving play counts, star ratings, and playlist membership.

    Upgrades happen by default as part of normal sync. Use --skip-upgrades or the skipUpgrades config option to disable file-replacement upgrades when short on time or space. The skipUpgrades setting follows the standard resolution order (CLI flag → device config → global config → default).

    Add replaceTrackFile() to @podkit/libgpod-node for replacing a track's audio file while preserving the database entry. The old file is deleted and libgpod generates a fresh path with the correct extension for the new format, ensuring the iPod firmware uses the right decoder.

    Add hasArtwork field to CollectionTrack — populated by the directory adapter (from embedded pictures) and Subsonic adapter (from cover art metadata).

    Fix copied tracks (MP3, M4A) not having their bitrate recorded in the iPod database, which is needed for quality-upgrade detection.

    Breaking: ConflictTrack type and SyncDiff.conflicts array removed from @podkit/core — metadata conflicts are now handled as metadata-correction upgrades.

  • d40371f Thanks @jvgomg! - Add Sound Check (volume normalization) support. podkit now reads ReplayGain and iTunNORM tags from source files and writes the Sound Check value to the iPod database during sync, enabling automatic volume normalization on playback. The dry-run output shows how many tracks have normalization data, and a new soundcheck field is available in device music and collection music commands via --fields.

podkit@0.3.0

Minor Changes

  • 2a4799b Thanks @jvgomg! - Add artwork change detection with --check-artwork flag. When enabled, podkit detects when album artwork has changed in your source collection and updates the artwork on your iPod without re-transferring audio files. Artwork fingerprints are written progressively during normal syncs, building baselines automatically over time. Sync tag display now shows consistency breakdown in device info and track listings. For directory sources, artwork added and removed is also detected automatically. Subsonic sources support artwork change detection but not artwork added/removed detection due to limitations in the Subsonic API.

  • 0aff870 Thanks @jvgomg! - Rename ftintitle transform to cleanArtists with a simpler config format

    Breaking change (minor bump — not yet v1): The [transforms.ftintitle] config section has been replaced with a top-level cleanArtists key. This is a cleaner, more intuitive name that communicates the feature's value. The new format supports both a simple boolean (cleanArtists = true) and a table form with options ([cleanArtists]). Per-device overrides use cleanArtists = false or [devices.<name>.cleanArtists]. Environment variables PODKIT_CLEAN_ARTISTS, PODKIT_CLEAN_ARTISTS_DROP, PODKIT_CLEAN_ARTISTS_FORMAT, and PODKIT_CLEAN_ARTISTS_IGNORE are now supported. The FtInTitleConfig type is renamed to CleanArtistsConfig and DEFAULT_FTINTITLE_CONFIG to DEFAULT_CLEAN_ARTISTS_CONFIG.

  • e47456a Thanks @jvgomg! - Add compilation album support to sync pipeline and CLI display. Compilation metadata from source files (FLAC, MP3, M4A) and Subsonic servers is now correctly written to the iPod database, ensuring compil...

Read more

podkit 0.2.0

Choose a tag to compare

@github-actions github-actions released this 13 Mar 15:27
25b356e

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.2.0

Minor Changes

  • d3b8eb2 Thanks @jvgomg! - Improve podkit device add to detect and handle unmounted iPods, including iFlash-modified devices that macOS refuses to automount.
    • Scans for both mounted and unmounted iPods — no longer requires the device to be pre-mounted
    • Assesses unmounted devices before attempting to mount: reads block size and capacity from diskutil, queries USB product ID via system_profiler, and resolves it to a model name (e.g. "iPod Classic 6th generation")
    • Confirms iFlash adapters via two independent signals: 2048-byte block size (iFlash emulates optical media sectors) and capacity exceeding the original iPod Classic maximum of 160 GB
    • Attempts diskutil mount first (no elevated privileges required); falls back to mount -t msdos for large FAT32 volumes that macOS refuses to mount through its normal mechanisms
    • When sudo is required, explains exactly why with per-signal detail and shows the exact command to run (sudo podkit device add <name>)
    • Exports DeviceAssessment, IFlashAssessment, IFlashEvidence, and UsbDeviceInfo types from @podkit/core

Patch Changes

  • f268d71 Thanks @jvgomg! - Extract filesystem validation into a shared utility module for improved testability

  • b3d530f Thanks @jvgomg! - Add support for PODKIT_CONFIG environment variable to set config file path

  • Updated dependencies [d3b8eb2]:

    • @podkit/core@0.2.0

@podkit/core@0.2.0

Minor Changes

  • d3b8eb2 Thanks @jvgomg! - Improve podkit device add to detect and handle unmounted iPods, including iFlash-modified devices that macOS refuses to automount.
    • Scans for both mounted and unmounted iPods — no longer requires the device to be pre-mounted
    • Assesses unmounted devices before attempting to mount: reads block size and capacity from diskutil, queries USB product ID via system_profiler, and resolves it to a model name (e.g. "iPod Classic 6th generation")
    • Confirms iFlash adapters via two independent signals: 2048-byte block size (iFlash emulates optical media sectors) and capacity exceeding the original iPod Classic maximum of 160 GB
    • Attempts diskutil mount first (no elevated privileges required); falls back to mount -t msdos for large FAT32 volumes that macOS refuses to mount through its normal mechanisms
    • When sudo is required, explains exactly why with per-signal detail and shows the exact command to run (sudo podkit device add <name>)
    • Exports DeviceAssessment, IFlashAssessment, IFlashEvidence, and UsbDeviceInfo types from @podkit/core

Changelog

Minor Changes

  • d3b8eb2 Thanks @jvgomg! - Improve podkit device add to detect and handle unmounted iPods, including iFlash-modified devices that macOS refuses to automount.
    • Scans for both mounted and unmounted iPods — no longer requires the device to be pre-mounted
    • Assesses unmounted devices before attempting to mount: reads block size and capacity from diskutil, queries USB product ID via system_profiler, and resolves it to a model name (e.g. "iPod Classic 6th generation")
    • Confirms iFlash adapters via two independent signals: 2048-byte block size (iFlash emulates optical media sectors) and capacity exceeding the original iPod Classic maximum of 160 GB
    • Attempts diskutil mount first (no elevated privileges required); falls back to mount -t msdos for large FAT32 volumes that macOS refuses to mount through its normal mechanisms
    • When sudo is required, explains exactly why with per-signal detail and shows the exact command to run (sudo podkit device add <name>)
    • Exports DeviceAssessment, IFlashAssessment, IFlashEvidence, and UsbDeviceInfo types from @podkit/core

Patch Changes

  • f268d71 Thanks @jvgomg! - Extract filesystem validation into a shared utility module for improved testability

  • b3d530f Thanks @jvgomg! - Add support for PODKIT_CONFIG environment variable to set config file path

  • Updated dependencies [d3b8eb2]:

    • @podkit/core@0.2.0

Checksums (SHA256)

16fcab7ae7b751dd2ca8c65abf21cd042fbe048a0d6cad0c591766f307fdfb33  podkit-darwin-arm64.tar.gz
3e232a9ae1d66061ee09f9ea7451db8062f1f5816b9d86a183861580c0178a97  podkit-darwin-x64.tar.gz
60a17e61caf2ad0b3c6a59078c1566ad2b5d40325b193c5ca03294949451311c  podkit-linux-arm64.tar.gz
7dc87508c07b0650a7a0bd1c3fb1599e4ab926eff2e5d2a612541cc1ff3c88e1  podkit-linux-x64.tar.gz

podkit 0.1.0

Choose a tag to compare

@github-actions github-actions released this 12 Mar 10:37
647cabd

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.1.0

Minor Changes

  • 83743dd Thanks @jvgomg! - Add device validation and capability communication

    • Detect unsupported devices (iPod Touch, iPhone, iPad, buttonless Shuffles, Nano 6th gen) with clear error messages explaining why they won't work
    • Warn when iPod model cannot be identified, with instructions to fix SysInfo
    • Show device capability indicators (+/-) in podkit device info output
    • Block podkit device add for unsupported devices and show capabilities during confirmation
    • Add sync pre-flight checks that block unsupported devices and warn about incompatible content types
    • Include structured capabilities and validation data in JSON output
  • 39e3129 Thanks @jvgomg! - Add stats, albums, and artists views to content listing commands

    • device music, device video, collection music, and collection video now show summary stats by default (track/album/artist counts and file type breakdown)
    • Add --tracks flag to list all tracks (previous default behavior)
    • Add --albums flag to list albums with track counts
    • Add --artists flag to list artists with album/track counts
    • --tracks --json on device commands now includes all iPod metadata fields (play stats, timestamps, video fields, etc.)

Patch Changes

  • Updated dependencies [83743dd]:
    • @podkit/core@0.1.0

@podkit/core@0.1.0

Minor Changes

  • 83743dd Thanks @jvgomg! - Add device validation and capability communication
    • Detect unsupported devices (iPod Touch, iPhone, iPad, buttonless Shuffles, Nano 6th gen) with clear error messages explaining why they won't work
    • Warn when iPod model cannot be identified, with instructions to fix SysInfo
    • Show device capability indicators (+/-) in podkit device info output
    • Block podkit device add for unsupported devices and show capabilities during confirmation
    • Add sync pre-flight checks that block unsupported devices and warn about incompatible content types
    • Include structured capabilities and validation data in JSON output

Changelog

Minor Changes

  • 83743dd Thanks @jvgomg! - Add device validation and capability communication

    • Detect unsupported devices (iPod Touch, iPhone, iPad, buttonless Shuffles, Nano 6th gen) with clear error messages explaining why they won't work
    • Warn when iPod model cannot be identified, with instructions to fix SysInfo
    • Show device capability indicators (+/-) in podkit device info output
    • Block podkit device add for unsupported devices and show capabilities during confirmation
    • Add sync pre-flight checks that block unsupported devices and warn about incompatible content types
    • Include structured capabilities and validation data in JSON output
  • 39e3129 Thanks @jvgomg! - Add stats, albums, and artists views to content listing commands

    • device music, device video, collection music, and collection video now show summary stats by default (track/album/artist counts and file type breakdown)
    • Add --tracks flag to list all tracks (previous default behavior)
    • Add --albums flag to list albums with track counts
    • Add --artists flag to list artists with album/track counts
    • --tracks --json on device commands now includes all iPod metadata fields (play stats, timestamps, video fields, etc.)

Patch Changes

  • Updated dependencies [83743dd]:
    • @podkit/core@0.1.0

Checksums (SHA256)

246f9f5bbf2892249392ad27d0d53ccbe06142805a09a9a5d56122a51de3b389  podkit-darwin-arm64.tar.gz
b4f0f943f9fc789d2c05b0863a50d998efe2dc9a16054460b4b4b424d906b4e0  podkit-darwin-x64.tar.gz
e06671d769a63ebc9f0cefdc3a5c67c00c5422531905aba3ea4f51308e8ac96a  podkit-linux-arm64.tar.gz
e2f6d12681eeea3394e3c7b21dec3e3eb27372c5cf45c4b8b1c950812eb0b69a  podkit-linux-x64.tar.gz

podkit 0.0.3

Choose a tag to compare

@github-actions github-actions released this 11 Mar 17:59
03985f1

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.0.3

Patch Changes

  • 3c2c3e8 Thanks @jvgomg! - Fix --version to show the correct version number instead of 0.0.0

Changelog

Patch Changes

  • 3c2c3e8 Thanks @jvgomg! - Fix --version to show the correct version number instead of 0.0.0

Checksums (SHA256)

d0242788652afb4dca25ea74dda74fd0ae9041a0f1947da650b1abdb629bd9f4  podkit-darwin-arm64.tar.gz
a666d0e3aff1f03a1b827639c764e25b2d326654fe62df3f6fc86dbc60cb6968  podkit-darwin-x64.tar.gz
517c303ffdb5783d63384cc1bbcc4018327d86d46331c7764fee1eaf184fd9c8  podkit-linux-arm64.tar.gz
e9e26e0e4af3cbff3ff29c4d4ae7509b217f5f4522fdf97e797ffb261920be0a  podkit-linux-x64.tar.gz

podkit 0.0.2

Choose a tag to compare

@github-actions github-actions released this 11 Mar 17:22
66b7c05

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

podkit@0.0.2

Patch Changes

  • 168a9d2 Thanks @jvgomg! - Fix release pipeline to correctly detect version merges

Changelog

Patch Changes

  • 168a9d2 Thanks @jvgomg! - Fix release pipeline to correctly detect version merges

Checksums (SHA256)

eb738bbfeda29a8ccaadc0ed59ff6bcc5acdd5feb95a026388e64eff72bac908  podkit-darwin-arm64.tar.gz
1088ede2dda52c4c1cd976684e833b185bf5cb94078176000d9d1a7abb591603  podkit-darwin-x64.tar.gz
e254e4156ccd05bcdc556ba05ccc7bca708bee09f260a03dadfd58075c305ebb  podkit-linux-arm64.tar.gz
fa7d2ddb8f1311f571f8aa9b375cceed6567860dc42e240472e9af66bc6eff0f  podkit-linux-x64.tar.gz