Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions autoplan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -1067,26 +1067,22 @@ Loaded review skills from disk. Starting full review pipeline with auto-decision
## Phase 0.5: Codex auth + version preflight

Before invoking any Codex voice, preflight the CLI: verify auth (multi-signal) and
warn on known-bad CLI versions. This is infrastructure for all 4 phases below —
source it once here and the helper functions stay in scope for the rest of the
workflow.
warn on known-bad CLI versions. Standalone probe binaries handle auth, version
checks, and telemetry — no `source` needed, no security hook triggers.

```bash
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
source ~/.claude/skills/gstack/bin/gstack-codex-probe

# Check Codex binary. If missing, tag the degradation matrix and continue
# with Claude subagent only (autoplan's existing degradation fallback).
if ! command -v codex >/dev/null 2>&1; then
_gstack_codex_log_event "codex_cli_missing"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_cli_missing"
echo "[codex-unavailable: binary not found] — proceeding with Claude subagent only"
_CODEX_AVAILABLE=false
elif ! _gstack_codex_auth_probe >/dev/null; then
_gstack_codex_log_event "codex_auth_failed"
elif ! ~/.claude/skills/gstack/bin/gstack-codex-auth-probe >/dev/null; then
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_auth_failed"
echo "[codex-unavailable: auth missing] — proceeding with Claude subagent only. Run \`codex login\` or set \$CODEX_API_KEY to enable dual-voice review."
_CODEX_AVAILABLE=false
else
_gstack_codex_version_check # non-blocking warn if known-bad
~/.claude/skills/gstack/bin/gstack-codex-version-check # non-blocking warn if known-bad
_CODEX_AVAILABLE=true
fi
```
Expand Down Expand Up @@ -1120,7 +1116,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex CEO voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

You are a CEO/founder advisor reviewing a development plan.
Challenge the strategic foundations: Are the premises valid or assumed? Is this the
Expand All @@ -1131,8 +1127,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -1237,7 +1233,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex design voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Read the plan file at <plan_path>. Evaluate this plan's
UI/UX design decisions.
Expand All @@ -1254,8 +1250,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
Be opinionated. No hedging." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -1318,7 +1314,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex eng voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Review this plan for architectural issues, missing edge cases,
and hidden complexity. Be adversarial.
Expand All @@ -1330,8 +1326,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -1439,7 +1435,7 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
**Codex DX voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Read the plan file at <plan_path>. Evaluate this plan's developer experience.

Expand All @@ -1456,8 +1452,8 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
Be adversarial. Think like a developer who is evaluating this against 3 competitors." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down
40 changes: 18 additions & 22 deletions autoplan/SKILL.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -237,26 +237,22 @@ Loaded review skills from disk. Starting full review pipeline with auto-decision
## Phase 0.5: Codex auth + version preflight

Before invoking any Codex voice, preflight the CLI: verify auth (multi-signal) and
warn on known-bad CLI versions. This is infrastructure for all 4 phases below —
source it once here and the helper functions stay in scope for the rest of the
workflow.
warn on known-bad CLI versions. Standalone probe binaries handle auth, version
checks, and telemetry — no `source` needed, no security hook triggers.

```bash
_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || echo off)
source ~/.claude/skills/gstack/bin/gstack-codex-probe

# Check Codex binary. If missing, tag the degradation matrix and continue
# with Claude subagent only (autoplan's existing degradation fallback).
if ! command -v codex >/dev/null 2>&1; then
_gstack_codex_log_event "codex_cli_missing"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_cli_missing"
echo "[codex-unavailable: binary not found] — proceeding with Claude subagent only"
_CODEX_AVAILABLE=false
elif ! _gstack_codex_auth_probe >/dev/null; then
_gstack_codex_log_event "codex_auth_failed"
elif ! ~/.claude/skills/gstack/bin/gstack-codex-auth-probe >/dev/null; then
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_auth_failed"
echo "[codex-unavailable: auth missing] — proceeding with Claude subagent only. Run \`codex login\` or set \$CODEX_API_KEY to enable dual-voice review."
_CODEX_AVAILABLE=false
else
_gstack_codex_version_check # non-blocking warn if known-bad
~/.claude/skills/gstack/bin/gstack-codex-version-check # non-blocking warn if known-bad
_CODEX_AVAILABLE=true
fi
```
Expand Down Expand Up @@ -290,7 +286,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex CEO voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

