Pencheff Studio (macOS)On-device agentic runner

On-device agentic runner

The web app’s Auto-fix PRs feature can take a single finding and open a single pull request. For complex remediations — a CVE chain that touches a config file, a service stub, and three call sites — the Fix-All agent loops over multiple findings, plans a series of edits, applies them, runs the relevant tests, and iterates.

Studio ships the same agent runtime as a desktop process, with one difference that matters for regulated codebases: your source code never leaves the Mac. Only LLM calls go out, proxied through Pencheff so we can meter token spend against your workspace’s quota.

When to use the desktop runner vs the cloud runner

ConcernCloud runnerDesktop runner
Source code is fine to clone into our workers✔ default✔ also works
Source code can’t leave the network / laptop✘ blocked✔ designed for this
You want the result as a GitHub PR✔ opens it✔ opens it (uses your local gh auth or PAT)
You want to watch the agent’s reasoning live✔ web stream✔ Studio side-panel
Repo is huge (>5 GB clone)works, slowerusually faster — no clone, no upload
Your workspace plan allows agentic spend✔ required✔ required (same quota)

If you’re unsure, start with the desktop runner. It’s the more conservative default for any private codebase.

How the loop works

  1. Pick a scope. From the Studio Findings list, multi-select the findings you want fixed — typically all open Critical + High in a single repo. Right-click → Run Fix-All agent.

  2. Plan. Studio opens an agent run via POST /agentic-fix/runs with the selected findings as scope. The plan is generated by a single LLM call (cloud-proxied) and surfaces in the agent side panel before any edits.

  3. Execute, locally. For each step in the plan, the agent runs the tool action — read_file, edit_file, run_tests, git_diff — on your Mac. The tool definitions are the standard Pencheff agent schema; the runtime is implemented in Swift inside Studio (pencheff-studio/Agent/DesktopAgenticRunner.swift).

  4. LLM calls are proxied. Every chat-completion call is forwarded through POST /api/llm-proxy/agentic so we can:

    • hold your provider API key (never shipped to the desktop),
    • apply per-workspace MTD spend limits,
    • record the call against your audit log,
    • cap iterations (60 by default) to prevent runaway loops.
  5. Stream reasoning to the side panel. Every plan revision, tool invocation, and observation is mirrored into the side panel so you can see exactly what the agent is doing on your filesystem.

  6. Pause or cancel. The side panel has a hard Cancel button that stops the loop at the next checkpoint. A canceled run is recorded as canceled and counts against your run history but does not bill for any further LLM calls.

  7. Open a PR. When the agent considers the plan complete, Studio stages the diff and offers two finishing moves:

    • Open PR — uses your local gh CLI auth (preferred) or a stored GitHub PAT.
    • Keep local — leaves the working tree dirty so you can review and commit manually.

What the agent can and cannot touch

Can:

  • Any file inside the registered local repo’s root.
  • The repo’s lockfiles (package-lock.json, Cargo.lock, …) — but only via the package manager’s own update commands, not direct edits.
  • A bounded set of allowed shell commands: git status, git diff, package-manager update / install, configured test runner.

Cannot:

  • Write anywhere outside the registered repo root.
  • Read the contents of any file outside the repo root (so it can’t exfiltrate your ~/.ssh/id_ed25519 or your env files).
  • Make arbitrary shell calls — the allowlist is set per repo in Studio → Repos → <repo> → Agent allowlist.
  • Open network connections directly. All external traffic goes through the LLM proxy and is logged.

The allowlist is enforced by the desktop runtime, not the LLM — even a fully prompt-injected model can’t escape it.

Quotas + cost

Agentic runs share the same workspace monthly token budget as the web Fix-All. You can see remaining budget in the side panel header. When the budget runs out:

  • The run pauses at the next checkpoint with a quota_exceeded reason.
  • You can top up (Pro+) or wait for the calendar month rollover.
  • Already-applied edits stay on disk so partial work isn’t lost.

Troubleshooting

SymptomLikely cause
Side panel shows “LLM proxy unreachable”Studio can’t reach api.pencheff.com/api/llm-proxy/agentic — check your VPN / proxy / firewall config
Agent stops with loop_cap_exceeded after 60 iterationsThe model is thrashing — usually a missing tool or a flaky test. Open the trace and look at the last 5 tool calls
tool_not_allowed: git pushPushing is intentionally not allowed. Use the Open PR affordance instead, which goes through the GitHub App
Working tree has changes you didn’t approveUse git restore . (or your IDE) to discard. The agent does not amend committed history, only the worktree

See also