remove all files
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Add validation reminders after Codex edits project coordination files."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
FORMAT_PATTERNS = (
|
||||
r"\.codex[\\/]agents[\\/].+\.toml\b",
|
||||
r"\.codex[\\/]config\.toml\b",
|
||||
r"\.codex[\\/]hooks\.json\b",
|
||||
r"\.codex[\\/]skills[\\/].+[\\/]SKILL\.md\b",
|
||||
r"\.codex[\\/]commands[\\/].+\.md\b",
|
||||
r"plugins[\\/].+[\\/]\.codex-plugin[\\/]plugin\.json\b",
|
||||
r"plugins[\\/].+[\\/]commands[\\/].+\.md\b",
|
||||
r"\.agents[\\/]plugins[\\/]marketplace\.json\b",
|
||||
)
|
||||
|
||||
SYNC_PATTERNS = (
|
||||
r"\bdocs[\\/]",
|
||||
r"\bphases[\\/]",
|
||||
r"\bPLAN\.md\b",
|
||||
r"\bPROGRESS\.md\b",
|
||||
r"\bAGENTS\.md\b",
|
||||
r"\bplugins[\\/]",
|
||||
r"\.agents[\\/]plugins[\\/]",
|
||||
)
|
||||
|
||||
|
||||
def matches(tool_input: object, patterns: tuple[str, ...]) -> bool:
|
||||
text = json.dumps(tool_input, ensure_ascii=False)
|
||||
return any(re.search(pattern, text, re.IGNORECASE) for pattern in patterns)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
return 0
|
||||
|
||||
tool_input = payload.get("tool_input", {})
|
||||
notes: list[str] = []
|
||||
|
||||
if matches(tool_input, FORMAT_PATTERNS):
|
||||
notes.append("parse changed .codex TOML/JSON/frontmatter files before finishing")
|
||||
|
||||
if matches(tool_input, SYNC_PATTERNS):
|
||||
notes.append("confirm PLAN.md and PROGRESS.md still reflect completed work and future work")
|
||||
|
||||
if not notes:
|
||||
return 0
|
||||
|
||||
notes.append("run python scripts/validate_workspace.py for changed repository state")
|
||||
json.dump(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": "FESA post-edit reminder: " + "; ".join(notes) + ".",
|
||||
}
|
||||
},
|
||||
sys.stdout,
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,58 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Add FESA context before repository files are edited."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
WATCHED_PATTERNS = (
|
||||
r"\bAGENTS\.md\b",
|
||||
r"\bPLAN\.md\b",
|
||||
r"\bPROGRESS\.md\b",
|
||||
r"\bdocs[\\/]",
|
||||
r"\bphases[\\/]",
|
||||
r"\.codex[\\/]agents[\\/]",
|
||||
r"\.codex[\\/]commands[\\/]",
|
||||
r"\.codex[\\/]skills[\\/]",
|
||||
r"\.codex[\\/]hooks",
|
||||
r"\.codex[\\/]config\.toml\b",
|
||||
r"\bplugins[\\/]",
|
||||
r"\.agents[\\/]plugins[\\/]",
|
||||
)
|
||||
|
||||
|
||||
def has_watched_path(tool_input: object) -> bool:
|
||||
text = json.dumps(tool_input, ensure_ascii=False)
|
||||
return any(re.search(pattern, text, re.IGNORECASE) for pattern in WATCHED_PATTERNS)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
return 0
|
||||
|
||||
if not has_watched_path(payload.get("tool_input", {})):
|
||||
return 0
|
||||
|
||||
json.dump(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PreToolUse",
|
||||
"additionalContext": (
|
||||
"FESA edit guardrail: after editing docs, phases, or .codex extension files, "
|
||||
"keep PLAN.md/PROGRESS.md synchronized and run python scripts/validate_workspace.py "
|
||||
"when the turn changes files."
|
||||
),
|
||||
}
|
||||
},
|
||||
sys.stdout,
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Block obviously destructive shell commands before Codex runs them."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
BLOCK_PATTERNS = (
|
||||
r"\brm\s+-rf\b",
|
||||
r"\brm\s+.*-[a-zA-Z]*r[a-zA-Z]*f\b",
|
||||
r"\brm\s+.*-[a-zA-Z]*f[a-zA-Z]*r\b",
|
||||
r"\bgit\s+push\s+--force(?:-with-lease)?\b",
|
||||
r"\bgit\s+reset\s+--hard\b",
|
||||
r"\bgit\s+clean\s+-[a-zA-Z]*f[a-zA-Z]*d\b",
|
||||
r"\bDROP\s+TABLE\b",
|
||||
r"\btruncate\s+table\b",
|
||||
r"\bRemove-Item\b.*\b-Recurse\b",
|
||||
r"\bRemove-Item\b.*\b-Force\b.*\b-Recurse\b",
|
||||
r"\bdel\b\s+/s\b",
|
||||
r"\brd\b\s+/s\b",
|
||||
r"\brmdir\b\s+/s\b",
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
return 0
|
||||
|
||||
command = payload.get("tool_input", {}).get("command", "")
|
||||
for pattern in BLOCK_PATTERNS:
|
||||
if re.search(pattern, command, re.IGNORECASE):
|
||||
json.dump(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PreToolUse",
|
||||
"permissionDecision": "deny",
|
||||
"permissionDecisionReason": "Harness guardrail blocked a risky shell command.",
|
||||
}
|
||||
},
|
||||
sys.stdout,
|
||||
)
|
||||
return 0
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Provide FESA handoff context at Codex session startup/resume."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
MAX_SECTION_CHARS = 700
|
||||
|
||||
|
||||
def find_repo_root(start: Path) -> Path:
|
||||
for candidate in (start, *start.parents):
|
||||
if (candidate / "AGENTS.md").exists() and (candidate / "PLAN.md").exists():
|
||||
return candidate
|
||||
return start
|
||||
|
||||
|
||||
def read_text(path: Path) -> str:
|
||||
try:
|
||||
return path.read_text(encoding="utf-8")
|
||||
except OSError:
|
||||
return ""
|
||||
|
||||
|
||||
def section(markdown: str, heading: str) -> str:
|
||||
marker = f"## {heading}"
|
||||
start = markdown.find(marker)
|
||||
if start < 0:
|
||||
return ""
|
||||
start = markdown.find("\n", start)
|
||||
if start < 0:
|
||||
return ""
|
||||
end = markdown.find("\n## ", start + 1)
|
||||
body = markdown[start:end if end >= 0 else len(markdown)].strip()
|
||||
body = " ".join(line.strip() for line in body.splitlines() if line.strip())
|
||||
if len(body) > MAX_SECTION_CHARS:
|
||||
body = body[:MAX_SECTION_CHARS].rstrip() + "..."
|
||||
return body
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
payload = {}
|
||||
|
||||
root = find_repo_root(Path(payload.get("cwd") or ".").resolve())
|
||||
plan = read_text(root / "PLAN.md")
|
||||
progress = read_text(root / "PROGRESS.md")
|
||||
|
||||
context_lines = [
|
||||
"FESA session startup context:",
|
||||
"- Before planning or editing, read AGENTS.md, PROGRESS.md, PLAN.md, and docs/README.md.",
|
||||
"- Keep completed work in PROGRESS.md and future tasks/open decisions in PLAN.md.",
|
||||
]
|
||||
|
||||
current_objective = section(plan, "Current Objective")
|
||||
if current_objective:
|
||||
context_lines.append(f"- Current objective: {current_objective}")
|
||||
|
||||
current_status = section(progress, "Current Status")
|
||||
if current_status:
|
||||
context_lines.append(f"- Current status: {current_status}")
|
||||
|
||||
blockers = section(progress, "Known Blockers") or section(plan, "Open Questions")
|
||||
if blockers:
|
||||
context_lines.append(f"- Blockers/open questions: {blockers}")
|
||||
|
||||
json.dump(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "SessionStart",
|
||||
"additionalContext": "\n".join(context_lines),
|
||||
}
|
||||
},
|
||||
sys.stdout,
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run repository validation when a Codex turn stops and request one more pass if it fails."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
try:
|
||||
payload = json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
return 0
|
||||
|
||||
if payload.get("stop_hook_active"):
|
||||
return 0
|
||||
|
||||
root = Path(payload.get("cwd") or ".").resolve()
|
||||
validator = root / "scripts" / "validate_workspace.py"
|
||||
if not validator.exists():
|
||||
return 0
|
||||
|
||||
result = subprocess.run(
|
||||
[sys.executable, str(validator)],
|
||||
cwd=root,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=240,
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
return 0
|
||||
|
||||
summary = (result.stdout or result.stderr or "workspace validation failed").strip()
|
||||
if len(summary) > 1200:
|
||||
summary = summary[:1200].rstrip() + "..."
|
||||
|
||||
json.dump(
|
||||
{
|
||||
"decision": "block",
|
||||
"reason": (
|
||||
"Validation failed. Review the output, fix the repo, then continue.\n\n"
|
||||
f"{summary}"
|
||||
),
|
||||
},
|
||||
sys.stdout,
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user