mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 18:44:45 +00:00
feat(skills): Spotify auth flow + sign-in sheet (Phase 3.1)
Hermes v2026.4.23 ships a `spotify` skill that needs OAuth via `hermes auth spotify`. Mirror the v2.3 Nous Portal in-app sign-in pattern so users don't have to drop to a shell. Mac (full sign-in flow): - SpotifyAuthFlow.swift in Core/Services — @Observable @MainActor, five-state machine (idle → starting → waitingForApproval(URL) → verifying → success | failure). Spawns `hermes auth spotify` via the transport, regex-detects the `https://accounts.spotify.com/authorize?...` URL on stdout/stderr, auto-opens it via NSWorkspace, and on subprocess exit polls `~/.hermes/auth.json` to confirm `providers.spotify.access_token` actually landed (exit code alone isn't proof). - SpotifySignInSheet.swift in Features/Skills/Views — five sub-views matching the state machine (starting / waiting / verifying / success / failure with retry). Auto-dismisses 1.2s after success. Mirrors NousSignInSheet shape. - SkillsView surfaces a "Sign in to Spotify" row in the skill detail pane when the selected skill is the spotify one. iOS (read-only documentation): - SkillsListView's SkillDetailView gains a "Authentication" section on the spotify skill explaining that OAuth needs to happen from Mac (or a shell). The credential lands in ~/.hermes/auth.json and ScarfGo picks it up automatically once the agent uses the skill. Editor sheet UX deferred to v2.6 — multi-line OAuth flows on iPhone are a separate UX problem. Verified: Mac + iOS builds clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,25 @@ private struct SkillDetailView: View {
|
||||
.textSelection(.enabled)
|
||||
}
|
||||
|
||||
if skill.name.lowercased() == "spotify" {
|
||||
Section("Authentication") {
|
||||
Label {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Spotify needs OAuth")
|
||||
.font(.callout.weight(.medium))
|
||||
Text("Run `hermes auth spotify` from the Scarf macOS app or a shell — it opens your browser to complete the OAuth flow. Once authorised, this skill picks up the credentials from `~/.hermes/auth.json` automatically.")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
} icon: {
|
||||
Image(systemName: "music.note")
|
||||
.foregroundStyle(.green)
|
||||
}
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
}
|
||||
|
||||
if !skill.files.isEmpty {
|
||||
Section("Files") {
|
||||
ForEach(skill.files, id: \.self) { file in
|
||||
|
||||
Reference in New Issue
Block a user