Skip to content
Draft
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
28 changes: 14 additions & 14 deletions .codex/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,33 @@ Follow ECC principles:
# MCP Servers
# Codex supports command-based MCP servers
[mcp_servers.github]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
command = "pnpm"
args = ["dlx", "@modelcontextprotocol/server-github"]

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp@latest"]
command = "pnpm"
args = ["dlx", "@upstash/context7-mcp@latest"]

[mcp_servers.memory]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-memory"]
command = "pnpm"
args = ["dlx", "@modelcontextprotocol/server-memory"]

[mcp_servers.sequential-thinking]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-sequential-thinking"]
command = "pnpm"
args = ["dlx", "@modelcontextprotocol/server-sequential-thinking"]

# Additional MCP servers (uncomment as needed):
# [mcp_servers.supabase]
# command = "npx"
# args = ["-y", "supabase-mcp-server@latest", "--read-only"]
# command = "pnpm"
# args = ["dlx", "supabase-mcp-server@latest", "--read-only"]
#
# [mcp_servers.firecrawl]
# command = "npx"
# args = ["-y", "firecrawl-mcp"]
# command = "pnpm"
# args = ["dlx", "firecrawl-mcp"]
#
# [mcp_servers.railway]
# command = "npx"
# args = ["-y", "@anthropic/railway-mcp"]
# command = "pnpm"
# args = ["dlx", "@anthropic/railway-mcp"]

# Features
[features]
Expand Down
77 changes: 77 additions & 0 deletions scripts/codex-git-hooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash
set -euo pipefail

# ECC Codex Git Hook: pre-commit
# Blocks commits that add high-signal secrets.

if [[ "${ECC_SKIP_GIT_HOOKS:-0}" == "1" || "${ECC_SKIP_PRECOMMIT:-0}" == "1" ]]; then
exit 0
fi

if [[ -f ".ecc-hooks-disable" || -f ".git/ecc-hooks-disable" ]]; then
exit 0
fi

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
exit 0
fi

staged_files="$(git diff --cached --name-only --diff-filter=ACMR || true)"
if [[ -z "$staged_files" ]]; then
exit 0
fi

has_findings=0

scan_added_lines() {
local file="$1"
local name="$2"
local regex="$3"
local added_lines
local hits

added_lines="$(git diff --cached -U0 -- "$file" | awk '/^\+\+\+ /{next} /^\+/{print substr($0,2)}')"
if [[ -z "$added_lines" ]]; then
return 0
fi

if hits="$(printf '%s\n' "$added_lines" | rg -n --pcre2 "$regex" 2>/dev/null)"; then
printf '\n[ECC pre-commit] Potential secret detected (%s) in %s\n' "$name" "$file" >&2
printf '%s\n' "$hits" | head -n 3 >&2
has_findings=1
fi
}

while IFS= read -r file; do
[[ -z "$file" ]] && continue

case "$file" in
*.png|*.jpg|*.jpeg|*.gif|*.svg|*.pdf|*.zip|*.gz|*.lock|pnpm-lock.yaml|package-lock.json|yarn.lock|bun.lockb)
continue
;;
esac

scan_added_lines "$file" "OpenAI key" 'sk-[A-Za-z0-9]{20,}'
scan_added_lines "$file" "GitHub classic token" 'ghp_[A-Za-z0-9]{36}'
scan_added_lines "$file" "GitHub fine-grained token" 'github_pat_[A-Za-z0-9_]{20,}'
scan_added_lines "$file" "AWS access key" 'AKIA[0-9A-Z]{16}'
scan_added_lines "$file" "private key block" '-----BEGIN (RSA|EC|OPENSSH|DSA|PRIVATE) KEY-----'
scan_added_lines "$file" "generic credential assignment" "(?i)\\b(api[_-]?key|secret|password|token)\\b\\s*[:=]\\s*['\\\"][^'\\\"]{12,}['\\\"]"
done <<< "$staged_files"

if [[ "$has_findings" -eq 1 ]]; then
cat >&2 <<'EOF'

[ECC pre-commit] Commit blocked to prevent secret leakage.
Fix:
1) Remove secrets from staged changes.
2) Move secrets to env vars or secret manager.
3) Re-stage and commit again.

Temporary bypass (not recommended):
ECC_SKIP_PRECOMMIT=1 git commit ...
EOF
exit 1
fi

exit 0
110 changes: 110 additions & 0 deletions scripts/codex-git-hooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env bash
set -euo pipefail

# ECC Codex Git Hook: pre-push
# Runs a lightweight verification flow before pushes.

if [[ "${ECC_SKIP_GIT_HOOKS:-0}" == "1" || "${ECC_SKIP_PREPUSH:-0}" == "1" ]]; then
exit 0
fi

if [[ -f ".ecc-hooks-disable" || -f ".git/ecc-hooks-disable" ]]; then
exit 0
fi

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
exit 0
fi

ran_any_check=0

log() {
printf '[ECC pre-push] %s\n' "$*"
}

fail() {
printf '[ECC pre-push] FAILED: %s\n' "$*" >&2
exit 1
}

detect_pm() {
if [[ -f "pnpm-lock.yaml" ]]; then
echo "pnpm"
elif [[ -f "bun.lockb" ]]; then
echo "bun"
elif [[ -f "yarn.lock" ]]; then
echo "yarn"
elif [[ -f "package-lock.json" ]]; then
echo "npm"
else
echo "npm"
fi
}

has_node_script() {
local script_name="$1"
node -e 'const fs=require("fs"); const p=JSON.parse(fs.readFileSync("package.json","utf8")); process.exit(p.scripts && p.scripts[process.argv[1]] ? 0 : 1)' "$script_name" >/dev/null 2>&1
}

run_node_script() {
local pm="$1"
local script_name="$2"
case "$pm" in
pnpm) pnpm run "$script_name" ;;
bun) bun run "$script_name" ;;
yarn) yarn "$script_name" ;;
npm) npm run "$script_name" ;;
*) npm run "$script_name" ;;
esac
}

if [[ -f "package.json" ]]; then
pm="$(detect_pm)"
log "Node project detected (package manager: $pm)"

for script_name in lint typecheck test build; do
if has_node_script "$script_name"; then
ran_any_check=1
log "Running: $script_name"
run_node_script "$pm" "$script_name" || fail "$script_name failed"
else
log "Skipping missing script: $script_name"
fi
done

if [[ "${ECC_PREPUSH_AUDIT:-0}" == "1" ]]; then
ran_any_check=1
log "Running dependency audit (ECC_PREPUSH_AUDIT=1)"
case "$pm" in
pnpm) pnpm audit --prod || fail "pnpm audit failed" ;;
bun) bun audit || fail "bun audit failed" ;;
yarn) yarn npm audit --recursive || fail "yarn audit failed" ;;
npm) npm audit --omit=dev || fail "npm audit failed" ;;
*) npm audit --omit=dev || fail "npm audit failed" ;;
esac
fi
fi

if [[ -f "go.mod" ]] && command -v go >/dev/null 2>&1; then
ran_any_check=1
log "Go project detected. Running: go test ./..."
go test ./... || fail "go test failed"
fi

if [[ -f "pyproject.toml" || -f "requirements.txt" ]]; then
if command -v pytest >/dev/null 2>&1; then
ran_any_check=1
log "Python project detected. Running: pytest -q"
pytest -q || fail "pytest failed"
else
log "Python project detected but pytest is not installed. Skipping."
fi
fi

if [[ "$ran_any_check" -eq 0 ]]; then
log "No supported checks found in this repository. Skipping."
else
log "Verification checks passed."
fi

exit 0
Loading