Skip to content

Commit fec27cb

Browse files
committed
feat: add initial styles and configuration for the simdeck app
- Created a new CSS file for styling the application with light and dark mode support. - Defined CSS variables for colors, typography, and layout. - Added responsive styles for various components including buttons, forms, and cards. - Introduced a new wrangler configuration file for the simdeck app with build output directory and compatibility date.
1 parent 34ff5ea commit fec27cb

13 files changed

Lines changed: 1343 additions & 6 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.wrangler
3+
.dev.vars
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# SimDeck Launchpad (`app.simdeck.sh`)
2+
3+
Static site deployed to Cloudflare Pages. Two jobs:
4+
5+
1. **Build SimDeck deeplinks.** Browse the simulators on your local SimDeck
6+
server, click one, and copy a `https://app.simdeck.sh/open?...` link (or its
7+
`simdeck://` twin). Paste that link into Codex, Claude, Slack, anywhere —
8+
tapping it on iPhone opens the SimDeck iOS app right on the chosen
9+
simulator via a Universal Link.
10+
2. **Talk to a local SimDeck.** The site is allowed to call
11+
`http://localhost:4310` (and other simdeck-server origins) directly from
12+
the browser. On Mac (Chrome, Firefox, Safari) the browser treats `localhost`
13+
as a secure context, so the HTTPS launchpad page can fetch `http://localhost`
14+
without mixed-content errors. The server's CORS allowlist bakes in
15+
`https://app.simdeck.sh`, and `Access-Control-Allow-Private-Network`
16+
is emitted for Chrome's CORS-RFC1918.
17+
18+
Mobile browsers (including iOS Safari) cannot reach `localhost` of a different
19+
machine and block mixed content from public→private targets, so the launchpad
20+
on a phone is deeplink-only — clicks open the iOS app.
21+
22+
## Layout
23+
24+
```
25+
public/
26+
index.html launchpad UI
27+
app.js vanilla JS, no build step
28+
styles.css
29+
simdeck.png favicon / apple-touch-icon
30+
_headers CF Pages headers (AASA content-type)
31+
_redirects legacy /apple-app-site-association alias
32+
.well-known/apple-app-site-association iOS Universal Link config
33+
```
34+
35+
The site is plain HTML/CSS/JS — no bundler, no framework. To preview locally:
36+
37+
```sh
38+
npm run dev # http://localhost:4311
39+
```
40+
41+
That fires `serve` on the `public/` directory. To preview through Wrangler's
42+
Pages emulator (closer to production, honors `_headers` / `_redirects`):
43+
44+
```sh
45+
npm run preview
46+
```
47+
48+
## Deploy to Cloudflare Pages
49+
50+
The project is set up for `wrangler pages deploy`:
51+
52+
```sh
53+
npm run deploy
54+
```
55+
56+
Or hook it up to a Cloudflare Pages project pointing at this directory with
57+
`public` as the build output dir. There's no build command — `_headers` and
58+
`_redirects` ship as-is.
59+
60+
## Universal Link contract
61+
62+
The iOS app's `StudioLinkResolver` handles these paths on `app.simdeck.sh`:
63+
64+
- `/open` — primary entry. Opens the app on a specific server/simulator.
65+
- `/connect` — alias.
66+
- `/pair` — alias when a pairing code is included.
67+
68+
Query params:
69+
70+
| param | meaning |
71+
| ---------------------------------- | ---------------------------------------------------------------- |
72+
| `host` (required) | Where SimDeck is reachable from the phone (LAN IP, tunnel host). |
73+
| `port` | Port (defaults vary). |
74+
| `scheme` | `http` or `https`. Default `http`. |
75+
| `udid` / `device` | Auto-select this simulator and auto-start streaming. |
76+
| `serverId` / `sid` / `s` | Hash identifying which SimDeck instance this is. |
77+
| `hostId` / `hid` | Stable host identifier (machine-level). |
78+
| `hostName` / `hname` | Human-readable host name for the picker. |
79+
| `serverKind` / `kind` | `launchAgent`, `foreground`, `standalone`, … |
80+
| `token` / `simdeckToken` | Pre-shared access token (optional). |
81+
| `code` / `pairingCode` (on /pair) | Pairing code for first-time link-up. |
82+
83+
The Universal Link `https://app.simdeck.sh/open?...` and the custom-scheme
84+
`simdeck://open?...` carry the same query string and are interchangeable.
85+
86+
## AASA file
87+
88+
`public/.well-known/apple-app-site-association` declares the
89+
`CS838V553Y.org.nativescript.simdeck` app and the path patterns iOS should
90+
treat as universal links. The `_headers` file forces the
91+
`application/json` content-type that iOS requires.
92+
93+
When you change the AASA file, force iOS to re-fetch it:
94+
95+
- toggle Airplane Mode, **or**
96+
- delete + reinstall the app, **or**
97+
- use the Apple `swcutil` CLI (`sudo swcutil reset`) on a developer device.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@simdeck/app-deeplink-pages",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "Static launchpad served at https://app.simdeck.sh. Builds SimDeck deeplinks against a local or remote SimDeck server.",
6+
"license": "Apache-2.0",
7+
"scripts": {
8+
"dev": "npx --yes serve@14 public -l 4311 --cors",
9+
"format": "prettier --write public",
10+
"deploy": "wrangler pages deploy public --project-name simdeck-app",
11+
"preview": "wrangler pages dev public --port 4311"
12+
},
13+
"devDependencies": {
14+
"wrangler": "^3.78.0"
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"applinks": {
3+
"apps": [],
4+
"details": [
5+
{
6+
"appID": "CS838V553Y.org.nativescript.simdeck",
7+
"paths": [
8+
"/open",
9+
"/open/*",
10+
"/connect",
11+
"/connect/*",
12+
"/pair",
13+
"/pair/*"
14+
],
15+
"components": [
16+
{ "/": "/open*" },
17+
{ "/": "/connect*" },
18+
{ "/": "/pair*" }
19+
]
20+
}
21+
]
22+
}
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Cloudflare Pages: per-path response headers.
2+
# https://developers.cloudflare.com/pages/configuration/headers/
3+
4+
/.well-known/apple-app-site-association
5+
Content-Type: application/json
6+
Cache-Control: public, max-age=300
7+
8+
/apple-app-site-association
9+
Content-Type: application/json
10+
Cache-Control: public, max-age=300
11+
12+
/*
13+
X-Frame-Options: DENY
14+
Referrer-Policy: strict-origin-when-cross-origin
15+
X-Content-Type-Options: nosniff
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Cloudflare Pages redirects.
2+
# Mirror the well-known AASA path to the legacy /apple-app-site-association path
3+
# so older iOS clients can still discover the universal-link config.
4+
/apple-app-site-association /.well-known/apple-app-site-association 200

0 commit comments

Comments
 (0)