mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 18:44:45 +00:00
feat(curator): archive + prune + list-archived (WS-4)
Catches the Curator surface up to Hermes v0.13's new write-side verbs
(`archive <skill>`, `prune`, `list-archived`, synchronous `run`). Adds
a new `CuratorService` actor in ScarfCore mirroring `KanbanService`'s
pattern (Sendable, pure I/O, `Task.detached(priority: .utility)` per
verb), tolerantly-decoded `HermesCuratorArchivedSkill` /
`CuratorPruneSummary` models, and `CuratorError` for inline-banner
surfacing.
Mac UX gains an "Archived" section between the leaderboards and the
last-report block (per-row Restore button), an "archivebox" button on
every active-skill leaderboard row to manually archive, a destructive
"Prune Archived…" confirm sheet enumerating each skill (template-
uninstall pattern — Cancel owns `.defaultAction`, Prune is on the red
`ScarfDestructiveButton`), and a synchronous-with-progress "Run Now"
on v0.13+ hosts (600s timeout, `ProgressView` while in-flight).
Failure path routes through a yellow inline error banner instead of a
modal alert. The legacy `CuratorRestoreSheet` stays accessible from
the overflow menu but only on pre-v0.13 hosts; on v0.13+ the per-row
Restore in the new Archived section replaces it.
All new surfaces gate on `HermesCapabilities.hasCuratorArchive` —
pre-v0.13 hosts see the v2.7.x layout unchanged. iOS picks up the new
`runNow(synchronous:)` signature with the v0.13 capability flag; the
read-only Archived section + WS-9 marker is left for the next stream.
14 new parser tests in `HermesCuratorParserTests` cover the JSON
happy path, the `{"archived": [...]}` envelope, the text fallback
(`--json` not supported), `"no archived skills"` sentinel folding,
prune-dry-run with both wrapper + bare-array shapes, and zero-skill
prune. All 369 ScarfCore tests pass; `xcodebuild` for the `scarf`
scheme succeeds.
Wire-shape unknowns (CLI flag presence on real v0.13) carry
`// TODO(WS-4-Q<N>)` markers in `CuratorService` and fall back
defensively when a flag isn't recognized. Implements WS-4 of Scarf
v2.8.0 (Hermes v0.13.0 catch-up). Plan:
scarf/docs/v2.8/WS-4-curator-archive-plan.md (on
coordination/v2.8.0-plans).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,11 +13,24 @@ import ScarfDesign
|
||||
/// `HermesCapabilities.hasCurator` is true.
|
||||
struct CuratorView: View {
|
||||
@State private var viewModel: CuratorViewModel
|
||||
@Environment(\.hermesCapabilities) private var capabilitiesStore
|
||||
|
||||
// TODO(WS-9): add a read-only "Archived" section mirroring the Mac
|
||||
// surface (no per-row Restore/Prune mutations on iOS in this
|
||||
// release). Gate on `capabilitiesStore?.capabilities.hasCuratorArchive`.
|
||||
|
||||
init(context: ServerContext) {
|
||||
_viewModel = State(initialValue: CuratorViewModel(context: context))
|
||||
}
|
||||
|
||||
/// Whether the connected host runs curator synchronously. Threaded
|
||||
/// into `runNow` so v0.13+ hosts block-with-spinner; pre-v0.13 fire
|
||||
/// and forget. WS-9 will surface a richer iOS progress affordance
|
||||
/// alongside the read-only Archived section.
|
||||
private var archiveAvailable: Bool {
|
||||
capabilitiesStore?.capabilities.hasCuratorArchive ?? false
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
Section {
|
||||
@@ -115,7 +128,7 @@ struct CuratorView: View {
|
||||
private var actionFooter: some View {
|
||||
HStack(spacing: 8) {
|
||||
Button {
|
||||
Task { await viewModel.runNow() }
|
||||
Task { await viewModel.runNow(synchronous: archiveAvailable, timeout: 600) }
|
||||
} label: {
|
||||
Label("Run now", systemImage: "play.fill")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user