Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
a23bd51
Make next/previous and Android Auto follow the visible library sort
GianniCarlo Aug 23, 2026
ff87002
Bring the Wear standalone library up to sort parity
GianniCarlo Aug 23, 2026
7c2e469
Merge pull request #97 from TortugaPower/feat/sort-parity-adjacent-auto
GianniCarlo Sep 2, 2026
9f8f8b5
Merge pull request #98 from TortugaPower/feat/wear-sort-parity
GianniCarlo Sep 2, 2026
93ebd1a
fix: bounded chapter extraction and cover decoding for files with hug…
GianniCarlo Sep 2, 2026
d70785a
fix: recover from a corrupt playback_settings DataStore instead of cr…
GianniCarlo Sep 2, 2026
cc7d9fa
chore: emulator crash-reproduction rig (scripts/chaos, docs/crash-rep…
GianniCarlo Sep 2, 2026
1528fff
fix: address review feedback (round 1)
GianniCarlo Sep 2, 2026
08020ea
fix: address review feedback (round 2)
GianniCarlo Sep 2, 2026
5688e53
Merge pull request #99 from TortugaPower/fix/crash-repro-datastore-moov
GianniCarlo Sep 2, 2026
d7799b8
fix: never write chapters or listening sessions for a book that is gone
GianniCarlo Sep 2, 2026
64d975e
fix: give each media session a unique id so a leaked one cannot block…
GianniCarlo Sep 2, 2026
8003760
docs: crash-repro entries for the orphaned child-row and duplicate se…
GianniCarlo Sep 2, 2026
b39f767
Merge pull request #100 from TortugaPower/fix/orphaned-child-rows-and…
GianniCarlo Sep 2, 2026
210b0f5
chore: media3 1.7.1 -> 1.11.0; drive the watch crown volume through A…
GianniCarlo Sep 2, 2026
cbad483
docs: crash-repro entry for the media3 bump (-Q) and what it changed …
GianniCarlo Sep 2, 2026
f97123e
Merge pull request #101 from TortugaPower/chore/media3-1-11-0
GianniCarlo Sep 3, 2026
252236d
fix(core): track storage-full state and stop writing when the disk is…
GianniCarlo Sep 3, 2026
b922e5d
fix: gate launch, refuse playback and hold transfers while storage is…
GianniCarlo Sep 3, 2026
f74432d
chore: drop the unused WorkManager dependency
GianniCarlo Sep 3, 2026
74c6638
fix: promote the sync host to the foreground before opening the database
GianniCarlo Sep 3, 2026
db16298
docs: storage-full repro recipe and fill-disk.sh
GianniCarlo Sep 3, 2026
b2489be
fix: address review feedback (round 1)
GianniCarlo Sep 3, 2026
f01d2e8
Merge pull request #102 from TortugaPower/fix/storage-full-guard
GianniCarlo Sep 3, 2026
464d97d
fix(core): create and release the LoudnessEnhancer off the main thread
GianniCarlo Sep 3, 2026
bf9d535
chore: keep dev-flavor builds out of Sentry unless opted in
GianniCarlo Sep 3, 2026
43dc9b5
fix: breadcrumb every foreground promotion so a bad-notification cras…
GianniCarlo Sep 3, 2026
84a39c1
Merge pull request #103 from TortugaPower/fix/loudness-enhancer-anr
GianniCarlo Sep 3, 2026
01ba964
build: optimized resource shrinking and class repackaging for release…
GianniCarlo Sep 3, 2026
d921e3e
ci: fail the build when a class resolved by name across processes los…
GianniCarlo Sep 3, 2026
270a7d5
docs: release R8 configuration and the by-name keep rule in CLAUDE.md
GianniCarlo Sep 3, 2026
7516c4f
fix: address review feedback (round 1)
GianniCarlo Sep 3, 2026
0973fd1
Merge pull request #104 from TortugaPower/chore/r8-optimized-shrinkin…
GianniCarlo Sep 3, 2026
b26824f
feat(core): groundwork for the connection-flow redesign
GianniCarlo Sep 3, 2026
6b8237a
fix(core): bracket only IPv6-looking hosts in the address model
GianniCarlo Sep 3, 2026
6fe7081
fix: address review feedback (round 2)
GianniCarlo Sep 3, 2026
c1b0be4
feat: rework the add-server flow into pushed onboarding screens
GianniCarlo Sep 3, 2026
818bbca
Merge pull request #105 from TortugaPower/feat/connection-flow-ground…
GianniCarlo Sep 4, 2026
a12b1e3
fix: address review feedback (round 1)
GianniCarlo Sep 4, 2026
57df93f
Merge pull request #106 from TortugaPower/feat/connection-flow-ui
GianniCarlo Sep 4, 2026
10d1071
feat: Jellyfin Quick Connect sign-in
GianniCarlo Sep 4, 2026
965faa8
fix: address review feedback (round 1)
GianniCarlo Sep 4, 2026
d897913
Merge pull request #107 from TortugaPower/feat/jellyfin-quick-connect
GianniCarlo Sep 4, 2026
0ffc9f4
feat: AudiobookShelf SSO through Chrome Auth Tab
GianniCarlo Sep 4, 2026
69b949e
fix: address review feedback (round 1)
GianniCarlo Sep 4, 2026
20d267e
Merge pull request #108 from TortugaPower/feat/audiobookshelf-sso
GianniCarlo Sep 4, 2026
302f45b
feat: connection-flow leftovers — in-library details, error alerts, r…
GianniCarlo Sep 4, 2026
80397a4
fix: address review feedback (round 2)
GianniCarlo Sep 4, 2026
a4e8036
Merge pull request #109 from TortugaPower/feat/connection-flow-leftovers
GianniCarlo Sep 4, 2026
7b14559
fix: never guess a media-server item's file extension on virtual import
GianniCarlo Sep 4, 2026
5035fc4
fix: address review feedback (round 2)
GianniCarlo Sep 4, 2026
00bff58
fix: library load-error alert offers Retry / Cancel, not Connection D…
GianniCarlo Sep 4, 2026
b1cc92a
Merge pull request #111 from TortugaPower/fix/load-error-alert-retry-…
GianniCarlo Sep 4, 2026
5b93269
Merge pull request #110 from TortugaPower/fix/virtual-import-real-ext…
GianniCarlo Sep 4, 2026
30f25d4
release: 1.2.0 (app 21, wear 100011)
GianniCarlo Sep 4, 2026
1f473a5
docs: rewrite the README for the open-source launch
GianniCarlo Sep 8, 2026
c165257
Merge pull request #113 from TortugaPower/docs/open-source-readme
GianniCarlo Sep 8, 2026
5e4120a
reviewer: port the hardened harness — sandbox, budgets, verification …
GianniCarlo Sep 11, 2026
fe86d9b
fix: address review feedback (round 1)
GianniCarlo Sep 11, 2026
ce50bd9
fix: address review feedback (round 2)
GianniCarlo Sep 11, 2026
dc9ffba
fix: address review feedback (round 3)
GianniCarlo Sep 11, 2026
82d3a23
reviewer: split review.mjs by seam; address review feedback (round 4)
GianniCarlo Sep 11, 2026
80e9ab9
reviewer: the job that holds the secrets never runs pull request code…
GianniCarlo Sep 11, 2026
466d0fa
Merge pull request #115 from TortugaPower/reviewer/hardened-harness
GianniCarlo Sep 11, 2026
9ad4339
reviewer: the per-repository shapes carry their own proof; the shared…
GianniCarlo Sep 11, 2026
ff52b76
reviewer: address review feedback (round 1)
GianniCarlo Sep 11, 2026
b870324
reviewer: the comment naming RegExp's lastIndex is allowlisted, with …
GianniCarlo Sep 11, 2026
8b869a3
Merge pull request #117 from TortugaPower/reviewer/portable-repo-tests
GianniCarlo Sep 11, 2026
8feaadf
ci: pin the reviewer workflow's actions to Node 24 commit SHAs
GianniCarlo Sep 12, 2026
e9806c4
fix: address review feedback (round 1)
GianniCarlo Sep 12, 2026
cd593a3
fix: address review feedback (round 2)
GianniCarlo Sep 12, 2026
d1f03dc
Merge pull request #118 from TortugaPower/ci/reviewer-pin-actions-node24
GianniCarlo Sep 12, 2026
0be43da
ci: attach release commits and record production deploys in Sentry
GianniCarlo Sep 20, 2026
bdfdee7
docs: Sentry crash-fix trailer and merge-to-main deploy marker in CLA…
GianniCarlo Sep 20, 2026
7f1996c
reviewer: bump the Agent SDK to 0.3.280 for Opus 5.5 and pin effort t…
GianniCarlo Sep 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions .github/claude/review-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ layout, and conventions before judging anything.

## How to review

1. Get the diff: `gh pr diff <number>`. The PR branch is already checked out in the working directory.
1. Read the unified diff the harness wrote for you; its path is in the task prompt. The PR branch is
already checked out in the working directory.
2. **Do not review the diff in isolation.** For each non-trivial change, open the surrounding code and
its **callers** with `Read`/`Grep`/`Glob` before forming an opinion. Diff-only opinions are not acceptable.
3. Cross-check changes against `CLAUDE.md` conventions and the matching area (UI/Compose, ViewModel,
repository, Room, network, Media3 playback, billing).
3. Cross-check changes against `CLAUDE.md` conventions and the matching area. For Compose UI, check state
hoisting, recomposition cost and accessibility. For ViewModels, check the StateFlow / coroutine-scope /
manual-DI conventions. For playback, follow the Media3 ExoPlayer and MediaSession path and what runs inside
the playback service. Repository, Room, network and billing code each have their own section below.
Behaviour should match the iOS app unless the PR says otherwise.
4. **Module boundaries:** the codebase is split into `:core` (shared Compose-free, playback-capable library —
Media3 lives here) and `:app` (phone) + `:wear`. See "Module conventions" in `CLAUDE.md` — check the flags
in the module section below.
4. Comment **only on lines changed by this PR**, in changed files. Skip everything in "what to skip".
Media3 lives here) and `:app` (phone) + `:wear`. `:core` never references `:app`, holds no Compose, and takes
config injected rather than read; for `:wear`, check the phone/watch split and what crosses the data layer.
See "Module conventions" in `CLAUDE.md` — check the flags in the module section below.
5. Comment **only on lines changed by this PR**, in changed files. Skip everything in "what to skip".

