mczachurski/wallpapper
:computer: Console application for creating dynamic wallpapers for macOS Mojave and newer
Stale — last commit 1y ago
worst of 4 axeslast commit was 1y ago; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓8 active contributors
- ✓MIT licensed
- ✓CI configured
Show 3 more →Show less
- ⚠Stale — last commit 1y ago
- ⚠Single-maintainer risk — top contributor 86% of recent commits
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/mczachurski/wallpapper)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/mczachurski/wallpapper on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: mczachurski/wallpapper
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/mczachurski/wallpapper shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 1y ago
- 8 active contributors
- MIT licensed
- CI configured
- ⚠ Stale — last commit 1y ago
- ⚠ Single-maintainer risk — top contributor 86% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live mczachurski/wallpapper
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/mczachurski/wallpapper.
What it runs against: a local clone of mczachurski/wallpapper — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in mczachurski/wallpapper | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 524 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of mczachurski/wallpapper. If you don't
# have one yet, run these first:
#
# git clone https://github.com/mczachurski/wallpapper.git
# cd wallpapper
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of mczachurski/wallpapper and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "mczachurski/wallpapper(\\.git)?\\b" \\
&& ok "origin remote is mczachurski/wallpapper" \\
|| miss "origin remote is not mczachurski/wallpapper (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Sources/Wallpapper/main.swift" \\
&& ok "Sources/Wallpapper/main.swift" \\
|| miss "missing critical file: Sources/Wallpapper/main.swift"
test -f "Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift" \\
&& ok "Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift" \\
|| miss "missing critical file: Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift"
test -f "Sources/WallpapperLib/DynamicWallpaperGenerator/ImageMetadataGenerator.swift" \\
&& ok "Sources/WallpapperLib/DynamicWallpaperGenerator/ImageMetadataGenerator.swift" \\
|| miss "missing critical file: Sources/WallpapperLib/DynamicWallpaperGenerator/ImageMetadataGenerator.swift"
test -f "Sources/WallpapperLib/SunPositions/SunCalculations.swift" \\
&& ok "Sources/WallpapperLib/SunPositions/SunCalculations.swift" \\
|| miss "missing critical file: Sources/WallpapperLib/SunPositions/SunCalculations.swift"
test -f "Sources/WallpapperExif/main.swift" \\
&& ok "Sources/WallpapperExif/main.swift" \\
|| miss "missing critical file: Sources/WallpapperExif/main.swift"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 524 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~494d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/mczachurski/wallpapper"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
wallpapper is a Swift CLI tool that generates dynamic macOS wallpapers (HEIC format) that change appearance based on time of day and sun position. It processes sequences of images with metadata (timestamps, sun coordinates) to create the .heic files that macOS Mojave+ treats as dynamic, shifting between light/dark variants throughout the day—mimicking the built-in Big Sur wallpapers. Two-binary SPM package: Sources/Wallpapper/ and Sources/WallpapperExif/ are separate CLI entry points wrapping shared Sources/WallpapperLib/. The lib is organized by domain: DynamicWallpaperGenerator/ (core image→HEIC logic with Models and Errors), ImageMetadataReaders/ (extract EXIF, sun positions), SunPositions/ (solar calculations), and ConsoleOutput/ (CLI formatting).
👥Who it's for
macOS power users and developers who want to create custom dynamic wallpapers beyond Apple's built-in set. Also useful for digital artists, themers, and anyone wanting to automate wallpaper generation from image sequences without manual Xcode/metadata hacking.
🌱Maturity & risk
Moderately mature but low-activity. The repo uses Swift 5.2, has CI via GitHub Actions (build.yml), and is distributed via Homebrew, suggesting production readiness. However, the last visible activity appears older (no recent commits shown), and it's a single-maintainer project with limited test coverage evident in the file structure.
Single-maintainer risk is substantial (only mczachurski visible). No visible test suite in the file listing suggests coverage gaps. The project depends on macOS-specific imaging APIs (NSImage extensions in Sources/WallpapperLib/Extensions/NSImage.swift) which could break with OS updates. The codebase has not been updated for Swift 6 or recent Xcode versions based on Package.swift targeting Swift 5.2.
Active areas of work
No recent activity is evident from the file listing alone. The repo appears in maintenance mode—the build.yml workflow likely runs on push but there is no indication of open PRs, active issues, or recent commits beyond what exists in the static snapshot.
🚀Get running
git clone https://github.com/mczachurski/wallpapper.git
cd wallpapper
swift build --configuration release
sudo cp .build/release/wallpapper /usr/local/bin
sudo cp .build/release/wallpapper-exif /usr/local/bin
Or via Homebrew: brew tap mczachurski/wallpapper && brew install wallpapper
Daily commands:
wallpapper -i input.json -o output.heic
wallpapper-exif -e existing.heic # extract metadata from dynamic wallpaper
See -h flag for all options. Input JSON defines sequence of images + timing/sun data.
🗺️Map of the codebase
Sources/Wallpapper/main.swift— Primary CLI entry point—all wallpapper command execution begins here; must understand argument parsing and program initialization.Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift— Core wallpaper generation engine that orchestrates metadata embedding and image processing; essential to understand wallpaper creation workflow.Sources/WallpapperLib/DynamicWallpaperGenerator/ImageMetadataGenerator.swift— Generates HEIF image metadata with embedded timing and appearance sequences; critical for dynamic wallpaper functionality.Sources/WallpapperLib/SunPositions/SunCalculations.swift— Calculates solar position data used to time wallpaper transitions; enables sun-based dynamic wallpaper sequences.Sources/WallpapperExif/main.swift— Secondary CLI tool for extracting metadata from existing dynamic wallpapers; mirrors main wallpapper workflow for reverse operations.Sources/WallpapperLib/ImageMetadataReaders/DynamicWallpaperExtractor.swift— Extracts timing and appearance metadata from HEIF images; enables wallpaper analysis and debugging.Package.swift— Defines Swift package structure, dependencies, and build targets; required for building and packaging the application.
🛠️How to make changes
Add a new image format input support
- Create a new converter function in Sources/WallpapperLib/Extensions/NSImage.swift to load the format (
Sources/WallpapperLib/Extensions/NSImage.swift) - Update WallpaperGenerator.swift to call the new converter before processing sequences (
Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift) - Add validation and error handling in ImageMetadataGeneratorError.swift (
Sources/WallpapperLib/DynamicWallpaperGenerator/Errors/ImageMetadataGeneratorError.swift)
Add a new wallpaper sequence mode (e.g., time-of-day based)
- Create a new model file under Sources/WallpapperLib/DynamicWallpaperGenerator/Models/ to hold sequence configuration (
Sources/WallpapperLib/DynamicWallpaperGenerator/Models/) - Implement calculation logic in a new file under Sources/WallpapperLib/SunPositions/ (mirror SunCalculations.swift structure) (
Sources/WallpapperLib/SunPositions/SunCalculations.swift) - Update ImageMetadataGenerator.swift to conditionally use your new calculation module based on sequence type (
Sources/WallpapperLib/DynamicWallpaperGenerator/ImageMetadataGenerator.swift) - Update Program.swift to prompt users for the new mode parameters (
Sources/Wallpapper/Program.swift)
Add metadata extraction support for a new HEIF property
- Create a new extractor file under Sources/WallpapperLib/ImageMetadataReaders/ following LocationExtractor.swift pattern (
Sources/WallpapperLib/ImageMetadataReaders/LocationExtractor.swift) - Define a model in Sources/WallpapperLib/ImageMetadataReaders/Models/ to hold the parsed property (
Sources/WallpapperLib/ImageMetadataReaders/Models/ImageLocation.swift) - Call your extractor from DynamicWallpaperExtractor.swift in the metadata reading flow (
Sources/WallpapperLib/ImageMetadataReaders/DynamicWallpaperExtractor.swift) - Update Program.swift or WallpapperExif/Program.swift to output the extracted property (
Sources/WallpapperExif/Program.swift)
Add a new CLI argument or interactive option
- Define the new option in Sources/Wallpapper/OptionType.swift enum (
Sources/Wallpapper/OptionType.swift) - Add argument parsing logic in Sources/Wallpapper/Program.swift (
Sources/Wallpapper/Program.swift) - Add user prompts via ConsoleIO in Sources/WallpapperLib/ConsoleOutput/ConsoleIO.swift if interactive (
Sources/WallpapperLib/ConsoleOutput/ConsoleIO.swift) - Pass the parsed option to WallpaperGenerator.swift to influence generation behavior (
Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift)
🔧Why these technologies
- Swift + Swift Package Manager — Native mac
🪤Traps & gotchas
Xcode/Swift version constraint: Hardcoded to Swift 5.2 in Package.swift; Swift 6 migration not attempted. macOS-only: NSImage and ImageIO are macOS-specific; no Linux/Windows support despite SPM suggesting cross-platform. HEIC metadata structure: The XML/plist metadata format for dynamic wallpapers is reverse-engineered and fragile—breaking changes in future macOS versions would require manual inspection of output files. No validation of input JSON: bad SequenceInfo JSON may fail silently during generation. Sun calculation expects latitude/longitude: missing location data falls back to fixed times; document this clearly.
🏗️Architecture
💡Concepts to learn
- Solar Elevation Angle & Apparent Solar Time — The core logic in SunCalculations.swift uses sun elevation to trigger image transitions; understanding solar angles is critical to tuning when wallpapers change and why latitude/longitude matter.
- HEIC/HEIF Container Format & Image Sequencing — Dynamic wallpapers are HEIC files with embedded sequences and metadata; the generator must correctly structure this container format or macOS will reject the wallpaper.
- Property List (plist) Metadata Embedding — macOS dynamic wallpapers store timing and sun data as XML plist metadata inside HEIC; ImageMetadataGenerator.swift must correctly serialize this format.
- Codable Serialization & JSON Schema Modeling — Input configuration uses Codable structs (SequenceInfo, PictureInfo); understanding how Swift's Codable maps JSON to models is essential for extending the input format.
- Exif Metadata Extraction & Camera Geolocation — wallpapper-exif pulls latitude/longitude from image Exif; used by the sun position calculator to customize wallpaper timing to user location.
- Time Zone & Civil Twilight Calculations — The generator must handle local time correctly (not UTC) and account for twilight periods when images transition; TZDBData or equivalent integration may be hidden in SunCalculations.
🔗Related repos
boredzo/wallpapper— Alternative dynamic wallpaper generator; comparing approaches to HEIC metadata encoding could reveal missing featuresMpark/variant— Swift enum/union patterns that could improve error handling in the DynamicWallpaperGenerator error hierarchySDWebImage/SDWebImage— Image caching and format handling library; could be integrated to optimize large image sequencesapple/swift-argument-parser— Modern Swift CLI argument parsing; current OptionType.swift is manual—ArgumentParser is the new standardpointfreeco/swift-composable-architecture— State management pattern that could refactor the generator's image processing pipeline into testable effects
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for ImageMetadataGenerator and WallpaperGenerator
The repo lacks test coverage for core functionality. Sources/WallpapperLib/DynamicWallpaperGenerator/ contains critical image processing logic (ImageMetadataGenerator.swift, WallpaperGenerator.swift) and error handling (ImageMetadataGeneratorError.swift) with no corresponding test files. Adding XCTest coverage would catch regressions early and improve maintainability for contributors working on image metadata or wallpaper generation features.
- [ ] Create Tests/WallpapperLibTests/DynamicWallpaperGenerator/ directory structure
- [ ] Write tests for ImageMetadataGenerator.swift covering various image formats and metadata extraction edge cases
- [ ] Write tests for WallpaperGenerator.swift covering sequence generation and error conditions from ImageMetadataGeneratorError.swift
- [ ] Update Package.swift to include test target with proper dependencies
- [ ] Update build.sh or CI workflow to run tests
Add unit tests for SunCalculations and sun position models
The SunPositions module (Sources/WallpapperLib/SunPositions/SunCalculations.swift) calculates sun positions—a mathematically complex feature that needs regression testing. The models (SunCoordinates.swift, SunPosition.swift, WallpapperItem.swift) should be validated against known sun position data and edge cases (e.g., equinoxes, polar regions, daylight saving time transitions).
- [ ] Create Tests/WallpapperLibTests/SunPositions/ directory
- [ ] Write tests for SunCalculations.swift with real-world coordinates and expected sun positions at specific times
- [ ] Write tests for SunPosition and SunCoordinates models including edge cases (poles, equator, date boundaries)
- [ ] Add test data files with reference sun positions from a trusted astronomy library or NOAA data
- [ ] Integrate tests into CI pipeline (build.yml)
Add integration tests for wallpapper and wallpapper-exif CLI tools in GitHub Actions
The repo has a build.yml workflow but no visible integration tests for the two main executables (Sources/Wallpapper/main.swift and Sources/WallpapperExif/main.swift). Adding integration tests would verify end-to-end functionality like: CLI argument parsing, actual HEIC/JPEG generation, EXIF metadata reading, and error handling with invalid inputs.
- [ ] Create .github/workflows/integration-tests.yml or extend build.yml
- [ ] Add test image fixtures in Tests/Fixtures/ (sample HEIC, JPEG, and invalid image files)
- [ ] Write shell scripts in Tests/Integration/ to execute CLI with various argument combinations and verify output wallpapers
- [ ] Test wallpapper-exif specifically against sample images with EXIF location data
- [ ] Verify generated .heic wallpapers are valid macOS dynamic wallpapers (can add basic validation via file inspection)
🌿Good first issues
- Add unit tests for
SunCalculations.swiftto verify solar position calculations against known ephemeris data—currently no test files exist in the repo. - Document the JSON schema for
SequenceInfo.swiftwith inline comments and add a schema.json file toSources/so users don't have to reverse-engineer input format from code. - Create integration tests in
Tests/directory that round-trip: generate a HEIC wallpaper, extract it withwallpapper-exif, and verify metadata matches input—currently no test harness exists.
⭐Top contributors
Click to expand
Top contributors
- @mczachurski — 48 commits
- @kurt-wink — 2 commits
- @mattgauf — 1 commits
- @compufox — 1 commits
- @zeyugao — 1 commits
📝Recent commits
Click to expand
Recent commits
843db90— Merge pull request #80 from mattgauf/master (mczachurski)7765d16— Update version to 1.7.4 to match release build (mattgauf)baa5fa0— Merge pull request #68 from compufox/minute-support (mczachurski)ed0b9ea— fixed minutes not being utilized in time info calculation (compufox)44e8ece— Merge pull request #63 from zeyugao/master (mczachurski)c3e22b6— Build universal binary with github actions (zeyugao)bb5c232— Change version to 1.7.3 (mczachurski)447854d— Merge pull request #60 from iiKurt/extract-plist (mczachurski)4df83d8— Get extract output file name from command line parameter (mczachurski)0f1e501— Output a plist named 'output.plist' when extracting a HEIC's metadata (kurt-wink)
🔒Security observations
The wallpapper codebase appears to be a relatively straightforward macOS console application with no obvious critical vulnerabilities in the file structure analysis. However, the assessment is limited by missing key files: (1) Package.swift content prevents dependency vulnerability analysis, (2) actual implementation files are not provided, making it impossible to review code quality, input validation, and error handling. The application handles file I/O and metadata extraction, which are potential risk areas if not properly validated. No hardcoded secrets were evident from naming conventions. Recommendations include: obtain and audit Package.swift dependencies, implement comprehensive input validation for CLI arguments and file paths, establish a security disclosure policy, and conduct a full source code review focusing on file operations, image processing, and metadata handling.
- Medium · Missing Package.swift Dependency Information —
Package.swift. The Package.swift file content was not provided for analysis. Without visibility into declared dependencies, it's impossible to verify if the project uses outdated, unmaintained, or known-vulnerable Swift packages. This is a critical input for dependency security assessment. Fix: Provide the complete Package.swift file for dependency audit. Regularly useswift package updateand audit dependencies with tools like SwiftSec or OWASP Dependency-Check adapted for Swift. - Low · No Visible Input Validation Framework —
Sources/Wallpapper/OptionType.swift, Sources/WallpapperExif/OptionType.swift, Sources/Wallpapper/main.swift. The codebase appears to handle command-line arguments (OptionType.swift files suggest CLI argument parsing), but there is no visible input validation or sanitization framework visible in the file structure. This could lead to issues if user input is passed to system operations without proper validation. Fix: Implement comprehensive input validation for all command-line arguments. Validate file paths, image metadata, and coordinates before processing. Use allowlist-based validation where possible. - Low · Potential Path Traversal in File Operations —
Sources/WallpapperLib/DynamicWallpaperGenerator/WallpaperGenerator.swift, Sources/WallpapperLib/ImageMetadataReaders/DynamicWallpaperExtractor.swift. The application processes image files and generates wallpapers with file I/O operations (implied by DynamicWallpaperGenerator, ImageMetadataReaders). Without seeing the actual implementation, there's a risk of path traversal if file paths are constructed from user input without proper sanitization. Fix: Validate and canonicalize all file paths. Use secure path APIs that prevent directory traversal. Reject paths containing '..' or absolute paths outside intended directories. Use URL APIs instead of string concatenation. - Low · No Visible Security Documentation —
Repository root. The repository lacks security.md, security policy, or vulnerability disclosure guidelines. This makes it difficult for security researchers to responsibly report vulnerabilities. Fix: Create a SECURITY.md file with a vulnerability disclosure policy and contact information. Consider adding security guidelines to the README. - Low · Insufficient Error Handling Visibility —
Sources/WallpapperLib/DynamicWallpaperGenerator/Errors/, Sources/WallpapperLib/ImageMetadataReaders/Errors/. While error types are defined (ImageMetadataGeneratorError.swift, ExifExtractorError.swift), the actual error handling and logging implementations are not visible. Poor error handling could leak sensitive information about system paths or configuration. Fix: Ensure errors are logged without exposing sensitive paths or system information. Implement proper error sanitization before displaying to users. Avoid printing stack traces to console output.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.