native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899import Foundationimport ProwlCLIShared
/// The local-settings identity of one effective workflow definition. Bundle and user/// definitions are global; repository definitions include the canonical repository root so/// a preference changed in one repository cannot affect a same-id definition in another.nonisolated enum WorkflowPreferenceKey { static func make(scope: WorkflowRunScope, workflowID: String) -> String { switch scope { case .bundle: return "bundle/\(workflowID)" case .user: return "user/\(workflowID)" case .repo(let repositoryID): let rootPath = URL(filePath: repositoryID, directoryHint: .isDirectory) .standardizedFileURL .path(percentEncoded: false) let separator = rootPath.hasSuffix("/") ? "" : "/" return "repo:\(rootPath)\(separator)\(workflowID)" } }
static func make( scope: WorkflowScope, workflowID: String, repositoryRootPath: String? ) -> String? { let runScope: WorkflowRunScope switch scope { case .bundle: runScope = .bundle case .user: runScope = .user case .repo: guard let repositoryRootPath else { return nil } runScope = .repo(repositoryID: repositoryRootPath) } return make(scope: runScope, workflowID: workflowID) }
static func legacyRepositoryWorkflowID(_ key: String) -> String? { let prefix = "repo/" guard key.hasPrefix(prefix) else { return nil } let workflowID = String(key.dropFirst(prefix.count)) return workflowID.isEmpty ? nil : workflowID }}
extension UserGlobalSettings { /// D1 originally keyed repository enablement and run-setup overrides as `repo/<id>`, /// sharing one preference across every repository. Before R2b ships, expand those values /// over the repositories Prowl knows and remove the legacy keys. With no repository yet, /// retain them so a later repository load can perform the migration without losing state. @discardableResult mutating func migrateLegacyRepositoryWorkflowPreferences( repositoryRootPaths: [String] ) -> Bool { let roots = Array(Set(repositoryRootPaths)).sorted() guard !roots.isEmpty else { return false }
let legacyDisabled = disabledWorkflowIDs.compactMap( WorkflowPreferenceKey.legacyRepositoryWorkflowID) let legacyOverrides = workflowBindModeOverrides.compactMap { override -> (String, WorkflowBindModeOverride.Mode)? in guard let workflowID = WorkflowPreferenceKey.legacyRepositoryWorkflowID(override.workflowKey) else { return nil } return (workflowID, override.mode) } guard !legacyDisabled.isEmpty || !legacyOverrides.isEmpty else { return false }
var disabled = Set( disabledWorkflowIDs.filter { WorkflowPreferenceKey.legacyRepositoryWorkflowID($0) == nil }) for root in roots { let scope = WorkflowRunScope.repo(repositoryID: root) for workflowID in legacyDisabled { disabled.insert(WorkflowPreferenceKey.make(scope: scope, workflowID: workflowID)) } } disabledWorkflowIDs = Self.normalizedWorkflowIDs(Array(disabled))
var overrides = workflowBindModeOverrides.filter { WorkflowPreferenceKey.legacyRepositoryWorkflowID($0.workflowKey) == nil } var existingKeys = Set(overrides.map(\.workflowKey)) for root in roots { let scope = WorkflowRunScope.repo(repositoryID: root) for (workflowID, mode) in legacyOverrides { let key = WorkflowPreferenceKey.make(scope: scope, workflowID: workflowID) guard existingKeys.insert(key).inserted else { continue } overrides.append(WorkflowBindModeOverride(workflowKey: key, mode: mode)) } } workflowBindModeOverrides = WorkflowBindModeOverride.normalized(overrides) return true }}