원클릭으로
create-permission
Create a pi-permissions module for a pi tool call that should require approval or be blocked.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Create a pi-permissions module for a pi tool call that should require approval or be blocked.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | create-permission |
| description | Create a pi-permissions module for a pi tool call that should require approval or be blocked. |
| disable-model-invocation | true |
Pi agents act through tools: they run shell commands, read or edit files, and call tools supplied by extensions. pi-permissions adds a decision point immediately before one of those tool calls executes.
Permission authors write small TypeScript modules that inspect a proposed tool call. A module may:
This supports deliberate workflow boundaries—reviewing commits, protecting generated files, checking deployments. TypeScript keeps the policy open-ended instead of forcing every workflow into a fixed rule language.
pi-permissions. Its default export registers permission hooks.git push within a longer shell command.A permission module registers hooks through api.onToolUse():
export default function permissions(api: PermissionsAPI) {
api.onToolUse({
name: "production deploy",
description: "Ask before deploying to production.",
handler(input) {
// Inspect the proposed tool call and optionally return a decision.
},
});
}
The main building blocks are:
input.tool identifies the tool and exposes convenient fields such as a bash command or a file's resolved path. input.cwd identifies the active project, while input.permissionRoot identifies the root assigned to the permission module or package.matchTool() branches cleanly across bash, file, and custom tools. Narrowing helpers support direct branching when that reads better.matchCommand() handles common program/subcommand policies. parseShellCommand() exposes parsed commands, arguments, flags, and source spans for structural checks.request() pauses for the Approver. block() stops the call. Returning undefined means this hook does not decide, so the next hook may evaluate it.Handlers are ordinary TypeScript and may combine these helpers with custom logic. The SDK supplies normalization, shell parsing, decisions, and prompt controls; the permission's author supplies the workflow policy.
Read the core permission API reference for the exact module and tool contracts. Bash policies also use the shell matching reference. Package-bundled permissions and approved third-party dependencies use the package layout reference.
Use this skill when someone can describe a desired workflow boundary but does not want to design the module against the SDK by hand. It turns that plain-language request into a precise policy, writes the permission at the correct scope, builds safe examples, and proves the behavior through Pi after reload.
The process begins by inspecting the current environment. It asks only questions whose answers materially change behavior; obvious choices are inferred and reported.
Inspect the current project, its instructions, existing permission modules, and package manifest before asking questions. Infer decisions already made by the request or repository. Ask the user one grouped set of questions only for unresolved choices that change behavior.
Resolve every field in this policy brief:
Choose scope with this tree:
Choose the decision deliberately: use block() when execution should never be offered and request() when the Approver may reasonably proceed after review.
Choose the highlight as the smallest complete evidence, not automatically the shortest match:
git push—when they alone explain the trigger.A permission defaults to one dependency-free TypeScript file. The loader already provides TypeScript, Node built-ins, the public pi-permissions API, Pi's core packages, and TypeBox; the shell helpers include their parser dependencies. If the policy genuinely requires another package, explain why and get explicit approval before adding it or creating dependency-owning package machinery.
The brief is complete when every field is resolved and the user has approved any third-party dependency.
Read the core permission API reference completely before writing code. If the trigger includes bash, also read bash matching completely. If the scope is package-level or the user approved a third-party dependency, also read permission package layout completely.
Prefer one hook per independently toggleable behavior. Match normalized tool input rather than rendered text. For bash, prefer matchCommand() or parseShellCommand() over raw-command regexes whenever command structure matters.
Place the module according to the brief:
~/.pi/agent/permissions/<name>.ts.pi/permissions/<name>.tspermissions/ directory, declared through pi.permissions when package.json contains an explicit pi manifestPreserve existing package manifests, filters, style, and unrelated work. A nonmatching handler returns undefined so evaluation continues.
Implementation is complete when every trigger and near miss in the brief maps visibly to code, the permission is independently toggleable at the intended granularity, and no unapproved dependency was added.
Inspect the finished change and run the formatter, typechecker, or tests provided by the owning project when they cover the changed files.
Build a smoke matrix containing:
The proof is ready when all policy branches are represented by safe cases and pre-reload checks pass, or each unavailable check has a precise reason.
Tell the user to run /reload, then wait. This skill is not complete at the reload instruction.
After reload:
/permissions.Finish with the module path, policy summary, checks run, and observed live results. Explicitly name anything that could not be exercised.