Let pages in the page view load their local files

This commit is contained in:
Ian Gulliver
2026-10-23 05:44:19 -07:00
parent dfb114ea64
commit d391b41bf6
5 changed files with 510 additions and 472 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ Every build is signed for distribution outside the App Store: the team's Develop
- The transcript is a plain `VStack` in a `ScrollView`, not lazy: a `LazyVStack` estimates the height of rows it hasn't shown yet and corrects it when they scroll into view, without moving the scroll offset, so scrolling up through rows not yet shown jumped by each correction; SwiftUI can't move the offset mid-scroll without stopping its momentum.
- The terminal cursor is a steady block: SwiftTerm's blinking cursor restarts its Core Animation fade on every keypress, scheduled 0.7 s out, and on a ProMotion display macOS then holds the window's screen update until that fade starts, so each typed letter appears about 0.7 s late. SwiftTerm redraws the whole screen whenever a terminal color is set, even when its value hasn't changed.
- The Page view loads a worktree page from a plain-HTTP server the app runs on a loopback port (`http://127.0.0.1:<port>/<task id>/<path>`), which fetches each file through the server's `getTaskRaw` endpoint. The page's relative links to its stylesheets, scripts and images resolve to files beside it, and "↗ Browser" opens the same address. Previews load from their loopback forwards at `<name>-<task>.localhost`. App Transport Security blocks plain HTTP to `*.localhost` even with `NSAllowsLocalNetworking`; the `localhost` exception domain with subdomains in `Info.plist` allows it (loopback IP addresses need no exception). `NSAllowsArbitraryLoadsInWebContent` lets the Page view load plain-HTTP websites without lifting ATS for the app's own requests.
- The Page view loads a page file from a plain-HTTP server the app runs on a loopback port, at the file's absolute path on the server (`http://127.0.0.1:<port>/<absolute path>`), which fetches each file through the server's `getRaw` endpoint. So a page's relative and absolute references to its stylesheets, scripts and images both resolve to files on the server, and the app turns `file://` references in the HTML and stylesheets it serves into plain absolute paths, since WebKit won't load `file://` into an http page. "↗ Browser" opens the same address. iOS reclaims the listening socket while the app is suspended, so the app binds it again on the same port each time it returns to the foreground. Previews load from their loopback forwards at `<name>-<task>.localhost`. App Transport Security blocks plain HTTP to `*.localhost` even with `NSAllowsLocalNetworking`; the `localhost` exception domain with subdomains in `Info.plist` allows it (loopback IP addresses need no exception). `NSAllowsArbitraryLoadsInWebContent` lets the Page view load plain-HTTP websites without lifting ATS for the app's own requests.
- Each Page view tab's `WKWebView` belongs to `Pages`, not to the SwiftUI view, so it keeps its page while the sheet is closed and agents can drive it with `drive_page` (navigate, JavaScript, capture) from the client connection. All tabs share WebKit's default persistent data store, so a site the human signs into stays signed in across launches. A link that opens a new window becomes a new tab of the same task. Capture refuses a tab that isn't on screen (sheet closed, or another tab showing), since its snapshot would show nothing the human sees. Passkey sign-in may fail, because WebKit allows WebAuthn in an embedded view only for apps with Apple's web browser entitlement; a password with a 2FA code works.
## Updates