Files
zeekay 12a4d94b8f Add the iOS lane: hanzo-templates had zero of them
The catalogue shipped 71 web templates and one EMPTY `mobile` repo, so
"build an app" had no starting point on the platform people actually
ship to. This is the iOS lane — Expo/React Native and Flutter for
cross-platform, SwiftUI for native.

The constraint that shaped every file here: an iOS archive needs macOS +
Xcode + a signing identity, and our arc fleet has none. hanzoai has 519
registered runners and every one reports `os: linux`; luxfi has 151, same
story; zooai has none. The only macOS builds in the org today
(hanzoai/world build-desktop.yml) run on GitHub-HOSTED macos-14, which is
exactly what the house CI rule says not to do.

So `hanzo.yml` declares only what a Linux arc runner can genuinely
execute — typecheck + web bundle for Expo, analyze + test + web for
Flutter, `swiftc -parse` for SwiftUI — and the macOS archive lives in a
separate `workflow_dispatch`-only `ios.yml`. A job pinned to a label no
runner advertises would sit queued forever if it fired on push; parking
it is honest, a permanently-yellow check is not. The README of every
template states the gap and the one command that closes it.

Same reasoning on the demos. Expo and Flutter both have a real web
target, so `<slug>.hanzo.app` serves the SAME source the simulator runs.
SwiftUI has no web target, so those two templates ship with no demo link
rather than a screenshot pretending to be one.

Upstreams are permissive only and recorded per template: expo/expo
templates (MIT), flutter/samples (BSD-3-Clause), XcodeGen (MIT).

Second measured gap, found while wiring this up: `hanzo-templates` is not in
arcd's `orgs:` list either (hanzoai, luxfi, zooai, parsdao, zenlm), so the
Linux jobs would queue with no runner too. Both gaps are one installer
re-run, no code change; both are spelled out in every README rather than
left to be discovered on the first red build.

Third gap, found by probing rather than assuming, and FIXED here: every
run in this org died as `startup_failure` with no logs and no annotation.
A bare `runs-on: [self-hosted, linux]` probe queued fine while the same
job importing hanzoai/ci failed identically at @v1 and at a pinned SHA —
so it was never the tag. The org defaulted GITHUB_TOKEN to `read`, and
the reusable declares `permissions: packages: write`; a caller cannot
exceed the org maximum, so GitHub kills the run before creating a job.
hanzo-templates now defaults to `write` like hanzoai/luxfi/zooai, and
runs reach `queued` — the honest state, waiting on gap 2.
2026-07-27 23:25:09 -07:00

48 lines
1.9 KiB
TypeScript

import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { signOut, useSession } from '../auth';
import { t } from '../theme';
export default function Profile() {
const session = useSession();
if (!session) return null; // the guard in _layout is already redirecting
const rows: [string, string][] = [
['Name', session.name ?? '—'],
['Email', session.email ?? '—'],
['Subject', session.sub ?? '—'],
['Refresh token', session.refresh ? 'stored in Keychain' : 'none'],
];
return (
<ScrollView style={s.wrap} contentContainerStyle={{ padding: t.pad, gap: 18, paddingTop: 64 }}>
<Text style={s.h1}>Signed in</Text>
<View style={s.group}>
{rows.map(([k, v], i) => (
<View key={k}>
{i > 0 && <View style={s.hr} />}
<View style={s.row}>
<Text style={s.label}>{k}</Text>
<Text style={s.value} numberOfLines={1}>{v}</Text>
</View>
</View>
))}
</View>
<Pressable style={s.btn} onPress={signOut}>
<Text style={s.btnText}>Sign out</Text>
</Pressable>
</ScrollView>
);
}
const s = StyleSheet.create({
wrap: { flex: 1, backgroundColor: t.bg },
h1: { color: t.text, fontSize: 30, fontWeight: '700', letterSpacing: -0.5 },
group: { backgroundColor: t.card, borderRadius: t.radius, borderWidth: 1, borderColor: t.line, paddingHorizontal: t.pad },
row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 14, gap: 16 },
hr: { height: 1, backgroundColor: t.line },
label: { color: t.text, fontSize: 16 },
value: { color: t.dim, fontSize: 15, flexShrink: 1 },
btn: { borderRadius: t.radius, borderWidth: 1, borderColor: t.line, paddingVertical: 15, alignItems: 'center' },
btnText: { color: '#ff6b6b', fontSize: 16, fontWeight: '600' },
});