mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-01 19:25:10 +02:00
fix: zsh glob compatibility across all skill templates (v0.12.8.1) (#559)
* fix: replace zsh-incompatible raw globs with find-based alternatives and setopt guards Zsh's NOMATCH option (on by default) causes raw globs like `*.yaml` and `*deploy*` to throw errors when no files match, instead of silently expanding to nothing as bash does. The preamble resolver already handled this correctly with find, but 38 glob instances across 13 templates and 2 resolvers still used raw shell globs. Two fix approaches based on complexity: - find-based replacement for cat/for/ls-with-pipes patterns (.github/workflows/) - setopt +o nomatch guard for simple ls -t patterns (~/.gstack/, ~/.claude/) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: regenerate SKILL.md files from updated templates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: bump version and changelog (v0.12.8.1) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add zsh glob safety test + fix 2 missed resolver globs Adds a test that scans all generated SKILL.md bash blocks for raw glob patterns and verifies they have either a find-based replacement or a setopt +o nomatch guard. The test immediately caught 2 unguarded blocks in review.ts (design doc re-check and plan file discovery). Also syncs package.json version to 0.12.8.1. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+4
-3
@@ -358,7 +358,7 @@ ls go.mod 2>/dev/null && echo "STACK: Go"
|
||||
ls Cargo.toml 2>/dev/null && echo "STACK: Rust"
|
||||
ls pom.xml build.gradle 2>/dev/null && echo "STACK: JVM"
|
||||
ls composer.json 2>/dev/null && echo "STACK: PHP"
|
||||
ls *.csproj *.sln 2>/dev/null && echo "STACK: .NET"
|
||||
find . -maxdepth 1 \( -name '*.csproj' -o -name '*.sln' \) 2>/dev/null | grep -q . && echo "STACK: .NET"
|
||||
```
|
||||
|
||||
**Framework detection:**
|
||||
@@ -395,7 +395,8 @@ Map what an attacker sees — both code surface and infrastructure surface.
|
||||
|
||||
**Infrastructure surface:**
|
||||
```bash
|
||||
ls .github/workflows/*.yml .github/workflows/*.yaml .gitlab-ci.yml 2>/dev/null | wc -l
|
||||
setopt +o nomatch 2>/dev/null || true # zsh compat
|
||||
{ find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null; [ -f .gitlab-ci.yml ] && echo .gitlab-ci.yml; } | wc -l
|
||||
find . -maxdepth 4 -name "Dockerfile*" -o -name "docker-compose*.yml" 2>/dev/null
|
||||
find . -maxdepth 4 -name "*.tf" -o -name "*.tfvars" -o -name "kustomization.yaml" 2>/dev/null
|
||||
ls .env .env.* 2>/dev/null
|
||||
@@ -445,7 +446,7 @@ grep -q "^\.env$\|^\.env\.\*" .gitignore 2>/dev/null && echo ".env IS gitignored
|
||||
|
||||
**CI configs with inline secrets (not using secret stores):**
|
||||
```bash
|
||||
for f in .github/workflows/*.yml .github/workflows/*.yaml .gitlab-ci.yml .circleci/config.yml; do
|
||||
for f in $(find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null) .gitlab-ci.yml .circleci/config.yml; do
|
||||
[ -f "$f" ] && grep -n "password:\|token:\|secret:\|api_key:" "$f" | grep -v '\${{' | grep -v 'secrets\.'
|
||||
done 2>/dev/null
|
||||
```
|
||||
|
||||
+4
-3
@@ -73,7 +73,7 @@ ls go.mod 2>/dev/null && echo "STACK: Go"
|
||||
ls Cargo.toml 2>/dev/null && echo "STACK: Rust"
|
||||
ls pom.xml build.gradle 2>/dev/null && echo "STACK: JVM"
|
||||
ls composer.json 2>/dev/null && echo "STACK: PHP"
|
||||
ls *.csproj *.sln 2>/dev/null && echo "STACK: .NET"
|
||||
find . -maxdepth 1 \( -name '*.csproj' -o -name '*.sln' \) 2>/dev/null | grep -q . && echo "STACK: .NET"
|
||||
```
|
||||
|
||||
**Framework detection:**
|
||||
@@ -110,7 +110,8 @@ Map what an attacker sees — both code surface and infrastructure surface.
|
||||
|
||||
**Infrastructure surface:**
|
||||
```bash
|
||||
ls .github/workflows/*.yml .github/workflows/*.yaml .gitlab-ci.yml 2>/dev/null | wc -l
|
||||
setopt +o nomatch 2>/dev/null || true # zsh compat
|
||||
{ find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null; [ -f .gitlab-ci.yml ] && echo .gitlab-ci.yml; } | wc -l
|
||||
find . -maxdepth 4 -name "Dockerfile*" -o -name "docker-compose*.yml" 2>/dev/null
|
||||
find . -maxdepth 4 -name "*.tf" -o -name "*.tfvars" -o -name "kustomization.yaml" 2>/dev/null
|
||||
ls .env .env.* 2>/dev/null
|
||||
@@ -160,7 +161,7 @@ grep -q "^\.env$\|^\.env\.\*" .gitignore 2>/dev/null && echo ".env IS gitignored
|
||||
|
||||
**CI configs with inline secrets (not using secret stores):**
|
||||
```bash
|
||||
for f in .github/workflows/*.yml .github/workflows/*.yaml .gitlab-ci.yml .circleci/config.yml; do
|
||||
for f in $(find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null) .gitlab-ci.yml .circleci/config.yml; do
|
||||
[ -f "$f" ] && grep -n "password:\|token:\|secret:\|api_key:" "$f" | grep -v '\${{' | grep -v 'secrets\.'
|
||||
done 2>/dev/null
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user