claude-skills/agent-launcher/hooks/session_end.py
Claude d1f2396c6f
feat(agent-launcher): new domain plugin for building Claude Managed Agents
Adds the agent-launcher/ top-level domain — a plugin re-implementation of
Anthropic's launch-your-agent reference skill (Apache-2.0; independent, not a
fork) for building Claude Managed Agents (CMA) in the user's own account.

Every session starts with a goal (./my-agent/goal.json, surfaced by an opt-in
AGENT_LAUNCHER_SESSION=1 SessionStart hook + /cs:goal); loop_compiler.py
compiles that goal into a bounded grade->iterate loop (CMA user.define_outcome
self-grading, max_iterations 1..20), a recurring POSIX-cron scheduled-deployment
loop, or a single-pass interview->stage->launch workflow.

- 6 skills: agent-launcher-orchestrator (context: fork goal router) + interview
  + stage-launch + grade-iterate + run-without-you + wrap-up
- 18 stdlib-only deterministic scaffolder tools (NO network/API calls; live
  launches emitted as BYOK curl that never prints the key); all pass --help/--sample
- 4 agents (orchestrator + interviewer + grader + deployer), 8 /cs:* commands
- opt-in SessionStart/SessionEnd hooks (exit 0 on any error), 5 shared
  references, 4 assets (build-sheet schema + overview/next-directions templates
  + example)
- validators enforce CMA limits (<=20 skills/session, <=8 memory stores,
  depth-1 multiagent, max_iterations <=20, <=1000 deployments/org)
- registered in marketplace.json; headline counters trued up via
  derive_counters.py --check (skills 362->368, domains 18->19, tools 644->664,
  refs 741->746, agents 102->106, commands 116->124, plugins 88->89)

Distinct from engineering/agent-harness (generic bounded loop over any domain)
and engineering/write-a-skill (authors Claude Code skills, not CMAs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FwXG6TqCXKZQvF4iD69cv
2026-08-17 02:39:34 +00:00

57 lines
1.5 KiB
Python

#!/usr/bin/env python3
"""SessionEnd hook for agent-launcher (OPT-IN).
Disabled unless AGENT_LAUNCHER_SESSION=1 (and additionally AGENT_LAUNCHER_SESSIONEND
!= 0). When enabled and an in-progress goal exists that is not yet at phase=done,
prints a one-line reminder to checkpoint/advance the goal so the next session
resumes cleanly. Any error exits 0 — a hook must never break a session.
Stdlib-only.
"""
import json
import os
import sys
from pathlib import Path
def disabled() -> bool:
if os.environ.get("AGENT_LAUNCHER_SESSION", "0") != "1":
return True
if os.environ.get("AGENT_LAUNCHER_SESSIONEND", "1") == "0":
return True
return False
def find_goal() -> Path | None:
for c in [Path.cwd() / "my-agent" / "goal.json", Path.cwd() / ".my-agent" / "goal.json"]:
if c.exists():
return c
try:
for d in sorted(Path.cwd().glob("my-agent-*/goal.json")):
return d
except OSError:
pass
return None
def main() -> int:
if disabled():
return 0
try:
gp = find_goal()
if not gp:
return 0
state = json.loads(gp.read_text())
phase = state.get("phase", "interview")
if phase == "done":
return 0
print(f"[agent-launcher] Launch still at phase '{phase}'. "
f"Checkpoint it: `goal_state.py set --phase {phase} --note '...'` "
f"(or `advance`). Resume next session with /cs:launch.")
except Exception:
return 0
return 0
if __name__ == "__main__":
sys.exit(main())