Skip to content

Native iOS app: prepare the first development build - #142

Merged
Programcode merged 10 commits into
feat/native-iosfrom
native-ios/09a-dev-build-prep
Oct 14, 2026
Merged

Programcode merged 10 commits into
feat/native-iosfrom
native-ios/09a-dev-build-prep

Conversation

@Programcode

Copy link
Copy Markdown
Owner

Prepares the first development build (config only). No cloud build was run and no EAS account command was used. Expo Go keeps working exactly as before.

What's in it

  • app.config.ts replaces app.json. With no env set, the config is identical to the old app.json; npx expo config diffs match apart from the config-path fields.
    • DEBATELAB_BUILD=dev (set by the development profile) adds expo-dev-client and speech recognition with permission prompts in en, es and hu (InfoPlist.strings read from mobile.permissions).
    • DEBATELAB_APP_GROUP=group.… (dev only) adds the expo-widgets Live Activity extension and the App Group.
    • Every development build drops aps-environment. expo-widgets adds it even with push off, and prebuild auto-applies expo-notifications' plugin (PR Native iOS app: push notifications (backend and opt-in) #140), which adds it too. The Signulous profile has no push entitlement, so it couldn't sign either way.
  • eas.json. A development profile with internal distribution, the dev client, credentialsSource: local (credentials.json is gitignored and written at build time) and Node 22.23.2.
  • New modules: expo-dev-client, expo-speech-recognition and expo-widgets, at SDK 57 versions.
  • The start script is now expo start --go. With the dev client installed, a plain expo start would open in dev-client mode.
  • native-capabilities.ts. Reports speech recognition and Live Activity support. In Expo Go it returns false without touching native modules, which a test covers.
  • docs/development.md "Build day" has the exact steps:
    1. decode and check the .mobileprovision
    2. run eas init and commit the project id
    3. count builds against the budget (1 a day, 3 a week, about 15 a month)
    4. write credentials.json with mode 600
    5. eas build --profile development --no-wait
    6. clean up

Checks (local; GitHub Actions is out of minutes)

At this head, after merging feat and a clean npm ci against the new lockfile:

  • npm run verify: exit 0. Vitest 315/315, collaboration 30/30, edge OK, build OK, smoke 30/30.
  • The mobile typecheck (app.config.ts is now covered), npx eslint apps/mobile and npx knip: exit 0.
  • Prebuild in a temp copy, three modes, all exit 0:
    • No env: CADisableMinimumFrameDurationOnPhone, the URL schemes, empty entitlements.
    • Dev: adds the speech and microphone prompts and the es and hu InfoPlist.strings.
    • Dev with App Group: adds NSSupportsLiveActivities and the ExpoWidgetsTarget extension. Entitlements are application-groups only, with no aps-environment.
  • Metro with --go: the manifest returns 200 and the iOS bundle returns 200 (3093 modules), with no dev-launcher, speech or widgets references in the Expo Go bundle.

