Skip to content

Hot-trigger corveil skill install when picker value changes (avoid app restart after configuring defaults.binaries.corveil) #490

@dgershman

Description

@dgershman

Friction: #482/#483 installed the embedded /query-corveil slash command into {devRoot}/.claude/commands/query-corveil.md via a Scaffolder pass at app launch (Scaffolder.swift:155 calls installCorveilSkill(...), invoked from AppDelegate.swift:418 initial-launch and :1087 workspace-switch). Changing the picker value in Settings (SettingsView.swift:603-609 writes config.defaults.binaries["corveil"]) doesn't fire a fresh Scaffolder pass, so the new path doesn't reach the installer until the user quits and relaunches Crow — or until they happen to switch workspaces and trip the alternate scaffold path.

The "Verify" button at SettingsView.swift:615 only runs --version. It doesn't re-install.

Result: user picks a path → Settings persists it → nothing else happens. User reasonably assumes it's installed, then discovers it isn't until they restart Crow. The fix is small.

Fix — hot-trigger the install on picker change

When config.defaults.binaries["corveil"] changes (path set, changed, or cleared), call Scaffolder.installCorveilSkill(newPath) once. Async, off the main thread (the existing Scaffolder.corveilInstallTimeout already bounds it; same Task wrapper SettingsView uses for --version at :699).

Three concrete places to wire:

  1. Settings picker didSet (or the SwiftUI binding's set closure) at SettingsView.swift:603-609. After persisting the new value, dispatch installCorveilSkill against the new path. If the new value is empty (user cleared the field), call the installer with nil so it skips and clears any prior warning.

  2. Reuse the existing warning surface. installCorveilSkill already returns a String? warning that's written to AppState.corveilSkillInstallWarning (per AppState.swift:237). Same plumbing applies here — surface success or the same banner that the launch-time pass uses.

  3. Don't re-run the rest of Scaffolder. This is just the corveil install step; the full scaffold pass is unnecessary and would be wasteful. Extract installCorveilSkill to be callable independently if it isn't already (it appears private in Scaffolder.swift:230 — make it accessible to Settings, either via a public Scaffolder method or via a small published service).

Acceptance

  1. Initial pick: With defaults.binaries.corveil unset and query-corveil.md not yet present, open Settings, set the picker to a valid corveil binary, save. Without restarting Crow, {devRoot}/.claude/commands/query-corveil.md exists and /query-corveil is invokable from any new Claude Code session in that devroot.
  2. Path change: With a working install, change the picker to point at a different corveil binary (e.g. a rebuilt version). Without restarting, {devRoot}/.claude/commands/query-corveil.md reflects the new binary's embedded skill content (byte-compare against <newPath> skill show).
  3. Clear: Setting the picker to empty triggers no install attempt and clears any prior corveilSkillInstallWarning. The existing query-corveil.md file is left in place — clearing the picker doesn't remove the skill (the user can do that manually if needed; not in scope here).
  4. Failure surfacing: Picking a broken path (non-existent / not executable) sets corveilSkillInstallWarning to the same diagnostic the launch-time path produces, and the existing banner in the app surfaces it. No crash, no startup-loop, no broken file written.
  5. Rebuild rebuild loop: With a stable picker pointing at a locally-built corveil, running go build ./cmd/corveil in the corveil repo and then clicking the Verify button (or any other trigger that re-evaluates) should not re-install (Verify is --version only — keep that contract). The user still gets a fresh install on the next launch, or could re-pick the same path to force one. (Optional follow-up: a "Reinstall skill" button next to Verify if this trips users; not in this ticket.)

Critical files

Purpose Path
Picker binding (where to fire the install on change) Packages/CrowUI/Sources/CrowUI/SettingsView.swift:597-615
Installer function Sources/Crow/App/Scaffolder.swift:230 (installCorveilSkill) — make accessible to Settings
Warning surface Packages/CrowCore/Sources/CrowCore/AppState.swift:237 (corveilSkillInstallWarning)
Existing async Task pattern to mirror Packages/CrowUI/Sources/CrowUI/SettingsView.swift:699 (the Verify Task wrapper)

Out of scope

Related

🐦‍⬛ Created with Crow via Claude Code

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions