{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:pi-quick-perms:permissions.schema.json",
  "title": "Pi Quick Perms Configuration",
  "description": "Unified config file combining runtime knobs and flat permission policy for pi-quick-perms.",
  "markdownDescription": "Unified config file combining runtime knobs and flat permission policy for pi-quick-perms.\n\nPlace at `~/.pi/agent/extensions/pi-quick-perms/config.json` (global) or `<project>/.pi/extensions/pi-permission-system/config.json` (project)."
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "description": "JSON Schema URI for editor autocomplete and validation.",
      "type": "string"
    },
    "debugLog": {
      "description": "Write verbose permission-system diagnostics to the extension logs directory.",
      "markdownDescription": "Write verbose pi-quick-perms diagnostics to `logs/pi-quick-perms-debug.jsonl` under the extension config directory.",
      "type": "boolean",
      "default": false
    },
    "permissionReviewLog": {
      "description": "Write permission request and decision audit events to the extension logs directory.",
      "markdownDescription": "Write permission request and decision audit events to `logs/pi-quick-perms-permission-review.jsonl` under the extension config directory.",
      "type": "boolean",
      "default": true
    },
    "yoloMode": {
      "description": "Auto-approve ask-state permission checks, including subagent approval forwarding.",
      "markdownDescription": "Auto-approve `ask`-state permission checks, including subagent approval forwarding.\n\n⚠️ **Use with caution** — this disables all interactive confirmation prompts.",
      "type": "boolean",
      "default": false
    },
    "piInfrastructureReadPaths": {
      "description": "Additional directories to auto-allow for reads as Pi infrastructure, bypassing the external_directory gate. Supports ~ expansion. Directory prefixes only (no globs).",
      "markdownDescription": "Additional directories to auto-allow for reads as Pi infrastructure, bypassing the `external_directory` gate.\n\nThe extension auto-discovers the global node_modules root (walks up from the extension's install path; falls back to `npm root -g` from a dev checkout), `agentDir`, `agentDir/git`, and project-local `.pi/npm/` and `.pi/git/`. Add entries here for edge cases where auto-discovery is insufficient (e.g. custom `npmCommand` pointing to pnpm).\n\nSupports `~` expansion. Directory prefixes only — no glob patterns.",
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "default": []
    },
    "permission": {
      "description": "Flat permission policy. Each key is a surface name; values are a PermissionState string (catch-all) or a pattern→action map.",
      "markdownDescription": "Flat permission policy.\n\nEach top-level key is a surface name:\n- `\"*\"` — universal fallback (replaces `defaultPolicy.tools` from the legacy format)\n- Tool names (`read`, `write`, `bash`, `mcp`, `skill`, `external_directory`, `path`, etc.)\n\nA **string** value is shorthand for `{ \"*\": action }` (surface-level catch-all).\nAn **object** value maps wildcard patterns to actions — last matching pattern wins.\n\nFor path-bearing tools (`read`, `write`, `edit`, `find`, `grep`, `ls`), patterns are matched against the file path from `input.path`. For example, `\"read\": { \"*\": \"allow\", \"*.env\": \"deny\" }` allows reads but denies `.env` files.\n\nThe `path` surface is a cross-cutting gate that applies to **all** file access — both Pi tools and bash commands. A `path` deny cannot be overridden by a per-tool allow. Use it to protect sensitive files (`.env`, `~/.ssh/*`) from all tools at once.\n\n**Merge order (lowest → highest precedence):** global → project → per-agent frontmatter.",
      "type": "object",
      "propertyNames": {
        "description": "A surface name or the universal fallback key '*'.",
        "type": "string",
        "minLength": 1
      },
      "additionalProperties": {
        "oneOf": [
          {
            "$ref": "#/$defs/permissionState",
            "description": "Catch-all shorthand: equivalent to { \"*\": action }."
          },
          {
            "$ref": "#/$defs/permissionMap",
            "description": "Pattern→action map for this surface."
          }
        ]
      },
      "examples": [
        {
          "*": "ask",
          "path": {
            "*": "allow",
            "*.env": "deny",
            "*.env.*": "deny",
            "*.env.example": "allow"
          },
          "read": "allow",
          "write": "deny",
          "edit": "deny",
          "bash": {
            "*": "ask",
            "git status": "allow",
            "git diff": "allow",
            "git *": "ask"
          },
          "mcp": { "*": "ask", "mcp_status": "allow", "exa:*": "allow" },
          "skill": { "*": "ask", "librarian": "allow" },
          "external_directory": "ask"
        }
      ]
    }
  },
  "$defs": {
    "permissionState": {
      "description": "A permission decision: allow (permit silently), deny (block with error), or ask (prompt the user for confirmation).",
      "oneOf": [
        {
          "const": "allow",
          "description": "Permit the action silently with no user interaction."
        },
        {
          "const": "deny",
          "description": "Block the action with an error message. The agent is told not to retry."
        },
        {
          "const": "ask",
          "description": "Prompt the user for confirmation via the interactive UI before proceeding."
        }
      ]
    },
    "permissionMap": {
      "description": "A map of wildcard patterns to permission states. Last matching pattern wins.",
      "markdownDescription": "A map of wildcard patterns to permission states.\n\nUse `*` for wildcard matching. When multiple patterns match, the **last matching rule wins** — put broad catch-alls first and specific overrides after them.\n\nPattern keys support home directory expansion:\n- `~/path` or `$HOME/path` — expanded to the OS home directory at match time.\n- `~` or `$HOME` alone — expands to the home directory itself.\n\nThe stored pattern is always shown in logs and approval dialogs as written (e.g. `~/dev/*`).",
      "type": "object",
      "propertyNames": {
        "description": "A non-empty pattern string. Use * for wildcard matching. Prefix with ~/ or $HOME/ for home-relative paths.",
        "type": "string",
        "minLength": 1
      },
      "additionalProperties": {
        "$ref": "#/$defs/permissionState"
      }
    }
  }
}
