Repository navigation
Conversation
Generated by create-expo 5.0.3.
Sideloaded Android client (Expo SDK 57 / React Native, New Architecture) for the True Tunes Sonos web-player client. Ports the Sonos client, WebSocket session, queue operations and office services from the desktop app's main process into platform-neutral, unit-tested modules, and exposes them through the same window.sonos surface the desktop preload provides so the ported React Query hooks run unchanged. Screens: Home, Search, Queue (drag reorder, multi-select, swipe to remove, DJ section), Now Playing, room picker, album / artist / container / playlist detail, lyrics, leaderboard, profile, Queuedle, identity picker. Local-build workflow; see README.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Mirrors the desktop repo's setup: .nvmrc (Node 24), Prettier config, ESLint flat config (typescript-eslint + react-hooks), lint / format / coverage scripts, and a CI workflow that runs lint, typecheck, expo-doctor and the test suite with test and coverage reports on PRs into main/develop and pushes to main. Adds CLAUDE.md, .gitattributes (LF) and formats the tree with Prettier. Also fixes real type errors the bridge typing had hidden: the Azure/Genius/presence members are now asserted explicitly per member, the socket and queue-list ref types are corrected, and three lint errors are fixed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Pushing a version tag (v1.2.3, or v1.2.3-rc.1 for a pre-release) builds a release-signed APK on GitHub Actions and publishes it as a GitHub Release with a checksum. A manual run is a dry run that only uploads an artifact. - plugins/withReleaseSigning.js: Expo config plugin that signs the release variant with our keystore when ANDROID_KEYSTORE_PATH is set, and throws if the generated Gradle file stops matching the template rather than silently signing with the debug key (unit tested). - release.yml: derives version and an ever-increasing versionCode from the tag, runs typecheck and tests before the long native build, and fails unless the APK's signing certificate matches the ANDROID_CERT_SHA256 repository variable. - docs/RELEASING.md: process, signing key location (1Password), secrets, local signed build, and the dev-build vs release-build install caveat. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Debug builds are now uk.co.truenorthit.truetunes.dev ("True Tunes (dev)") while release
builds keep uk.co.truenorthit.truetunes, so a development build and a release build install
side by side instead of failing with INSTALL_FAILED_UPDATE_INCOMPATIBLE (they are signed with
different keys). Implemented as an Expo config plugin that patches the debug build type and adds
a debug-only app_name resource; it throws if the generated Gradle file stops matching the
template. Documents the change in RELEASING.md and CLAUDE.md.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed release pipeline (version tags) and separate dev package name
Promote develop to main: signed release pipeline and dev package name
Regenerates the Android icons from the desktop app's icon (navy square with the white globe): a solid navy adaptive-icon background, the globe alone on transparency inside the launcher safe zone (also used for the themed monochrome icon and the splash), and the full artwork as the legacy 1024px icon. scripts/generate-icons.py reproduces them from the desktop icon.png; the source is 512px so the 1024px outputs are upscaled. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Use the desktop app icon
Promote develop to main: desktop app icon
The 1.0.46 installer shipped without smtc.node: nothing compiled it in CI and build.files excluded native/, so the require failed silently and SMTC was a no-op. Add a build:native step to the Windows build/publish scripts and ship the addon via files + asarUnpack. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTQFG7usNZcdYDTqmHr4QR
Ship the Windows media controls addon in the installer
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
iOS 27 asserts at launch unless the app uses scenes. Expo 57 has the runtime (ExpoAppSceneDelegate) but its prebuild template does not use it; withIosSceneDelegate applies the SDK 58 template shape. Delete it on SDK 58. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
feat(ios): add iOS platform and bundle identifier
Imported from TrueNorthIT/TrueTunes-Android at 92f87cd with git filter-repo --to-subdirectory-filter apps/mobile; its tag v1.0.0 is now android-v1.0.0.
Also drop apps/mobile/relcheck.log, a stray log from a release check.
…e.json renderer/package.json and its lock only held @vitest/coverage-v8, which the root devDependencies already provide at the same version.
- publish.yml becomes desktop.yml and ignores apps/mobile/** and the mobile workflows, so a mobile-only commit to main no longer publishes a desktop release. - The mobile CI and release workflows move to mobile-ci.yml and mobile-release.yml, run from apps/mobile and only on mobile changes. - Android releases are tagged android-vX.Y.Z, are created with --latest=false so desktop auto-update keeps reading the desktop release, and their notes start at the previous android-v tag.
The repo is public now, so RELEASING.md no longer says a GitHub sign-in is needed to download the APK.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
- git mv the Electron app (src, renderer, native, assets, examples, icons, configs, SonosWebPlayerAPI.yaml, package.json) into apps/desktop. server/, .github, the docs, .nvmrc and .prettierrc stay at the root. - The root package.json is now a private workspace root (apps/*, packages/*) with one package-lock.json; the per-app locks are gone. Overrides pin react and react-dom to 19.2.3 (Expo SDK 57), @tanstack/react-query to 5.104.0 and @types/react to 19.2.18, so each resolves to a single copy. - The new lock was seeded with every direct dependency at the version the old per-app locks resolved, so neither app picks up unrelated upgrades. - electron is pinned to 41.2.1 exactly: electron-builder cannot find the hoisted electron package from apps/desktop and falls back to the declared version. - build:main also reads the root .env (still used by server/scripts/deploy.mjs). - The root lint keeps linting server/ with the desktop ESLint config, as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
- desktop.yml installs at the root and runs from apps/desktop. It only runs for apps/desktop, packages, the root package files and itself (PRs also for server/, which it lints). The version bump is npm version patch -w apps/desktop --package-lock-only, and the report, coverage and commit paths follow the move. - The mobile workflows install from the root lock with ELECTRON_SKIP_BINARY_DOWNLOAD=1; mobile CI also runs for packages/ and the root package files. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Vitest 5 (with coverage-v8 and ui), ESLint 10 with @eslint/js 10, typescript-eslint 8.71, eslint-plugin-react-hooks 7.1 (7.0 does not accept ESLint 10), jsdom 30 and @testing-library/jest-dom 7, at the versions the mobile app already resolves, so each tool is installed once. - The renderer test setup imports @testing-library/jest-dom/vitest, which extends Vitest's expect explicitly. - ESLint 10's recommended no-useless-assignment flagged three initial values in main.ts that are always overwritten before use; they are removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Formatting only: prettier --write over apps/desktop/src and apps/desktop/renderer/src with the shared root .prettierrc. No code changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
- git mv apps/mobile/src/{sonos,office,core} and their tests into
packages/core (@truetunes/core): private, TypeScript source with no build
step, exported by subpath (@truetunes/core/sonos/*, office/*, core/*). None of
them import React Native or Expo.
- Core has its own Vitest config (node environment), typecheck and ESLint
config; no-restricted-imports makes react-native, expo* and react-dom an
error there. Its tsconfig includes the mobile app's ambient window.sonos
contract (src/types/globals.d.ts), which createCore satisfies.
- The mobile app depends on @truetunes/core and imports it by subpath; its
node test project now only covers the config plugins.
- core.yml runs core's lint, typecheck and tests in CI. The root lint,
typecheck and test:run scripts already cover every workspace.
- The desktop does not use core yet.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
Contributor
Contributor
Coverage Report for Mobile
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contributor
Coverage Report for Desktop
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
…ckages/ Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves the Android/iOS app (
TrueNorthIT/TrueTunes-Android, with its history) into this repo and turns it into an npm-workspaces monorepo. Phases 1–3 of the plan; sharing the React hooks (phase 4) is deferred.Base: branched from
main(b3230f9), becausedevelopis 3 commits behindmain. Those 3 commits (the v1.0.46/1.0.47 bumps and the SMTC packaging merge) show up in this PR's diff too.Layout
apps/desktopgit mv)apps/mobilegit log -- apps/mobile/src/...; tagv1.0.0becameandroid-v1.0.0, not pushed)packages/core@truetunes/core: the platform-neutralsonos/office/coremodules from mobile, TypeScript source, subpath exports. Desktop does not use it yetserver/server/node_modules)package-lock.json.overridespinreact/react-dom19.2.3 (SDK 57),@tanstack/react-query5.104.0 and@types/react19.2.18;npm lsshows one copy each. Desktop goes from React 19.2.5 to 19.2.3.no-useless-assignmentremoved three dead initial values inmain.ts. Prettier ran over the desktop sources in a separate, formatting-only commit.electronis pinned to41.2.1exactly: electron-builder can't see the hoisted package fromapps/desktopand falls back to the declared version..envstays at the root (the server deploy reads it); desktopbuild:mainreads it from there.Workflows
desktop.yml(waspublish.yml): only runs forapps/desktop/**,packages/**, the root package files and itself (PRs also forserver/**, which it lints). A mobile-only commit tomainno longer publishes a desktop release. The version bump isnpm version patch -w apps/desktop --package-lock-only.mobile-ci.yml/mobile-release.yml: run fromapps/mobileand install from the root lock withELECTRON_SKIP_BINARY_DOWNLOAD=1. The release triggers onandroid-v*tags (plusworkflow_dispatchdry run) and usesgh release create --latest=false, so an APK release never becomes "Latest" and desktop auto-update keeps working.core.yml: core's lint (including ano-restricted-importsban onreact-native,expo*andreact-dom), typecheck and tests.actionlint1.7.7.Verified locally (Windows, Node 24.17, npm 11.13)
npm ciat the root, thennpm run lint(0 errors),typecheckandtest:runacross all workspaces: desktop 782 tests, mobile 454, core 241 (mobile + core = the 695 mobile had before).npx expo-doctor: 21/21.npx expo export -p androidand-p iosboth bundle.npm run electron:build:wininapps/desktopproducesTrue Tunes Setup 1.0.47.exe;app.asarcontainsws,electron-updaterand@azure/msal-node, and no React, Expo or Electron.Not verified
node_modules(no Android SDK on this machine). Run a Mobile Release dry run (workflow_dispatch) once this is onmain, before the firstandroid-v*tag.Before merging / after
TrueTunes-Androidinto this repo (Settings → Secrets and variables → Actions): secretsANDROID_KEYSTORE_BASE64,ANDROID_KEYSTORE_PASSWORD,ANDROID_KEY_ALIAS,ANDROID_KEY_PASSWORD, and variableANDROID_CERT_SHA256. Optionally also theGENIUS_ACCESS_TOKENandAPPINSIGHTS_CONNECTION_STRINGsecrets, if the mobile repo had different values.renderer/.envtoapps/desktop/renderer/.env, delete the old rootnode_modules,dist,releaseandrenderer/node_modules, and runnpm installat the root.🤖 Generated with Claude Code
https://claude.ai/code/session_01UMj5XGHLroJb9q68jXkw8B