diff --git a/bin/gstack-config b/bin/gstack-config index a7d67a4f1..01defcef8 100755 --- a/bin/gstack-config +++ b/bin/gstack-config @@ -298,6 +298,10 @@ case "${1:-}" in echo "Warning: redact_prepush_hook '$VALUE' not recognized. Valid values: true, false. Using false." >&2 VALUE="false" fi + if [ "$KEY" = "plan_tune_hooks" ] && [ "$VALUE" != "prompt" ] && [ "$VALUE" != "yes" ] && [ "$VALUE" != "no" ]; then + echo "Warning: plan_tune_hooks '$VALUE' not recognized. Valid values: prompt, yes, no. Using prompt." >&2 + VALUE="prompt" + fi mkdir -p "$STATE_DIR" # Write annotated header on first creation if [ ! -f "$CONFIG_FILE" ]; then diff --git a/setup b/setup index 973aaeb1d..9d6453882 100755 --- a/setup +++ b/setup @@ -1319,10 +1319,14 @@ if [ "$NO_TEAM_MODE" -ne 1 ] \ PT_DECISION="$PLAN_TUNE_HOOKS_MODE" [ -z "$PT_DECISION" ] && PT_DECISION="${GSTACK_PLAN_TUNE_HOOKS:-}" [ -z "$PT_DECISION" ] && PT_DECISION="$("$GSTACK_CONFIG" get plan_tune_hooks 2>/dev/null || true)" + # Normalize: strip whitespace + lowercase so "YES", "Yes", " yes" from a flag + # or env var all resolve correctly (an unrecognized opt-in must NOT silently + # downgrade to skip). Unknown values fall through to "prompt". + PT_DECISION=$(printf '%s' "$PT_DECISION" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]') case "$PT_DECISION" in - y|yes|true|install) PT_DECISION="yes" ;; - n|no|false|skip) PT_DECISION="no" ;; - *) PT_DECISION="prompt" ;; + y|yes|true|install|on|1) PT_DECISION="yes" ;; + n|no|false|skip|off|0) PT_DECISION="no" ;; + *) PT_DECISION="prompt" ;; esac _install_plan_tune_hooks() { @@ -1362,6 +1366,7 @@ if [ "$NO_TEAM_MODE" -ne 1 ] \ # Real interactive terminal with no recorded preference: ask, with explicit # consent + diff preview. The read is time-bounded and defaults to "skip" so # it can never hang an automated/forwarded TTY (the conductor failure mode). + _PT_PROMPT_TIMEOUT=10 # single source of truth for the read + the countdown text log "" log "──────────────────────────────────────────────────────────" log "Plan-tune cathedral: install Claude Code hooks?" @@ -1386,8 +1391,8 @@ if [ "$NO_TEAM_MODE" -ne 1 ] \ log "Backup: settings.json.bak. written before any mutation." log "Rollback: $SETTINGS_HOOK rollback" log "" - printf "Install both hooks now? [y/N] (default: N, auto-skips in 10s): " - read -t 10 -r PLAN_TUNE_INSTALL_REPLY /dev/null || PLAN_TUNE_INSTALL_REPLY="" + printf "Install both hooks now? [y/N] (default: N, auto-skips in %ss): " "$_PT_PROMPT_TIMEOUT" + read -t "$_PT_PROMPT_TIMEOUT" -r PLAN_TUNE_INSTALL_REPLY /dev/null || PLAN_TUNE_INSTALL_REPLY="" case "$PLAN_TUNE_INSTALL_REPLY" in y|Y) _install_plan_tune_hooks diff --git a/test/fixtures/parity-baseline-v1.53.0.0.json b/test/fixtures/parity-baseline-v1.53.0.0.json new file mode 100644 index 000000000..d3736bcc8 --- /dev/null +++ b/test/fixtures/parity-baseline-v1.53.0.0.json @@ -0,0 +1,633 @@ +{ + "tag": "v1.53.0.0", + "capturedAt": "2026-05-30T18:00:56.209Z", + "capturedFromCommit": "352f6a57", + "capturedFromBranch": "garrytan/setup-plan-tune-hooks-flags", + "totalSkills": 52, + "totalCorpusBytes": 3179282, + "estTotalCatalogTokens": 4116, + "topHeaviest": [ + { + "skill": "ship", + "skillMdBytes": 170491, + "skillMdLines": 3153, + "estTokens": 42623, + "tmplBytes": 53240, + "descriptionLen": 291, + "hasGateEval": true, + "hasPeriodicEval": true + }, + { + "skill": "plan-ceo-review", + "skillMdBytes": 137751, + "skillMdLines": 2290, + "estTokens": 34438, + "tmplBytes": 63461, + "descriptionLen": 794, + "hasGateEval": true, + "hasPeriodicEval": true + }, + { + "skill": "office-hours", + "skillMdBytes": 118280, + "skillMdLines": 2161, + "estTokens": 29570, + "tmplBytes": 55534, + "descriptionLen": 860, + "hasGateEval": true, + "hasPeriodicEval": false + }, + { + "skill": "plan-design-review", + "skillMdBytes": 112728, + "skillMdLines": 2019, + "estTokens": 28182, + "tmplBytes": 28717, + "descriptionLen": 218, + "hasGateEval": true, + "hasPeriodicEval": true + }, + { + "skill": "plan-devex-review", + "skillMdBytes": 111292, + "skillMdLines": 2212, + "estTokens": 27823, + "tmplBytes": 35773, + "descriptionLen": 250, + "hasGateEval": true, + "hasPeriodicEval": true + }, + { + "skill": "spec", + "skillMdBytes": 109688, + "skillMdLines": 2239, + "estTokens": 27422, + "tmplBytes": 30590, + "descriptionLen": 282, + "hasGateEval": true, + "hasPeriodicEval": false + }, + { + "skill": "plan-eng-review", + "skillMdBytes": 107655, + "skillMdLines": 1849, + "estTokens": 26914, + "tmplBytes": 26302, + "descriptionLen": 231, + "hasGateEval": true, + "hasPeriodicEval": true + }, + { + "skill": "design-review", + "skillMdBytes": 96618, + "skillMdLines": 1936, + "estTokens": 24155, + "tmplBytes": 11674, + "descriptionLen": 304, + "hasGateEval": true, + "hasPeriodicEval": false + }, + { + "skill": "review", + "skillMdBytes": 95012, + "skillMdLines": 1766, + "estTokens": 23753, + "tmplBytes": 14099, + "descriptionLen": 205, + "hasGateEval": true, + "hasPeriodicEval": false + }, + { + "skill": "land-and-deploy", + "skillMdBytes": 92850, + "skillMdLines": 1860, + "estTokens": 23213, + "tmplBytes": 48624, + "descriptionLen": 160, + "hasGateEval": true, + "hasPeriodicEval": false + } + ], + "skills": { + "autoplan": { + "skill": "autoplan", + "skillMdBytes": 91834, + "skillMdLines": 1788, + "estTokens": 22959, + "tmplBytes": 45271, + "descriptionLen": 366, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "benchmark": { + "skill": "benchmark", + "skillMdBytes": 33266, + "skillMdLines": 747, + "estTokens": 8317, + "tmplBytes": 9378, + "descriptionLen": 213, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "benchmark-models": { + "skill": "benchmark-models", + "skillMdBytes": 29333, + "skillMdLines": 622, + "estTokens": 7333, + "tmplBytes": 6631, + "descriptionLen": 217, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "browse": { + "skill": "browse", + "skillMdBytes": 48151, + "skillMdLines": 930, + "estTokens": 12038, + "tmplBytes": 10805, + "descriptionLen": 181, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "canary": { + "skill": "canary", + "skillMdBytes": 48069, + "skillMdLines": 994, + "estTokens": 12017, + "tmplBytes": 8033, + "descriptionLen": 180, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "careful": { + "skill": "careful", + "skillMdBytes": 2551, + "skillMdLines": 68, + "estTokens": 638, + "tmplBytes": 2435, + "descriptionLen": 315, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "codex": { + "skill": "codex", + "skillMdBytes": 80584, + "skillMdLines": 1523, + "estTokens": 20146, + "tmplBytes": 34143, + "descriptionLen": 187, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "context-restore": { + "skill": "context-restore", + "skillMdBytes": 42457, + "skillMdLines": 852, + "estTokens": 10614, + "tmplBytes": 5255, + "descriptionLen": 238, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "context-save": { + "skill": "context-save", + "skillMdBytes": 46654, + "skillMdLines": 970, + "estTokens": 11664, + "tmplBytes": 9293, + "descriptionLen": 168, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "cso": { + "skill": "cso", + "skillMdBytes": 78849, + "skillMdLines": 1462, + "estTokens": 19712, + "tmplBytes": 35646, + "descriptionLen": 196, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "design-consultation": { + "skill": "design-consultation", + "skillMdBytes": 80186, + "skillMdLines": 1565, + "estTokens": 20047, + "tmplBytes": 25899, + "descriptionLen": 888, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "design-html": { + "skill": "design-html", + "skillMdBytes": 67511, + "skillMdLines": 1453, + "estTokens": 16878, + "tmplBytes": 22567, + "descriptionLen": 233, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "design-review": { + "skill": "design-review", + "skillMdBytes": 96618, + "skillMdLines": 1936, + "estTokens": 24155, + "tmplBytes": 11674, + "descriptionLen": 304, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "design-shotgun": { + "skill": "design-shotgun", + "skillMdBytes": 63800, + "skillMdLines": 1315, + "estTokens": 15950, + "tmplBytes": 13331, + "descriptionLen": 786, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "devex-review": { + "skill": "devex-review", + "skillMdBytes": 65377, + "skillMdLines": 1237, + "estTokens": 16344, + "tmplBytes": 7984, + "descriptionLen": 201, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "document-generate": { + "skill": "document-generate", + "skillMdBytes": 54797, + "skillMdLines": 1194, + "estTokens": 13699, + "tmplBytes": 15939, + "descriptionLen": 334, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "document-release": { + "skill": "document-release", + "skillMdBytes": 59827, + "skillMdLines": 1248, + "estTokens": 14957, + "tmplBytes": 20974, + "descriptionLen": 192, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "freeze": { + "skill": "freeze", + "skillMdBytes": 3154, + "skillMdLines": 92, + "estTokens": 789, + "tmplBytes": 3038, + "descriptionLen": 503, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "gstack-upgrade": { + "skill": "gstack-upgrade", + "skillMdBytes": 10817, + "skillMdLines": 285, + "estTokens": 2704, + "tmplBytes": 10667, + "descriptionLen": 163, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "guard": { + "skill": "guard", + "skillMdBytes": 3297, + "skillMdLines": 91, + "estTokens": 824, + "tmplBytes": 3181, + "descriptionLen": 686, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "health": { + "skill": "health", + "skillMdBytes": 48880, + "skillMdLines": 1018, + "estTokens": 12220, + "tmplBytes": 11617, + "descriptionLen": 184, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "investigate": { + "skill": "investigate", + "skillMdBytes": 51373, + "skillMdLines": 1016, + "estTokens": 12843, + "tmplBytes": 11561, + "descriptionLen": 1379, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "ios-clean": { + "skill": "ios-clean", + "skillMdBytes": 42009, + "skillMdLines": 817, + "estTokens": 10502, + "tmplBytes": 3851, + "descriptionLen": 252, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "ios-design-review": { + "skill": "ios-design-review", + "skillMdBytes": 42595, + "skillMdLines": 819, + "estTokens": 10649, + "tmplBytes": 4417, + "descriptionLen": 209, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "ios-fix": { + "skill": "ios-fix", + "skillMdBytes": 41724, + "skillMdLines": 815, + "estTokens": 10431, + "tmplBytes": 3574, + "descriptionLen": 187, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "ios-qa": { + "skill": "ios-qa", + "skillMdBytes": 48235, + "skillMdLines": 935, + "estTokens": 12059, + "tmplBytes": 10090, + "descriptionLen": 223, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "ios-sync": { + "skill": "ios-sync", + "skillMdBytes": 41701, + "skillMdLines": 808, + "estTokens": 10425, + "tmplBytes": 3544, + "descriptionLen": 269, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "land-and-deploy": { + "skill": "land-and-deploy", + "skillMdBytes": 92850, + "skillMdLines": 1860, + "estTokens": 23213, + "tmplBytes": 48624, + "descriptionLen": 160, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "landing-report": { + "skill": "landing-report", + "skillMdBytes": 44949, + "skillMdLines": 878, + "estTokens": 11237, + "tmplBytes": 6806, + "descriptionLen": 195, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "learn": { + "skill": "learn", + "skillMdBytes": 42686, + "skillMdLines": 895, + "estTokens": 10672, + "tmplBytes": 5594, + "descriptionLen": 178, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "make-pdf": { + "skill": "make-pdf", + "skillMdBytes": 29890, + "skillMdLines": 670, + "estTokens": 7473, + "tmplBytes": 5546, + "descriptionLen": 177, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "office-hours": { + "skill": "office-hours", + "skillMdBytes": 118280, + "skillMdLines": 2161, + "estTokens": 29570, + "tmplBytes": 55534, + "descriptionLen": 860, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "open-gstack-browser": { + "skill": "open-gstack-browser", + "skillMdBytes": 47095, + "skillMdLines": 958, + "estTokens": 11774, + "tmplBytes": 7702, + "descriptionLen": 204, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "pair-agent": { + "skill": "pair-agent", + "skillMdBytes": 47903, + "skillMdLines": 1014, + "estTokens": 11976, + "tmplBytes": 8548, + "descriptionLen": 167, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "plan-ceo-review": { + "skill": "plan-ceo-review", + "skillMdBytes": 137751, + "skillMdLines": 2290, + "estTokens": 34438, + "tmplBytes": 63461, + "descriptionLen": 794, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "plan-design-review": { + "skill": "plan-design-review", + "skillMdBytes": 112728, + "skillMdLines": 2019, + "estTokens": 28182, + "tmplBytes": 28717, + "descriptionLen": 218, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "plan-devex-review": { + "skill": "plan-devex-review", + "skillMdBytes": 111292, + "skillMdLines": 2212, + "estTokens": 27823, + "tmplBytes": 35773, + "descriptionLen": 250, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "plan-eng-review": { + "skill": "plan-eng-review", + "skillMdBytes": 107655, + "skillMdLines": 1849, + "estTokens": 26914, + "tmplBytes": 26302, + "descriptionLen": 231, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "plan-tune": { + "skill": "plan-tune", + "skillMdBytes": 64017, + "skillMdLines": 1355, + "estTokens": 16004, + "tmplBytes": 26922, + "descriptionLen": 325, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "qa": { + "skill": "qa", + "skillMdBytes": 74827, + "skillMdLines": 1626, + "estTokens": 18707, + "tmplBytes": 12701, + "descriptionLen": 218, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "qa-only": { + "skill": "qa-only", + "skillMdBytes": 57385, + "skillMdLines": 1198, + "estTokens": 14346, + "tmplBytes": 3851, + "descriptionLen": 165, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "retro": { + "skill": "retro", + "skillMdBytes": 83853, + "skillMdLines": 1754, + "estTokens": 20963, + "tmplBytes": 42427, + "descriptionLen": 648, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "review": { + "skill": "review", + "skillMdBytes": 95012, + "skillMdLines": 1766, + "estTokens": 23753, + "tmplBytes": 14099, + "descriptionLen": 205, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "scrape": { + "skill": "scrape", + "skillMdBytes": 44605, + "skillMdLines": 891, + "estTokens": 11151, + "tmplBytes": 5220, + "descriptionLen": 167, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "setup-browser-cookies": { + "skill": "setup-browser-cookies", + "skillMdBytes": 26618, + "skillMdLines": 594, + "estTokens": 6655, + "tmplBytes": 2724, + "descriptionLen": 222, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "setup-deploy": { + "skill": "setup-deploy", + "skillMdBytes": 44891, + "skillMdLines": 923, + "estTokens": 11223, + "tmplBytes": 7780, + "descriptionLen": 197, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "setup-gbrain": { + "skill": "setup-gbrain", + "skillMdBytes": 81964, + "skillMdLines": 1777, + "estTokens": 20491, + "tmplBytes": 44851, + "descriptionLen": 323, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "ship": { + "skill": "ship", + "skillMdBytes": 170491, + "skillMdLines": 3153, + "estTokens": 42623, + "tmplBytes": 53240, + "descriptionLen": 291, + "hasGateEval": true, + "hasPeriodicEval": true + }, + "skillify": { + "skill": "skillify", + "skillMdBytes": 54498, + "skillMdLines": 1172, + "estTokens": 13625, + "tmplBytes": 15107, + "descriptionLen": 233, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "spec": { + "skill": "spec", + "skillMdBytes": 109688, + "skillMdLines": 2239, + "estTokens": 27422, + "tmplBytes": 30590, + "descriptionLen": 282, + "hasGateEval": true, + "hasPeriodicEval": false + }, + "sync-gbrain": { + "skill": "sync-gbrain", + "skillMdBytes": 53201, + "skillMdLines": 1070, + "estTokens": 13300, + "tmplBytes": 16077, + "descriptionLen": 299, + "hasGateEval": false, + "hasPeriodicEval": false + }, + "unfreeze": { + "skill": "unfreeze", + "skillMdBytes": 1504, + "skillMdLines": 49, + "estTokens": 376, + "tmplBytes": 1386, + "descriptionLen": 199, + "hasGateEval": false, + "hasPeriodicEval": false + } + } +}