feat(ios): add direct HLS playback checkpoint - #182
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
🟡 Changes recommended
Cancellation paths can surface as user-visible “unknown” failures because callers only check Task.isCancelled while the runtime can throw CancellationError without cancelling the task, and there’s also a potential public API break via an internal initializer on a public type.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR extends the harness/runtime stack to support a deterministic iOS “files-browser” journey (UI-driven proof capture + attachments + trimmed recording) and introduces a new PutioRuntime API layer (with session generation gating and direct HLS playback resolution) to back both the app and harness flows.
Changes:
- Add
putio-harness journey --platform ios --scenario files-browser, including xcresult attachment extraction and AVFoundation-based recording trimming. - Introduce
PutioRuntime(+ runtime models) and update the iOS app/browser to use it, including system-player video playback and a seeded in-process API for the journey scenario. - Expand snapshot testing from a single scheme to snapshot suites (iOS component + iOS feature + tvOS), and adjust CI to allow
next-rollout/**PR bases.
File summaries
| File | Description |
|---|---|
| Tools/PutioHarness/Tests/PutioHarnessKitTests/ProcessRunnerTests.swift | Adds regression coverage for large stdout/stderr capture and diagnostics preservation. |
| Tools/PutioHarness/Tests/PutioHarnessKitTests/ModelsTests.swift | Adds tests for snapshot suite config and journey contract helpers. |
| Tools/PutioHarness/Tests/PutioHarnessKitTests/JourneyRecordingTests.swift | New tests for journey trimming window selection and capture completion logic. |
| Tools/PutioHarness/Tests/PutioHarnessKitTests/ArgumentParserTests.swift | Adds parser coverage for the new journey command and validations. |
| Tools/PutioHarness/Sources/PutioHarnessKit/SimulatorHarness.swift | Implements journey command, trims recordings, extracts xcresult attachments, and runs snapshot suites. |
| Tools/PutioHarness/Sources/PutioHarnessKit/ProcessRunner.swift | Reworks process output capture to file-backed handles to avoid pipe backpressure. |
| Tools/PutioHarness/Sources/PutioHarnessKit/Models.swift | Adds SnapshotSuite, JourneyScenario, journey contract helpers, and attachment/summary parsing. |
| Tools/PutioHarness/Sources/PutioHarnessKit/HarnessService.swift | Wires the journey invocation into service execution and output selection. |
| Tools/PutioHarness/Sources/PutioHarnessKit/ArgumentParser.swift | Adds CLI usage + parsing for journey and updates test platform gating. |
| Tests/Shared/SnapshotSupport/SnapshotRendering.swift | Adds a shared SwiftUI render helper for app-hosted feature snapshots. |
| Tests/iOSUITests/Sources/FilesBrowserJourneyTests.swift | New XCUITest journey driving the files browser and playback handoff. |
| Tests/iOS/Sources/PutioVideoPlaybackModelTests.swift | New unit tests for playback resolution state machine and retry/cancellation behavior. |
| Tests/iOS/Sources/PutioSystemVideoPlayerCoordinatorTests.swift | New unit tests for coordinator seek/play/failure boundaries and teardown behavior. |
| Tests/iOS/Sources/PutioFolderModelTests.swift | New unit tests for folder loading/refresh generation and error/cancellation behavior. |
| Tests/iOS/Sources/PutioFileRouteTests.swift | New tests for stable folder route identity and route-kind separation. |
| Tests/iOS/Sources/FilesBrowserSeededAPIIntegrationTests.swift | New integration test validating seeded runtime + route mapping. |
| Tests/iOS/Sources/FilesBrowserRenderingTests.swift | New snapshot tests for the browser screen in default and accessibility sizes. |
| Tests/iOS/Sources/BrowserTestFixtures.swift | Adds deterministic fixtures used across browser/playback tests. |
| scripts/legacy-delivery-workflows.test.ts | Tightens Next CI branch trigger expectations for rollout PR bases. |
| Project.swift | Adds iOS audio background mode and introduces PutioFeatureTests + PutioUITests targets; shares snapshot support folders. |
| Packages/PutioCore/Tests/PutioCoreTests/PutioSessionStoreTests.swift | Expands session-store assertions and adds tests for overlapping restore/sign-in flows. |
| Packages/PutioCore/Tests/PutioCoreTests/PutioRuntimeTests.swift | New comprehensive runtime tests (auth gating, mapping, cancellation, and session isolation). |
| Packages/PutioCore/Tests/PutioCoreTests/ComponentKitTests.swift | Extends harness scenario parsing and adds a PutioFileRow disclosure behavior test. |
| Packages/PutioCore/Sources/PutioCore/Session/PutioSessionStore.swift | Adds session generation gating, signing-out state, and snapshots account data for Sendable use. |
| Packages/PutioCore/Sources/PutioCore/Runtime/PutioRuntimeModels.swift | New Sendable runtime model types for account/files/playback. |
| Packages/PutioCore/Sources/PutioCore/Runtime/PutioRuntime.swift | New runtime wrapper enforcing authenticated-operation rules and SDK error classification. |
| Packages/PutioCore/Sources/PutioCore/HarnessScenario.swift | Adds .filesBrowser harness scenario. |
| Packages/PutioCore/Sources/PutioCore/Components/PutioFileRow.swift | Allows optionally hiding folder disclosure when using NavigationLink. |
| Packages/PutioCore/Package.swift | Pins PutioSDK dependency to a specific revision (temporary stack pin). |
| Packages/PutioCore/Package.resolved | Updates resolution to the pinned SDK revision. |
| docs/HARNESS.md | Documents the new journey command and its proof outputs/constraints. |
| CONTRIBUTING.md | Updates harness guidance to include the browser journey for iOS browser changes. |
| Apps/Shared/Sources/PutioRuntimeFactory.swift | Switches factory to construct PutioRuntime (seeded API enabled for signed-in + files-browser). |
| Apps/Shared/Sources/HarnessSeededAPI.swift | Extends seeded fixtures to cover browser surfaces and playback resolution. |
| Apps/iOS/Sources/VideoPlayback.swift | Adds playback model/view and system player coordinator with failure boundaries. |
| Apps/iOS/Sources/PutioApp.swift | Switches app root from session-only to runtime, integrates browser UI + harness capture gates. |
| Apps/iOS/Sources/FilesBrowserView.swift | Adds SwiftUI files browser screens and navigation wiring. |
| Apps/iOS/Sources/FilesBrowserModel.swift | Adds browser models/routes/presentation and folder loading state machine. |
| .github/workflows/ci-next.yml | Allows next-rollout/** PR bases while keeping push restricted to next. |
Review details
Suppressed comments (1)
Packages/PutioCore/Sources/PutioCore/Session/PutioSessionStore.swift:53
PutioSessionStoreis declaredpublic, but its initializer is now internal. If this type is meant to be constructed only viaPutioRuntime, consider making the type internal; otherwise, keep the initializerpublicto avoid an accidental public-API break for module consumers.
public private(set) var state: PutioSessionState = .unknown
private(set) var authenticationGeneration: UInt64 = 0
private let sdk: PutioSDK
private let tokenStore: PutioTokenStore
private let callbackScheme: String
private let callbackHost = "auth"
private var pendingOAuthState: String?
private var pendingOAuthGeneration: UInt64?
init(
sdk: PutioSDK,
tokenStore: PutioTokenStore,
callbackScheme: String = "putio"
) {
self.sdk = sdk
self.tokenStore = tokenStore
self.callbackScheme = callbackScheme
}
- Files reviewed: 39/41 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a40fefd2f1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
cbd4c80 to
0e6dce4
Compare
The direct HLS resolver shipped in putio-sdk-swift 3.5.0, so the temporary branch-head pin can return to a released version.
53d5e18 to
e173cf4
Compare
Summary
PutioRuntimewithout exposing token-bearing values.AVPlayerViewController, honor resume position, and return to the originating folder on dismissal.This delivers the direct-playback checkpoint in #132 under #123. It does not close #132.
Reviewer Guide
Apps/iOS/Sources/VideoPlayback.swift.PutioRuntimeplayback-source boundary, then the coordinator tests and harness trim/capture tests.Visual Aids
a40fefd2f145193985050d01718eb4de358fbc1ddfe63c8d337173626d0e8ae87d5c02757a0c5ed038d9c2ce9a80fa7b851a6a56Validation
mise run verifymise run harness -- journey --platform ios --scenario files-browser --run-id direct-hls-a40fefd --output jsonSanity Checks
AVPlayerItem.statusfailures are delivered once and remain retryable.play()after failure.Benchmarks
N/A. This checkpoint changes behavior and proof coverage, not a performance-sensitive path.
Notes
Conversion, progress reporting, next-video/autoplay, offline playback, and full subtitle parity remain in #132. Search, sorting, pagination, downloads, tvOS/watchOS feature work, and
PutioNightlyremain out of scope.@putdotio/designstays pinned to3.0.0.