Files
web-terminal/ios/project.yml
Yaojia Wang 4871e8ac3d feat(ios): P1-A — server touch-points (lastOutputAt, APNs sender+token endpoint) + APIClient P1 contract
T-iOS-37: LiveSessionInfo.lastOutputAt additive-optional field + manager.list() mapping (+4 tests; web consumers unaffected)
T-iOS-20: src/push/apns.ts — env-gated (all-or-disabled, no crash, zero key-material logging), hand-rolled ES256 JWT
(node:crypto ieee-p1363, zero new deps), NEEDS-INPUT/DONE payloads with structural minimization, token store per
subscription-store conventions, combineNotifyServices parallel to web-push, POST/DELETE /push/apns-token per frozen
wire shape (G-guard, 5/min/IP, 8kb); 65 tests incl. dual-channel e2e vs local fake APNs
T-iOS-38: APIClient builders — apns-token (client-side hex mirror, pre-network reject), projects/detail (lossy decode,
single-point percent-encoding), prefs (unknown-key byte-exact round-trip preservation), public four-tier HostNetworkTier
Coordination: webterminal:// CFBundleURLTypes pre-registered in project.yml for T-iOS-22
Verified: root 1470 tests + tsc clean; APIClient 76 tests, 95.26% coverage; wire-shape cross-check zero mismatches
2026-07-05 13:34:01 +02:00

160 lines
5.8 KiB
YAML

# XcodeGen project spec — regenerate with: cd ios && xcodegen generate
# The generated WebTerm.xcodeproj is NOT committed (see ios/.gitignore).
#
# TOOLCHAIN DEVIATION (recorded per plan §7 T-iOS-1): the plan names
# "default MainActor isolation" (SWIFT_DEFAULT_ACTOR_ISOLATION), which is
# Swift 6.2+/Xcode 26 only. On Swift 6.1 / Xcode 16.3 the closest supported
# equivalent is Swift 6 language mode + strict concurrency, with explicit
# @MainActor annotations where isolation is required.
name: WebTerm
options:
bundleIdPrefix: com.yaojia
deploymentTarget:
iOS: "17.0"
createIntermediateGroups: true
settings:
base:
SWIFT_VERSION: "6.0" # Swift 6 language mode
SWIFT_STRICT_CONCURRENCY: complete
IPHONEOS_DEPLOYMENT_TARGET: "17.0"
TARGETED_DEVICE_FAMILY: "1" # iPhone only (iPad layout is out of v1 scope)
CODE_SIGN_STYLE: Automatic
packages:
WireProtocol:
path: Packages/WireProtocol
SessionCore:
path: Packages/SessionCore
HostRegistry:
path: Packages/HostRegistry
APIClient:
path: Packages/APIClient
TestSupport:
path: Packages/TestSupport # test doubles — WebTermTests only, never the app target
# SwiftTerm is the ONLY third-party dependency, attached to the App target
# ONLY (plan §2) — packages must never import it.
SwiftTerm:
url: https://github.com/migueldeicaza/SwiftTerm
from: 1.13.0
targets:
WebTerm:
type: application
platform: iOS
sources:
- App/WebTerm
dependencies:
- package: WireProtocol
- package: SessionCore
- package: HostRegistry
- package: APIClient
- package: SwiftTerm
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.yaojia.webterm
# Target-level on purpose (T-iOS-19 finding): XcodeGen's target platform
# default ("1,2") overrides a project-level value, shipping an
# installable-but-untested iPad layout. Target-level wins.
TARGETED_DEVICE_FAMILY: "1"
info:
path: App/WebTerm/Resources/Info.plist
properties:
CFBundleDisplayName: WebTerm
UILaunchScreen: {}
# Deep-link scheme (P1 T-iOS-22): webterminal://open?host=<id>&join=<uuid>
# Registered here by the orchestrator (project.yml coordination point);
# all parsing/validation lives in DeepLinkRouter (untrusted input).
CFBundleURLTypes:
- CFBundleURLName: com.yaojia.webterm.deeplink
CFBundleURLSchemes: [webterminal]
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
# ── Security-critical keys, transcribed verbatim from PLAN_IOS_CLIENT §5.2 ──
# NO NSAllowsArbitraryLoads anywhere (release OR debug): the five CIDR
# exceptions below cover LAN + hotspot + Tailscale CGNAT + simulator
# loopback, so no arbitrary-loads escape hatch is needed in P0.
# T-iOS-19 re-verifies all five CIDR blocks in the release ipa.
NSAppTransportSecurity:
NSAllowsLocalNetworking: true # only covers .local / dotless hostnames, not bare IPs
NSExceptionDomains: # bare IPs use CIDR exceptions (iOS 17+ semantics)
"192.168.0.0/16":
NSExceptionAllowsInsecureHTTPLoads: true
"10.0.0.0/8":
NSExceptionAllowsInsecureHTTPLoads: true
"172.16.0.0/12": # RFC1918 third block (iPhone hotspot 172.20.10.x / corp LAN)
NSExceptionAllowsInsecureHTTPLoads: true
"100.64.0.0/10": # Tailscale CGNAT
NSExceptionAllowsInsecureHTTPLoads: true
"127.0.0.0/8": # simulator dev-loop (CIDR, not a single-IP key — DevForums 6205)
NSExceptionAllowsInsecureHTTPLoads: true
NSLocalNetworkUsageDescription: "连接你自己电脑上的 web-terminal 服务器"
NSCameraUsageDescription: "扫描 web 终端的配对二维码"
# Unit-test bundle for App-target logic (ViewModels & pure UI components,
# W3 T-iOS-11…14). Added by the orchestrator as a coordination point
# (project.yml is T-iOS-1's Owns; same precedent as the W1 manifest wiring).
# Coverage GATE still counts only the 4 packages (plan §9) — these tests
# exist for correctness, not for the gate.
WebTermTests:
type: bundle.unit-test
platform: iOS
sources:
- App/WebTermTests
dependencies:
- target: WebTerm
- package: WireProtocol
- package: SessionCore
- package: HostRegistry
- package: APIClient
- package: TestSupport
settings:
base:
GENERATE_INFOPLIST_FILE: true
TARGETED_DEVICE_FAMILY: "1"
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/WebTerm.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/WebTerm"
BUNDLE_LOADER: "$(TEST_HOST)"
# XCUITest — exactly ONE scripted happy path per plan §9 (T-iOS-18 finding):
# pair via manual entry against a live loopback server → attach → type →
# approve a held gate. Kept deliberately minimal (fragile-surface rule).
WebTermUITests:
type: bundle.ui-testing
platform: iOS
sources:
- App/WebTermUITests
dependencies:
- target: WebTerm
settings:
base:
GENERATE_INFOPLIST_FILE: true
TARGETED_DEVICE_FAMILY: "1"
TEST_TARGET_NAME: WebTerm
schemes:
WebTerm:
build:
targets:
WebTerm: all
WebTermTests: [test]
run:
config: Debug
test:
config: Debug
targets:
- WebTermTests
# Separate scheme so the slow UI pass never gates the fast unit loop; CI
# runs it as its own leg (see .github/workflows/ios.yml).
WebTermUITests:
build:
targets:
WebTerm: all
WebTermUITests: [test]
test:
config: Debug
targets:
- WebTermUITests