feat(fleet): integrate device auth, enrollment, and live runner management - #320
Merged
Conversation
Add a FleetControlClient Swift package with generated protobuf and gRPC stubs for the fleet agent local control API. Wire the local package into the ArcBox app target so phase 1 desktop integration can import the generated client types.
Wrap the generated fleet control stubs in a high-level client for lifecycle, state watch, and settings RPCs. Map proto responses into desktop-facing models while preserving optional settings update presence semantics, and cover the mapping behavior with tests.
Add the local fleet control client to SwiftUI environment values and app scene injection. Start the fleet control transport outside daemon startup, log through the fleet category, and close it during app termination.
Drive fleet agent state from the local control watch stream. Add lifecycle actions, settings updates, reconnect backoff, and user-readable error handling for the runners dashboard.
Consume the signed-in OIDC session to list Platform workspaces and issue workspace-scoped Fleet enrollment tokens. Wire token issuance into local Fleet Agent enrollment and configure the Platform endpoint for app and CI builds.
Replace RUN-9 sample data and stub actions with FleetViewModel watch snapshots, workspace enrollment, and local drain/resume controls. Expose the runner section in release builds and cover the presentation-state mapping.
Let ArcBoxTests consume FleetControlClient through the hosted ArcBox target, avoiding Xcode’s duplicate dynamic gRPC package graph. Handle runner item-selection deep links explicitly so navigation remains exhaustive.
- coordinate authenticated token handoff with local Agent state - keep Fleet watch and client transport app-scoped - reconcile unknown outcomes and graceful termination
On macOS 26, any state change inside a fixedSize(vertical: true) subtree triggers a window-sizing pass that resizes the window — or the NavigationSplitView content when the window cannot grow — to the screen's visible-frame height, sliding the sidebar under the title bar and pushing the account button off-screen. Drop the modifier from the dynamic error label (it wraps identically without it) and document the pitfall in AGENTS.md.
Replace the OIDC Authorization Code + PKCE flow with the Better Auth device-authorization grant: request a device code, open the approval page in the default browser, and poll the token endpoint per RFC 8628. The polled access token is an opaque Better Auth session token with a sliding server-side expiry, sent as the platform API bearer — the token the platform actually accepts, unblocking fleet enrollment token issuance. Identity now comes from the provider session endpoint instead of OIDC userinfo/ID-token claims, and sign-out revokes the session server-side. The Keychain store self-heals by clearing pre-device-flow token blobs. PKCE, discovery, code exchange, token refresh, and the custom-scheme OAuth callback (including its DeepLinkRouter leg) are gone; build configuration keys are unchanged. The Account pane and runner section show the confirmation code with reopen-browser and cancel affordances while approval is pending.
KafuChino123
force-pushed
the
feat/abxd-99-device-auth
branch
from
July 24, 2026 08:46
c3f4c5a to
97e5cde
Compare
📝 WalkthroughWalkthroughThis change replaces browser-based OIDC authentication with Better Auth device authorization and adds Fleet platform/local-agent clients, enrollment orchestration, runner monitoring, VM image preparation, Fleet settings, application wiring, and associated tests. ChangesFleet authentication and runner integration
Estimated code review effort: 5 (Critical) | ~120 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
KafuChino123
marked this pull request as ready for review
July 24, 2026 09:05
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
Prevent concurrent device sign-in tasks, expose recovery for terminal Fleet states, and complete the test-target and cancellation cleanup validated by the full app suite.
…hots Credential-rejected and detached snapshots ignored loadState, so a disconnected watch still offered the unenroll recovery action against a stale snapshot. Extract the unenrolled branch's loadState switch into connectivityOverride and reuse it for all three terminal cases.
…-auth # Conflicts: # ArcBox.xcodeproj/project.pbxproj # ArcBox/App/AppDelegate.swift # ArcBox/App/DeepLinkRouter.swift # ArcBox/ArcBoxApp.swift # ArcBox/Info.plist # ArcBox/Models/NavItem.swift # ArcBox/Views/Settings/AccountSettingsView.swift # ArcBox/Views/Settings/SettingsView.swift # ArcBox/Views/SidebarAccountButton.swift # Packages/ArcBoxAuth/Sources/ArcBoxAuth/Session/AuthSession+SignIn.swift # Packages/ArcBoxAuth/Tests/ArcBoxAuthTests/AuthSessionTests.swift
KafuChino123
added a commit
that referenced
this pull request
Aug 12, 2026
The 1.35.0 release PR merged with an empty `### Highlights` section, so `cargo xtask release notes` now fails on every PR against master. That step runs before Lint, Build and Test, so no PR gets as far as compiling. The release DMG extracts the same section to feed Sparkle's update dialog and refuses to build without it, so 1.35.0 cannot be packaged either. Write the section from what 1.35.0 actually shipped: the Fleet device auth, enrollment and runner management in #320, the authoritative sandbox port reconciliation in #374, and the telemetry identification and Privacy toggle ordering in #367.
AprilNEA
pushed a commit
that referenced
this pull request
Aug 12, 2026
* fix(ui): slide the detail tab indicator instead of morphing glass The detail tab bar played an exaggerated stretch on every tab switch, worst on the four-tab container view, and the first switch after a cold launch was worse still. GlassEffectContainer's spacing is a blend threshold, not a layout gap: the higher it is, the sooner shapes start merging as they approach. It was set to tabCount * detailTabSegment -- 320pt for containers, 480pt for sandboxes -- against an HStack spacing of 2pt, so the blend field spanned the whole bar. Apple documents that a container spacing larger than the interior stack's spacing blends the effects together at rest. The indicator also toggled glassEffect between .regular and .identity per segment under one shared glassEffectID. That ID stays constant while the segment beneath it changes, which is the documented trigger for GlassEffectTransition.matchedGeometry to apply "additional scale and offset effects to content" -- on top of the oversized blend. Render one persistent glass capsule instead and position it with matchedGeometryEffect against the selected segment. The pill now moves rather than appearing and disappearing, so there is no morph to overshoot and no appearance transition to misfire on first mount. GlassEffectContainer is no longer needed for a single effect. * chore(release): curate the 1.35.0 highlights The 1.35.0 release PR merged with an empty `### Highlights` section, so `cargo xtask release notes` now fails on every PR against master. That step runs before Lint, Build and Test, so no PR gets as far as compiling. The release DMG extracts the same section to feed Sparkle's update dialog and refuses to build without it, so 1.35.0 cannot be packaged either. Write the section from what 1.35.0 actually shipped: the Fleet device auth, enrollment and runner management in #320, the authoritative sandbox port reconciliation in #374, and the telemetry identification and Privacy toggle ordering in #367.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Architecture boundary
ArcBox Desktop owns authentication, Fleet Platform REST requests, enrollment orchestration, local Fleet Agent gRPC communication, and UI state.
Desktop does not install, create, start, stop, or update the Fleet Agent. The Fleet Agent process remains managed by launchd and its corresponding daemon. Runner VM lifecycle operations remain Fleet Agent → arcbox-daemon responsibilities.
Validation
make verify-arcbox-protobufswift-format lint -r --strict ArcBox/ Packages/swiftlint lint --strict --config .swiftlint.ymlxcodegen generatewith no tracked project-file driftSKIP_RUST_BUILD=1Draft status
Remaining end-to-end validation includes:
Supersedes #281.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation