Skip to content

feat(mobile): ship iOS, Android, and Bots companion apps - #41

Merged
sambitcreate merged 42 commits into
mainfrom
feature/mobile-apps-bots-pr
Aug 25, 2026
Merged

feat(mobile): ship iOS, Android, and Bots companion apps#41
sambitcreate merged 42 commits into
mainfrom
feature/mobile-apps-bots-pr

Conversation

@sambitcreate

Copy link
Copy Markdown
Owner

Summary

Ships the unified Aiden companion experience across iOS, Android, and Bots while preserving the existing Mac-hosted security boundary.

  • adds the native SwiftUI iPhone/iPad companion app and native Jetpack Compose Android app
  • brings Android Bots, Workspaces, recent chats, usage, schedules, attachments, speech input, image showcase/carousel, and composer behavior to iOS parity
  • adds paired-Mac speech transcription and companion vision endpoints with best-effort usage accounting
  • retains Bots/workspace data across switching and refreshes it after mutations instead of reloading from an empty state
  • secures Android pairing credentials, backup behavior, installation switching, deep links, and revoked-installation cleanup
  • adds the compact scroll-to-latest controls and floating composers on both platforms
  • publishes the Android debug APK from CI as aiden-on-the-go-debug-apk

Intentionally separate

Verification

  • Node 22: npm test — passed
  • Node 22: npm run type-check, npm run lint, npm run build — passed
  • Desktop Playwright E2E: 8/8 passed
  • Android JVM tests: 98 passed
  • Android lint: 0 errors
  • Android debug APK assembly and instrumentation-test compilation — passed
  • Physical Pixel 10 Pro XL: installed and manually verified in portrait orientation
  • Physical iPhone 13 Pro: 300 tests, 294 passed, 0 failed, 6 skipped
  • Physical iPhone 13 Pro: installed and manually verified in portrait orientation

Device review notes

Portrait captures cover the Android Bots view, text-only app switcher, Workspaces landing view, populated Usage dashboard, elevated chat composer, keyboard placement, attachment chooser, native photo picker, and the iOS compact scroll-to-latest glass control.

Review focus

  • paired-installation isolation and cleanup
  • independent capability loading when a permission is missing
  • cached Bots/workspace data and SSE lifecycle behavior
  • native speech and attachment flows
  • iPhone/iPad and Android layout parity

@sambitcreate

Copy link
Copy Markdown
Owner Author

Final validation is green on commit 78a43dd7f.

@sambitcreate
sambitcreate marked this pull request as ready for review August 25, 2026 05:24

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes

Reviewed feature/mobile-apps-bots-pr at 78a43dd end-to-end: the raw diff TOC plus working-tree reads of the remote boundary, plus five focused reviewfrog specialists on the remaining orthogonal security surfaces. The substantive changes:

  • Aiden Remote HTTP surface — a single router (main/services/aiden-remote-router.ts) with per-route device grants, idempotency-key/if-match concurrency, origin rejection, and body/URL/JSON limits.
  • Pairing & credential lifecycle — QR + manual Crockford codes sealed into one consumed secret (HKDF/AES-256-GCM), scrypt credential digests, and a revocation fence that drains per-device authorizations.
  • Opaque file/browser handles — hashed device/root/policy/snapshot-bound handles with realpath + device/inode re-resolution and single-use selection consume.
  • Bot authority — Full/Custom policy resolution that fails closed on missing/corrupt/future-version policy, per-bot managed homes with incarnation identity, and authoritative prompt rules appended after editable persona.
  • Bot generationllm-client.ts admits/revalidates the Bot authority around the provider call and allowlists tools per capability.
  • iOS / Android companion apps — native SwiftUI and Jetpack Compose trees with Keychain/EncryptedSharedPreferences credential storage, backup exclusion, and bounded ID-only Live Activity / App Intent surfaces.
  • Desktop-side refactors — chat/workspace/schedule/provider IPC handlers moved behind application services; onboarding, provider thinking/visibility, and remote-access settings wiring.

The implementation is unusually consistent with its own docs/security/aiden-remote-threat-model.md, and the negative-path tests (bot-policy fail-closed, avatar decode, speech PCM bounds, idempotency replay, mobile credential leakage) are substantial and load-bearing rather than theatrical.

