Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 128 additions & 19 deletions CLI Pulse Bar/CLI Pulse Bar/ProviderConfigEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -835,11 +835,28 @@ struct ProviderConfigEditor: View {

@discardableResult
private func save() -> Bool {
state.withProviderAccountPersistenceLock(or: false) {
saveAssumingProviderAccountPersistenceLock()
}
}

@discardableResult
private func saveAssumingProviderAccountPersistenceLock()
-> Bool
{
guard let idx = state.providerConfigs.firstIndex(
where: { $0.accountID == accountID }
) else {
return false
}
guard state.recoverPendingProviderAccountSave(accountID) else {
#if os(macOS)
testState = .failure(
"Could not restore the previous provider configuration. Please retry before saving new changes."
)
#endif
return false
}
guard
state.persistProviderAccountCredentialRecoveryAnchor(
accountID
Expand All @@ -852,22 +869,39 @@ struct ProviderConfigEditor: View {
#endif
return false
}
#if os(macOS)
if kind == .gemini && allowsLiveProviderActions {
let secretCheckpoint:
ProviderConfig.SecretPersistenceCheckpoint?
if allowsLiveProviderActions {
guard
geminiCredentialDraft.commit(
accountID: accountID
)
let captured =
state.providerConfigs[idx]
.makeSecretPersistenceCheckpoint()
else {
#if os(macOS)
testState = .failure(
GeminiOAuthError
.credentialPersistenceFailed
.localizedDescription
"Could not safely read existing provider credentials. Please retry."
)
#endif
return false
}
secretCheckpoint = captured
} else {
secretCheckpoint = nil
}
let secretRecoveryConfig = state.providerConfigs[idx]
guard
let persistenceCheckpoint =
state.makeProviderAccountPersistenceCheckpoint(
accountID
)
else {
#if os(macOS)
testState = .failure(
"Could not safely prepare provider configuration. Please retry."
)
#endif
return false
}
#endif
state.providerConfigs[idx].sourceMode = sourceMode
state.providerConfigs[idx].accountLabel = accountLabel.isEmpty ? nil : accountLabel
state.providerConfigs[idx].setPlanOverride(
Expand Down Expand Up @@ -899,24 +933,99 @@ struct ProviderConfigEditor: View {
? true
: nil
#endif
if allowsLiveProviderActions {
guard state.providerConfigs[idx].saveSecrets() else {
let transactionResult = ProviderAccountSaveTransaction.commit(
persistSecrets: {
guard allowsLiveProviderActions else {
return true
}
guard state.providerConfigs[idx].saveSecrets() else {
#if os(macOS)
testState = .failure(
"Could not safely save provider credentials. Please retry."
)
#endif
return false
}
return true
},
rollbackSecrets: {
guard allowsLiveProviderActions else {
return true
}
guard let secretCheckpoint else {
return false
}
return secretRecoveryConfig
.restoreSecrets(
from: secretCheckpoint
)
},
persistMetadata: {
guard state.persistProviderAccountDraftMetadata(accountID) else {
#if os(macOS)
testState = .failure(
"Could not safely save provider configuration. Please retry."
)
#endif
return false
}
return true
},
rollbackMetadata: {
persistenceCheckpoint.restore()
},
commitProviderCredential: {
#if os(macOS)
testState = .failure(
"Could not safely save provider credentials. Please retry."
)
guard kind == .gemini && allowsLiveProviderActions else {
return true
}
guard geminiCredentialDraft.commit(accountID: accountID) else {
testState = .failure(
GeminiOAuthError
.credentialPersistenceFailed
.localizedDescription
)
return false
}
#endif
return false
return true
},
finalize: {
state.finalizeProviderAccountDraft(accountID)
}
}
guard state.commitProviderAccountDraft(accountID) else {
)
switch transactionResult {
case .committed:
return true
case .failedRolledBack:
return false
case .failedRollbackIncomplete:
let recovery = ProviderAccountSaveRecovery(
restoreMetadata: {
persistenceCheckpoint.restore()
},
restoreSecrets: {
guard allowsLiveProviderActions else {
return true
}
guard let secretCheckpoint else {
return false
}
return secretRecoveryConfig.restoreSecrets(
from: secretCheckpoint
)
}
)
state.retainProviderAccountSaveRecovery(
recovery,
for: accountID
)
#if os(macOS)
testState = .failure(
"Could not safely save provider configuration. Please retry."
"Save failed and recovery is incomplete. Retry to restore the previous configuration before saving again."
)
#endif
return false
}
return true
}
}
Loading
Loading