86 lines
2.3 KiB
Python
86 lines
2.3 KiB
Python
#!/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())
|