Files
Termind/openwiki/quickstart.md
T
2026-09-27 11:38:10 +08:00

16 KiB

type, title, description, tags, verified, sources, generated
type title description tags verified sources generated
engineering quickstart Termind Engineering Quickstart Task-oriented routes to Termind's owning layer, startup and shutdown lifetimes, focused tests, and build gates.
engineering
architecture
routing
testing
macos
ios
by at
openwiki/0.5.2 2026-09-26T22:20:04.073Z
id resource
openwiki-source-8037e2358a2c4f9b2c722a11 repo://AGENTS.md
id resource
openwiki-source-d2d4c06f734241db3badc1f5 repo://Frameworks/TermindRemoteInfrastructure/Agent/TermindAgentTools.swift
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-c8d832474c03f5ebad7b0578 repo://TFI/App/MobileRootView.swift
id resource
openwiki-source-e43a0da5ab77c2fc3554244d repo://TFI/App/MobileSceneModel.swift
id resource
openwiki-source-5b8c72c5373a41af34fa9fd4 repo://TFI/App/MobileStartupView.swift
id resource
openwiki-source-c1f5a86747a33d4e8472672c repo://TFI/App/MobileWorkspaceSessionModel.swift
id resource
openwiki-source-6c9f797fc6a1e7ce639b72b8 repo://TFI/App/TermindIOSApp.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-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-73c75477db0674192248aa00 repo://TFMTests/AppTerminationTests.swift
id resource
openwiki-source-d3d065330c730839f5cc6112 repo://TFMTests/ArchitectureBoundaryTests.swift
id resource
openwiki-source-0dd012e3740bcc348fc36ccb repo://TFMTests/StoreKitTrialTests.swift
id resource
openwiki-source-a08489338be00125d646c77e repo://TFMTests/VisibleWindowTestTrait.swift
by at
openwiki/0.5.2 2026-09-26T22:20:04.073Z

Termind Engineering Quickstart

Termind is one Xcode project with native TFM (macOS) and TFI (iPhone/iPad) products over shared frameworks; platform UI and lifecycle remain app-owned. Source and tests are authoritative. Before changing an ownership boundary, read Cross-Cutting Engineering Invariants and the narrowest topic page below.

Find the owner

Change Route and focused check
Module placement, imports, nested directories, or shared resources Module and Product Map, Dependency and Ownership Boundaries, Shared Framework Responsibilities, Native App Responsibilities, and Supporting Products and Tooling; run ArchitectureBoundaryTests for dependency changes.
Composition, startup failure, window/scene state, backgrounding, quit Platform Composition and Lifetimes; use AppTerminationTests, MobileAppTests, MobileWorkspaceSessionTests, or MobileForwardingLifecycleTests for the changed lifetime.
Desktop Navigator, sidebar, workspaces, Vault, Assistant layout macOS UI and Workspace Ownership; target window/navigation or layout tests.
Desktop Workspace/Pane sorting, merging, drag-out new windows, or Assistant list reordering TFM Drag and Drop; preserve the native Workspace List source and live receiver contracts. Use WorkspaceNavigatorDropTests, WorkspaceLayoutDropTests, WorkspaceWindowMoveTests or AssistantConversationListDropTests, plus the source/cancellation/animation suites listed in that guide.
File-drop events, Assistant attachments, SSH terminal/SFTP uploads, desktop remote-file dragging or Key import File Drag and Drop Across TFM and TFI; trace native routing, payload priority, provider staging and transfer lifetimes. Use FileURLDropTargetTests, MobileDropTests, upload/attachment/import suites listed there; the guide also locates the shared Overlay UI.
Mobile tabs, scene routes, cards, editors, terminal continuity iOS and iPadOS UI and Scene Ownership; use MobileWorkspaceSessionTests for window-owned connection/routing changes, MobileAdaptiveLayoutTests or MobileNavigationParityTests for UI changes.
Shared UI conventions, fields, tokens, accessibility UI Design and Shared Presentation; check platform renderings and ArchitectureBoundaryTests.
SSH/Telnet, credentials, routes, host-key trust, session cleanup SSH, Telnet, Trust, and Workspace Session Lifecycle; run connection, trust, authentication, and session tests. For channel admission and backpressure see SSH Multiplexing and I/O Scheduling.
Terminal, metrics, forwards, shell hooks or forwarding pools Remote Services and Forwarding, Shell Integration, Port Forwarding Dispatch; choose the matching service or pump tests.
SFTP browsing, transfer scheduling, external edit SFTP Transfer, Scheduling, and External Edit Workflow; select the transfer, conflict, or edit suite.
Assistant turns, approvals, host tools, skills, memory Assistant and Agent Runtime; target preparation, cancellation, persistence, tools, or memory tests.
SwiftData, secrets, migrations, CloudKit, settings Persistent Data, Migrations, and Secrets, Settings, Vault, Metrics, History, Device, and Cloud Sync, and CloudKit Release Readiness; select repository, migration, or sync lifecycle tests.
MCP server, external upload/download, bridge MCP Server, Transfers, and Stdio Bridge; run token, server-session, transfer, or bridge tests.
StoreKit, localized copy, widgets, screenshots, website Commerce, Localization, and Product Surfaces, Storefront Commerce Release Checks, Marketing Assets and App Icons, and Build, Test, and Release; use localization, app, screenshot, StoreKit, or website checks as appropriate.
Picking a deterministic test seam Behavioral Tests and Fixtures; run the narrow behavioral test before the affected target suite.

Lifetime and change boundaries