Two defense-in-depth observations below, neither actionable in this PR.

ℹ️ Legacy Bot migration relies on the seal file surviving alongside the policy store

For a pre-policy Bot, Full Access is minted during migrateLegacyBotsToFull. A missing/corrupt policy record with the migration seal intact fails closed (bot-application-service.ts throws when externallySealed && audit.missingBotIds.length > 0), and the checkpoint anchor adds a second guard. The only scenario where full is re-inferred from persisted-state absence is when an attacker with local filesystem write access deletes both bot-capabilities.json and the seal file together, making the app look like a first run. That is a filesystem-integrity loss beyond the stated "missing/corrupt/future-version record" threat, and the seal + checkpoint are the designed anchors — flagged for awareness, not as a fix request.

ℹ️ Android installation metadata asymmetry vs iOS

Android persists endpoint, serverSpkiSha256, deviceId, instanceId, and the pairing CA certificate in a plaintext app-private installations.json (excluded from cloud backup and device-to-device transfer via data_extraction_rules.xml). None of these are a credential or pairing secret, and the actual credential lives only in EncryptedSharedPreferences under a Keystore-bound MasterKey. iOS stores the equivalent metadata in the Keychain instead. Within the stated threat model on both platforms — noted only for cross-platform parity.

Pullfrog  | View workflow run | Using DeepSeek Pro𝕏

@pullfrog pullfrog Bot 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.

ℹ️ No critical issues — one minor suggestion inline.

Reviewed changes

Reviewed the delta since the prior review at 78a43dd — a single Merge main into mobile companion apps commit (4476dbf) that folds main's display-image and speech work into the companion branch.

  • Added fail-closed display-image recovery gates — chat reads now return imageArtifactRecoveryPending / imageArtifactRecoveryUnavailable, and the remote HTTP layer maps both to a 409 operation_in_progress so paired devices fail closed while a staged image response awaits recovery or storage repair.
  • Hardened chat deletion ordering — staged image artifacts are deleted after the durable subagent tombstone but before Pi effects, compaction, and the chat, with a source-reading test pinning the sequence.
  • Moved PCM16 decode off the main processvalidateAidenRemotePcm16Base64 bounds the wire payload without allocating a decode buffer; a versioned encoding discriminator shifts PCM16→float32 conversion into the utility process.
  • Wired display_image into generation — artifacts are staged before announcement, displayedImages is tracked separately from sharedImages, and committed artifacts are cleared after persistence.
  • Extracted the message image gallery into a shared message-attachments.tsx component.
  • Bumped the release to 0.31.0 and refreshed onboarding bento copy.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Pro𝕏

Comment thread package.json

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes

Reviewed the delta since the prior pullfrog review (4476dbf) — a single fix(remote): avoid IPv4 listener collisions commit (16b0221) touching aiden-remote-service.ts and its test suite.

  • Added an IPv4-loopback availability probe to LAN port selection — before committing a candidate, AidenRemoteService now checks that 127.0.0.1 can bind the port. On macOS an IPv4-only loopback listener can coexist with the dual-stack :: wildcard bind, which previously let Aiden report its HTTPS listener as ready while the IPv4 loopback still reached an unrelated plaintext service; fresh profiles now skip such a port, and committed profiles fail closed with AidenRemotePortInUseError.
  • Added a load-bearing regression testa fresh profile skips a LAN candidate occupied only on IPv4 loopback reserves 127.0.0.1 on the preferred port and asserts the service commits the next complete pair, backed by a new ipv4LoopbackPortIsAvailable helper that mirrors the existing isAddressInUse/listen/closeServer seam.

The probe is additive and safe: it only rejects a port that is genuinely occupied on the IPv4 loopback (the exact unsafe condition), never forces a false skip of a usable port, and leaves the Tailscale loopback half to the existing listen-error handling. The suite passes 35/35 locally.

Pullfrog  | View workflow run | Using DeepSeek Pro𝕏

@sambitcreate
sambitcreate merged commit 171d087 into main Aug 25, 2026
5 checks passed
@sambitcreate
sambitcreate deleted the feature/mobile-apps-bots-pr branch August 25, 2026 16:49
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.

1 participant