Files
weichen 5618cfc8cf feat(tooling): add Cursor governance hooks, skills, and rule pointers
Layer advisory Cursor hooks and skills on the PI executor, shrink the
test-report rule to the validation contract, and fix MCP relative paths.
2026-09-24 09:25:38 +00:00

57 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Advisory beforeShellExecution: bare pi_subagents.py run / broad pkill."""
from __future__ import annotations
import re
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _lib as lib # noqa: E402
HOOK = "guard-pi-shell"
def main() -> None:
raw = lib.read_stdin()
lib.maybe_probe(raw, HOOK)
data = lib.parse_json_loose(raw)
if data is None:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
lib.allow()
cmd = lib.shell_command(data)
if not cmd:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_command", keys=sorted(data.keys())[:40])
lib.allow()
compact = re.sub(r"\s+", " ", cmd).strip()
if re.search(r"(^|[;&|]\s*)pkill(\s|$)", compact) and re.search(r"\s-f(\s|$)", compact):
lib.audit(HOOK, "PKILL_ASK", command=compact[:500])
lib.ask(
"检测到 pkill -f(广谱杀进程)。AGENTS/PI 规则禁止广谱杀;请确认范围后再继续。",
"Hook requires confirmation for pkill -f.",
)
if re.search(r"pi_subagents\.py(\s|$)", compact) and re.search(r"(^|\s)run(\s|$)", compact):
has_lease = (
re.search(r"agentctl(\.py)?\s+with\b", compact) is not None
and re.search(r"--resource\s+path:", compact) is not None
)
if re.search(r"pi_subagents\.py\s+(roles|result|status|config)\b", compact):
lib.allow()
if not has_lease:
lib.audit(HOOK, "BARE_RUN_ASK", command=compact[:500])
lib.ask(
"裸调 pi_subagents.py run 缺少 agentctl with --resource path:… 租约。"
"报告路径须在 path:.doc/test-reports/assets/pi-subagents/<task>/<request> 租约内。",
"Hook: bare PI run without lease resource.",
)
lib.allow()
if __name__ == "__main__":
main()