## What to skip

Expand Down Expand Up @@ -83,9 +88,14 @@ layout, and conventions before judging anything.

## Reporting findings

Your findings are consumed by an automated harness (it posts the comments, de-duplicates them across
pushes, and resolves stale ones) — **do not post comments or create reviews yourself.** The exact JSON
shape to emit is defined by the output contract in your system prompt.
Your findings are consumed by an automated harness — **do not post comments or create reviews yourself.**
It posts each finding as an inline comment, recognises a finding you reported on an earlier push and leaves
that comment alone, and closes an earlier comment only when a second pass has judged it against the current
code — fixed, no longer applicable, accepted by a maintainer, or a duplicate of something reported on this
push. Nothing closes because you stopped mentioning it. A finding whose line the API will not accept as an
inline anchor, and any finding past the inline cap, is listed in the summary comment rather than lost — but a
finding with no usable line number at all is dropped, so tie every finding to a line this PR changed. The
exact JSON shape to emit is defined by the output contract in your system prompt.

- Report each issue with its severity, file, the **changed line** it applies to, and a concrete fix.
Tie every finding to a line the PR actually changed.
Expand Down
3 changes: 3 additions & 0 deletions .github/claude/reviewer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Installed in CI with `npm ci`; the lockfile is committed. Kept here, not in the repository root, so the
# directory is self-contained: copying it to another repository copies this rule too.
node_modules/
263 changes: 263 additions & 0 deletions .github/claude/reviewer/README.md

