From db092c79a175e3283f479ee0b234b24bde3c736e Mon Sep 17 00:00:00 2001 From: soryu-co Date: Fri, 24 Apr 2026 13:15:29 +0000 Subject: Add Makima iOS app scaffold (M0 + M1 design system) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure-native SwiftUI client for makima.jp under makima/ios/. M0 (scaffold) - XcodeGen project (iOS 18+, Swift 5.10, bundle co.soryu.makima) - Makefile targets: bootstrap, xcgen, ios-sim-fast, ios-device-fast, test, lint - GitHub Actions workflow ios-ci.yml — builds + runs XCTest on macos-14 - MIT repo root license already in place M1 (design system, web-aesthetic port) - Palette: #0c1729 background, #9bc3ff accent, #3f6fb3 border (ported from Tailwind) - Typography: SF Mono for chrome, uppercase tracked nav labels - Components: DashedBorder, GridOverlay, MastheadBar + WebSocketStatus pill, NavStripPlaceholder (NAV// prefix), JapaneseLongPressText (mobile analogue of JapaneseHoverText), Logo (reuses frontend/public/logo/makima-logo.svg with Canvas concentric-ring fallback), Badge - RootView demo screen: masthead, nav strip, logo, CONTROL SYSTEM badge, SYSTEM// status card, GLOSSARY// card with 命令/契約/聴取/史料 long-press terms Auth (v1 plan, not wired here): x-makima-api-key header — verified against src/server/auth.rs. Authorization: Bearer reserved for v1.1 Supabase OAuth. v1 plan doc: makima/ios/docs/ios-v1-plan.md Not in this PR: networking, WebSocket client, stores, feature surfaces (Home/Contracts/Tasks/Directives/Daemons/Listen), notifications. Those land across M2-M8 per the plan. --- makima/ios/Sources/Makima/App/Info.plist | 18 ++++ makima/ios/Sources/Makima/App/MakimaApp.swift | 12 +++ makima/ios/Sources/Makima/App/RootView.swift | 125 ++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 makima/ios/Sources/Makima/App/Info.plist create mode 100644 makima/ios/Sources/Makima/App/MakimaApp.swift create mode 100644 makima/ios/Sources/Makima/App/RootView.swift (limited to 'makima/ios/Sources/Makima/App') diff --git a/makima/ios/Sources/Makima/App/Info.plist b/makima/ios/Sources/Makima/App/Info.plist new file mode 100644 index 0000000..39a5741 --- /dev/null +++ b/makima/ios/Sources/Makima/App/Info.plist @@ -0,0 +1,18 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + + diff --git a/makima/ios/Sources/Makima/App/MakimaApp.swift b/makima/ios/Sources/Makima/App/MakimaApp.swift new file mode 100644 index 0000000..907bf8e --- /dev/null +++ b/makima/ios/Sources/Makima/App/MakimaApp.swift @@ -0,0 +1,12 @@ +import SwiftUI + +@main +struct MakimaApp: App { + var body: some Scene { + WindowGroup { + RootView() + .preferredColorScheme(.dark) + .tint(Palette.accent) + } + } +} diff --git a/makima/ios/Sources/Makima/App/RootView.swift b/makima/ios/Sources/Makima/App/RootView.swift new file mode 100644 index 0000000..bb724fc --- /dev/null +++ b/makima/ios/Sources/Makima/App/RootView.swift @@ -0,0 +1,125 @@ +import SwiftUI + +/// Root view for M1. Shows the masthead + a placeholder "system online" card +/// so we can judge the aesthetic port against makima.jp side-by-side. +struct RootView: View { + var body: some View { + ZStack { + Palette.background.ignoresSafeArea() + GridOverlay() + + VStack(spacing: 0) { + MastheadBar( + serverLabel: "makima.jp", + wsStatus: .idle, + version: Bundle.main.shortVersion + ) + NavStripPlaceholder() + + ScrollView { + VStack(spacing: 24) { + Spacer(minLength: 32) + + Logo(size: 140) + + VStack(spacing: 6) { + Badge(text: "支配する", subtitle: "CONTROL SYSTEM") + Text("Mesh Orchestration Platform") + .font(Typography.titleChrome) + .foregroundStyle(Palette.foreground) + .tracking(1) + Text("Makima is listening.") + .font(Typography.body) + .foregroundStyle(Palette.foregroundMuted) + } + + statusCard + .padding(.horizontal, 16) + + languageDemoCard + .padding(.horizontal, 16) + + Spacer(minLength: 40) + } + .padding(.top, 12) + } + } + } + } + + private var statusCard: some View { + VStack(alignment: .leading, spacing: 10) { + HStack { + Text("SYSTEM//") + .font(Typography.navLabel) + .foregroundStyle(Palette.foregroundMuted) + Spacer() + Text("M0 + M1") + .font(Typography.navLabel) + .foregroundStyle(Palette.accent) + } + Divider().overlay(Palette.borderMuted) + ForEach(StatusRow.samples) { row in + HStack { + Circle() + .fill(row.ok ? Palette.ok : Palette.warn) + .frame(width: 6, height: 6) + Text(row.label) + .font(Typography.body) + .foregroundStyle(Palette.foreground) + Spacer() + Text(row.value) + .font(Typography.mono) + .foregroundStyle(Palette.foregroundMuted) + } + } + } + .padding(14) + .dashedBorder() + } + + private var languageDemoCard: some View { + VStack(alignment: .leading, spacing: 8) { + Text("GLOSSARY//") + .font(Typography.navLabel) + .foregroundStyle(Palette.foregroundMuted) + Divider().overlay(Palette.borderMuted) + VStack(alignment: .leading, spacing: 8) { + JapaneseLongPressText(japanese: "命令", english: "Directives") + JapaneseLongPressText(japanese: "契約", english: "Contracts") + JapaneseLongPressText(japanese: "聴取", english: "Listen") + JapaneseLongPressText(japanese: "史料", english: "History") + } + Text("Long-press any term to reveal the English gloss.") + .font(Typography.caption) + .foregroundStyle(Palette.foregroundMuted) + .padding(.top, 4) + } + .padding(14) + .dashedBorder() + } +} + +private struct StatusRow: Identifiable { + let id = UUID() + let label: String + let value: String + let ok: Bool + + static let samples: [StatusRow] = [ + StatusRow(label: "Scaffold", value: "READY", ok: true), + StatusRow(label: "Design Sys", value: "M1", ok: true), + StatusRow(label: "Network", value: "NOT WIRED", ok: false), + StatusRow(label: "WebSocket", value: "NOT WIRED", ok: false) + ] +} + +private extension Bundle { + var shortVersion: String { + (infoDictionary?["CFBundleShortVersionString"] as? String) ?? "0.0.0" + } +} + +#Preview { + RootView() +} -- cgit v1.2.3