mirror of https://github.com/garrytan/gstack.git
54 lines
2.2 KiB
Bash
Executable File
54 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# gstack-session-kind — classify the current agent session so skills know whether
|
|
# a human can answer an interactive prompt (AskUserQuestion).
|
|
#
|
|
# Usage: gstack-session-kind → prints one of: spawned | headless | interactive
|
|
#
|
|
# Used by the preamble (generate-preamble-bash.ts) which echoes
|
|
# SESSION_KIND: <value>
|
|
# so the AskUserQuestion-failure fallback rule can branch without a shell-out at
|
|
# failure time:
|
|
# spawned → orchestrator session (OpenClaw). Auto-choose recommended option
|
|
# per the skill's SPAWNED_SESSION block. Never prose, never BLOCKED.
|
|
# headless → no human present (claude -p evals / CI). BLOCK on AUQ failure.
|
|
# interactive → a human is present. Prose-fallback on AUQ failure.
|
|
#
|
|
# Detection is best-effort. On ANY ambiguity it prints `interactive` — BLOCK only on
|
|
# a positive headless signal, since a stray prose message in an unmarked one-shot
|
|
# `-p` run just ends the turn (harmless), whereas wrongly BLOCKING a real human is not.
|
|
#
|
|
# Why env vars and not TTY/entrypoint: an interactive Conductor session reports
|
|
# CLAUDE_CODE_ENTRYPOINT=sdk-ts with no TTY — identical to a headless SDK eval. The
|
|
# signals that actually discriminate are the host/orchestrator/CI env markers below.
|
|
set -euo pipefail
|
|
|
|
# 1. Orchestrator-spawned session (OpenClaw). Authoritative block lives in the skill;
|
|
# we only surface the classification.
|
|
if [ -n "${OPENCLAW_SESSION:-}" ]; then
|
|
echo "spawned"
|
|
exit 0
|
|
fi
|
|
|
|
# 2. Explicit headless override (set by the eval/E2E harness for determinism).
|
|
if [ -n "${GSTACK_HEADLESS:-}" ]; then
|
|
echo "headless"
|
|
exit 0
|
|
fi
|
|
|
|
# 3. Positive interactive-host signals: a human-driven host is present.
|
|
# - Conductor app sets CONDUCTOR_* workspace vars.
|
|
# - Plain interactive `claude` CLI sets CLAUDE_CODE_ENTRYPOINT=cli.
|
|
if [ -n "${CONDUCTOR_WORKSPACE_PATH:-}" ] || [ -n "${CONDUCTOR_PORT:-}" ] || [ "${CLAUDE_CODE_ENTRYPOINT:-}" = "cli" ]; then
|
|
echo "interactive"
|
|
exit 0
|
|
fi
|
|
|
|
# 4. CI / automation markers with no interactive host → headless.
|
|
if [ -n "${CI:-}" ] || [ -n "${GITHUB_ACTIONS:-}" ]; then
|
|
echo "headless"
|
|
exit 0
|
|
fi
|
|
|
|
# 5. No positive headless signal → assume a human is present (degrade-safe default).
|
|
echo "interactive"
|