Make the reusable prompt terminal-only

This commit is contained in:
2026-09-22 21:22:02 -04:00
parent 2e763cfa77
commit f2e354ac39
10 changed files with 63 additions and 148 deletions
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/env bash
# Manually control the durable NestQuest development cycle from OpenCode.
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "usage: nq-cycle start|stop|status" >&2
exit 64
fi
unit=nestquest-controller.service
controller=/home/overseer/.local/share/nestquest-controller/scripts/nq-controller
show_status() {
systemctl --user show "$unit" -p ActiveState -p SubState -p UnitFileState
if [[ -f /home/overseer/.local/state/nestquest-controller/last-run.json ]]; then
python3 -c 'import json,pathlib; p=pathlib.Path.home()/".local/state/nestquest-controller/last-run.json"; d=json.loads(p.read_text()); print("LastTickState="+str(d.get("state","unknown"))); print("LastTickTime="+str(d.get("time","unknown")))'
fi
}
case "$1" in
start)
systemctl --user start "$unit"
show_status
if session_status=$("$controller" --check-interactive); then
echo "$session_status"
if [[ "$session_status" == "interactive NestQuest session open" ]]; then
echo "Close the interactive NestQuest OpenCode session to let the controller run its first tick."
fi
else
echo "The controller will wait for OpenCode session detection to recover."
fi
;;
stop)
systemctl --user stop "$unit"
show_status
;;
status)
show_status
;;
*)
echo "usage: nq-cycle start|stop|status" >&2
exit 64
;;
esac
+2 -2
View File
@@ -18,7 +18,7 @@ for required in "$renderer" "$profile"; do
[[ -e "$required" ]] || { echo "missing required path: $required" >&2; exit 66; }
done
prompt=$("$renderer" "$profile" --runtime terminal)
prompt=$("$renderer" "$profile")
if [[ ${1:-} == "--print-prompt" ]]; then
printf '%s\n' "$prompt"
exit 0
@@ -41,7 +41,7 @@ fi
# Foreground mode owns orchestration. A dormant service must never race it.
"$systemctl_bin" --user stop nestquest-controller.service
session_status=$("$control_home/scripts/nq-controller" --check-interactive)
session_status=$("$control_home/scripts/nq-controller" --check-interactive --project "$project")
if [[ "$session_status" == "interactive NestQuest session open" ]]; then
echo "Another interactive NestQuest OpenCode session is open." >&2
echo "Close it, then run nq-orchestrate again." >&2
+1 -14
View File
@@ -11,7 +11,6 @@ import sys
TEMPLATE = Path(__file__).resolve().parent.parent / "templates/ORCHESTRATOR-PROMPT.template.md"
RUNTIME_DIR = TEMPLATE.parent / "runtime"
PLACEHOLDER = re.compile(r"\{\{([A-Z][A-Z0-9_]*)\}\}")
@@ -29,27 +28,15 @@ def render(template: str, profile: dict[str, str]) -> str:
return result
def select_runtime(template: str, runtime: str) -> str:
if runtime == "service":
return template
marker = "# 27. HOST CONTROLLER RUNTIME"
if template.count(marker) != 1:
raise ValueError("controller runtime section is missing or duplicated")
prefix = template.split(marker, 1)[0].rstrip()
overlay = (RUNTIME_DIR / f"{runtime}.md").read_text().strip()
return prefix + "\n\n" + overlay + "\n"
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("profile", type=Path)
parser.add_argument("--runtime", choices=("service", "terminal"), default="service")
parser.add_argument("--output", type=Path)
args = parser.parse_args()
profile = json.loads(args.profile.read_text())
if not isinstance(profile, dict):
parser.error("profile must be a JSON object")
content = render(select_runtime(TEMPLATE.read_text(), args.runtime), profile)
content = render(TEMPLATE.read_text(), profile)
if args.output:
args.output.write_text(content)
print(args.output)