diff --git a/scarf/Packages/ScarfCore/Sources/ScarfCore/Models/HermesConfig.swift b/scarf/Packages/ScarfCore/Sources/ScarfCore/Models/HermesConfig.swift index ccbce32..a62ccef 100644 --- a/scarf/Packages/ScarfCore/Sources/ScarfCore/Models/HermesConfig.swift +++ b/scarf/Packages/ScarfCore/Sources/ScarfCore/Models/HermesConfig.swift @@ -260,8 +260,11 @@ public struct VoiceSettings: Sendable, Equatable { /// Per-task auxiliary model overrides. /// -/// `flush_memories` was removed entirely in Hermes v0.12 (the underlying -/// task no longer exists), so the corresponding field was dropped here. +/// `flush_memories` was removed in Hermes v0.12 but remains alive on +/// pre-v0.12 hosts — the field is preserved here so the YAML parser +/// can round-trip it and `AuxiliaryTab` can render the row when +/// `HermesCapabilities.hasFlushMemoriesAux` is set. On v0.12+ the +/// field stays empty and is never surfaced. /// `curator` was added in v0.12 — Curator's review fork uses its own /// model so users can keep main-model spend separate from background /// maintenance. @@ -273,6 +276,8 @@ public struct AuxiliarySettings: Sendable, Equatable { public var skillsHub: AuxiliaryModel public var approval: AuxiliaryModel public var mcp: AuxiliaryModel + /// pre-v0.12 only; on v0.12+ this stays `.empty` and the row is hidden. + public var flushMemories: AuxiliaryModel /// v0.12+; pre-v0.12 Hermes installs ignore this slot. public var curator: AuxiliaryModel @@ -285,6 +290,7 @@ public struct AuxiliarySettings: Sendable, Equatable { skillsHub: AuxiliaryModel, approval: AuxiliaryModel, mcp: AuxiliaryModel, + flushMemories: AuxiliaryModel, curator: AuxiliaryModel ) { self.vision = vision @@ -294,6 +300,7 @@ public struct AuxiliarySettings: Sendable, Equatable { self.skillsHub = skillsHub self.approval = approval self.mcp = mcp + self.flushMemories = flushMemories self.curator = curator } public nonisolated static let empty = AuxiliarySettings( @@ -304,6 +311,7 @@ public struct AuxiliarySettings: Sendable, Equatable { skillsHub: .empty, approval: .empty, mcp: .empty, + flushMemories: .empty, curator: .empty ) } diff --git a/scarf/Packages/ScarfCore/Sources/ScarfCore/Parsing/HermesConfig+YAML.swift b/scarf/Packages/ScarfCore/Sources/ScarfCore/Parsing/HermesConfig+YAML.swift index dfba138..d172bbc 100644 --- a/scarf/Packages/ScarfCore/Sources/ScarfCore/Parsing/HermesConfig+YAML.swift +++ b/scarf/Packages/ScarfCore/Sources/ScarfCore/Parsing/HermesConfig+YAML.swift @@ -122,6 +122,7 @@ public extension HermesConfig { skillsHub: aux("skills_hub"), approval: aux("approval"), mcp: aux("mcp"), + flushMemories: aux("flush_memories"), curator: aux("curator") ) diff --git a/scarf/scarf/Core/Services/HermesFileService.swift b/scarf/scarf/Core/Services/HermesFileService.swift index c1a8362..57e139a 100644 --- a/scarf/scarf/Core/Services/HermesFileService.swift +++ b/scarf/scarf/Core/Services/HermesFileService.swift @@ -129,6 +129,7 @@ struct HermesFileService: Sendable { skillsHub: aux("skills_hub"), approval: aux("approval"), mcp: aux("mcp"), + flushMemories: aux("flush_memories"), curator: aux("curator") ) diff --git a/scarf/scarf/Features/Settings/Views/Tabs/AuxiliaryTab.swift b/scarf/scarf/Features/Settings/Views/Tabs/AuxiliaryTab.swift index ec157f0..84e718b 100644 --- a/scarf/scarf/Features/Settings/Views/Tabs/AuxiliaryTab.swift +++ b/scarf/scarf/Features/Settings/Views/Tabs/AuxiliaryTab.swift @@ -10,11 +10,13 @@ import ScarfCore /// the gateway routing from that single field; there is no separate /// `use_gateway` key to write. /// -/// v0.12 dropped the `flush_memories` aux task (the underlying memory -/// pipeline was rewritten upstream) and added `curator` (the autonomous -/// skill-maintenance review fork). The Curator row only appears when -/// `HermesCapabilities.hasCuratorAux` is set so v0.11 hosts don't see a -/// row that writes a key Hermes ignores. +/// v0.12 dropped the `flush_memories` aux task on the server side and +/// added `curator` (the autonomous skill-maintenance review fork). The +/// Curator row only appears when `HermesCapabilities.hasCuratorAux` is +/// set; the Flush Memories row only appears when +/// `HermesCapabilities.hasFlushMemoriesAux` is set (inverse semantics — +/// `true` only on pre-v0.12 hosts where the task still exists). v0.11 +/// users keep their edit surface; v0.12 users never see it. struct AuxiliaryTab: View { @Bindable var viewModel: SettingsViewModel @@ -38,6 +40,9 @@ struct AuxiliaryTab: View { private var tasks: [(key: String, title: LocalizedStringKey, icon: String)] { var t = baseTasks + if capabilitiesStore?.capabilities.hasFlushMemoriesAux ?? false { + t.append(("flush_memories", "Flush Memories", "trash.slash")) + } if capabilitiesStore?.capabilities.hasCuratorAux ?? false { t.append(("curator", "Curator", "sparkles")) } @@ -110,6 +115,7 @@ struct AuxiliaryTab: View { case "skills_hub": return viewModel.config.auxiliary.skillsHub case "approval": return viewModel.config.auxiliary.approval case "mcp": return viewModel.config.auxiliary.mcp + case "flush_memories": return viewModel.config.auxiliary.flushMemories case "curator": return viewModel.config.auxiliary.curator default: return .empty }