[BUG] Desktop app: skill allowed-tools grants never arm — pre-approved commands always prompt

Status Open
Reported on v2.1.206
Maintainer reply None cached
Activity 0 comments · opened Jul 23, 2026

Summary

allowed-tools in a plugin skill's SKILL.md frontmatter pre-approves the listed tool patterns for the invoking turn in the CLI, but in the desktop app the same byte-perfect commands always raise permission dialogs. It appears the desktop shell's skill-invocation path never arms the per-turn grant.

Reproduction

Plugin: https://github.com/nikicat/claude-ppq (skill ppq:claude-code), frontmatter includes e.g.:

allowed-tools:
  - Bash(${CLAUDE_SKILL_DIR}/scripts/claude-ppq *)
  - Bash(bash ${CLAUDE_SKILL_DIR}/scripts/claude-ppq *)

In the Windows desktop app (current, 1.24012.x train), invoke /ppq:claude-code glm. The model runs:

C:/Users/<user>/.claude/plugins/cache/ppq/ppq/0.4.5/skills/claude-code/scripts/claude-ppq --models glm

— an exact match for the first pattern after ${CLAUDE_SKILL_DIR} substitution — and a permission dialog appears. Every pre-approved shape across four plugin versions (0.3.2 → 0.4.5) has behaved the same on desktop. Denied the canonical path often enough, the model falls back to improvised curl + parsing chains — strictly worse for the user and for security posture.

Evidence it's the desktop shell, not the engine or the plugin

  • CLI is clean, verified continuously: our CI drives real headless sessions (claude -p with a --permission-prompt-tool recorder that logs any would-be prompt) on ubuntu/macos/windows. Identical skill flows produce zero permission requests: https://github.com/nikicat/claude-ppq/blob/main/.github/workflows/e2e.yml
  • The engine the desktop fetches supports the feature: downloads.claude.ai/claude-code-releases serves 2.1.206 (stable) / 2.1.218 (latest), well past 2.1.129 where ${CLAUDE_SKILL_DIR} substitution landed — and substitution demonstrably works in the desktop transcript (paths render resolved).
  • The CLI's permission pipeline consults the host (permission-prompt tool / canUseTool) only after grant filtering — verified empirically. On desktop, grant-covered commands reach the dialog, implying the grant was never registered for the turn.

Expected

Skill invocation in the desktop app arms the skill's allowed-tools for that turn, as the CLI does (docs: "Tools Claude can use without asking permission during the turn that invokes this skill").

Environment

  • Claude desktop app, Windows x64, 1.24012.x train (also inspected the Linux 1.24012.0 deb: Electron shell driving the engine via the Agent SDK with a custom canUseTool host)
  • Plugin installed from a GitHub marketplace; CLI 2.1.210 with the identical plugin behaves correctly on the same machine class

View original on GitHub ↗