summaryrefslogtreecommitdiff
path: root/makima/ios/Sources
Commit message (Collapse)AuthorAgeFilesLines
* Makima iOS — Screenshots scheme + demo modemakima-ios-m2-authsoryu-co2026-04-244-25/+173
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adds an opt-in `Makima-Screenshots` scheme + `Screenshots` build config that short-circuits auth with an in-process URLProtocol and seeds the app with canned demo data. Lets us run the app past onboarding in UI tests or on a fresh simulator without touching a real Makima server. What lands - ScreenshotMode: compile-time flag via -DSCREENSHOT_MODE (set in the new Screenshots configuration in project.yml). - AppState: when the flag is on, calls auth.seedScreenshotData() in init. - AuthStore: adds seedSetClient/seedSetState helpers (internal, only useful for screenshot + future preview builds) and a seedScreenshotData that wires up a fake APIClient backed by DemoSession. - DemoSession: URLSession wired to DemoURLProtocol, which answers /api/v1/mesh/daemons, /contracts, /mesh/tasks, /directives, /listen/sessions, /mesh/tasks/{id}, /mesh/tasks/{id}/output with deterministic demo JSON. Host-scoped to makima.jp so production URL remains an operational realm. - Tests/MakimaUITests/ScreenshotTests.swift: five XCTest cases that drive the app through Home, Contracts, Task detail, Directives, and Settings. Each attaches an XCTAttachment screenshot with a stable name. - project.yml: adds MakimaUITests target + Screenshots configuration + Makima-Screenshots scheme. Usage (on a Mac) make xcgen xcodebuild \\ -project Makima.xcodeproj \\ -scheme Makima-Screenshots \\ -configuration Screenshots \\ -destination 'platform=iOS Simulator,name=iPhone 16 Pro' \\ test Screenshots appear as attachments inside the resulting .xcresult bundle; open the bundle in Xcode > Report Navigator to browse them, or use `xcrun xcresulttool get test-results attachments` to export to PNG. Scope - Normal Debug/Release builds are unaffected — SCREENSHOT_MODE is only defined under the Screenshots configuration. - DemoURLProtocol only matches host=makima.jp, so any real request made during screenshot tests (to non-makima.jp hosts) still fails normally. - No production code path gates on ScreenshotMode beyond the init-time seed call; ensureWebSocket is stubbed to a fake online status so the masthead pill shows LIVE during screenshots. Not included in this commit: the matching GitHub Actions workflow (.github/workflows/ios-ci.yml) — requires a workflow-scoped token to push and will land as a follow-up. The Swift helper that extracts screenshots from xcresult is also queued for that follow-up.
* Makima iOS M3-M8 — Home, Tasks, WebSocket, notifications, polishsoryu-co2026-04-2428-146/+2087
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Extends the M2 auth scaffold with the rest of the v1 surface area. All milestones from docs/ios-v1-plan.md land here. M3 — Composite Home dashboard - HomeStore (@Observable): parallel fetch of contracts, daemons, directives, tasks, latest listen session. Each card degrades independently on error. - HomeView: NavigationStack routing to Contracts, Tasks, Daemons, Directives, Listen, and per-item detail views. Pull-to-refresh. - HomeCards: SectionCard chrome + Contracts/Daemons/Directives/Listen/ RecentTasks cards with StatusDot, CountPill, relative-time helpers. M4 — Contracts + Tasks - ContractsListView: filter (active/completed/archived/all), sorted by updatedAt. - ContractDetailView: phase card + per-contract tasks. - TasksListView: status filter pills. - TaskDetailView: metadata card, completion-gate card (rendered only when <COMPLETION_GATE> present in output), output card that merges polled body with live WS events. Polls every 8s as a fallback when WS is offline. M5 — WebSocket + markdown/code rendering - TaskWebSocket: URLSessionWebSocketTask wrapper for /api/v1/mesh/tasks/subscribe. Wire messages match mesh_ws.rs (subscribeAll / subscribe / subscribeOutput / taskUpdated / taskOutput / error). Exponential-backoff reconnect (1s -> 30s cap), status callback feeds the masthead WS pill. - CompletionGate: parses <COMPLETION_GATE>…</COMPLETION_GATE> into {ready, reason, progress, blockers}. CompletionGateView renders it as a status card with dashed accent border (ok/warn tint). - MarkdownBlocks: hand-rolled split-on-fences renderer. Prose blocks via AttributedString(markdown:), code blocks via a monospaced, horizontally- scrollable CodeBlockView with optional language chip. - TaskOutputRenderer: merges polled body + streamed LIVE// events with per-kind colour (assistant / tool_use / tool_result / error). M6 — Directives, Daemons, Listen (read-only) - DirectivesListView: status dot (pending -> warn), goal preview. Notes that answering questions is web-only in v1. - DaemonsListView: online/total, heartbeat relative time, task concurrency. - ListenHistoryView: session preview list; tolerates 404 if the endpoint isn't deployed on the user's instance. Notes that live listen is web-only in v1. - ScreenShell: shared chrome (back chevron, title, WS pill, grid bg) for all detail screens. M7 — Notifications + deep links - NotificationCenterBridge: requests .alert/.badge/.sound auth on first launch; fires local notifications on task-done/failed/blocked and directive-question events with a makima:// deepLink in userInfo. - DeepLink enum: parses makima://task/<uuid>, makima://contract/<uuid>, makima://directive/<uuid>. Wired in MakimaApp via .onOpenURL; AppState holds a pendingDeepLink for consumers. - URL scheme registered in project.yml's CFBundleURLTypes. M8 — Polish - RELEASING.md: pre-flight checklist, xcodebuild archive/export flow, ExportOptions.plist template, App Store submission checklist. - README: full 'what's implemented' matrix, architecture overview, deep-link reference, privacy statement. M2 bug fixes rolled in - ListEnvelope<Item>: generic decoder for the daemons/tasks/contracts/ directives/orders wrapper endpoints ({items:[...], total:N}). Falls back to a bare array for resilience. - AuthStore: now uses ListEnvelope<Daemon> for the probe (was bare array). - rotateKey: accepts both apiKey and api_key casings in the response. - Logo: adds missing import UIKit. Tests added - CompletionGateTests: parse ready=true, blockers list, nil on missing. - MarkdownBlocksTests: prose/code splitting, pure prose. - DeepLinkTests: task/directive parsing, wrong-scheme rejection, unknown host rejection. - ListEnvelopeTests: daemons wrapper, tasks wrapper, bare-array fallback. - APIClientTests: updated stub to return the envelope shape. Not wired (deferred to v1.1 per plan) - Supabase OAuth (Authorization: Bearer path) - APNs push via services/push-proxy/ - Answer directive questions in-app - Live Listen with mic + transcription - Speak (TTS) - Files editor, mesh merge UI, worktree diff viewer, daemon reauth flow File count: 34 new/modified, ~2670 LOC.
* Makima iOS M2 — networking, auth, onboarding, settingssoryu-co2026-04-2414-88/+1052
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Stacked on #91 (M0+M1 scaffold). Wires the app up to a real Makima server via a two-step onboarding flow. Networking - APIClient: async URLSession wrapper. Injects x-makima-api-key on every request (verified against src/server/auth.rs — API keys use the custom header, not Authorization: Bearer). Standard error mapping: 401/403 -> unauthorized, 404 -> notFound, 2xx -> decode, else -> http(status, msg). - APIError: LocalizedError, Equatable. - ServerProfile: id, label, base URL, last-connected timestamp. Derived apiBaseURL ('<base>/api/v1') and apiWebSocketBaseURL (ws/wss scheme upgrade). Keychain ID is stable per profile so key storage survives label/URL edits. - Keychain: thin wrapper over SecItem, scoped to service co.soryu.makima. kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly. - ServerProfileStore: @Observable, UserDefaults-backed list of profiles with an active-profile UUID. List-ready today for v1.x multi-profile. Auth state - AuthStore: @Observable state machine — needsOnboarding | validating | authenticated | error(message). configure() validates (server, key) via GET /mesh/daemons, then persists. updateBaseURL() hot-swaps the server while keeping the key (forces re-onboarding on 401). rotateKey() hits POST /auth/api-keys/refresh and swaps in the new key. signOut() wipes Keychain + profile. - AppState: top-level environment bag. UI - RootView routes to OnboardingFlow / ValidatingView / HomePlaceholderView based on AuthStore.state. Home placeholder shows the masked key so you can eyeball that round-trip worked; real Home lands at M3. - OnboardingFlow: two steps (Server URL, API key paste). Dashed-border cards with a 01 SERVER -> 02 KEY pill indicator. 'Open Web Settings' deep-links to <server>/settings via UIApplication openURL. Inline 'mk_' prefix validation on the key field. - SettingsView: server URL edit, rotate key (with in-flight spinner + error surface), sign out. Opened as a sheet from Home. Tests - ServerProfileTests: URL normalisation, WebSocket scheme upgrade, Keychain ID stability across encode/decode. - APIClientTests: URLProtocol stub verifies x-makima-api-key injection + URL composition + 401 -> APIError.unauthorized mapping. Not in this PR (landing at M3+): Home composite dashboard, Contracts, Tasks, WebSocket client, markdown/code rendering, notifications.
* Add Makima iOS app scaffold (M0 + M1 design system)makima-ios-scaffoldsoryu-co2026-04-2417-0/+554
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.