Files
2026-10-19 12:41:32 +08:00

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.
engineering
architecture
routing
testing
macos
ios
id resource
openwiki-source-ed77bc20b48d193bace3dde6 repo://.gitmodules
id resource
openwiki-source-8037e2358a2c4f9b2c722a11 repo://AGENTS.md
id resource
openwiki-source-1635d0be12e44ef9134ffabc repo://Frameworks/TermindApplication/Connections/ConnectionJourney.swift
id resource
openwiki-source-e08ad235d9d92a20cf09290b repo://Frameworks/TermindDomain/Vault/SyncRecordFormats.swift
id resource
openwiki-source-7a9c6d90cba4ebd1d1398673 repo://Frameworks/TermindPersistence/TermindPersistence.swift
id resource
openwiki-source-131881b779429a1d1d605e52 repo://Frameworks/TermindPresentation/ConnectionJourneyRouteView.swift
id resource
openwiki-source-d2d4c06f734241db3badc1f5 repo://Frameworks/TermindRemoteInfrastructure/Agent/TermindAgentTools.swift
id resource
openwiki-source-b41ffbd407a598b50512e10b repo://FrameworkTests/HostIconTests.swift
id resource
openwiki-source-db40aa993661b07f1a9aff6d repo://FrameworkTests/SSHInteractionPolicyTests.swift
id resource
openwiki-source-eaed8c88a9a3f24e3feb1f9c repo://FrameworkTests/WebAuthnVaultMetadataTests.swift
id resource
openwiki-source-d125bef219ce9eee56abf917 repo://Scripts/check-localization.py
id resource
openwiki-source-cd0be716a2446029f345525a repo://Termind.xcodeproj/project.pbxproj
id resource
openwiki-source-105d05d558f14996921a83f6 repo://Termind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
id resource
openwiki-source-906678adb91c2fce2d3fcaed repo://TFI/App/MobileAppModel.swift
id resource
openwiki-source-e43a0da5ab77c2fc3554244d repo://TFI/App/MobileSceneModel.swift
id resource
openwiki-source-c1f5a86747a33d4e8472672c repo://TFI/App/MobileWorkspaceSessionModel.swift
id resource
openwiki-source-f7aa24af0100c1767226879a repo://TFI/Features/Workspaces/MobileWorkspaceSearchModifier.swift
id resource
openwiki-source-4c2de67bfdb2238d765a642a repo://TFI/Features/Workspaces/MobileWorkspaceView.swift
id resource
openwiki-source-350d4a794cfef67e406ddf9b repo://TFI/Infrastructure/MobileWorkspaceStore.swift
id resource
openwiki-source-707053bb7defcfbf9343584b repo://TFI/UI/Components/MobileConnectionJourneyView.swift
id resource
openwiki-source-5147eea728b12cb304c33011 repo://TFITests/KeyWindowTestTrait.swift
id resource
openwiki-source-fffc181d864b6caea779a6f5 repo://TFITests/MobileAdaptiveLayoutTests.swift
id resource
openwiki-source-b822b041afbf829d09a8555a repo://TFITests/MobileAppTests.swift
id resource
openwiki-source-7341d7b266d976d7aac5d161 repo://TFITests/MobileEditorToolbarTests.swift
id resource
openwiki-source-2c7245a9a1462a5a8d09b739 repo://TFITests/MobileMetricsJourneyTests.swift
id resource
openwiki-source-28243bbeecc381626d39eeb6 repo://TFITests/MobileTerminalRestorationTests.swift
id resource
openwiki-source-b360f8803ec98b554faad9bb repo://TFITests/MobileWorkspaceSessionTests.swift
id resource
openwiki-source-4dbea0ff2808163cb4ecdd8f repo://TFM/App/AppModel.swift
id resource
openwiki-source-873894299539cce9a737a860 repo://TFM/App/RootView.swift
id resource
openwiki-source-6570374eaac2e0278fa84640 repo://TFM/App/TermindApp.swift
id resource
openwiki-source-dad03c68d6b805a4170ffc02 repo://TFM/Platform/WorkspaceCloseConfirmation.swift
id resource
openwiki-source-dc041600497a72c229d5eef4 repo://TFM/UI/Components/ConnectionJourneyView.swift
id resource
openwiki-source-73c75477db0674192248aa00 repo://TFMTests/AppTerminationTests.swift
id resource
openwiki-source-d3d065330c730839f5cc6112 repo://TFMTests/ArchitectureBoundaryTests.swift
id resource
openwiki-source-85c3f954351f96433cb1fb4b repo://TFMTests/ConnectionJourneyTests.swift
id resource
openwiki-source-c7d015a20982da4e8b0599d1 repo://TFMTests/MetricsJourneyRenderingTests.swift
id resource
openwiki-source-a08489338be00125d646c77e repo://TFMTests/VisibleWindowTestTrait.swift
id resource
openwiki-source-402244fee941f965f41388e4 repo://TFMTests/WebAuthnSSHTests.swift
id resource
openwiki-source-d798805795e92534f3b13250 repo://TFMTests/WorkspaceCloseConfirmationTests.swift
by at
pi 2026-10-19T04:32:02.799Z
by at
openwiki/0.7.2 2026-10-19T04:32:02.799Z

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 Build, Test, and Release 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: TermindDomain owns portable rules; TermindApplication owns ports/use cases; TermindPersistence exclusively owns SwiftData models, historical schemas and container construction. Infrastructure implements services; TermindPresentation owns reusable content/copy; apps assemble concrete dependencies and native UI. ArchitectureBoundaryTests uses 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 to MobileSceneModel. Mobile descriptors and live workspaces belong to persistent native UIKit scene sessions, not an interchangeable cross-window pool. Desktop RootView registers 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.v1 and mobile.recentlyClosed.v2 defaults are retired without migration, but mobile.restorableWorkspaces.v1 stores 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. MobileTerminalRestorationTests covers 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 ConnectionJourney owns route progress and authentication/host-key checkpoints; ConnectionJourneyRouteView draws the shared route while apps supply native controls. ConnectionJourneyTests checks shared state; MobileMetricsJourneyTests checks native authentication presentation with a test sampler rather than live SSH. These checks 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-owned TerminalFindController; SFTP filters bind to sftpChannel.query.
  • Local and wire compatibility are independent: the live local schema is V59. Use migration/reopen tests rather than hard-coding the latest schema into unrelated tests. SyncRecordFormats independently 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 remote dependencies: AgentKit owns the host-neutral runtime; Termind registers SSH/SFTP tools through TermindAgentTools. Keep the Xcode requirement and Package.resolved aligned when adopting package releases. AgentKit, libssh2-spm and libtailscale-spm are remote SPM dependencies, not maintenance submodules; there is no dependency gitlink to update or initialize. App builds consume remote pins, not sibling working-tree edits. The current AgentKit requirement is upToNextMinorVersion from 4.0.0, also the resolved version; libssh2 starts at 2.0.3-termind-4 under the same rule. Ghostty comes directly from Lakr233/libghostty-spm, currently upToNextMinorVersion from 2.2.2026101502, with no local Ghostty maintenance submodule. AGENTS.md describes Ghostty as up-to-next-major, but the actual project requirement is up-to-next-minor: inspect the project and resolved pins for build behavior.

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 .requiresVisibleWindow and TEST_RUNNER_TERMIND_WINDOW_TESTS=1 (or TERMIND_WINDOW_TESTS=1 in 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 NO and narrow -only-testing:TFITests/<Suite> filters. MobileAdaptiveLayoutTests gates native-window cases individually, leaving pure width logic enabled; MobileMetricsJourneyTests is serialized and suite-level key-window-gated. Desktop MetricsJourneyRenderingTests is 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.