Skip to content

Commit 3c46221

Browse files
davutclaude
andcommitted
Initial commit
Wirdi — a macOS Quran reading companion with word-by-word tracking in a Dynamic Island-style overlay. Includes speech recognition, multiple display modes, CI/CD release workflow, and Homebrew cask support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0 parents  commit 3c46221

46 files changed

Lines changed: 5887 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Build & Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
runs-on: macos-15
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
with:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
20+
- name: Get version from tag
21+
id: version
22+
run: |
23+
TAG="${GITHUB_REF#refs/tags/}"
24+
VERSION="${TAG#v}"
25+
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
26+
echo "number=${VERSION}" >> "$GITHUB_OUTPUT"
27+
28+
- name: Update app version in Xcode project
29+
run: |
30+
sed -i '' "s/MARKETING_VERSION = .*;/MARKETING_VERSION = ${{ steps.version.outputs.number }};/g" Wirdi/Wirdi.xcodeproj/project.pbxproj
31+
32+
- name: Commit version bump
33+
run: |
34+
git config user.name "github-actions[bot]"
35+
git config user.email "github-actions[bot]@users.noreply.github.com"
36+
git add Wirdi/Wirdi.xcodeproj/project.pbxproj
37+
git commit -m "Bump version to ${{ steps.version.outputs.number }}" || echo "No changes to commit"
38+
git push origin HEAD:refs/heads/main || echo "Push skipped"
39+
40+
- name: Select Xcode
41+
run: sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
42+
43+
- name: Build universal app
44+
working-directory: Wirdi
45+
run: |
46+
chmod +x build.sh
47+
./build.sh
48+
49+
- name: Upload DMG to GitHub Release
50+
uses: softprops/action-gh-release@v2
51+
with:
52+
files: Wirdi/build/release/Wirdi.dmg
53+
name: Wirdi ${{ steps.version.outputs.tag }}
54+
draft: false
55+
prerelease: false
56+
generate_release_notes: true
57+
body: |
58+
## Installation
59+
60+
1. Download **Wirdi.dmg** below
61+
2. Open the DMG and drag **Wirdi** to Applications
62+
3. Since the app is not notarized, macOS may block it on first launch. Run the following command in Terminal to fix this:
63+
64+
```
65+
xattr -cr /Applications/Wirdi.app
66+
```
67+
68+
Then open Wirdi normally.
69+
70+
- name: Compute DMG SHA256
71+
id: sha
72+
run: echo "sha256=$(shasum -a 256 Wirdi/build/release/Wirdi.dmg | awk '{print $1}')" >> "$GITHUB_OUTPUT"
73+
74+
- name: Update Homebrew Cask tap
75+
env:
76+
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
77+
VERSION: ${{ steps.version.outputs.tag }}
78+
SHA256: ${{ steps.sha.outputs.sha256 }}
79+
run: |
80+
VERSION_NUM="${VERSION#v}"
81+
git clone https://x-access-token:${TAP_REPO_TOKEN}@github.com/davut/homebrew-wirdi.git tap
82+
mkdir -p tap/Casks
83+
cat > tap/Casks/wirdi.rb << EOF
84+
cask "wirdi" do
85+
version "${VERSION_NUM}"
86+
sha256 "${SHA256}"
87+
88+
url "https://github.com/davut/wirdi/releases/download/${VERSION}/Wirdi.dmg"
89+
name "Wirdi"
90+
desc "Quran reading companion with word-by-word tracking in a Dynamic Island overlay"
91+
homepage "https://github.com/davut/wirdi"
92+
93+
depends_on macos: ">= :sequoia"
94+
95+
app "Wirdi.app"
96+
97+
postflight do
98+
system_command "/usr/bin/xattr", args: ["-cr", "#{appdir}/Wirdi.app"]
99+
end
100+
101+
zap trash: [
102+
"~/Library/Preferences/co.owlapps.wirdi.plist",
103+
"~/Library/Saved Application State/co.owlapps.wirdi.savedState",
104+
]
105+
end
106+
EOF
107+
cd tap
108+
git config user.name "github-actions[bot]"
109+
git config user.email "github-actions[bot]@users.noreply.github.com"
110+
git add .
111+
git commit -m "Update Wirdi to ${VERSION}"
112+
git push

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Xcode
2+
build/
3+
DerivedData/
4+
xcuserdata/
5+
*.xcuserstate
6+
*.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
7+
8+
# Archives & build artifacts
9+
*.xcarchive
10+
*.app
11+
*.dmg
12+
*.ipa
13+
*.dSYM.zip
14+
*.dSYM
15+
16+
# macOS
17+
.DS_Store
18+
.AppleDouble
19+
.LSOverride
20+
._*
21+
22+
# SwiftPM
23+
.build/
24+
Package.resolved
25+
26+
# CocoaPods
27+
Pods/
28+
29+
# Misc
30+
*.swp
31+
*~
32+
*.orig
33+
*.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Davut Jepbarov
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<p align="center">
2+
<img src="Wirdi/Wirdi/Assets.xcassets/AppIcon.appiconset/icon_256x256.png" width="128" height="128" alt="Wirdi icon">
3+
</p>
4+
5+
<h1 align="center">Wirdi</h1>
6+
7+
<p align="center">
8+
<strong>A macOS Quran reading companion with word-by-word tracking in a Dynamic Island-style overlay.</strong>
9+
</p>
10+
11+
<p align="center">
12+
<a href="#download">Download</a> · <a href="#features">Features</a> · <a href="#building-from-source">Build</a>
13+
</p>
14+
15+
---
16+
17+
<p align="center">
18+
<img src="docs/wirdi-video.gif" width="600" alt="Wirdi demo">
19+
</p>
20+
21+
## What is Wirdi?
22+
23+
Wirdi is a macOS app that helps you maintain a daily Quran reading habit. It displays ayahs word-by-word in a **Dynamic Island-style overlay** at the top of your screen, tracks your reading progress, and reminds you when it's time for your next session. All processing happens on-device — no accounts, no cloud, no data leaves your Mac.
24+
25+
## Download
26+
27+
**[Download the latest .dmg from Releases](https://github.com/davut/wirdi/releases/latest)**
28+
29+
> Requires **macOS 15 Sequoia** or later. Works on Apple Silicon and Intel.
30+
31+
### First launch
32+
33+
Since Wirdi is not notarized, macOS may block it on first open. Run this once in Terminal:
34+
35+
```bash
36+
xattr -cr /Applications/Wirdi.app
37+
```
38+
39+
Then right-click the app → **Open**. After the first launch, macOS remembers your choice.
40+
41+
## Features
42+
43+
### Quran Reading
44+
45+
- **Word-by-word display** — Ayahs shown with authentic Uthmanic Hafs, Nastaleeq, or IndoPak script
46+
- **Reading progress** — Remembers where you left off across sessions
47+
- **Configurable reading length** — Choose how long each session is (10 seconds to 30 minutes)
48+
- **Reading reminders** — Configurable intervals with snooze support
49+
- **Estimated completion** — Shows how long it will take to finish the Quran at your pace
50+
51+
### Three Guidance Modes
52+
53+
- **Word Tracking** — Real-time word-by-word highlighting as you speak, using speech recognition with Arabic-aware fuzzy matching
54+
- **Classic** — Auto-scrolling at a constant speed (no microphone needed)
55+
- **Voice-Activated** — Scrolls when you speak, pauses when you're silent
56+
57+
### Display
58+
59+
- **Dynamic Island overlay** — A notch-shaped overlay at the top of your screen, always on top
60+
- **Floating window mode** — A draggable window you can place anywhere, with optional glass effect
61+
- **Multi-display support** — Follow your mouse across displays, or pin the overlay to a specific screen
62+
63+
### Customization
64+
65+
- **3 Quran fonts** — Uthmanic Hafs, Nastaleeq, IndoPak with adjustable size
66+
- **6 highlight colors** — White, yellow, green, blue, pink, orange
67+
- **Right-to-left layout** — Native RTL support for Arabic text
68+
69+
## Building from Source
70+
71+
### Requirements
72+
73+
- macOS 15+
74+
- Xcode 16+
75+
76+
### Build
77+
78+
```
79+
cd Wirdi
80+
open Wirdi.xcodeproj
81+
```
82+
83+
Build and run with `Cmd+R`.
84+
85+
## Acknowledgments
86+
87+
Wirdi was inspired by and built on top of [Textream](https://github.com/f/textream) by [Fatih Kadir Akin](https://github.com/f).
88+
89+
## License
90+
91+
MIT

Wirdi/Info.plist

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>ATSApplicationFontsPath</key>
6+
<string>.</string>
7+
<key>NSMicrophoneUsageDescription</key>
8+
<string>Wirdi uses the microphone to track your Quran recitation word by word during reading sessions.</string>
9+
<key>NSSpeechRecognitionUsageDescription</key>
10+
<string>Wirdi uses speech recognition to follow along as you recite the Quran and highlight the current word.</string>
11+
</dict>
12+
</plist>

0 commit comments

Comments
 (0)