You are a CEO/founder advisor reviewing a development plan.
Challenge the strategic foundations: Are the premises valid or assumed? Is this the
Expand All @@ -301,8 +297,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -407,7 +403,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex design voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Read the plan file at <plan_path>. Evaluate this plan's
UI/UX design decisions.
Expand All @@ -424,8 +420,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
Be opinionated. No hedging." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -488,7 +484,7 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
**Codex eng voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Review this plan for architectural issues, missing edge cases,
and hidden complexity. Be adversarial.
Expand All @@ -500,8 +496,8 @@ Override: every AskUserQuestion → auto-decide using the 6 principles.
File: <plan_path>" -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down Expand Up @@ -609,7 +605,7 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
**Codex DX voice** (via Bash):
```bash
_REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; }
_gstack_codex_timeout_wrapper 600 codex exec "IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.
~/.claude/skills/gstack/bin/gstack-codex-timeout-wrapper 600 codex exec"IMPORTANT: Do NOT read or execute any SKILL.md files or files in skill definition directories (paths containing skills/gstack). These are AI assistant skill definitions meant for a different system. Stay focused on repository code only.

Read the plan file at <plan_path>. Evaluate this plan's developer experience.

Expand All @@ -626,8 +622,8 @@ Log: "Phase 3.5 skipped — no developer-facing scope detected."
Be adversarial. Think like a developer who is evaluating this against 3 competitors." -C "$_REPO_ROOT" -s read-only --enable web_search_cached < /dev/null
_CODEX_EXIT=$?
if [ "$_CODEX_EXIT" = "124" ]; then
_gstack_codex_log_event "codex_timeout" "600"
_gstack_codex_log_hang "autoplan" "0"
~/.claude/skills/gstack/bin/gstack-codex-log-event "codex_timeout" "600"
~/.claude/skills/gstack/bin/gstack-codex-log-hang "autoplan" "0"
echo "[codex stalled past 10 minutes — tagging as [codex-unavailable] for this phase and proceeding with Claude subagent only]"
fi
```
Expand Down
16 changes: 16 additions & 0 deletions bin/gstack-codex-auth-probe
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# gstack-codex-auth-probe: standalone auth check. Prints AUTH_OK (exit 0) or
# AUTH_FAILED (exit 1). Replaces _gstack_codex_auth_probe() from gstack-codex-probe
# for skill templates that cannot safely source the probe file.
#
# Multi-signal: env vars OR auth file. Avoids false negatives for env-auth users
# (CI, platform engineers) that a file-only check would reject.
_codex_home="${CODEX_HOME:-$HOME/.codex}"
_k1=$(printf '%s' "${CODEX_API_KEY:-}" | tr -d '[:space:]')
_k2=$(printf '%s' "${OPENAI_API_KEY:-}" | tr -d '[:space:]')
if [ -n "$_k1" ] || [ -n "$_k2" ] || [ -f "$_codex_home/auth.json" ]; then
echo "AUTH_OK"
exit 0
fi
echo "AUTH_FAILED"
exit 1
64 changes: 64 additions & 0 deletions bin/gstack-codex-jsonl-parser
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""
gstack-codex-jsonl-parser: parse Codex CLI --json streaming output to human-readable form.

Usage: gstack-codex-jsonl-parser [--mode challenge|consult]
Reads JSONL from stdin (codex exec --json output), prints formatted lines to stdout.

Modes:
challenge Track turn.completed count; warn on disconnect (no events received).
consult Extract SESSION_ID from thread.started for follow-up sessions.
"""
import sys
import json

mode = "consult"
args = sys.argv[1:]
i = 0
while i < len(args):
if args[i] == "--mode" and i + 1 < len(args):
mode = args[i + 1]
i += 2
else:
i += 1

turn_completed_count = 0
for line in sys.stdin:
line = line.strip()
if not line:
continue
try:
obj = json.loads(line)
t = obj.get("type", "")
if t == "thread.started" and mode == "consult":
tid = obj.get("thread_id", "")
if tid:
print(f"SESSION_ID:{tid}", flush=True)
elif t == "item.completed" and "item" in obj:
item = obj["item"]
itype = item.get("type", "")
text = item.get("text", "")
if itype == "reasoning" and text:
print(f"[codex thinking] {text}", flush=True)
print(flush=True)
elif itype == "agent_message" and text:
print(text, flush=True)
elif itype == "command_execution":
cmd = item.get("command", "")
if cmd:
print(f"[codex ran] {cmd}", flush=True)
elif t == "turn.completed":
turn_completed_count += 1
usage = obj.get("usage", {})
tokens = usage.get("input_tokens", 0) + usage.get("output_tokens", 0)
if tokens:
print(f"\ntokens used: {tokens}", flush=True)
except Exception:
pass

if mode == "challenge" and turn_completed_count == 0:
print(
"[codex warning] No turn.completed event received — possible mid-stream disconnect.",
flush=True,
file=sys.stderr,
)
20 changes: 20 additions & 0 deletions bin/gstack-codex-log-event
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# gstack-codex-log-event: standalone telemetry emitter. Replaces
# _gstack_codex_log_event() from gstack-codex-probe for skill templates
# that cannot safely source the probe file.
#
# Usage: gstack-codex-log-event <event> [duration_s]
# Event types: codex_timeout, codex_auth_failed, codex_cli_missing,
# codex_version_warning.
# Payload: {skill, event, duration_s, ts}. NEVER includes prompt content,
# env var values, or auth tokens.
_event="${1:-unknown}"
_duration="${2:-0}"
_bin_dir="$(cd "$(dirname "$0")" && pwd)"
_TEL=$("$_bin_dir/gstack-config" get telemetry 2>/dev/null || echo "off")
[ "$_TEL" = "off" ] && exit 0
mkdir -p "$HOME/.gstack/analytics" 2>/dev/null || exit 0
_ts=$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo unknown)
printf '{"skill":"codex","event":"%s","duration_s":"%s","ts":"%s"}\n' \
"$_event" "$_duration" "$_ts" \
>> "$HOME/.gstack/analytics/skill-usage.jsonl" 2>/dev/null || true
Loading