22 KiB
type, title, description, tags, sources, generated, verified
| type | title | description | tags | sources | generated | verified | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| engineering quickstart | Termind Engineering Quickstart | Route Termind changes to architecture owners, connection and data workflows, focused regressions, and safe build and release checks. Source and tests remain authoritative. |
|
|
|
|
Termind Engineering Quickstart
Termind is one Xcode project with native TFM (macOS) and TFI (iPhone/iPad) apps over shared frameworks, plus separate test, widget, and macOS MCP bridge products. Native UI and lifecycle remain app-owned. Start with Engineering Invariants, choose the changed boundary below, then follow its guide to source and behavioral tests.
Find the owner
Architecture and presentation
| Task | Owning guide | Focused starting checks |
|---|---|---|
| Place shared code, change imports or dependency construction | Module and Dependency Map → System Boundaries | ArchitectureBoundaryTests |
| Startup, shared services, backgrounding, termination | Platform Runtime and Lifetimes | AppTerminationTests, WorkspaceCloseConfirmationTests, MobileAppTests, MobileForwardingLifecycleTests |
| Desktop navigation, window commands, workspace ownership | Desktop UI and Window Ownership | Window/navigation and layout regressions |
| Mobile tabs, scene routes, editors, workspace continuity | Mobile UI and Scene Ownership | MobileWorkspaceSessionTests, MobileAdaptiveLayoutTests, MobileNavigationParityTests |
| Shared fields, tokens, accessibility, native presentation contracts | UI Design and Presentation Contracts | Affected platform rendering and ArchitectureBoundaryTests |
| Workspace/pane sorting, merging, drag-out windows, Assistant reordering | Desktop Workspace Drag and Drop | WorkspaceNavigatorDropTests, WorkspaceLayoutDropTests, WorkspaceWindowMoveTests, AssistantConversationListDropTests |
| File drops, Assistant attachments, terminal uploads, remote-file dragging, key import | File Drops and Terminal Uploads | FileURLDropTargetTests, MobileDropTests, then the guide's upload/import suites |
Connections and remote services
| Task | Owning guide | Focused starting checks |
|---|---|---|
| Host entitlement verification, locked-host admission, operation access | Commerce, Localization and Product Surfaces and Remote Services and Forwarding Boundaries | HostAccessTests, HostOperationAdmissionTests, MetricsHostAccessTests |
| LAN discovery, permission handling, MAC lookup, manual/automatic wake | Remote Services and Forwarding Boundaries | LocalNetworkTests, LocalNetworkActionTests, LocalNetworkLifecycleTests |
| SSH/Telnet, routes, credentials, trust, activation and cleanup | Terminal Connection and Session Lifecycle | Connection, authentication, host-key and PTY activation suites; ConnectionJourneyTests |
| Mosh and Eternal Terminal routing, startup and transport recovery | Mosh + Eternal Terminal | ResumableTerminalEngineTests, TerminalTransportTests |
| Remote multiplexer persistence, managed ownership and teardown | Session Persistence | SessionPersistenceTests, MobileTerminalRestorationTests |
| SSH admission/backpressure and multiplexed I/O | SSH Multiplexing and Scheduling | Multiplexer and worker-lifecycle tests |
| Security Key registration, signing, Vault metadata, silent-connection restrictions | SSH Security-Key Authentication | WebAuthnVaultMetadataTests, WebAuthnSSHTests, SSHInteractionPolicyTests |
| Terminal Find, mobile search dismissal, SFTP filtering, retained surfaces | Ghostty Terminal Integration and Mobile UI | TerminalFindControllerTests, MobileTerminalSearchIntegrationTests in TFITests/MobileTerminalSearchTests.swift |
| Ghostty menus, touch selection, fonts/themes, surface identity or dependency APIs | Ghostty Terminal Integration and Ghostty Dependency Maintenance | MobileTerminalUploadMenuTests, TerminalContextMenuTests; review resolved upstream source for package internals |
| Active directory, draft input, command lifecycle and context consumers | Shell Integration and Terminal Context | Context and command-monitor tests |
| Terminal/metrics/Agent service ownership, host-scoped forwarding | Remote Services and Forwarding Boundaries → Port Forwarding Pool and Dispatch | Service/pump/pool tests; native metrics authentication uses MetricsJourneyRenderingTests and MobileMetricsJourneyTests |
| Tailscale groups, login/logout, peer identity, routing and cleanup | Tailscale Integration | Group-editor, identity, integration, cleanup, metrics and sync-safety tests |
| SFTP browsing, transfers, conflict handling, external edits | SFTP Transfers and External Editing | Transfer, channel-lifetime, conflict and edit suites |
Data, Assistant and operations
| Task | Owning guide | Focused starting checks |
|---|---|---|
| SwiftData models, secrets, historical migrations and local recovery | Persistence, Compatibility and Secrets | Historical-store upgrade and reopen tests; HostIconTests, SnippetColorTests, RetiredTerminalHighlightingTests as relevant |
| Settings writes or explicit CloudKit replication | Settings and Cloud Sync → CloudKit Release Readiness | CloudSyncLifecycleTests, CloudSyncSafetyTests, coordinator and record-evolution tests |
| Assistant turns, approvals, host tools, skills and memory | Agent Runtime and Assistant | Preparation, cancellation, persistence, tool and memory regressions |
| MCP server, external transfers or stdio bridge | MCP Server and Bridge | Token, server-session, transfer and bridge tests |
| Commerce, localized app copy, widgets or website | Commerce, Localization and Product Surfaces | RevenueCatCommerceTests, ProPaywallStateTests, feature-access tests, AppLanguageTests and localization checks |
| Capture, framing, app icons, Host artwork | Marketing Assets and App Icons | Quiet plan:true and focused Ruby checks before capture; HostIconTests for runtime artwork |
| Live offers, purchase/restore, store imagery and delivery | Storefront and Commerce Release | RevenueCat, App Store Connect and Sandbox checks plus actual final localized artwork review |
| Build/dependency/release tooling or forwarding measurements | Build, Test and Release; Port Forwarding Benchmarks | Resolved-only native validation or the benchmark's own measurement procedure |
| Choose a deterministic fixture or understand what a test proves | Behavioral Boundaries and Test Fixtures | Narrow behavioral regression first, then affected target suite |
Preserve the changed boundary
These are routing reminders, not substitute specifications.
- Layers:
TermindDomainowns portable rules;TermindApplicationowns ports/use cases;TermindPersistenceexclusively owns SwiftData models, historical schemas and container construction. Infrastructure implements services;TermindPresentationowns reusable content/copy; apps assemble concrete dependencies and native UI.ArchitectureBoundaryTestsuses root-specific import and construction rules, not a blanket ban on every UI symbol. Shared Application cannot import Infrastructure, Persistence or SwiftData. Fix the ownership boundary rather than bypassing its tests. - Runtime owners: app services are shared, desktop workspaces belong to window-local
WindowModels, and mobile navigation/Assistant presentation belongs toMobileSceneModel. Mobile descriptors and live workspaces belong to persistent native UIKit scene sessions, not an interchangeable cross-window pool. DesktopRootViewregisters its window and publishes the focused window value while preserving mounted workspace views across destination changes. - Saved mobile intent is not a live connection: legacy
mobile.workspaces.v1andmobile.recentlyClosed.v2defaults are retired without migration, butmobile.restorableWorkspaces.v1stores scene-keyed saved descriptors. Persistence is not limited to resumable transports or SSH with remote persistence: ordinary saved workspaces also retain connection intent; transient external connections are excluded. Cold launch loads descriptors without creating live connections. Selecting a descriptor publishes one live workspace before connecting; repeated selection reuses it, and links in another scene activate its owner. One-shot commands and initial paths are live construction inputs, not restoration descriptors, so restoration must not replay them. Recently closed records remain process-local. See Mobile UI and Session Lifecycle. - Separate the recovery mechanisms: SSH session persistence uses remote-session references and selection/attachment policy; Mosh/Eternal Terminal use resumable transport checkpoints and their recovery state, not ordinary SSH reconnect. A missing or incompatible checkpoint must not silently bootstrap a replacement shell.
MobileTerminalRestorationTestscovers this distinction, retained terminal identity and cold-launch restoration; shared engine/journey tests cover retry without startup replay. - Scene lifecycle: disconnect/background alone preserves workspace ownership. Native-session reconciliation can transfer live objects without reconnecting; a late explicit discard still targets only the source session's recovered workspaces. Background services pause when all scenes background; expiration suspends workspaces, stops forwards, pauses transfers and expires Assistant work. An active scene resumes eligible services. Follow Platform Runtime.
- Desktop close and quit: live connections alone no longer trigger a window-close or application-wide quit confirmation. Native window vetoes and unsaved terminal-theme protection remain; quit saves theme edits, asks before discarding any still-unsaved theme, then rechecks pending SFTP edits with cancellation before shutdown. Termination fences new Assistant work and drains conversations/preparations before agent resource closure while stopping MCP/transfers. Its three-second fallback bounds the once-only AppKit reply, not asynchronous cleanup completion. Debug tests do not terminate on last-window close; otherwise menu-bar metrics settings and running metrics decide. See Desktop UI and Platform Runtime.
- Connection presentation: shared
ConnectionJourneyowns route progress and authentication/host-key checkpoints;ConnectionJourneyRouteViewdraws the shared route while apps supply native controls. State tests and opt-in native rendering fixtures are not live SSH validation. Mobile terminal search stays on stable chrome, and terminal surfaces remain mounted beneath journey gates. SSH, Mosh, Eternal Terminal and Telnet use workspace-ownedTerminalFindController; SFTP filters bind tosftpChannel.query. - Local and wire compatibility are independent: the live local schema is V58. Use migration/reopen tests rather than hard-coding the latest schema into unrelated tests.
SyncRecordFormatsindependently defines per-kind wire readers/writers: Host writes V8, HostGroup V7, SSHKey V3, Snippet V2, WorkspaceTemplate V2 and Metrics V2. Follow the persistence/sync guides before changing compatibility; a successful build does not prove migration or CloudKit readiness. - Released dependencies, not maintenance trees: AgentKit owns the host-neutral runtime; Termind registers SSH/SFTP tools through
TermindAgentTools. Test and release cross-repository package changes before updating the Xcode requirement andPackage.resolvedtogether. App builds consume remote pins, not sibling or optional maintenance working-tree edits. The current AgentKit requirement isupToNextMinorVersionfrom2.1.0, also the version recorded inTermind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved; libssh2 starts at2.0.3-termind-4under the same rule despite older exact-version guidance. Ghostty comes directly fromLakr233/libghostty-spm, currentlyupToNextMinorVersionfrom2.2.2026101502, with no local Ghostty maintenance submodule. For resolved-build behavior, inspect the project and pin rather than relying on conflicting generic dependency guidance.
Validate narrowly, then validate the product
Use AGENTS.md and Build, Test and Release for full setup and release procedures. Project settings use Swift 6, complete strict concurrency, warnings as errors, approachable concurrency and default MainActor isolation; bridge/benchmark targets use nonisolated isolation. Read the selected target's effective settings rather than treating project defaults as product metadata.
Keep -onlyUsePackageVersionsFromResolvedFile so routine validation cannot silently move the dependency graph:
xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile build
xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile test
xcodebuild -project Termind.xcodeproj -scheme TFI -destination 'generic/platform=iOS Simulator' -onlyUsePackageVersionsFromResolvedFile build
xcrun swift-format lint --strict --recursive Frameworks TFM TFI FrameworkTests TFMTests TFITests TermindMCPBridge
python3 Scripts/check-localization.py
Run mobile tests on an installed simulator. For a focus-changing search regression, replace the destination placeholder locally:
TEST_RUNNER_TERMIND_MOBILE_UI_TESTS=1 xcodebuild -project Termind.xcodeproj -scheme TFI -destination 'platform=iOS Simulator,name=<installed simulator>' -onlyUsePackageVersionsFromResolvedFile -parallel-testing-enabled NO -only-testing:TFITests/MobileTerminalSearchIntegrationTests test
Keep native presentation opt-ins explicit
- macOS tests that present windows or activate the app require
.requiresVisibleWindowandTEST_RUNNER_TERMIND_WINDOW_TESTS=1(orTERMIND_WINDOW_TESTS=1in Xcode), preferably with-only-testing:TFMTests/<Suite>. Debug XCTest launches the real app but suppresses automatic main/external-auth windows by default and disables scene restoration; the visible-window opt-in or screenshot demo lifts window suppression. Keep gates off for routine checks; offscreen logic/layout tests remain enabled. - Mobile key-window suites require
TEST_RUNNER_TERMIND_MOBILE_UI_TESTS=1,-parallel-testing-enabled NOand narrow-only-testing:TFITests/<Suite>filters.MobileAdaptiveLayoutTestsgates native-window cases individually, leaving pure width logic enabled;MobileMetricsJourneyTestsis serialized and suite-level key-window-gated. DesktopMetricsJourneyRenderingTestsis visible-window-gated. These fixtures exercise native presentation and restore temporary windows, not quiet model-only coverage. - Journey screenshot export remains separately opt-in under
TERMIND_JOURNEY_SCREENSHOTS. Check individual suite annotations and the fixture guide, not an assumption that every window-creating test shares one gate.
Copy and external delivery boundaries
App-facing copy belongs in Frameworks/TermindPresentation/Strings and manually maintained catalogs. After catalog edits run Scripts/normalize-string-catalogs.py --write, Scripts/check-appstrings.sh, and python3 Scripts/check-localization.py. The validator checks zh-Hans, zh-Hant, ja, ko, de and fr, including formats, plurals, spacing and canonical formatting; use AppLanguageTests for language behavior. Run localization validation even without intentional copy changes.
The independent com.akinokaede.termind/ website/assets submodule is optional for native builds. Initialize it only for website/asset work, inspect its own source and consumers, and follow the asset guide. Parent guidance calls for a production website build and visual English/Chinese checks; native catalog/commerce tests do not verify external copy, deployed routes or RevenueCat dashboard content. StoreKit/Termind.storekit is a manual development fixture, not proof of live products, trial eligibility or purchase/restore behavior: use the storefront guide for separate live checks.
Before submission, inspect the diff for secrets, generated artifacts, cross-layer imports and accidental Package.resolved churn. The commands above are validation entrypoints, not results: no builds, tests, captures or live integrations were executed during this documentation research.