Skip to content
Back to skills

Multi Platform Project

ASecurity

Multi-platform apps: protocol-first, parallel delegation.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 10, 2026
developmenttypescriptpythonrustgoswiftkotlinreactnodeapifrontend

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add LoopyLuci/Skills --skill multi-platform-project --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Multi Platform Project?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Multi Platform Project
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loopyluci-multi-platform-project/badge)](https://www.skillsdirectory.com/skills/loopyluci-multi-platform-project)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: multi-platform-project
description: "Multi-platform apps: protocol-first, parallel delegation."
tags: [cross-platform, multi-platform, protocol-first, protobuf, parallel-delegation, monorepo]
related_skills: [python-package-build, frontend-bootstrap, spike, service-orchestration, test-driven-development]
---

# Multi-Platform Project (Protocol-First + Parallel Delegation)

## When to Use

- A user asks to build the same app on **Android + iOS + Desktop** (or any multi-platform combination)
- The project has multiple runtime components that share a **wire protocol or data contract**
- You need to **generate a complete project tree** with shared libraries and per-platform implementations
- The request is large enough that **parallel delegation** saves wall-clock time over building each component sequentially

Do **not** use for:
- Adding a feature to an existing single-platform project (use the platform's own skill)
- A pure library with no platform-specific UI (use `spike` or a library-scaffold skill)
- A task where the platforms share so much logic that one codebase (e.g. React Native, Flutter) is a better answer

## Core Pattern

```
1.  PROTOCOL FIRST
2.  DELEGATE PLATFORMS IN PARALLEL
3.  BUILD PRIMARY PLATFORM DIRECTLY IN THIS SESSION
4.  VERIFY WITH AVAILABLE TOOLCHAINS
5.  CLEAN UP (remove temp scaffolding, verification scripts)
```

## Phase 1 — Protocol First

Before writing platform code, define the wire protocol. This becomes the contract every platform implements against.

### Recommended approach

- **Protobuf** (`.proto` file) — strongly typed, cross-platform, code-gen for Rust/Kotlin/Swift/Python
- Alternative: a JSON schema + documented message shapes (lighter weight, no code-gen)
- Keep the proto at the repo root under `protocol/`

### Structure

```
project/
├── protocol/
│   └── streamsync.proto        ← shared contract
├── shared/                     ← cross-platform shared libs
│   ├── rust/                   ← core library (serialization, crypto, discovery)
│   └── kotlin/                 ← KMP shared module (optional)
├── android/                    ← primary platform (Kotlin/Jetpack Compose)
├── ios/                        ← companion (Swift/SwiftUI)
├── desktop-rust/               ← companion (Rust + Tauri)
├── desktop-python/             ← companion (Python CLI/GUI)
└── README.md
```

### Key rules

- The proto file must be **the single source of truth** — every platform reads the same spec
- Define all message types, enums, and wrapper structures up front
- Document the message flow (discovery → handshake → transfer → completion) in the README
- Use protocol versioning for forward compatibility

### Alternative: MCP as the Unifying Protocol

For **agent-native** applications where AI agents need to control every platform, use the **Model Context Protocol** (JSON-RPC 2.0 over WebSocket/stdio) instead of Protobuf:

```
project/
├── mcp-spec/
│   └── schema.yaml              ← shared MCP tool/resource/event contract
├── rust-core/                   ← primary platform (Rust, speaks MCP natively)
├── python-bridge/               ← orchestrator (Python MCP client)
├── clojure-engine/              ← rule engine (Clojure MCP server)
├── web-frontend/                ← Svelte/TypeScript MCP client
├── ios/                         ← Swift MCP client (NEDNSSettingsManager)
├── android/                     ← Kotlin MCP client (VpnService)
└── cross-build/                 ← CI matrix
```

**Each platform implements an MCP client** that connects to the Rust core's MCP server on `ws://host:9822`. The MCP contract (10+ tools for status, block, firewall, config) is the single source of truth — identical tool signatures across every language.

| Platform | MCP Client Implementation | Transport |
|----------|--------------------------|-----------|
| Rust | `tokio-tungstenite` WebSocket server | ws:// |
| Python | `websockets` library | ws:// |
| TypeScript | `WebSocket` API (browser) | ws:// |
| Swift | `URLSessionWebSocketTask` | ws:// |
| Kotlin | raw `Socket` + buffered I/O | ws:// |

**Advantages over Protobuf:**
- No code-gen step — tools are discovered dynamically via `tools/list`
- AI agents (Hermes, Claude) can control every platform without language-specific bindings
- Runtime capability discovery — tools self-describe via JSON Schema
- Event subscription model for real-time updates
- Same protocol powers the web dashboard, mobile apps, and agent control

**Trade-off**: Higher per-message overhead (JSON vs binary), but negligible for control-plane operations.

## Phase 2 — Delegate Platform Components in Parallel

Use `delegate_task` with the **batch `tasks` array** to dispatch N platform implementations concurrently.

```
delegate_task(tasks=[
    {
        "goal": "Build the Rust core library + Tauri desktop app...",
        "context": "Protocol at <path>. Project root at <path>.",
    },
    { "goal": "Build the iOS Swift/SwiftUI companion...", "context": "..." },
    { "goal": "Build the Python desktop companion...", "context": "..." },
])
```

### Rules for subagent context

1. **Be maximally explicit** — the subagent has NO conversation history. Include absolute paths, directory trees, file names, and import paths.
2. **Each subagent owns its own directory** — never overlap paths between subagents.
3. **Give each subagent a `todo` plan first** — it should plan its files, then write them.

### Sibling file conflict warning

When subagents write under the same project root, `write_file` warns if a sibling modified a file since your last read. The file IS written; acknowledge the warning. If you must re-write a sibling's file, read it first to clear the "last-read" state.

## Phase 3 — Build Primary Platform Directly

Build the primary platform (usually the first one the user named) while subagents work.

### Android (Kotlin + Jetpack Compose)

| Layer | Key files |
|---|---|
| Build | `settings.gradle.kts`, `app/build.gradle.kts`, `gradle.properties` |
| Manifest | `AndroidManifest.xml`, `file_paths.xml`, `network_security_config.xml` |
| Theme & Nav | `Theme.kt`, `NavGraph.kt` |
| Models | `Models.kt` — Device, Transfer, StreamSession, ClipboardEntry, enums |
| Protocol | `ProtocolHandler.kt` — JSON serialization, AES-256-GCM, chunking |
| Services | `DiscoveryService.kt` (NSD), `TransferService.kt` (Ktor WS), `StreamService.kt` (ExoPlayer), `ClipboardSyncService.kt` |
| UI | Dashboard, Devices, Transfers, Stream, Settings, Clipboard, DeviceDetail, StreamPlayer |

### iOS (Swift + SwiftUI)

| Layer | Key files |
|---|---|
| Entry | `StreamSyncApp.swift`, `ContentView.swift` |
| Models | `DeviceIdentity.swift`, `DiscoveredDevice.swift`, `TransferSession.swift`, `StreamSession.swift` |
| Services | `DiscoveryService.swift` (NWBrowser), `TransferService.swift` (NWConnection), `StreamService.swift` (AVPlayer), `CryptoService.swift`, `ClipboardService.swift` |
| Views | Dashboard, Devices, Transfer, Stream, Settings, ClipboardSync |

### Desktop (Rust + Tauri)

| Layer | Key files |
|---|---|
| Backend | `src-tauri/Cargo.toml`, `build.rs`, `tauri.conf.json` |
| Rust | `main.rs` (commands), `discovery.rs`, `transfer.rs`, `crypto.rs`, `streaming.rs` |
| Frontend | `index.html` — single-page app, embedded CSS+JS, no build step |

### Desktop (Python CLI + GUI)

| Layer | Key files |
|---|---|
| Config | `pyproject.toml`, `requirements.txt`, `README.md` |
| Core | `protocol.py`, `discovery.py` (zeroconf), `transport.py` (websockets), `crypto.py` (AES-GCM), `transfer.py`, `streaming.py`, `clipboard.py`, `config.py` |
| UI | `__init__.py` (backend auto-detect), `cli_app.py` (click), `qt_app.py` (PyQt6), `tui_app.py` (textual) |
| Server | `server.py` (async WebSocket daemon) |

## Phase 4 — Ad-Hoc Verification

Create a self-contained Python script that validates what the available toolchains support.

| Platform | Can verify | Cannot verify without |
|---|---|---|
| **Rust** | `cargo test` (compile + unit tests) | `cargo tauri build` (needs node + tauri-cli) |
| **Python** | `py_compile` every `.py` | PyQt6 GUI (needs display) |
| **Kotlin/Android** | Structural: files exist, named correctly | `./gradlew assembleDebug` (needs Android SDK) |
| **Swift/iOS** | Structural: files exist, named correctly | `xcodebuild` (needs macOS + Xcode) |

**Always clean up the verifier** after running — it's a one-shot tool, not a project artifact.

## Phase 5 — Final Inventory

Run a final file count per component (files, lines, KB). Prints a completeness table.

## Common Pitfalls

### Rust: prost-build

- Add `protoc-bin-vendored = "3"` to `[build-dependencies]`
- Set `PROTOC` env var in `build.rs`
- Generated module name is **snake_case** of the proto package: `streamsync_message` → `stream_sync_message`
- Use `include!(concat!(env!("OUT_DIR"), "/streamsync.rs"))` — not relative
- `prost 0.13` generates `bytes::Bytes` for bytes fields; use `.to_vec()` for Vec
- Delete `target/` after proto changes

### Rust: third-party crate quirks

- **`mdns-sd 0.13`**: `ServiceInfo::new(type, instance, host, target, port, props: HashMap<String,String>)`. `ServiceEvent` has `ServiceResolved` and `ServiceRemoved(_, name)` — no `ServiceAdded`.
- **`aes-gcm 0.10`**: Use `Aes256Gcm::new_from_slice(key)`, 12-byte nonce prepended to ciphertext. Import `aead::{Aead, KeyInit}`, not `AeadInOut`.
- **`tokio-tungstenite 0.24`**: Bind `TcpListener` with `SocketAddr`, not `u16`. `accept_async` returns `WebSocketStream<MaybeTlsStream<TcpStream>>`.

### Python: no protobuf

Hand-write JSON message serialization matching proto shapes. No code-gen needed.

### Subagents: don't poll

`delegate_task` returns immediately. The consolidated result re-enters when all finish. Read live transcripts to watch progress.

## Verification Checklist

- [ ] Protocol file: all message types, enums, wrapper envelope defined
- [ ] Protocol version field for forward compat
- [ ] Every platform has complete directory + build config
- [ ] Rust: `cargo check` + `cargo test` pass
- [ ] Python: all `.py` files pass `py_compile`
- [ ] Source files present, named correctly, non-empty
- [ ] Verification ran and cleaned up
- [ ] README documents protocol, architecture, build
- [ ] Project structure matches the plan

### Reference files in this skill
- `references/cross-platform-firewall-threads.md` — Platform-specific firewall backends, thread pool config for 24-core CPUs, AhoCorasick API migration, Hickory DNS rename, SvelteKit + Tailwind v4 compatibility notes.
- `references/rust-build-patterns.md` — Rust crate selection and build config patterns.

Files in this skill

  • SKILL.md10.6 KB
  • references/cross-platform-firewall-threads.md3.8 KB
  • references/rust-build-patterns.md3.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.