Repository navigation
Update Everything: one action updates the app, every machine's daemon and agent CLIs (cx-1mbnu) #20940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Update Everything: one action updates the app, every machine's daemon and agent CLIs (cx-1mbnu) #20940
Changes from 19 commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
613caed
Update Everything: one action updates the app, every machine's daemon…
teamleaderleo 4ace32e
chore(next): PR autofix at 613caed1dc12
ad4e307
Update Everything: its three entry types are structs (namespace lint)
teamleaderleo b5d67a3
Merge remote-tracking branch 'origin/feat-cmux-next' into recut/updat…
teamleaderleo 2fc1a2e
Update Everything: translate the catalog into all 21 languages
teamleaderleo 64d4162
Merge remote-tracking branch 'origin/feat-cmux-next' into recut/updat…
teamleaderleo 1683682
Merge remote-tracking branch 'origin/feat-cmux-next' into codex/cx-1m…
teamleaderleo 90889de
chore(next): PR autofix at 168368272e98
b77f2d8
Merge remote-tracking branch 'origin/feat-cmux-next' into codex/cx-1m…
teamleaderleo 77dd4d1
chore(next): regenerate ci-target-graph.json
teamleaderleo 5976f56
chore(next): PR autofix at 77dd4d17f2bd
282c136
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo 3ece2c8
test(next): Update Everything relaunch, deferred daemons and launch-c…
teamleaderleo e355e58
fix(next): Update Everything finishes only after a real relaunch, onc…
teamleaderleo 1e5d6c1
test(next): Update Everything run expects devbox after the relaunch; …
teamleaderleo 59acaf8
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo ca42462
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo a1d58df
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo 9471ca7
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo 98e400f
Merge origin/feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo d542db0
chore(next): PR autofix at 98e400f4b1b7
6c76066
Merge feat-cmux-next into codex/cx-1mbnu-update-everything
teamleaderleo 1f102c9
fix(cmux-next): keep SettingsActionCatalog under its god-file size; i…
teamleaderleo 7bf44b0
Merge remote-tracking branch 'origin/feat-cmux-next' into orphan-20940
teamleaderleo 8e71df2
chore(cmux-next): regenerate ci-target-graph.json on the merged head
teamleaderleo 5d16013
chore(cmux-next): take base's action exports; the PR autofix regenera…
teamleaderleo 2484b62
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 38c7577
Update Everything: paired servers stay out by default; updates.update…
teamleaderleo 6bc856b
Update Everything: debug.update_everything and a tour capture its con…
teamleaderleo 63f61d2
ci-target-graph.json: take base's copy; only the base autofix writes it
teamleaderleo eca67ca
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 103bbec
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 7a2dbd6
chore(next): settings and action exports from PR autofix run 39602257463
teamleaderleo c242dc8
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 59ae151
fix(next updates): the relaunched app finishes only the machines the …
teamleaderleo 9dd5810
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 4ce25c6
Regenerate generated files from the PR autofix (run 39651226919)
teamleaderleo 897eac6
Merge remote-tracking branch 'origin/feat-cmux-next' into adopt-20940
teamleaderleo 395a5e1
Regenerate generated files from the PR autofix (run 39661203445)
teamleaderleo 78eaf08
Give updates.updateEverythingServers an agent policy (user only)
teamleaderleo d63c78b
Merge feat-cmux-next (eb423e12) into Update Everything
teamleaderleo 15a20a7
Merge feat-cmux-next (47ae435f) into Update Everything
teamleaderleo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
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
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
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
26 changes: 26 additions & 0 deletions
26
Packages/macOS/CmuxNext/Sources/CmuxNextApp/Updates/UpdateEverythingHost+App.swift
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import AppKit | ||
| import CmuxNextDaemonService | ||
| import CmuxNextUpdateEverything | ||
|
|
||
| extension UpdateEverythingHost { | ||
| /// Update Everything over the App's services (cx-1mbnu); the rest lives in its module. | ||
| static func app(_ services: AppServices) -> Self { | ||
| let machines = services.machines | ||
| return Self(local: { machines.local }, remotes: { | ||
| machines.ssh.filter { $0.daemon.connection != nil }.map { ($0.machineID, $0.host.label, .ssh, $0.daemon) } | ||
| + machines.cloud.filter { $0.daemon.connection != nil }.map { ($0.machineID, $0.machine.title, .cloud, $0.daemon) } | ||
| }, daemon: { machines.anyDaemon(machine: $0) }, installSSH: { id in | ||
| guard let session = machines.sshSession(id) else { throw ActionFailure(message: UpdateEverythingMachine.disconnected) } | ||
| try await services.ssh.install(session) | ||
| }, updateCloud: { socket in | ||
| // Gated like SSH's install: turned off by the organization (or no managed team) refuses. | ||
| if let refusal = services.cloud.unavailableReason { throw ActionFailure(message: refusal) } | ||
| guard let binary = services.cloud.move.cli else { throw ActionFailure(message: UpdateEverythingMachine.disconnected) } | ||
| let answer = try await CloudMoveCLI(binary: binary).machineUpdate(socket: socket, toBundled: true) | ||
| if !answer.ok { throw ActionFailure(message: UpdateEverythingMachine.failureText(answer.error)) } | ||
| return answer.updated | ||
| }, updater: services.updater, appVersion: Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String, | ||
| window: { services.windows.active?.window ?? NSApp.mainWindow }, | ||
| journal: UpdateEverythingDaemon.journalURL(bundleID: services.environment.launch.bundleID)) | ||
| } | ||
| } |
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
88 changes: 88 additions & 0 deletions
88
Packages/macOS/CmuxNext/Sources/CmuxNextDaemon/Requests/Agents/AgentUpdate.swift
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| import Foundation | ||
|
|
||
| /// `agent-update-plan {}`: the machine's agent CLIs that are outdated and that its acpmux can | ||
| /// update without sudo, and its threads (Update Everything's confirmation). | ||
| public struct AgentUpdatePlanRequest: DaemonRequest { | ||
| public struct Harness: Decodable, Sendable, Equatable { | ||
| public var id: String | ||
| /// The harness's display name, when its profile has one. | ||
| public var name: String? | ||
| public var version: String? | ||
| public var latest: String? | ||
| } | ||
|
|
||
| public struct Response: Decodable, Sendable, Equatable { | ||
| public var harnesses: [Harness] | ||
| /// Threads with a running agent. | ||
| public var liveThreads: Int | ||
| /// Threads in a turn now. | ||
| public var runningThreads: Int | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case harnesses | ||
| case liveThreads = "live_threads" | ||
| case runningThreads = "running_threads" | ||
| } | ||
| } | ||
|
|
||
| public static let command = "agent-update-plan" | ||
| /// The capability of a daemon that updates its machine's agent CLIs (`agent-update-v1`, | ||
| /// cmux-tui/spec/commands.md agent-update-plan / agent-update-apply): it asks the machine's own | ||
| /// acpmux, so Update Everything reaches this Mac, SSH and Cloud machines the same way. | ||
| public static let capability = "agent-update-v1" | ||
| public static var requiredCapability: String? { capability } | ||
| public init() {} | ||
| } | ||
|
|
||
| /// `agent-update-apply {ids, continue_threads}`: runs the acpmux's own update of each named | ||
| /// harness that is still outdated and waits for them; with `continue_threads`, then restarts each | ||
| /// live thread on its harness's new version, resuming its conversation (a thread in a turn | ||
| /// restarts when the turn ends). No command travels: the machine builds every update itself. | ||
| public struct AgentUpdateApplyRequest: DaemonRequest { | ||
| public struct Result: Decodable, Sendable, Equatable { | ||
| public var id: String | ||
| public var ok: Bool | ||
| /// The version after the update. | ||
| public var version: String? | ||
| /// Why it failed (the updater's last output line). | ||
| public var error: String? | ||
| } | ||
|
|
||
| public struct Response: Decodable, Sendable, Equatable { | ||
| public var results: [Result] | ||
| /// Threads restarted now (they were idle). | ||
| public var threadsRestarted: Int | ||
| /// Threads that restart when their running turn ends. | ||
| public var threadsAfterTurn: Int | ||
| /// Threads that could not restart and still run the old agent (nil from an older daemon). | ||
| public var threadsFailed: Int? | ||
| /// Why threads could not restart: the restart call's error, or the first thread's. | ||
| public var threadsError: String? | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case results | ||
| case threadsRestarted = "threads_restarted" | ||
| case threadsAfterTurn = "threads_after_turn" | ||
| case threadsFailed = "threads_failed" | ||
| case threadsError = "threads_error" | ||
| } | ||
| } | ||
|
|
||
| public static let command = "agent-update-apply" | ||
| public static var requiredCapability: String? { AgentUpdatePlanRequest.capability } | ||
| /// The longest an apply may take: each updater may run 15 minutes (acpmux `probe.rs`). | ||
| public static let timeout: Duration = .seconds(30 * 60) | ||
|
|
||
| public var ids: [String] | ||
| public var continueThreads: Bool | ||
|
|
||
| public init(ids: [String], continueThreads: Bool) { | ||
| self.ids = ids | ||
| self.continueThreads = continueThreads | ||
| } | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case ids | ||
| case continueThreads = "continue_threads" | ||
| } | ||
| } | ||
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AgentUpdateApplyRequest.timeoutis fixed at 30 minutes. The daemon runs updaters one at a time, allowing 15 minutes each plus a margin, up to two hours, followed by chat restarts. Three slow but valid updates can outlast the app's deadline. The app reports failure and can move on to its own relaunch while the daemon is still updating. Match the daemon's full deadline, including chat restarts.