diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fe889ac0d..194d65fe13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.58.6.0] - 2026-06-28 + +## **gstack runs on Windows 11 under Smart App Control without OS bypass.** +## **Resolvers automatically detect binary execution blocks and fall back to source invocation via `bun run`.** + +On Windows 11 with Smart App Control (SAC) enabled, the unsigned binaries bundled with gstack (`browse.exe`, `design.exe`, and `pdf.exe`) are blocked from executing by the OS safety policies. To support Windows developers without requiring them to permanently disable SAC or purchase developer certs, gstack now automatically detects execution failure during setup validation and falls back to invoking the TypeScript source directly via `bun run` (e.g. `bun run browse/src/cli.ts`). Since the `bun` interpreter itself is code-signed and trusted by Windows, it executes the skill logic successfully. Additionally, binary discovery shim paths are updated to prioritize `.exe` suffixes for compatibility under Git-Bash environment. + +### Added +- Setup resolver detection of binary execution failure with `bun run` fallback for `browse`, `design`, and `make-pdf` skills. + +### Changed +- Prioritized `.exe` executable searches in `browse/bin/find-browse` and resolver templates to ensure correct resolution on Windows under Git-Bash. + ## [1.58.5.0] - 2026-06-21 ## **A fresh install now lands on a concrete first move, not a dead end.** diff --git a/CLAUDE.md b/CLAUDE.md index 9848449020..c50148e7e8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -196,6 +196,14 @@ structures. Instead: This applies to test commands, eval commands, deploy commands, and any other project-specific behavior. The project owns its config; gstack reads it. +## Windows Smart App Control (SAC) & git-bash + +On Windows 11 with Smart App Control (SAC) enabled, unsigned local binaries compiled by Bun (e.g. `browse.exe`, `design.exe`, `pdf.exe`) are blocked by the OS policy. +To resolve this without requiring irreversible OS changes (disabling SAC), gstack implements an automatic fallback: +- The setup check templates in `scripts/resolvers/` verify if the compiled binary can execute. +- If execution is blocked, they automatically fall back to invoking the TS files via `bun run` (e.g., `bun run browse/src/cli.ts`). Since `bun` itself is signed and trusted, it runs successfully. +- For Git-Bash support, binary resolution logic always prioritizes checking the `.exe` extension version over the extension-less paths. + ## Writing SKILL templates SKILL.md.tmpl files are **prompt templates read by Claude**, not bash scripts. diff --git a/README.md b/README.md index 4bb177c3a7..35e981e624 100644 --- a/README.md +++ b/README.md @@ -468,7 +468,7 @@ Data is stored in [Supabase](https://supabase.com) (open source Firebase alterna **Codex says "Skipped loading skill(s) due to invalid SKILL.md"?** Your Codex skill descriptions are stale. Fix: `cd ~/.codex/skills/gstack && git pull && ./setup --host codex` — or for repo-local installs: `cd "$(readlink -f .agents/skills/gstack)" && git pull && ./setup --host codex` -**Windows users:** gstack works on Windows 11 via Git Bash or WSL. Node.js is required in addition to Bun — Bun has a known bug with Playwright's pipe transport on Windows ([bun#4253](https://github.com/oven-sh/bun/issues/4253)). The browse server automatically falls back to Node.js. Make sure both `bun` and `node` are on your PATH. +**Windows users:** gstack works on Windows 11 via Git Bash or WSL. Node.js is required in addition to Bun — Bun has a known bug with Playwright's pipe transport on Windows ([bun#4253](https://github.com/oven-sh/bun/issues/4253)). The browse server automatically falls back to Node.js. Make sure both `bun` and `node` are on your PATH. Additionally, if Windows Smart App Control (SAC) blocks execution of local compiled binaries (`browse.exe`, `design.exe`, `pdf.exe`), setup resolvers automatically fall back to running the TypeScript sources directly via `bun run`. On Windows without Developer Mode (MSYS2 / Git Bash), `setup` falls back to file copies instead of symlinks because `ln -snf` produces frozen copies that don't refresh on `git pull`. **Re-run `cd ~/.claude/skills/gstack && ./setup` after every `git pull`** so your skill files match the repo. `setup` prints a one-line note reminding you. Unix and WSL keep symlinks and don't need the re-run. diff --git a/VERSION b/VERSION index 2153ce66b6..c510b88545 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.58.5.0 +1.58.6.0 diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index 9451d2d4f9..f3363b0336 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -540,9 +540,30 @@ Skills that run plan reviews (`/plan-*-review`, `/codex review`) include the EXI ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/browse/SKILL.md b/browse/SKILL.md index a8138dbbc3..7c62341a83 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -543,9 +543,30 @@ State persists between calls (cookies, tabs, login sessions). ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/browse/bin/find-browse b/browse/bin/find-browse index 8f441b499c..25279350c6 100755 --- a/browse/bin/find-browse +++ b/browse/bin/find-browse @@ -4,14 +4,24 @@ DIR="$(cd "$(dirname "$0")/.." && pwd)/dist" if test -x "$DIR/find-browse"; then exec "$DIR/find-browse" "$@" +elif test -x "$DIR/find-browse.exe"; then + exec "$DIR/find-browse.exe" "$@" fi # Fallback: basic discovery with priority chain ROOT=$(git rev-parse --show-toplevel 2>/dev/null) for MARKER in .codex .agents .claude; do + if [ -n "$ROOT" ] && test -x "$ROOT/$MARKER/skills/gstack/browse/dist/browse.exe"; then + echo "$ROOT/$MARKER/skills/gstack/browse/dist/browse.exe" + exit 0 + fi if [ -n "$ROOT" ] && test -x "$ROOT/$MARKER/skills/gstack/browse/dist/browse"; then echo "$ROOT/$MARKER/skills/gstack/browse/dist/browse" exit 0 fi + if test -x "$HOME/$MARKER/skills/gstack/browse/dist/browse.exe"; then + echo "$HOME/$MARKER/skills/gstack/browse/dist/browse.exe" + exit 0 + fi if test -x "$HOME/$MARKER/skills/gstack/browse/dist/browse"; then echo "$HOME/$MARKER/skills/gstack/browse/dist/browse" exit 0 diff --git a/canary/SKILL.md b/canary/SKILL.md index 08d4d7369e..739f3652e5 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -783,9 +783,30 @@ Skills that run plan reviews (`/plan-*-review`, `/codex review`) include the EXI ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 83eed0a2d9..d7c4a824f2 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -869,9 +869,30 @@ If the codebase is empty and purpose is unclear, say: *"I don't have a clear pic ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" @@ -909,17 +930,59 @@ If browse is not available, that's fine — visual research is optional. The ski ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ] && D="$_ROOT/.claude/skills/gstack/design/dist/design" -[ -z "$D" ] && D="$HOME/.claude/skills/gstack/design/dist/design" -if [ -x "$D" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design.exe" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design" +fi +D_OK=0 +if [ -n "$D" ] && [ -x "$D" ]; then + if "$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $_ROOT/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $HOME/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + fi + fi +fi +if [ "$D_OK" -eq 1 ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" diff --git a/design-html/SKILL.md b/design-html/SKILL.md index a480bd62c4..bd72e8b2d7 100644 --- a/design-html/SKILL.md +++ b/design-html/SKILL.md @@ -797,17 +797,59 @@ around obstacles. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ] && D="$_ROOT/.claude/skills/gstack/design/dist/design" -[ -z "$D" ] && D="$HOME/.claude/skills/gstack/design/dist/design" -if [ -x "$D" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design.exe" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design" +fi +D_OK=0 +if [ -n "$D" ] && [ -x "$D" ]; then + if "$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $_ROOT/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $HOME/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + fi + fi +fi +if [ "$D_OK" -eq 1 ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" @@ -925,9 +967,30 @@ else a few taps away with an obvious path to get there. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 6454531625..2151f6edd3 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -856,9 +856,30 @@ After the user chooses, execute their choice (commit or stash), then continue wi ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" @@ -1050,17 +1071,59 @@ Only commit if there are changes. Stage all bootstrap files (config, test direct ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ] && D="$_ROOT/.claude/skills/gstack/design/dist/design" -[ -z "$D" ] && D="$HOME/.claude/skills/gstack/design/dist/design" -if [ -x "$D" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design.exe" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design" +fi +D_OK=0 +if [ -n "$D" ] && [ -x "$D" ]; then + if "$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $_ROOT/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $HOME/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + fi + fi +fi +if [ "$D_OK" -eq 1 ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" diff --git a/design-shotgun/SKILL.md b/design-shotgun/SKILL.md index 3386d18fa5..a44bfd8247 100644 --- a/design-shotgun/SKILL.md +++ b/design-shotgun/SKILL.md @@ -810,17 +810,59 @@ visual brainstorming, not a review process. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ] && D="$_ROOT/.claude/skills/gstack/design/dist/design" -[ -z "$D" ] && D="$HOME/.claude/skills/gstack/design/dist/design" -if [ -x "$D" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design.exe" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design" +fi +D_OK=0 +if [ -n "$D" ] && [ -x "$D" ]; then + if "$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $_ROOT/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $HOME/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + fi + fi +fi +if [ "$D_OK" -eq 1 ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" diff --git a/devex-review/SKILL.md b/devex-review/SKILL.md index 7ef324b3ec..22f04a586e 100644 --- a/devex-review/SKILL.md +++ b/devex-review/SKILL.md @@ -846,9 +846,30 @@ branch name wherever the instructions say "the base branch" or ``. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index 54ebf52c0f..53ed54f0d1 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -800,9 +800,30 @@ Skills that run plan reviews (`/plan-*-review`, `/codex review`) include the EXI ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/make-pdf/SKILL.md b/make-pdf/SKILL.md index 600eb47ca4..90a2b99ebf 100644 --- a/make-pdf/SKILL.md +++ b/make-pdf/SKILL.md @@ -146,10 +146,32 @@ echo "GSTACK_PLAN_MODE: $GSTACK_PLAN_MODE" ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) P="" -[ -n "$MAKE_PDF_BIN" ] && [ -x "$MAKE_PDF_BIN" ] && P="$MAKE_PDF_BIN" -[ -z "$P" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf" ] && P="$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf" -[ -z "$P" ] && P="$HOME/.claude/skills/gstack/make-pdf/dist/pdf" -if [ -x "$P" ]; then +if [ -n "$MAKE_PDF_BIN" ] && [ -x "$MAKE_PDF_BIN" ]; then + P="$MAKE_PDF_BIN" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf.exe" ]; then + P="$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf" ]; then + P="$_ROOT/.claude/skills/gstack/make-pdf/dist/pdf" +elif [ -x "$HOME/.claude/skills/gstack/make-pdf/dist/pdf.exe" ]; then + P="$HOME/.claude/skills/gstack/make-pdf/dist/pdf.exe" +elif [ -x "$HOME/.claude/skills/gstack/make-pdf/dist/pdf" ]; then + P="$HOME/.claude/skills/gstack/make-pdf/dist/pdf" +fi +P_OK=0 +if [ -n "$P" ] && [ -x "$P" ]; then + if "$P" --help >/dev/null 2>&1; then + P_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/make-pdf/src/cli.ts" ]; then + P="bun run $_ROOT/.claude/skills/gstack/make-pdf/src/cli.ts" + P_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/make-pdf/src/cli.ts" ]; then + P="bun run $HOME/.claude/skills/gstack/make-pdf/src/cli.ts" + P_OK=1 + fi + fi +fi +if [ "$P_OK" -eq 1 ]; then echo "MAKE_PDF_READY: $P" alias _p_="$P" # shellcheck alias helper (not exported) export P # available as $P in subsequent blocks within the same skill invocation diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index 83161b8ca9..bb6fb8169c 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -838,9 +838,30 @@ Skills that run plan reviews (`/plan-*-review`, `/codex review`) include the EXI ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/open-gstack-browser/SKILL.md b/open-gstack-browser/SKILL.md index 28fb1ddb27..dc7e42adb0 100644 --- a/open-gstack-browser/SKILL.md +++ b/open-gstack-browser/SKILL.md @@ -805,9 +805,30 @@ anti-bot stealth, and custom branding. You see every action in real time. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/package.json b/package.json index 4727042e5c..ae713d454e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.58.5.0", + "version": "1.58.6.0", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/pair-agent/SKILL.md b/pair-agent/SKILL.md index eed9d171af..273a512d58 100644 --- a/pair-agent/SKILL.md +++ b/pair-agent/SKILL.md @@ -825,9 +825,30 @@ The skill will tell you if one is needed and how to set it up. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index e81f7f12af..5e958c4821 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -1051,17 +1051,59 @@ Report findings before proceeding to Step 0. ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ] && D="$_ROOT/.claude/skills/gstack/design/dist/design" -[ -z "$D" ] && D="$HOME/.claude/skills/gstack/design/dist/design" -if [ -x "$D" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/design/dist/design" ]; then + D="$_ROOT/.claude/skills/gstack/design/dist/design" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design.exe" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design.exe" +elif [ -x "$HOME/.claude/skills/gstack/design/dist/design" ]; then + D="$HOME/.claude/skills/gstack/design/dist/design" +fi +D_OK=0 +if [ -n "$D" ] && [ -x "$D" ]; then + if "$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $_ROOT/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/design/src/cli.ts" ]; then + D="bun run $HOME/.claude/skills/gstack/design/src/cli.ts" + D_OK=1 + fi + fi +fi +if [ "$D_OK" -eq 1 ]; then echo "DESIGN_READY: $D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "BROWSE_READY: $B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index 801a935c06..088bc945dd 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -823,9 +823,30 @@ You are a QA engineer. Test web applications like a real user — click everythi ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/qa/SKILL.md b/qa/SKILL.md index c1ac10253f..da38547f0a 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -900,9 +900,30 @@ After the user chooses, execute their choice (commit or stash), then continue wi ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP" diff --git a/scripts/resolvers/browse.ts b/scripts/resolvers/browse.ts index a0ae37a70e..29a3fae424 100644 --- a/scripts/resolvers/browse.ts +++ b/scripts/resolvers/browse.ts @@ -103,12 +103,33 @@ export function generateBrowseSetup(ctx: TemplateContext): string { return `## SETUP (run this check BEFORE any browse command) \`\`\`bash -_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) +_ROOT=\$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" -[ -z "$B" ] && B="$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" -if [ -x "$B" ]; then - echo "READY: $B" +if [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse.exe" ]; then + B="\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse.exe" +elif [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ]; then + B="\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" +elif [ -x "\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse.exe" ]; then + B="\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse.exe" +elif [ -x "\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" ]; then + B="\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" +fi +B_OK=0 +if [ -n "\$B" ] && [ -x "\$B" ]; then + if "\$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "\$_ROOT/${ctx.paths.localSkillRoot}/browse/src/cli.ts" ]; then + B="bun run \$_ROOT/${ctx.paths.localSkillRoot}/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "\$HOME${ctx.paths.browseDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" ]; then + B="bun run \$HOME${ctx.paths.browseDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" + B_OK=1 + fi + fi +fi +if [ "\$B_OK" -eq 1 ]; then + echo "READY: \$B" else echo "NEEDS_SETUP" fi diff --git a/scripts/resolvers/design.ts b/scripts/resolvers/design.ts index 9f31b36197..0a5f15cd16 100644 --- a/scripts/resolvers/design.ts +++ b/scripts/resolvers/design.ts @@ -789,20 +789,62 @@ export function generateDesignSetup(ctx: TemplateContext): string { return `## DESIGN SETUP (run this check BEFORE any design mockup command) \`\`\`bash -_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) +_ROOT=\$(git rev-parse --show-toplevel 2>/dev/null) D="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ] && D="$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" -[ -z "$D" ] && D="$HOME${ctx.paths.designDir.replace(/^~/, '')}/design" -if [ -x "$D" ]; then - echo "DESIGN_READY: $D" +if [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design.exe" ]; then + D="\$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design.exe" +elif [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" ]; then + D="\$_ROOT/${ctx.paths.localSkillRoot}/design/dist/design" +elif [ -x "\$HOME${ctx.paths.designDir.replace(/^~/, '')}/design.exe" ]; then + D="\$HOME${ctx.paths.designDir.replace(/^~/, '')}/design.exe" +elif [ -x "\$HOME${ctx.paths.designDir.replace(/^~/, '')}/design" ]; then + D="\$HOME${ctx.paths.designDir.replace(/^~/, '')}/design" +fi +D_OK=0 +if [ -n "\$D" ] && [ -x "\$D" ]; then + if "\$D" --help >/dev/null 2>&1; then + D_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "\$_ROOT/${ctx.paths.localSkillRoot}/design/src/cli.ts" ]; then + D="bun run \$_ROOT/${ctx.paths.localSkillRoot}/design/src/cli.ts" + D_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "\$HOME${ctx.paths.designDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" ]; then + D="bun run \$HOME${ctx.paths.designDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" + D_OK=1 + fi + fi +fi +if [ "\$D_OK" -eq 1 ]; then + echo "DESIGN_READY: \$D" else echo "DESIGN_NOT_AVAILABLE" fi B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ] && B="$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" -[ -z "$B" ] && B="$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" -if [ -x "$B" ]; then - echo "BROWSE_READY: $B" +if [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse.exe" ]; then + B="\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse.exe" +elif [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" ]; then + B="\$_ROOT/${ctx.paths.localSkillRoot}/browse/dist/browse" +elif [ -x "\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse.exe" ]; then + B="\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse.exe" +elif [ -x "\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" ]; then + B="\$HOME${ctx.paths.browseDir.replace(/^~/, '')}/browse" +fi +B_OK=0 +if [ -n "\$B" ] && [ -x "\$B" ]; then + if "\$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "\$_ROOT/${ctx.paths.localSkillRoot}/browse/src/cli.ts" ]; then + B="bun run \$_ROOT/${ctx.paths.localSkillRoot}/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "\$HOME${ctx.paths.browseDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" ]; then + B="bun run \$HOME${ctx.paths.browseDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" + B_OK=1 + fi + fi +fi +if [ "\$B_OK" -eq 1 ]; then + echo "BROWSE_READY: \$B" else echo "BROWSE_NOT_AVAILABLE (will use 'open' to view comparison boards)" fi diff --git a/scripts/resolvers/make-pdf.ts b/scripts/resolvers/make-pdf.ts index c73d0bf136..902d2faa6a 100644 --- a/scripts/resolvers/make-pdf.ts +++ b/scripts/resolvers/make-pdf.ts @@ -15,14 +15,36 @@ export function generateMakePdfSetup(ctx: TemplateContext): string { return `## MAKE-PDF SETUP (run this check BEFORE any make-pdf command) \`\`\`bash -_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) +_ROOT=\$(git rev-parse --show-toplevel 2>/dev/null) P="" -[ -n "$MAKE_PDF_BIN" ] && [ -x "$MAKE_PDF_BIN" ] && P="$MAKE_PDF_BIN" -[ -z "$P" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf" ] && P="$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf" -[ -z "$P" ] && P="$HOME${ctx.paths.makePdfDir.replace(/^~/, '')}/pdf" -if [ -x "$P" ]; then - echo "MAKE_PDF_READY: $P" - alias _p_="$P" # shellcheck alias helper (not exported) +if [ -n "\$MAKE_PDF_BIN" ] && [ -x "\$MAKE_PDF_BIN" ]; then + P="\$MAKE_PDF_BIN" +elif [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf.exe" ]; then + P="\$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf.exe" +elif [ -n "\$_ROOT" ] && [ -x "\$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf" ]; then + P="\$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/dist/pdf" +elif [ -x "\$HOME${ctx.paths.makePdfDir.replace(/^~/, '')}/pdf.exe" ]; then + P="\$HOME${ctx.paths.makePdfDir.replace(/^~/, '')}/pdf.exe" +elif [ -x "\$HOME${ctx.paths.makePdfDir.replace(/^~/, '')}/pdf" ]; then + P="\$HOME${ctx.paths.makePdfDir.replace(/^~/, '')}/pdf" +fi +P_OK=0 +if [ -n "\$P" ] && [ -x "\$P" ]; then + if "\$P" --help >/dev/null 2>&1; then + P_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "\$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/src/cli.ts" ]; then + P="bun run \$_ROOT/${ctx.paths.localSkillRoot}/make-pdf/src/cli.ts" + P_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "\$HOME${ctx.paths.makePdfDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" ]; then + P="bun run \$HOME${ctx.paths.makePdfDir.replace(/^~/, '').replace(/\/dist$/, '/src')}/cli.ts" + P_OK=1 + fi + fi +fi +if [ "\$P_OK" -eq 1 ]; then + echo "MAKE_PDF_READY: \$P" + alias _p_="\$P" # shellcheck alias helper (not exported) export P # available as $P in subsequent blocks within the same skill invocation else echo "MAKE_PDF_NOT_AVAILABLE (run './setup' in the gstack repo to build it)" diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 77df27da2c..1606761f1e 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -557,9 +557,30 @@ If `CDP_MODE=true`: tell the user "Not needed — you're connected to your real ```bash _ROOT=$(git rev-parse --show-toplevel 2>/dev/null) B="" -[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/gstack/browse/dist/browse" -[ -z "$B" ] && B="$HOME/.claude/skills/gstack/browse/dist/browse" -if [ -x "$B" ]; then +if [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/gstack/browse/dist/browse" ]; then + B="$_ROOT/.claude/skills/gstack/browse/dist/browse" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse.exe" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse.exe" +elif [ -x "$HOME/.claude/skills/gstack/browse/dist/browse" ]; then + B="$HOME/.claude/skills/gstack/browse/dist/browse" +fi +B_OK=0 +if [ -n "$B" ] && [ -x "$B" ]; then + if "$B" status >/dev/null 2>&1; then + B_OK=1 + else + if command -v bun >/dev/null 2>&1 && [ -f "$_ROOT/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $_ROOT/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + elif command -v bun >/dev/null 2>&1 && [ -f "$HOME/.claude/skills/gstack/browse/src/cli.ts" ]; then + B="bun run $HOME/.claude/skills/gstack/browse/src/cli.ts" + B_OK=1 + fi + fi +fi +if [ "$B_OK" -eq 1 ]; then echo "READY: $B" else echo "NEEDS_SETUP"