Commit Graph
59 Commits
Author SHA1 Message Date
Claude 4dfa16bcb0 Merge dev: update channels, clearer Euchre table, bolder Sequence highlight
Publishes a new production release so installs on v1.0.1 are offered an
OTA upgrade.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-06 00:54:47 +00:00
Claude 1bcd2a951e Add dev/production update channels, clearer Euchre table, bolder Sequence highlight
Update channels
- ci.yml now publishes each green push to dev as a prerelease tagged
  v1.0.<n>-dev, so the dev channel has something to install. Workflow
  artifacts could not serve this: downloading one needs authentication,
  which the app does not have.
- Prereleases specifically, because GitHub's "latest release" endpoint
  skips them — a production install can never be handed a dev build.
  Pull requests build and check but never publish.
- Settings gains a channel picker. The two channels are numbered by
  separate workflow run counters, so versions are only compared within a
  channel; the app reads the -dev suffix in its own versionName to know
  where it stands, and treats a channel change as an explicit switch. The
  screen warns that such a switch can be a downgrade Android will refuse.
- PLG_RELEASE becomes PLG_CHANNEL, naming the channel rather than a flag.

Euchre
- Cards in a trick now sit on the side of the table belonging to whoever
  played them, rotated to face them, labelled You / Left / Partner /
  Right. Previously they were a flat row tagged with seat numbers, which
  made it hard to tell who had played what.
- Bidding says what it will actually do. As dealer the button reads "Pick
  it up" rather than "Order up", since the turn card comes to your hand,
  and a line of explanatory text spells out the consequence either way.

Sequence
- Playable squares get a much heavier outline, scaled off cell size and
  in a fixed amber that reads against a white card, a green corner and a
  chip alike. The old 2dp theme-coloured border was hard to see.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-06 00:18:59 +00:00
Claude cf235929c2 Merge dev: app shell with Euchre and Sequence, plus CI/release pipelines
Brings the first playable slice to main and, with it, the first run of the
release pipeline: an APK published as v1.0.<run-number> for the in-app
updater to pick up.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 23:52:47 +00:00
Claude 80ff178437 Pin OTA releases to main and stop dev builds outranking them
Two ways the updater could have served or blocked the wrong build:

- release.yml also triggers on workflow_dispatch, which can be aimed at
  any branch from the Actions UI. That would have built dev code and
  published it as a real Release, which every install would then offer to
  download. The job now refuses to run off anything but main.

- versionCode came from GITHUB_RUN_NUMBER, but that counter is per
  workflow, so the dev pipeline had its own independent sequence. A debug
  APK installed from a CI artifact already carried a higher versionCode
  than the first several releases would, and the updater's check is
  latest <= installed, so those users would have been told they were up
  to date indefinitely. Only release.yml now sets PLG_RELEASE, and only
  that stamps a real version; everything else stays at 1.0.0-dev.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 23:47:20 +00:00
Claude 85ec10836b Request only the Bluetooth permission the app actually uses
Lint flagged ACCESS_FINE_LOCATION declared without ACCESS_COARSE_LOCATION,
which Android 12 requires to be requested together.

Rather than add the missing one, drop location entirely: the Bluetooth
transport only talks to already-paired devices, enumerating bonded
devices and opening an RFCOMM socket. Neither is a scan, so no location
access is needed. BLUETOOTH_SCAN and BLUETOOTH_ADVERTISE go for the same
reason — nothing was using them.

Discovery of unpaired devices would bring all of these back; the manifest
notes what that would require.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 22:56:27 +00:00
Claude 4ad0f52331 Fix serialization import and quieten CI build logs
- Transport.kt used the reified Json.encodeToString extension without
  importing kotlinx.serialization.encodeToString, so it resolved to the
  two-argument member overload and failed to compile.
- Opt in to ExperimentalMaterial3Api for the clickable game tile.
- Drop --stacktrace from the CI build. A one-line Kotlin error was being
  buried under 150 lines of Gradle internals, which made the actual
  message hard to find in the log.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 22:50:15 +00:00
Claude 487c68419e Add app shell with Euchre and Sequence, LAN/Bluetooth play
First vertical slice: the whole shell plus two games playable end to end,
so every layer is exercised before the other nine games are built on it.

Games
- Euchre: bowers, ordering up, dealer discard, going alone, stick the
  dealer, and full scoring. Rule variants (deck size, points to win,
  stick the dealer, going alone) are toggles in game setup.
- Sequence: two-eyed and one-eyed jacks, free corners, locked sequences,
  the shared-chip limit, and dead-card exchange. Teams, players per team
  and the sequence target are toggles.
- The board layout in SequenceBoard is generated, not the commercial
  board — it holds every structural property the rules need, but does not
  match a physical board. Documented in docs/RULES-sequence.md.

Multiplayer
- One transport abstraction over newline-delimited JSON, implemented
  twice: LAN via NSD discovery and TCP, Bluetooth via Classic RFCOMM.
  A lobby advertises on both at once, so a table can mix them.
- Host-authoritative: clients send move intents, the host re-validates
  every one against the rules, and each client receives a state redacted
  for its own seat so hidden information never crosses the wire.
- Seats start as AI and are handed to people as they join, which is what
  makes any mix of humans and AI work without a separate code path.

Shell
- Main menu lists all eleven games; the nine without engines are marked
  coming soon and are driven entirely by GameCatalog.
- Settings: sound, animation speed (one multiplier drives card movement
  and AI thinking time), and OTA updates from the latest GitHub release.
- Layouts measure available space rather than assuming an orientation.

The game package is free of Android types, so the rules engines and AI
run under plain JUnit; 43 tests cover ranking, following suit, scoring,
sequence detection, redaction, wire round-trips and full random and AI
playthroughs.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 22:37:05 +00:00
Claude 4312616efa Add CI and release pipelines for Android APK builds
Mirrors the Holio setup:

- release.yml: on push to main (e.g. a merged PR), builds the debug APK
  and publishes it as a GitHub Release tagged v1.0.<run-number>.
- ci.yml: pre-merge checks on the dev branch and on PRs targeting dev or
  main — same build plus unit tests and lint, uploaded as artifacts only.

Both expect a Gradle Android project at the repo root with an :app module,
matching Holio's layout.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
2026-08-05 21:54:13 +00:00
adrianoftyriel a5258c8ee6 Initial commit 2026-08-05 15:50:56 -06:00