Large diffs are not rendered by default.

477 changes: 477 additions & 0 deletions .github/claude/reviewer/agent.mjs

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions .github/claude/reviewer/config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Environment access for the harness: the PR coordinates the workflow passes in, the run's flags, and the
// `num` knob reader. Read when ASKED, never at import — the tests load the harness once per scenario with a
// different environment each time, and a value frozen at import would be the first scenario's for all of them.

// A non-numeric override must fall back to the default rather than become NaN: setTimeout(fn, NaN) fires
// immediately, which would degrade every run to the "incomplete" note with no hint why.
export const num = (v, fallback) => (Number.isFinite(Number(v)) && Number(v) > 0 ? Number(v) : fallback);

export const DRY_RUN = () => process.env.DRY_RUN === '1' || process.env.DRY_RUN === 'true';

export const RUN_URL = () => process.env.RUN_URL || '';

export function requireEnv(name) {
const v = process.env[name];
if (!v) throw new Error(`Missing required env var: ${name}`);
return v;
}

// Validated in runReview(), not here: importing this module (e.g. from a test) must not throw, and a value read at
// call time is the current scenario's.
export const PR_NUMBER = () => Number(process.env.PR_NUMBER || 0);

export const COMMIT = () => process.env.COMMIT || ''; // PR head SHA — anchors inline comments

export const BASE = () => process.env.BASE_REF || 'main';
Loading
Loading