<feed xmlns='http://www.w3.org/2005/Atom'>
<title>soryu, branch makima-ios-m2-auth</title>
<subtitle>soryu-co/soryu mirror</subtitle>
<id>http://src.eirin.xyz/soryu/atom?h=makima-ios-m2-auth</id>
<link rel='self' href='http://src.eirin.xyz/soryu/atom?h=makima-ios-m2-auth'/>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/'/>
<updated>2026-04-24T18:13:01+00:00</updated>
<entry>
<title>Makima iOS — Screenshots scheme + demo mode</title>
<updated>2026-04-24T18:13:01+00:00</updated>
<author>
<name>soryu-co</name>
<email>bot@soryu.co</email>
</author>
<published>2026-04-24T18:13:01+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=3ea85b0d8d3cb6dca522578cb29a676bbac6809f'/>
<id>urn:sha1:3ea85b0d8d3cb6dca522578cb29a676bbac6809f</id>
<content type='text'>
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 &gt; 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.
</content>
</entry>
<entry>
<title>Makima iOS M3-M8 — Home, Tasks, WebSocket, notifications, polish</title>
<updated>2026-04-24T16:45:51+00:00</updated>
<author>
<name>soryu-co</name>
<email>bot@soryu.co</email>
</author>
<published>2026-04-24T16:45:51+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=105730ceaa292b1e3589c23d5aad8f35ccf04b8e'/>
<id>urn:sha1:105730ceaa292b1e3589c23d5aad8f35ccf04b8e</id>
<content type='text'>
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
  &lt;COMPLETION_GATE&gt; 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 -&gt; 30s cap), status callback
  feeds the masthead WS pill.
- CompletionGate: parses &lt;COMPLETION_GATE&gt;…&lt;/COMPLETION_GATE&gt; 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 -&gt; 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/&lt;uuid&gt;, makima://contract/&lt;uuid&gt;,
  makima://directive/&lt;uuid&gt;. 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&lt;Item&gt;: 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&lt;Daemon&gt; 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.
</content>
</entry>
<entry>
<title>Makima iOS M2 — networking, auth, onboarding, settings</title>
<updated>2026-04-24T14:16:03+00:00</updated>
<author>
<name>soryu-co</name>
<email>bot@soryu.co</email>
</author>
<published>2026-04-24T14:16:03+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=8f8e3b54cbecf51ce6a87e9e028caaad428879be'/>
<id>urn:sha1:8f8e3b54cbecf51ce6a87e9e028caaad428879be</id>
<content type='text'>
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 -&gt;
  unauthorized, 404 -&gt; notFound, 2xx -&gt; decode, else -&gt; http(status, msg).
- APIError: LocalizedError, Equatable.
- ServerProfile: id, label, base URL, last-connected timestamp. Derived
  apiBaseURL ('&lt;base&gt;/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 -&gt; 02 KEY pill indicator. 'Open Web Settings'
  deep-links to &lt;server&gt;/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 -&gt; APIError.unauthorized mapping.

Not in this PR (landing at M3+): Home composite dashboard, Contracts,
Tasks, WebSocket client, markdown/code rendering, notifications.
</content>
</entry>
<entry>
<title>Add Makima iOS app scaffold (M0 + M1 design system)</title>
<updated>2026-04-24T13:21:12+00:00</updated>
<author>
<name>soryu-co</name>
<email>bot@soryu.co</email>
</author>
<published>2026-04-24T13:15:29+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=db092c79a175e3283f479ee0b234b24bde3c736e'/>
<id>urn:sha1:db092c79a175e3283f479ee0b234b24bde3c736e</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat: soryu-co/soryu - makima: Fix build errors in daemon protocol and task manager (#89)</title>
<updated>2026-03-10T17:33:23+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-10T17:33:23+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=3679ceb3325033faa2f889ef3dfee5668ef7aeea'/>
<id>urn:sha1:3679ceb3325033faa2f889ef3dfee5668ef7aeea</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: worktree diff/commit endpoints and frontend diff viewing (#88)</title>
<updated>2026-03-09T17:20:52+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-09T17:20:52+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=f49aaa39a32661b54c109ba002d24cbdf73f4ea3'/>
<id>urn:sha1:f49aaa39a32661b54c109ba002d24cbdf73f4ea3</id>
<content type='text'>
* feat: soryu-co/soryu - makima: Fix worktree info failing when origin ref is missing

* WIP: heartbeat checkpoint

* WIP: heartbeat checkpoint

* WIP: heartbeat checkpoint

* feat: soryu-co/soryu - makima: Add worktree commit endpoint and diff endpoint for regular users

* feat: soryu-co/soryu - makima: Add frontend diff viewing with clickable worktree files</content>
</entry>
<entry>
<title>Merge pull request #87 from soryu-co/makima/directive-soryu-co-soryu---makima-19fd3e1d-v1772943648</title>
<updated>2026-03-09T16:53:49+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-09T16:53:49+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=afaae8aba719bf74404a64b57426ecc6a7e70775'/>
<id>urn:sha1:afaae8aba719bf74404a64b57426ecc6a7e70775</id>
<content type='text'>
feat: compact order header &amp; add context menus to orders/directives</content>
</entry>
<entry>
<title>fix: resolve merge conflicts with master (integrate DOG features into compact header)</title>
<updated>2026-03-09T16:31:31+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-09T16:31:31+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=e11e7225861c3063f08461ac01005f3315d41be5'/>
<id>urn:sha1:e11e7225861c3063f08461ac01005f3315d41be5</id>
<content type='text'>
- Resolved conflict in OrderDetail.tsx: kept PR compact header layout
  with inline badges while adding DOG badge from master
- DOG selector in Actions section preserved from master
- orders.tsx correctly passes dogs prop to OrderDetail (auto-merged correctly)
- directives.tsx auto-merged correctly with DOG props for DirectiveDetail
- Frontend builds successfully with no TypeScript errors

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/makima/soryu-co-soryu---makima--add-right-click-context-m-6bf81c58' into makima/directive-soryu-co-soryu---makima-19fd3e1d-v1772943648</title>
<updated>2026-03-08T04:21:10+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-08T04:21:10+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=76566d32a88aa88e5b22e5209f9beb025ab6c299'/>
<id>urn:sha1:76566d32a88aa88e5b22e5209f9beb025ab6c299</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Merge remote-tracking branch 'origin/makima/soryu-co-soryu---makima--add-right-click-context-m-f42926a8' into makima/directive-soryu-co-soryu---makima-19fd3e1d-v1772943648</title>
<updated>2026-03-08T04:21:06+00:00</updated>
<author>
<name>soryu</name>
<email>soryu@soryu.co</email>
</author>
<published>2026-03-08T04:21:06+00:00</published>
<link rel='alternate' type='text/html' href='http://src.eirin.xyz/soryu/commit/?id=1dc01df7fd5ecfb85e8f776d8d6894dc5c52a6d3'/>
<id>urn:sha1:1dc01df7fd5ecfb85e8f776d8d6894dc5c52a6d3</id>
<content type='text'>
</content>
</entry>
</feed>
