mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
fix(kanban): enrich LocalTransport subprocess env so kanban dispatcher can spawn workers
GUI-launched Scarf inherits macOS's launch-services PATH (`/usr/bin:/bin:/usr/sbin:/sbin`). Scarf itself finds `hermes` via absolute-path resolution in `HermesPathSet.hermesBinaryCandidates`, but when the kanban dispatcher (a child of Scarf) tries to spawn a worker, the worker inherits the same stripped PATH and Hermes's spawn machinery prints `\`hermes\` executable not found on PATH. Install Hermes Agent or activate its venv before running the kanban dispatcher.` — recording `outcome=spawn_failed` on the run. `LocalTransport` now mirrors `SSHTransport.environmentEnricher`: adds an `environmentEnricher: (() -> [String: String])?` static, and applies it to every subprocess. `scarfApp.swift` wires it at launch to the same `HermesFileService.enrichedEnvironment()` login-shell probe (`zsh -l -i` → `zsh -l` fallback) the SSH transport already uses, so subprocesses see `~/.local/bin`, `/opt/homebrew/bin`, and the user's credential env vars. Defense-in-depth: `subprocessEnvironment(forExecutable:)` always prepends the executable's own directory to PATH if missing — covers early-startup paths and test harnesses where the enricher hasn't been wired yet. Two new tests in `KanbanModelsTests` lock in: 1. The fallback (no enricher → executable's dir lands on PATH) 2. The enricher win for PATH + the empty-string-aware copy semantics for credential env vars (process env happens to set `ANTHROPIC_API_KEY=""` as an empty string in some environments; the enricher's non-empty value must still take effect) Release notes for v2.7.5 updated to document the fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,8 @@ A diagnostic round driving real tasks end-to-end exposed a connected bug pattern
|
||||
|
||||
- **`hermes kanban assignees` empty-state was leaking into the picker.** The CLI prints a literal sentinel `(no assignees — create a profile with hermes -p <name> setup)` when the table is empty; the parser was tokenizing it on whitespace and offering `(no` as a profile in the menu. Parser now skips the sentinel, validates each candidate against `^[a-zA-Z0-9_-]+$`, and falls back cleanly to the active local profile when the table is empty.
|
||||
|
||||
- **`spawn_failed` from "executable not found on PATH"** — most subtle of the lot. macOS GUI apps inherit a launch-services PATH (`/usr/bin:/bin:/usr/sbin:/sbin`) that doesn't include `~/.local/bin` (where pipx installs `hermes`) or `/opt/homebrew/bin`. Scarf was finding `hermes` for its own invocation via the absolute-path resolver in `HermesPathSet.hermesBinaryCandidates`, but when the dispatcher then spawned a worker process, that worker inherited Scarf's GUI PATH and couldn't find `hermes` by name — recording an `outcome=spawn_failed` run with the exact "executable not found on PATH" message. `LocalTransport` now grows an `environmentEnricher` static (mirroring `SSHTransport.environmentEnricher`) wired by `scarfApp.swift` to the same `HermesFileService.enrichedEnvironment()` login-shell probe the SSH transport uses. Every local subprocess Scarf spawns now sees the user's full PATH and credential env, so a spawned-from-Scarf hermes can spawn its children by name without reaching for absolute paths. Defense-in-depth: `subprocessEnvironment(forExecutable:)` also unconditionally prepends the executable's parent directory to PATH, so the fix works even if the enricher hasn't been wired (early startup, tests).
|
||||
|
||||
### Migrating from 2.7.1
|
||||
|
||||
Sparkle will offer the update automatically. No config migration, no schema changes — `~/.hermes/kanban.db` is shared across all Hermes clients and Scarf only reads/writes through the documented CLI surface. Existing Scarf projects pick up the new project Kanban tab on first open; the tenant slug is minted lazily on first kanban interaction inside the project, so projects with no kanban activity stay byte-identical until the user opens the tab.
|
||||
|
||||
Reference in New Issue
Block a user