mobile-apps
Skill121 starsChanged 4 days agoApache-2.0View on GitHub
Guides changes to Poracode's mobile clients — the compact mobile web/PWA layout, the native SwiftUI iOS app, and the native Jetpack Compose Android app. Use when a task mentions mobile, iOS, Android, PWA, compact layout, SwiftUI, Compose, pairing, push notifications, Live Activities, the remote-v3 contract, or UI that must stay in parity across mobile platforms. Also use to assess mobile impact when implementing desktop or renderer client changes.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Porabuild/Poracodeword for word, first seen Oct 13, 2026
Other versions1 project uses a version of this.
Word for word · 1
- Porabuild/Poracode★ 121100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- AGENTS.mdAGENTS.md
- website/AGENTS.mdAGENTS.md
- website/CLAUDE.mdCLAUDE.md
- add-providerSkill
- address-pr-feedbackSkill
- commitSkill
- finalizeSkill
- heroui-reactSkill
- interactive-testingSkill
- news-lineSkill
- provider-chat-smokeSkill
- pull-requestSkill
- release-notesSkill
- supported-version-updateSkill
- verifySkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 4 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 60
Before implementing a client-side feature or fix, including desktop or renderer work, inspect its counterparts in Electron desktop, desktop …
- Very specific: line 82
If the user scopes work to one platform, deliver that platform, mark applicable deferred clients planned when wire-facing, and name the …
- Distinctive: line 96
All clients render the transcript the same way (same items, grouping, and information per tool call) in their own widgets.
- Distinctive: line 102
Never move provider- or tool-specific interpretation into a client.
- Very specific: line 135
After an intentional contract edit: bun run protocol:remote:v3:generate, then bun run protocol:remote:v3:check and bun run vitest run …
- Distinctive: line 166
Verify each affected client and report the evidence per client.
- Very specific: line 191
Do not claim push, Live Activities, or universal links work from configuration alone.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Mobile Apps — Poracode
Poracode has three mobile client surfaces. They share behavior, feature vocabulary, and the remote-v3 wire contract, but not UI code:
| Surface | Stack | Location | Design language |
| Mobile web / PWA | React, same renderer as desktop | src/renderer (compact layout) | Poracode PWA patterns + HeroUI v3 |
| iOS app | Swift / SwiftUI, native (no WebView) | ios/App (App, AppTests, PoracodeActivities targets) | Apple HIG |
| Android app | Kotlin / Jetpack Compose | android/ | Material 3 |
The native apps do not embed the web renderer; they are independent apps speaking remote-v3 to a desktop or headless host. The mobile web client is a behavior and interaction reference for them, never a code source.
Runbooks: docs/MOBILE_DEV.md (toolchains and required versions, runners,
pairing, dev host), docs/RELEASE_MOBILE.md (release), and
docs/REMOTE_ARCHITECTURE.md (system shape).
Scope: "mobile web" is not "web"
One renderer serves Electron desktop, desktop browsers, and mobile; there is no separate mobile app tree. Mobile is the compact presentation of the shared tree:
- TSX: gate with
useCompactLayout()fromsrc/renderer/adaptiveLayout.ts(viewport ≤ 767px, web clients only). - CSS: gate with
html[data-compact-layout],[data-coarse-input](touch), and[data-mobile-standalone](installed PWA) insrc/renderer/styles.css. - Electron desktop never enters compact layout (
window.poracodeHostis set), but it shares every component you touch.
A task scoped to mobile changes only compact-gated branches and compact CSS; do not restyle or restructure the shared/desktop path as a side effect. A task scoped to the web client as a whole may change shared code, but verify both presentations across the 767px boundary.
Mobile building blocks: src/renderer/components/mobileComposer/; PWA plumbing
(install, push, service worker, device id, port forward):
src/renderer/pwa/; remote-browser bridge and offline cache:
src/renderer/browser/; pairing UI:
src/renderer/views/MainView/parts/BrowserConnectionPage/.
Platform design languages
Behavior and layout logic stay in parity; visual expression is idiomatic per platform. Never port web CSS to native, clone iOS styling on Android, or bring Material patterns to iOS. Before styling, read references/design.md for the per-platform rules (neutral icon and menu color, bottom thumb-reachable actions and the shared components that implement them, drawers, tabs, density, and visual verification).
Client coverage and feature parity
Before implementing a client-side feature or fix, including desktop or renderer work, inspect its counterparts in Electron desktop, desktop browser, compact mobile browser/PWA, native iOS, and native Android. For each client, decide whether it needs an implementation, already inherits the change through shared code, or is unaffected. Check browser and installed PWA behavior separately when the change involves standalone mode, installation, offline use, or push.
Shared capabilities such as chat, thread actions, permissions, and settings normally need matching behavior on all applicable clients in the same change, using each platform's idiom. A desktop window integration or a layout fix specific to one client may need no mobile counterpart. Respect explicit user scope; do not add placeholder implementations or edit unaffected clients just to touch every platform.
- Feature modules mirror by name:
ios/App/App/Features/<Name>↔android/.../ui/<name>(plus matchingTransport/transportlayers) ↔ the renderer's compact surfaces. - The parity ledger is enforced:
protocol/remote/v3/native-parity.jsonrecords a disposition (implemented/planned/desktop-only/unsupported-by-wire) with evidence paths for every HTTP route and socket event per platform, andnative-parity.test.tsfails on drift. Any wire-facing change updates the ledger in the same change. - If the user scopes work to one platform, deliver that platform, mark
applicable deferred clients
plannedwhen wire-facing, and name the parity gap in the final report. - Genuine platform differences are recorded, not skipped — e.g. Live
Activities exist only on iOS (
ios/App/PoracodeActivities/); Android push is plain FCM notification messages. Use ledger dispositions or an explicit note. - Parity includes localization: web via Lingui (see
.agents/docs/i18n.md), iOS via.xcstringscatalogs (ios/App/App/Resources/and per-feature files), Android viavalues-<locale>/strings.xml. A user-facing string added on any platform is localized there in the same change, across the same locale set.
Transcript rendering: one definition per tool call
All clients render the transcript the same way (same items, grouping, and information per tool call) in their own widgets.
- Normalization is single-source. Provider adapters
(
src/supervisor/agents/*/canonicalMapping*) translate provider payloads into the canonical vocabulary ofsrc/shared/contracts/runtimeEvent.ts, host-side. Never move provider- or tool-specific interpretation into a client. - Reducers are per-platform but fixture-pinned.
src/renderer/state/slices/runtimeEventReducer.ts,ios/App/App/Protocol/RuntimeEventReducer.swift, andandroid/.../protocol/RuntimeEventReducer.ktare locked to the shared fixtures inprotocol/remote/v3/fixtures/(rich-*.json,runtime-events.json), which all three suites load directly. A change to decoding, nesting, hiding, grouping, or text extraction starts with a fixture change, then updates all three reducers until all three suites pass. Never change one reducer alone. - Per-tool presentation is not forked into Swift/Kotlin. The renderer's
per-tool branches (
ChatPane/parts/items/toolDisplay.ts,toolCallCategorization.ts, cards likeFileChangeandCommandExecution) are the reference semantics; native apps render a generic activity card. To close that gap, compute presentation on the host: a small, closed vocabulary of generic blocks (title, icon token, category, and sections such as diff, terminal output, key-value args, markdown, table, image) derived once in shared TS and sent over the wire, so each client implements only the block vocabulary. - A new tool-call kind means: map it in the supervisor's canonical mapping, give it display metadata in the shared presentation layer, and add a shared fixture item. It never means a bespoke Swift or Kotlin card; if a client cannot express it, extend the generic block vocabulary (a parity-gated, fixture-pinned change across all three clients).
Remote-v3 contract
- Source of truth:
src/shared/remote/contract/(TypeScript). Fixtures, the contract inventory (manifest.json), the parity ledger, and committed generated artifacts live inprotocol/remote/v3/. - Generated Swift:
ios/App/App/Protocol/Generated*.swift; generated Kotlin:android/.../protocol/Generated*.kt. Never hand-write or fork protocol types in either app. - After an intentional contract edit:
bun run protocol:remote:v3:generate, thenbun run protocol:remote:v3:checkandbun run vitest run --configLoader runner protocol/remote/v3. - The wire protocol is a versioned compatibility boundary; apply
.agents/docs/versioning.md. Native apps check their committed bindings at startup, and old installed apps must keep working with new hosts.
Dev workflows
bun run dev:iosbuilds, installs, and launches on the required iOS simulator and keeps watching; Swift function/bodyedits hot-inject through InjectionNext (fetched into.tmp/). While injection is running, save and verify against the live app instead of rebuilding; rebuild only for structural changes, an injection failure, or a final compile check.bun run dev:androiddoes the same on the project emulator; Kotlin-only saves hot-apply via ART Apply Changes and structural changes fall back to an incremental APK install.-- --onceruns once.bun run dev:webserves only the PWA (port 3101) against an already running desktop app, whose dev renderer stays on 3100.bun run dev:web:serverruns a separate headless remote host when needed.- Required Xcode, SDK, JDK, and Android SDK versions are enforced by
scripts/native-dev-ios.mjs/scripts/native-dev-android.mjsand listed indocs/MOBILE_DEV.md. - Capacitor is fully removed; never reintroduce
@capacitor/*packages or shell-era workflows, and do not resurrect Android WebView workarounds. The one intentional legacy reference is thecapacitor:///ionic://origin allowlist insrc/host/remote/server/security.ts, kept so already-installed shell builds keep pairing — leave it alone.
Verification
- Verify each affected client and report the evidence per client. Shared renderer code still needs checks in the affected desktop, compact, and PWA presentations; an Electron check does not prove browser or native behavior. Name unavailable platform checks explicitly.
- Cross-platform E2E:
bun run native:e2e(configtests/native-e2e/), withnative:e2e:mock-host/native:e2e:real-hostharnesses. Run it when the wire or session flows change. - Contract and parity:
bun run vitest run --configLoader runner protocol/remote/v3. - Android:
cd android && ./gradlew testDebugUnitTest lintDebug --no-daemon(needsJAVA_HOME/ANDROID_HOME). - iOS: the
AppTeststarget;NativeE2ETestsfor the E2E harness. - Mobile web:
bun run vitest runon touched files plus theinteractive-testingskill for renderer surfaces. For simulator-level web checks,xcrun simctlscreenshots andidbtouch injection work headless. - CI:
.github/workflows/native-ci.ymlis the required PR gate for native changes (iOS AppTests, Android unit + lint + instrumentation, headless-host smoke).
Releases
- Native apps:
.github/workflows/release-mobile.yml, triggered by amobile-vX.Y.Ztag or manual dispatch; builds and signs both apps with no web build. Process and evidence:docs/RELEASE_MOBILE.md. - Hosted PWA: separate
release-pwa.yml/deploy-nightly-pwa.ymlworkflows; not an input to native store builds. - Do not claim push, Live Activities, or universal links work from
configuration alone;
docs/RELEASE_MOBILE.mdrequires device-tested evidence.
Platform gotchas
- iOS Safari viewport: in browser mode only document-level scrolling
collapses the toolbar; inner
overflowscrollers letterbox,position: fixedroots clip at the dynamic-viewport line, andenv(safe-area-inset-*)is 0 by design. The compact CSS instyles.cssalready encodes this (100lvh/svhmath,data-mobile-standalonegating); extend those blocks rather than fighting them. - Push and Live Activities are per-platform surfaces: host side in
src/host/remote/push/, web side insrc/renderer/pwa/push/, plus native registrations. A push/notification change is a three-surface parity change plus the host.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

