Imported from Eilgnaw/dexo (
AGENTS.md). Install upstream withnpx skills add Eilgnaw/dexo. Copyright stays with the author.
AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
Build Commands
make setup # First-time setup: install mise tools, tuist install, tuist generate
make generate # Regenerate Xcode project after changing Project.swift
make clean # Clean Tuist build artifacts
The .xcodeproj is not committed. Always run make generate after modifying Project.swift.
Tests
Only the CookedHTML package has tests. There are no app-level tests.
cd Packages/CookedHTML && swift test
Architecture
Dexo is a native iOS Discourse forum client (UIKit, iOS 15+). No SwiftUI.
MVVM with @Observable
- ViewModels use Swift 5.9
@Observablemacro - ViewControllers subclass
ObservableViewController, which drives UI updates via a recursivewithObservationTracking { updateUI() }loop started inviewWillAppear SWIFT_DEFAULT_ACTOR_ISOLATION = MainActorapplies project-wide
Key layers:
dexo/Networking/—DiscourseAPI(one instance per forum, Alamofire-based) +DiscourseRouter(all API routes as enum)dexo/Core/Auth/— Discourse User API Key OAuth flow viaASWebAuthenticationSession+ RSA key pair in Keychaindexo/Database/— GRDBDatabasePoolwith versioned migrations, storesForumInstancerecordsdexo/Core/Settings/—AppSettings(@Observablesingleton) for user preferencesPackages/CookedHTML/— Local Swift package for parsing Discourse-cooked HTML intoBlockNode/InlineNodetrees, withNSAttributedStringrendering support
Topic rendering is fully native — posts go through the UIKit block renderers under dexo/Features/ForumDetail/TopicDetail/NativeContent/ (one renderer per ContentBlock type, all summed into PostNativeCell's content stack). Block heights are precomputed by BlockHeightCalculator so heightForRowAt doesn't fall back to systemLayoutSizeFitting; whenever you change a renderer, mirror the layout math in the calculator's matching case.
Localization
- Source language: English (
en); also supports Simplified Chinese (zh-Hans) - Use
String(localized: "key")for all user-facing strings — never hardcode string literals - Xcode automatically extracts keys into
dexo/Localizable.xcstringsat build time (SWIFT_EMIT_LOC_STRINGS = YES) - Add Chinese translations directly in
Localizable.xcstrings - When adding or modifying user-facing strings, always provide both English and Chinese translations
Theming
- Use
ThemeManager.sharedfor colors (e.g.codeBackgroundColor) — never hardcode colors like.systemBackground - Set theme-dependent colors in display-time methods (
willDisplay(),configure(),updateUI()) rather thaninit, so they respond to runtime theme/color changes
Project Configuration
- Tuist version is pinned in
.mise.toml - Development Team ID goes in
.mise.local.toml(not committed) asTUIST_DEVELOPMENT_TEAM - Dependencies declared in
Tuist/Package.swift: Alamofire, GRDB, SDWebImage, Lightbox