TermindDomain defines portable rules; TermindApplication owns ports and use cases; TermindPersistence owns SwiftData models, repositories and container construction; infrastructure implements services; TermindPresentation owns reusable SwiftUI content and copy; apps assemble concrete dependencies and native UI. ArchitectureBoundaryTests checks specific forbidden imports per root, not an all-UI-framework ban: its five-framework rule excludes Presentation and rejects app targets plus AppKit, UIKit, IOKit and ServiceManagement; the separate Presentation rule allows SwiftUI but rejects app targets, AppKit/UIKit, storage, concrete infrastructure and StoreKit. Shared Application cannot import Infrastructure, Persistence or SwiftData; desktop Application/Features and mobile layers have their own checks. The tests also guard concrete constructions in selected feature/application roots, AgentKit type duplication and SwiftData ownership. Fix an ownership violation rather than bypassing the test; see Dependency and Ownership Boundaries for the precise scope.

TermindApp makes the macOS container and shared AppModel at launch; XCTest and debug screenshot demos use in-memory stores. If the local database cannot open, startup fails rather than replacing it with an empty store. Each main WindowGroup instance gets its own WindowModel for selection and workspaces while app services are shared; RootView registers the window, installs its focused scene value and keeps mounted workspace views when switching destinations. The separate external-authentication Window shares the app environment, but removes its manual Window-menu command; it is not another main workspace. TermindIOSApp migrates language preferences and creates one live or testing MobileAppModel; MobileStartupView injects its container on success and shows unavailable data on failure. MobileBoundSceneRoot constructs a MobileSceneModel for each persistent UIKit session; the scene owns navigation and an Assistant presentation model, while its MobileWorkspaceSessionModel owns that window's live workspaces and saved descriptors. The app model aggregates shared services and sessions, not one interchangeable workspace pool across windows. Cold launch consolidates saved descriptors into the first bound session without connecting; selecting one publishes its workspace in that owner's session before connecting. A link received in another window activates the owner rather than making another connection. If a native session truly disappears, reconciliation can transfer its live workspace to an active session without reconnecting; explicit discard closes the affected workspace. Do not persist transports, secrets, one-shot commands or initial paths in descriptors. Desktop session/pane and mobile workspace owners end their own connection-history entries on close. See iOS and iPadOS UI and Scene Ownership and SSH, Telnet, Trust, and Workspace Session Lifecycle.

In Debug XCTest runs, the real desktop app still launches. By default it suppresses automatic launch of the main and external-auth scenes and disables main-scene restoration; an explicit TERMIND_WINDOW_TESTS=1 lifts suppression, as does an active screenshot demo. This host-level safeguard complements, rather than replaces, .requiresVisibleWindow on any test that presents a window or takes focus. Screenshot demos also disable main-scene restoration. See Behavioral Tests and Fixtures and Build, Test, and Release.

Mobile phase changes are aggregated across scenes: background work is paused when all registered scenes are backgrounded; the expiration handler suspends workspaces, stops forwards, pauses transfers, and expires Assistant work. An active scene resumes monitoring, memory, workspaces, eligible sync, and metrics. On macOS, closing the last window does not always quit: during tests it never terminates the test host; otherwise the menu-bar metrics preference and running metrics decide. Quit first rechecks unuploaded SFTP edits and can be cancelled; confirmed termination fences new Assistant runs, drains cancellation/persistence, stops transfers and MCP, then closes agent resources. The delegate replies to AppKit only once, after cleanup or a three-second fallback. Use Platform Runtime for the full sequence and ownership rules.

AgentKit is a separately versioned, host-neutral remote package for the agent loop, approvals, providers, MCP client and built-in tools; Termind owns SSH/SFTP tools and registers them additively. The Xcode project currently requires AgentKit 0.15.2 or later within the next major version; Package.resolved pins 0.15.2 at revision 4540847d4762f9040be7a8bab4cadd82e494c36d. For a cross-repository change, test and release ../AgentKit, then update minimumVersion in Termind.xcodeproj/project.pbxproj and re-resolve Termind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved; the sibling working tree does not affect Xcode's resolved build. Keep metadata in persistence and secret values behind Keychain references. Follow Dependency and Ownership Boundaries for imports and Build, Test, and Release for release steps.

Focused validation

Run the nearest behavioral regression first, then the relevant product suite. Always keep -onlyUsePackageVersionsFromResolvedFile so ordinary builds do not silently move the resolved 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
Scripts/check-zh-localization.sh

For TFI tests use an installed iPhone/iPad simulator. Visible-window macOS suites require .requiresVisibleWindow and explicit TEST_RUNNER_TERMIND_WINDOW_TESTS=1 (or TERMIND_WINDOW_TESTS=1 in the Xcode test action), preferably with -only-testing:TFMTests/<Suite>; the opt-in enables both the test and automatic app-host windows. Opt-in mobile key-window suites require TEST_RUNNER_TERMIND_MOBILE_UI_TESTS=1, -parallel-testing-enabled NO, and a narrow -only-testing:TFITests/<Suite>; MobileAdaptiveLayoutTests is serialized but not gated by that variable. StoreKit suites require manual authorization and TERMIND_STOREKIT_TESTS=1. Keep these gates off for routine checks; offscreen tests remain enabled. Define app copy via shared TermindPresentation/Strings resources; new app text needs completed zh-Hans and zh-Hant translations in Frameworks/Resources/Localizable.xcstrings. Shared catalogs are manually managed: after catalog edits run Scripts/normalize-string-catalogs.py --write, then Scripts/check-appstrings.sh and Scripts/check-zh-localization.sh (requires jq); run the Chinese check even without intended copy changes, and AppLanguageTests for language behavior. For web changes run cd LandingPage && npm ci && npm run build and check English and /zh/ routes.

Before submitting, inspect the diff for secrets, generated artifacts, cross-layer imports and accidental Package.resolved churn; use the routed operations pages for CloudKit deployment, StoreKit release, marketing assets, and forwarding benchmark measurement semantics.