Not provable here

  • the cloud build itself and signing with the real profile (waiting on Adam's secrets)
  • whether iOS shows the translated permission prompts
  • the compiled widget extension

A follow-up after #140 merges reruns the dev-mode prebuild to show aps-environment stays out with expo-notifications installed.

Codex review rounds follow as comments.

🤖 Generated with Claude Code

Programcode and others added 7 commits October 14, 2026 12:56
expo-dev-client, expo-speech-recognition and expo-widgets, installed with
`npx expo install` for SDK 57. The permission prompts for dictation are
under mobile.permissions in all three catalogs.

With expo-dev-client a direct dependency, `expo start` would default to
the development client, so the start script now passes --go to keep the
Expo Go run as it was. knip ignores the speech and widget modules: the app
reaches them by native module name, not by import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without DEBATELAB_BUILD the config is exactly the old app.json, so Expo Go
and the web export are unchanged (`expo config --json` differs only in
_internal's config path). DEBATELAB_BUILD=dev adds expo-dev-client, speech
recognition with en usage strings and es/hu InfoPlist.strings from the
catalogs. DEBATELAB_APP_GROUP also adds the expo-widgets extension and its
App Group, and drops the push entitlement expo-widgets adds even with push
off, since the profiles we can sign with today carry no push.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One profile: an internal-distribution development client built with
DEBATELAB_BUILD=dev, signed from a credentials.json that is written from
the secrets on build day and never committed (gitignored with the
credentials/ folder). Node is pinned to the version the repo uses. No
preview or production profile yet: each would be one more build to pay for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nativeCapabilities() says whether speech recognition and a Live Activity
are available. In Expo Go it answers false without looking any native
module up; elsewhere it uses requireOptionalNativeModule, and counts a Live
Activity only when expo-widgets has its App Group container. Nothing calls
it yet: the voice and lock-screen timer PRs will.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/development.md gains a Development build section: what the two
config switches add, how to inspect a mode without a Mac, the build
budget, where the signing files live, and the exact commands for build
day (decode the profile and match its certificate to the .p12, link the
project, count builds, write credentials.json without printing the
password, build with --no-wait, clean up) plus how Adam installs it.
The Expo Go command now passes --go. The app's AGENTS.md says how a
native module Expo Go lacks may enter the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prebuild applies expo-notifications' config plugin on its own once the
package is installed, and it adds aps-environment like expo-widgets
does. The signing profile has no push, so every development build drops
it, not only the App Group one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
debate-navigator Ready Ready Preview Oct 14, 2026 5:10pm UTC
debatelab-staging Ready Ready Preview Oct 14, 2026 5:10pm UTC

Copilot AI balanced review requested due to automatic review settings October 14, 2026 14:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Free
  • Run ID: dc2ba2bc-2de9-4481-adad-1ab66025e040

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.

Comment @coderabbitai help to get the list of available commands.

Autolinking puts expo-speech-recognition and expo-widgets into any native
build; DEBATELAB_BUILD=dev only adds their config plugins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A first non-interactive eas init needs --account and --force to link or
create the project, and with an App Group the widget extension needs
its own credentials entry, which the script now writes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

Codex review r1 at 1dcfd20 (gpt-6.1-sol, high): 2 findings, both in the build-day runbook, verified and fixed in 4d019d5.

  • docs/development.md:204: a first non-interactive eas init needs --account and --force to link or create the project (checked against eas-cli 24.13.0 init --help).
  • docs/development.md:234: with an App Group, the credentials script now writes a second entry for ExpoWidgetsTarget; the step also says to export DEBATELAB_APP_GROUP in that shell.
    Codex found config identity for Expo Go/web, capability guards, permission catalogs, gitignore coverage and credential handling sound. docs:check passes. Codex r2 next.

…he App Group

Exporting DEBATELAB_APP_GROUP in the build shell made eas init fail,
because the config only accepts it alongside DEBATELAB_BUILD=dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

Codex review r3 at 429e233 (gpt-6.1-sol, high): no findings. Steps 1-6 traced in one fresh shell with and without an App Group; credential shapes and target names match eas-cli 24.13.0. Local checks at 277bcbc (verify 315, typecheck, eslint, knip, Metro --go bundle 200) still apply: later commits change docs only (docs:check passes). Merging into feat/native-ios. No cloud build was run; that waits for Adam's signing secrets.

@Programcode
Programcode merged commit 376f746 into feat/native-ios Oct 14, 2026
6 of 15 checks passed
@Programcode
Programcode deleted the native-ios/09a-dev-build-prep branch October 14, 2026 17:10
Programcode added a commit that referenced this pull request Oct 14, 2026
Brings in Sparring (#138), development-build prep (#142), App Store
entitlements (#141) and offline reading (#139).

- The push migration becomes 20261014130000_push_tokens.sql so it sorts
  after 20261014123154_app_store_entitlements.sql.
- auth.tsx and _layout.tsx keep both the push wiring (release on sign-out,
  refresh on launch and language change) and setCacheOwner/watchNetwork.
- package-lock.json is feat's lock plus `npm install` for expo-notifications.
- app.config.ts is unchanged: #142 already strips aps-environment from
  development builds. The mobile guide now says so, and that real push needs
  a profile with push and an APNs key from Adam's Apple Developer account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

2 active deployments
Preview – debate-navigator — 429e233b Deployed Oct 14, 2026 by vercel[bot]
Preview – debatelab-staging — 429e233b Deployed Oct 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants