diff --git a/.agents/workflows/test-install.md b/.agents/workflows/test-install.md index 5a58c6d..bdfd4b5 100644 --- a/.agents/workflows/test-install.md +++ b/.agents/workflows/test-install.md @@ -9,30 +9,31 @@ Run this workflow to verify that `install.sh` correctly extracts the `templates/ ## Steps 1. Create and enter a temporary test directory: + ```bash mkdir -p /tmp/test-bootstrap && cd /tmp/test-bootstrap && git init ``` -// turbo -2. Run the install script from the bootstrap repo (using local copy, not remote): +// turbo 2. Run the install script from the bootstrap repo (using local copy, not remote): + ```bash BOOTSTRAP_DEV=1 bash /Users/lynnwallenstein/workspace/penguinranch/bootstrap/install.sh ``` -// turbo -3. Verify the expected file structure exists: +// turbo 3. Verify the expected file structure exists: + ```bash ls -la /tmp/test-bootstrap/.devcontainer/ /tmp/test-bootstrap/scripts/ /tmp/test-bootstrap/docs/decisions/ && echo "✅ Structure intact" || echo "❌ Missing files" ``` -// turbo -4. Verify key files are present: +// turbo 4. Verify key files are present: + ```bash for f in AGENTS.md Makefile .editorconfig .env.example .gitattributes .gitignore .prettierrc CHANGELOG.md LICENSE CODE_OF_CONDUCT.md README.md; do [ -f "/tmp/test-bootstrap/$f" ] && echo "✅ $f" || echo "❌ $f MISSING"; done ``` -// turbo -5. Clean up: +// turbo 5. Clean up: + ```bash rm -rf /tmp/test-bootstrap ``` diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..1fd5d2a --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,12 @@ +FROM mcr.microsoft.com/devcontainers/base:bookworm + +# [Optional] Uncomment this section to install additional OS packages. +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends shellcheck + +# [Optional] Uncomment if you want to install an additional version of node using nvm +# ARG EXTRA_NODE_VERSION=10 +# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" + +# [Optional] Uncomment if you want to install more global node modules +# RUN su node -c "npm install -g " diff --git a/.devcontainer/boot-check.sh b/.devcontainer/boot-check.sh new file mode 100644 index 0000000..dc74b67 --- /dev/null +++ b/.devcontainer/boot-check.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -euo pipefail + +if [ ! -f .env ]; then + echo "⚠️ WARNING: .env file not found." + echo "Please run './scripts/setup-env.sh' in the terminal to initialize your environment variables." +else + echo "✅ .env found. Exporting variables safely..." + while IFS='=' read -r key value; do + # Skip empty lines and comments + if [[ -n "$key" && ! "$key" =~ ^# ]]; then + # Trim leading/trailing whitespace + key="${key#"${key%%[![:space:]]*}"}" + key="${key%"${key##*[![:space:]]}"}" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + export "$key=$value" + fi + done < ".env" + + # Configure Git if found in .env + if [ -n "${GIT_NAME:-}" ]; then + git config --global user.name "$GIT_NAME" + fi + if [ -n "${GIT_EMAIL:-}" ]; then + git config --global user.email "$GIT_EMAIL" + fi + if [ -n "${SSH_PUBLIC_KEY:-}" ]; then + git config --global gpg.format ssh + git config --global user.signingkey "key::${SSH_PUBLIC_KEY}" + git config --global commit.gpgsign true + fi + + # Configure GitHub CLI as credential helper if token is present + if [ -n "${GITHUB_TOKEN:-}" ] && command -v gh &> /dev/null; then + gh auth setup-git + fi +fi \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..7ea54a0 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,41 @@ +{ + "name": "bootstrap", + "build": { + "dockerfile": "Dockerfile", + "args": { "VARIANT": "latest" } + }, + "forwardPorts": [3000, 9222], + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "configureZshAsDefaultShell": true + }, + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/node:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + "postCreateCommand": "bash ./scripts/setup-gemini.sh", + "customizations": { + "vscode": { + "extensions": [ + "esbenp.prettier-vscode", + "GitHub.github-vscode-theme", + "bierner.markdown-mermaid", + "mechatroner.rainbow-csv", + "ms-vscode.makefile-tools", + "ms-azuretools.vscode-containers", + "ms-azuretools.vscode-docker", + "github.vscode-github-actions", + "github.vscode-pull-request-github" + ], + "settings": { + "workbench.startupEditor": "none" + } + } + }, + "postAttachCommand": "code README.md AGENTS.md", + "containerEnv": { + "GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}", + "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}" + }, + "postStartCommand": "/bin/bash ./scripts/start-container.sh" +} diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5e3e53d --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +# Project Environment Variables +# Copy to .env and fill in your details + +# Git Configuration (for signing commits within container) +GIT_NAME= +GIT_EMAIL= +SSH_PUBLIC_KEY= + +# Gemini CLI API Key (for AI tooling inside the Devcontainer) +# Get your key at: https://aistudio.google.com/app/apikey +GEMINI_API_KEY= + +# Add project specific secrets below diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 0000000..f3cd3aa --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,36 @@ +#!/bin/bash +# Commit message hook: enforces Conventional Commits format. +# Installed automatically by `make setup`. +# +# Valid prefixes: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert +# Format: [optional scope]: +# Examples: +# feat: add user authentication +# fix(api): handle null response from endpoint +# docs: update README with setup instructions + +commit_msg_file="$1" +commit_msg=$(cat "$commit_msg_file") + +# Allow merge commits and fixup/squash commits +if echo "$commit_msg" | grep -qE "^(Merge|fixup!|squash!)"; then + exit 0 +fi + +# Validate conventional commit format +pattern="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,}" + +if ! echo "$commit_msg" | head -1 | grep -qE "$pattern"; then + echo "❌ Commit message does not follow Conventional Commits format." + echo "" + echo "Expected: [optional scope]: " + echo "Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert" + echo "" + echo "Examples:" + echo " feat: add user authentication" + echo " fix(api): handle null response" + echo " docs: update README with setup instructions" + echo "" + echo "Your message: $commit_msg" + exit 1 +fi diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..dd8ad56 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,12 @@ +#!/bin/bash +# Pre-commit hook: runs lint checks before allowing a commit. +# Installed automatically by `make setup`. + +# Only lint staged files if make lint is available +if make lint 2>/dev/null; then + echo "✅ Lint checks passed." +else + echo "⚠️ Lint check failed or not configured. Skipping pre-commit lint." + # Exit 0 so commits aren't blocked before the stack is configured + exit 0 +fi diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..431ded7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,27 @@ +## Description + +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. + +## Type of Change + +- [ ] 🐛 Bug fix (non-breaking change which fixes an issue) +- [ ] 🚀 New feature (non-breaking change which adds functionality) +- [ ] 🧹 Chore (refactoring, formatting, dependencies) +- [ ] 📖 Documentation update +- [ ] 🏗 Infrastructure / Environment change + +## How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. + +- [ ] Local manual test +- [ ] CI Automated tests (E2E, Linting, Build) + +## Checklist + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] Any dependent changes have been merged and published in downstream modules diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e6b08db --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + # Maintain GitHub Actions used in this repo + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + + # Maintain Docker base images in the root devcontainer + - package-ecosystem: 'docker' + directory: '/.devcontainer' + schedule: + interval: 'weekly' diff --git a/.github/workflows/devcontainer-test.yml b/.github/workflows/devcontainer-test.yml new file mode 100644 index 0000000..82da4d3 --- /dev/null +++ b/.github/workflows/devcontainer-test.yml @@ -0,0 +1,32 @@ +name: Devcontainer Build Validation + +on: + push: + branches: [main, booting] + pull_request: + branches: [main] + +jobs: + build-root: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build root devcontainer + uses: devcontainers/ci@v0.3 + with: + subFolder: . + push: never + + build-template: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build template devcontainer + uses: devcontainers/ci@v0.3 + with: + subFolder: templates + push: never diff --git a/.github/workflows/e2e-install.yml b/.github/workflows/e2e-install.yml new file mode 100644 index 0000000..38b482d --- /dev/null +++ b/.github/workflows/e2e-install.yml @@ -0,0 +1,52 @@ +name: E2E Install Verification + +on: + push: + branches: [main, booting] + pull_request: + branches: [main] + +jobs: + test-install: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run installer + run: | + mkdir test-project + cd test-project + # We point to the local install.sh but it will still try to download a tarball. + # To test the logic of the script using the CURRENT branch changes, + # we override REPO_TAR_URL to point to this repository's current commit. + export REPO_TAR_URL="https://github.com/${{ github.repository }}/tarball/${{ github.sha }}" + bash ../install.sh + env: + BOOTSTRAP_DEV: 1 + + - name: Verify files + run: | + cd test-project + echo "Verifying critical files exist..." + test -d .devcontainer + test -f .gitignore + test -f Makefile + test -f README.md + test -f AGENTS.md + test -d scripts + test -f scripts/setup-env.sh + test -f scripts/troubleshooting.sh + + echo "Verifying execute permissions..." + test -x scripts/setup-env.sh + test -x scripts/start-container.sh + test -x scripts/troubleshooting.sh + + echo "Verifying no root-only files leaked..." + if [ -f "install.sh" ]; then + echo "Error: install.sh should not be in the project root." + exit 1 + fi + + echo "✅ E2E Verification Passed!" diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml new file mode 100644 index 0000000..cba7f49 --- /dev/null +++ b/.github/workflows/prettier.yml @@ -0,0 +1,23 @@ +name: Formatting Check + +on: + push: + branches: [main, booting] + pull_request: + branches: [main] + +jobs: + prettier: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Run Prettier check + run: | + npx -y prettier --check "**/*.{md,json,yml}" diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 0000000..9d94caf --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,18 @@ +name: Shell Script Linting + +on: + push: + branches: [main, booting] + pull_request: + branches: [main] + +jobs: + shellcheck: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run shellcheck + run: | + shellcheck install.sh .devcontainer/*.sh scripts/*.sh templates/scripts/*.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cb575b --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +# Environment +.env +.env.* +!.env.example + +# Node +node_modules/ +dist/ +build/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.eslintcache + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +venv/ + +# Go +bin/ +obj/ +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.test +*.out + +# Mac +.DS_Store + +# IDEs +.idea/ +.vscode/ +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.swp + +# Testing +.tmp-test/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ca8527e --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2 +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..b1ae22b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,12 @@ +{ + "recommendations": [ + "esbenp.prettier-vscode", + "bierner.markdown-mermaid", + "mechatroner.rainbow-csv", + "ms-vscode.makefile-tools", + "ms-azuretools.vscode-containers", + "ms-azuretools.vscode-docker", + "github.vscode-github-actions", + "github.vscode-pull-request-github" + ] +} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index cb59757..c4a929e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,6 +25,13 @@ The repository is divided into two distinct parts: 1. **The Generator (`install.sh`)**: The script users curl and pipe to bash. It acts as the mechanism for fetching the repository's tarball and extracting the inner `/templates` directory safely onto the user's host machine. 2. **The Payload (`/templates/`)**: This directory contains the exact file structure, dotfiles, and scripts that will become the root directory of the _new downstream project_. +### Devcontainer Boundaries + +It is critical to distinguish between the two development environments in this repository: + +- **Root Devcontainer (`/.devcontainer`)**: This environment is used _only_ for developing the `bootstrap` repository itself (e.g., testing `install.sh`, committing updates to the payload). +- **Template Devcontainer (`/templates/.devcontainer`)**: This is the payload that gets extracted to user machines. Editing files here modifies the _future_ environment of generated projects. **Changes to the root devcontainer are not inherited by downstream templates automatically.** + ### Modifying the Payload (`/templates/`) - Any file added or modified within `templates/` will automatically be downloaded by future users. There is no need to update `install.sh` when simply adding a new file to the template payload. @@ -34,7 +41,7 @@ The repository is divided into two distinct parts: ### Modifying the Generator (`install.sh`) - Changes to `install.sh` should be extremely rare. It must remain lightweight. -- Ensure that the tarball extraction logic (`tar -xz --strip-components=2 "*/templates/"`) remains robust. It relies on GitHub's tarball structure. +- Ensure that the tarball extraction logic (utilizing `--wildcards` for the `/templates` directory) remains robust. It relies on GitHub's tarball structure. ## 📝 Contribution & Maintenance Rules diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c24257c --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +.PHONY: help setup dev test build lint clean + +# Default variables +APP_NAME := {{PROJECT_NAME}} + +help: ## Show available make targets + @echo "Available targets:" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' + +setup: ## Install dependencies and configure git hooks + @git config core.hooksPath .githooks + @chmod +x .githooks/* + @echo "✅ Git hooks configured." + @echo "⚠️ Run your package manager's install command to finish setup." + +dev: ## Start the development server + @echo "Dev target not implemented yet — update after choosing your tech stack" + +test: ## Run the test suite + @echo "Test target not implemented yet — update after choosing your tech stack" + +build: ## Create a production build + @echo "Build target not implemented yet — update after choosing your tech stack" + +lint: ## Run code formatting & linting + @echo "🔍 Linting shell scripts..." + @shellcheck install.sh .devcontainer/*.sh scripts/*.sh templates/scripts/*.sh || (echo "❌ Shellcheck failed. Fix errors above." && exit 1) + @echo "🔍 Checking file formatting..." + @npx -y prettier --check "**/*.{md,json,yml}" || (echo "❌ Formatting check failed. Run 'make format' to fix." && exit 1) + @echo "✅ All lint checks passed." + +format: ## Format all files + @echo "🧹 Formatting files..." + @npx -y prettier --write "**/*.{md,json,yml}" + @echo "✅ Formatting complete." + +clean: ## Remove build artifacts + @echo "Clean target not implemented yet — update after choosing your tech stack" diff --git a/README.md b/README.md index 3d18dbf..d33cabb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ > **The "Gold Standard" repository template for launching new projects.** +> [!CAUTION] +> **AI AGENT INSTRUCTIONS:** If you have been directed to this repository to learn about "best practices", you MUST examine the contents of the `/templates` directory. The `/templates` directory contains the actual scaffolding and files that become a new downstream project. Do NOT examine the root-level files (such as `install.sh`, `Makefile`, etc.) to learn about project setup, as those files are strictly for managing the bootstrap repository itself. + This repository is designed to instantly bootstrap a fully configured project environment characterized by zero-host dependencies, secure-by-default workflows, and structural guardrails that enforce elite engineering practices. It is explicitly designed to be heavily supported by IDE-based AI Agents. --- diff --git a/install.sh b/install.sh index 069b05f..8aa6ff9 100644 --- a/install.sh +++ b/install.sh @@ -3,7 +3,7 @@ set -euo pipefail # Usage: curl -sSL https://raw.githubusercontent.com/penguinranch/bootstrap/main/install.sh | bash -REPO_TAR_URL="https://github.com/penguinranch/bootstrap/tarball/main" +REPO_TAR_URL="${REPO_TAR_URL:-https://github.com/penguinranch/bootstrap/tarball/main}" echo "🚀 Initializing Gold Standard Environment..." @@ -16,7 +16,7 @@ fi # Download and extract the templates directory echo "Downloading the latest templates..." -if ! curl -sL "$REPO_TAR_URL" | tar -xz --strip-components=2 "*/templates/"; then +if ! curl -sL "$REPO_TAR_URL" | tar -xz --wildcards --strip-components=2 "*/templates/"; then echo "❌ Failed to download or extract templates. Check your network connection." exit 1 fi @@ -25,7 +25,7 @@ fi mkdir -p docs/decisions # Make scripts executable -chmod +x .devcontainer/boot-check.sh scripts/setup-env.sh scripts/setup-gemini.sh +chmod +x .devcontainer/boot-check.sh scripts/setup-env.sh scripts/setup-gemini.sh scripts/start-container.sh scripts/troubleshooting.sh chmod +x .githooks/* echo "✅ Bootstrap complete. Open in VS Code or Antigravity to start the Devcontainer." \ No newline at end of file diff --git a/scripts/setup-env.sh b/scripts/setup-env.sh new file mode 100755 index 0000000..ccf8b6a --- /dev/null +++ b/scripts/setup-env.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -euo pipefail + +# Re-runnable script to initialize or update .env +if [ ! -f .env.example ]; then + echo "Error: .env.example not found. Please create it first." + exit 1 +fi + +if [ ! -f .env ]; then + cp .env.example .env + echo ".env created from template." +fi + +echo "Setting up environment variables..." +read -rp "Enter your Git Name: " GIT_NAME +read -rp "Enter your Git Email: " GIT_EMAIL + +echo "" +echo "Optional: SSH Public Key for commit signing." +echo "If you use 1Password as your SSH agent, you can copy the public key string directly." +echo "(e.g., ssh-ed25519 AAAAC3Nz...)" +read -rp "Enter your SSH Public Key (press Enter to skip): " SSH_PUBLIC_KEY + +echo "" +echo "Optional: The Gemini API Key is used by the Gemini CLI inside this Devcontainer." +echo "You can get an API key from: https://aistudio.google.com/app/apikey" +read -rp "Enter your Gemini API Key (press Enter to skip): " GEMINI_API_KEY + +echo "" +echo "Optional: Authenticate with GitHub CLI for automations inside the Devcontainer." +echo "To authenticate, you can run: gh auth login" + +# Portable sed: works on both macOS (BSD sed) and Linux (GNU sed) +portable_sed() { + if sed --version 2>/dev/null | grep -q GNU; then + sed -i "$@" + else + sed -i '' "$@" + fi +} + +# Function to securely update or append inside .env +update_env() { + local key=$1 + local value=$2 + if grep -q "^${key}=" .env; then + portable_sed "s|^${key}=.*|${key}=${value}|" .env + else + echo "${key}=${value}" >> .env + fi +} + +update_env "GIT_NAME" "$GIT_NAME" +update_env "GIT_EMAIL" "$GIT_EMAIL" + +if [ -n "$SSH_PUBLIC_KEY" ]; then + update_env "SSH_PUBLIC_KEY" "$SSH_PUBLIC_KEY" +fi + +# Also configure git locally for the current environment +git config --global user.name "$GIT_NAME" +git config --global user.email "$GIT_EMAIL" + +if [ -n "$SSH_PUBLIC_KEY" ]; then + git config --global gpg.format ssh + git config --global user.signingkey "key::${SSH_PUBLIC_KEY}" + git config --global commit.gpgsign true +fi + +if [ -n "$GEMINI_API_KEY" ]; then + update_env "GEMINI_API_KEY" "$GEMINI_API_KEY" +fi + +# Update the LICENSE file if it exists +if [ -f "LICENSE" ] && [ -n "$GIT_NAME" ]; then + CURRENT_YEAR=$(date +"%Y") + portable_sed "s|\[Year\]|${CURRENT_YEAR}|g" LICENSE + portable_sed "s|\[Full Name\]|${GIT_NAME}|g" LICENSE +fi + +echo "✅ Configuration complete. Restart your terminal or source the .env file." \ No newline at end of file diff --git a/scripts/setup-gemini.sh b/scripts/setup-gemini.sh new file mode 100755 index 0000000..6c74282 --- /dev/null +++ b/scripts/setup-gemini.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail + +# Install Gemini CLI globally +if command -v gemini &> /dev/null; then + echo "Gemini CLI is already installed." +else + echo "Installing Gemini CLI..." + npm install -g @google/gemini-cli +fi + +echo "✅ Gemini CLI setup complete! Run 'gemini' to start." diff --git a/scripts/start-container.sh b/scripts/start-container.sh new file mode 100755 index 0000000..940fa80 --- /dev/null +++ b/scripts/start-container.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -euo pipefail + +# Change to the repository root relative to the script's location +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +echo "🚀 Starting Antigravity Devcontainer environment..." + +# 1. Check existing environment variables and apply Git configuration +echo "Checking environment variables..." +bash ./.devcontainer/boot-check.sh + +# 2. Configure Git hooks via Makefile +echo "Ensuring Git hooks are configured..." +make setup + +echo "✅ Container startup complete." diff --git a/scripts/troubleshooting.sh b/scripts/troubleshooting.sh new file mode 100755 index 0000000..3b89574 --- /dev/null +++ b/scripts/troubleshooting.sh @@ -0,0 +1,84 @@ +#!/bin/bash +set -u + +echo "🔍 Starting Devcontainer Troubleshooting..." +echo "----------------------------------------" + +# Change to the repository root relative to the script's location +cd "$(dirname "${BASH_SOURCE[0]}")/.." || exit + +ISSUE_FOUND=0 + +# 1. Check for .env file +echo "Checking for .env file..." +if [ ! -f .env ]; then + echo "❌ Error: .env file is missing." + if [ -f .env.example ]; then + echo " -> .env.example found. Creating .env from template..." + cp .env.example .env + echo " ✅ .env created. Please run './scripts/setup-env.sh' to populate it." + else + echo " ❌ Error: .env.example is also missing. Cannot create .env block automatically." + ISSUE_FOUND=1 + fi +else + # Basic check to see if .env has been filled out (checking for placeholder values or empty critical values) + if grep -q "YOUR_GIT_NAME_HERE" .env || grep -q "YOUR_GIT_EMAIL_HERE" .env; then + echo "⚠️ Warning: .env file contains placeholder values." + echo " -> Please run './scripts/setup-env.sh' to configure your environment variables." + ISSUE_FOUND=1 + else + echo "✅ .env file found and appears to be configured." + fi +fi +echo "----------------------------------------" + +# 2. Check script permissions +echo "Checking script permissions..." +PERM_ISSUE=0 +for script in scripts/*.sh templates/scripts/*.sh; do + if [ -f "$script" ]; then + if [ ! -x "$script" ]; then + echo "❌ Error: $script is missing execute permissions." + PERM_ISSUE=1 + fi + fi +done + +if [ $PERM_ISSUE -eq 1 ]; then + echo " -> Attempting to fix permissions..." + chmod +x scripts/*.sh templates/scripts/*.sh 2>/dev/null || true + echo " ✅ Added execute permissions to scripts." +else + echo "✅ All scripts have correct execute permissions." +fi +echo "----------------------------------------" + +# 3. Check for specific dependencies (e.g., Make, Git) +echo "Checking dependencies..." +if ! command -v make &> /dev/null; then + echo "❌ Error: 'make' is not installed." + echo " -> Please ensure your Devcontainer has the necessary build tools." + ISSUE_FOUND=1 +else + echo "✅ 'make' is installed." +fi + +if ! command -v git &> /dev/null; then + echo "❌ Error: 'git' is not installed." + echo " -> Git is required for this Devcontainer." + ISSUE_FOUND=1 +else + echo "✅ 'git' is installed." +fi +echo "----------------------------------------" + +# Final summary +if [ $ISSUE_FOUND -eq 1 ]; then + echo "⚠️ Troubleshooting complete, but some issues require your attention." + echo " Please review the warnings and errors above." + exit 1 +else + echo "🚀 Troubleshooting complete. Everything looks good!" + exit 0 +fi diff --git a/templates/.devcontainer/boot-check.sh b/templates/.devcontainer/boot-check.sh index 6560424..0ec767c 100644 --- a/templates/.devcontainer/boot-check.sh +++ b/templates/.devcontainer/boot-check.sh @@ -28,4 +28,9 @@ else git config --global user.signingkey "key::${SSH_PUBLIC_KEY}" git config --global commit.gpgsign true fi + + # Configure GitHub CLI as credential helper if token is present + if [ -n "${GITHUB_TOKEN:-}" ] && command -v gh &> /dev/null; then + gh auth setup-git + fi fi \ No newline at end of file diff --git a/templates/.devcontainer/devcontainer.json b/templates/.devcontainer/devcontainer.json index 454ddf6..8284394 100644 --- a/templates/.devcontainer/devcontainer.json +++ b/templates/.devcontainer/devcontainer.json @@ -18,10 +18,13 @@ "vscode": { "extensions": [ "esbenp.prettier-vscode", - "GitHub.github-vscode-theme", "bierner.markdown-mermaid", "mechatroner.rainbow-csv", - "ms-vscode.makefile-tools" + "ms-vscode.makefile-tools", + "ms-azuretools.vscode-containers", + "ms-azuretools.vscode-docker", + "github.vscode-github-actions", + "github.vscode-pull-request-github" ], "settings": { "workbench.startupEditor": "none" @@ -30,7 +33,8 @@ }, "postAttachCommand": "code README.md AGENTS.md", "containerEnv": { - "GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}" + "GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}", + "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}" }, - "postStartCommand": "/bin/bash ./.devcontainer/boot-check.sh" -} \ No newline at end of file + "postStartCommand": "/bin/bash ./scripts/start-container.sh" +} diff --git a/templates/.env.example b/templates/.env.example index 42be933..5e3e53d 100644 --- a/templates/.env.example +++ b/templates/.env.example @@ -10,9 +10,4 @@ SSH_PUBLIC_KEY= # Get your key at: https://aistudio.google.com/app/apikey GEMINI_API_KEY= -# GitHub Token (for GitHub CLI and AI agents interacting with PRs/Issues) -# Generate a Fine-grained PAT: https://github.com/settings/tokens?type=beta -# Required scopes: 'Pull Requests: Read-only' and 'Contents: Read-only' -GITHUB_TOKEN= - # Add project specific secrets below diff --git a/templates/.githooks/commit-msg b/templates/.githooks/commit-msg old mode 100644 new mode 100755 diff --git a/templates/.githooks/pre-commit b/templates/.githooks/pre-commit old mode 100644 new mode 100755 diff --git a/templates/.github/CODEOWNERS b/templates/.github/CODEOWNERS index 50f0ca5..80674e8 100644 --- a/templates/.github/CODEOWNERS +++ b/templates/.github/CODEOWNERS @@ -1,4 +1,5 @@ -# Default owners for everything +# Default owners for everything. Note: team slugs like @core-maintainers +# are placeholders and must be updated to match teams in your GitHub organization. * @core-maintainers # Architecture decisions require Tech Lead review diff --git a/templates/.github/ISSUE_TEMPLATE/bug_report.md b/templates/.github/ISSUE_TEMPLATE/bug_report.md index 984661e..8b581f5 100644 --- a/templates/.github/ISSUE_TEMPLATE/bug_report.md +++ b/templates/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: "\U0001F41B Bug Report" about: Report a bug or unexpected behavior -title: "[BUG] " +title: '[BUG] ' labels: bug assignees: '' --- diff --git a/templates/.github/ISSUE_TEMPLATE/feature_request.md b/templates/.github/ISSUE_TEMPLATE/feature_request.md index f0a94c4..6b5aa02 100644 --- a/templates/.github/ISSUE_TEMPLATE/feature_request.md +++ b/templates/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: "\U0001F680 Feature Request" about: Suggest a new feature or improvement -title: "[FEATURE] " +title: '[FEATURE] ' labels: enhancement assignees: '' --- diff --git a/templates/.github/dependabot.yml b/templates/.github/dependabot.yml index 782a0ad..0ba72df 100644 --- a/templates/.github/dependabot.yml +++ b/templates/.github/dependabot.yml @@ -1,10 +1,14 @@ version: 2 updates: - - package-ecosystem: "npm" - directory: "/" + - package-ecosystem: 'npm' + directory: '/' schedule: - interval: "weekly" - - package-ecosystem: "github-actions" - directory: "/" + interval: 'weekly' + - package-ecosystem: 'github-actions' + directory: '/' schedule: - interval: "weekly" + interval: 'weekly' + - package-ecosystem: 'docker' + directory: '/.devcontainer' + schedule: + interval: 'weekly' diff --git a/templates/.github/workflows/ci.yml b/templates/.github/workflows/ci.yml index 7a76dd3..fd24ec7 100644 --- a/templates/.github/workflows/ci.yml +++ b/templates/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI Pipeline on: push: - branches: ["main"] + branches: ['main'] pull_request: - branches: ["main"] + branches: ['main'] # Cancel redundant runs on the same branch concurrency: @@ -24,8 +24,8 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: "20.x" - cache: "npm" + node-version: '20.x' + cache: 'npm' - name: Install dependencies run: npm ci --ignore-scripts diff --git a/templates/.github/workflows/security.yml b/templates/.github/workflows/security.yml index d1e383b..46b4bc9 100644 --- a/templates/.github/workflows/security.yml +++ b/templates/.github/workflows/security.yml @@ -2,9 +2,9 @@ name: Security Scan on: push: - branches: ["main"] + branches: ['main'] pull_request: - branches: ["main"] + branches: ['main'] # Cancel redundant runs on the same branch concurrency: @@ -37,6 +37,6 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v4 if: always() && hashFiles('trivy-results.sarif') != '' - continue-on-error: true # SARIF upload requires GitHub Advanced Security (paid for private repos) + continue-on-error: true # SARIF upload requires GitHub Advanced Security (paid for private repos) with: sarif_file: 'trivy-results.sarif' diff --git a/templates/.gitignore b/templates/.gitignore index b99ae2b..2cb575b 100644 --- a/templates/.gitignore +++ b/templates/.gitignore @@ -58,3 +58,6 @@ obj/ !.vscode/launch.json !.vscode/extensions.json *.swp + +# Testing +.tmp-test/ diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 430bd4f..a1d33f4 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -29,6 +29,14 @@ Before implementing any significant change: - **Pragmatism (YAGNI & KISS):** Build for current requirements. Avoid premature abstraction (Rule of Three) and over-engineering. - **Observability:** Code is not complete until it emits the necessary telemetry (logs/traces). +## 🔄 Devcontainer Lifecycle Scripts + +When adding or modifying automation scripts for the devcontainer, you must adhere to the following execution contexts defined in `devcontainer.json`: + +1. **`postCreateCommand`**: Use for heavy, one-time global installations (e.g., global `npm` packages, binaries) that should be baked into the image after the `Dockerfile` completes. Examples: `setup-gemini.sh`. This runs _only once_ when the container is built. +2. **`postStartCommand`**: Use for fast, idempotent environment checks and initializations that must be present every time the developer connects. Examples: `start-container.sh` (which configures git hooks and reads `.env`). This runs _every time_ the container starts or wakes up. +3. **Manual Interactive Scripts**: Any script that requires user interaction (e.g., using `read -p`) must **never** be added to an automated lifecycle hook. If added to `postStartCommand`, the container boot process will hang indefinitely waiting for input on a detached TTY. Examples: `setup-env.sh`. Instead, ensure the idempotent `start-container.sh` script checks for the required state and warns the user to run the interactive script manually. + ## 🏗 Coding Standards - **Linting:** Run Prettier before every commit. The pre-commit hook (`.githooks/pre-commit`) runs `make lint` automatically. @@ -47,7 +55,7 @@ Before implementing any significant change: ## 🤖 Token Optimization & CLI Usage -- **GitHub CLI:** The `gh` command is available in this container and authenticated if you need to create/review PRs, manage issues, or check GitHub Actions status. See [.env.example](.env.example) for required `GITHUB_TOKEN` scopes. +- **GitHub CLI:** The `gh` command is available in this container. Use `gh auth login` to authenticate. This enables seamless GitHub operations and can configure Git as your credential helper. - **Offload Structured Edge-Tasks:** To preserve your context window (tokens) for complex logic, use the Gemini CLI (`@google/gemini-cli`) installed in this container for well-structured tasks. - **Usage:** Run `gemini` in the terminal to start an interactive session, or `gemini -p ""` for one-shot tasks. - **Examples:** Ask the CLI to review code, analyze architecture, or investigate issues—this keeps your IDE context window focused on the primary task. diff --git a/templates/CONTRIBUTING.md b/templates/CONTRIBUTING.md index 6977438..ee952d6 100644 --- a/templates/CONTRIBUTING.md +++ b/templates/CONTRIBUTING.md @@ -13,6 +13,7 @@ Thank you for considering contributing to this project! This guide will help you ### 1. Create an Issue Before starting work, create or find a GitHub issue describing the change. Use the provided issue templates: + - **🐛 Bug Report** for bugs - **🚀 Feature Request** for new features @@ -30,12 +31,12 @@ Use `docs/decisions/000-template.md` as a starting point. Use scoped branch naming: -| Prefix | Use Case | -| ------------ | --------------------------- | -| `feat/...` | New features | -| `fix/...` | Bug fixes | -| `task/...` | Chores, refactors, cleanup | -| `docs/...` | Documentation-only changes | +| Prefix | Use Case | +| ---------- | -------------------------- | +| `feat/...` | New features | +| `fix/...` | Bug fixes | +| `task/...` | Chores, refactors, cleanup | +| `docs/...` | Documentation-only changes | ### 4. Write Code @@ -64,12 +65,12 @@ The `commit-msg` hook enforces this automatically. ## Standards -| Tool | Purpose | -| ----------------- | -------------------------------- | -| **EditorConfig** | Consistent whitespace & encoding | -| **Prettier** | Code formatting | -| **Makefile** | Universal task runner | -| **Git hooks** | Automated quality gates | +| Tool | Purpose | +| ---------------- | -------------------------------- | +| **EditorConfig** | Consistent whitespace & encoding | +| **Prettier** | Code formatting (`make format`) | +| **Makefile** | Universal task runner | +| **Git hooks** | Automated quality gates | ## Need Help? diff --git a/templates/Makefile b/templates/Makefile index 4f807d4..50e673a 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -25,5 +25,8 @@ build: ## Create a production build lint: ## Run code formatting & linting @echo "Lint target not implemented yet — update after choosing your tech stack" +format: ## Format all files + @echo "Format target not implemented yet — update after choosing your tech stack" + clean: ## Remove build artifacts @echo "Clean target not implemented yet — update after choosing your tech stack" diff --git a/templates/README.md b/templates/README.md index 8d8a3a8..5f1a8e0 100644 --- a/templates/README.md +++ b/templates/README.md @@ -33,8 +33,10 @@ Here's what was installed and why: │ └── commit-msg # Enforces Conventional Commits format │ ├── scripts/ # ⚙️ Setup & automation scripts -│ ├── setup-env.sh # Interactive setup for Git credentials & API keys -│ └── setup-gemini.sh # Installs Gemini CLI +│ ├── start-container.sh # [postStartCommand] Fast, idempotent checks +│ ├── setup-env.sh # [Manual] Interactive setup for credentials +│ ├── troubleshooting.sh # [Manual] Diagnose common environment issues +│ └── setup-gemini.sh # [postCreateCommand] Global tool installations │ ├── docs/ │ └── decisions/ # 📝 Architecture Decision Records (ADRs) @@ -68,7 +70,8 @@ Before opening the Devcontainer, define your tech stack. The language and framew > _1. Fill out the `001-initial-tech-stack.md` ADR._ > _2. Update the `.devcontainer/` configuration (Dockerfile and devcontainer.json) for our chosen stack, and replace the `{{PROJECT_NAME}}` placeholder in `devcontainer.json` with the project name._ > _3. Configure the universal `Makefile` and setup `dependabot.yml`._ -> _4. Rewrite `README.md` to describe this new project and how to run it."_ +> _4. Update `SECURITY.md` with your contact details._ +> _5. Rewrite `README.md` to describe this new project and how to run it."_ ### 2. Open in a Devcontainer @@ -82,7 +85,7 @@ Once the container is ready, open a terminal and run: ./scripts/setup-env.sh ``` -This will configure your Git identity, SSH signing, and prompt for any required API keys (Gemini, GitHub). +This will configure your Git identity and prompt for any required API keys (Gemini). For GitHub operations, run `gh auth login` inside the container for seamless HTTPS authentication. Then activate the git hooks and project setup: @@ -90,34 +93,34 @@ Then activate the git hooks and project setup: make setup ``` -> **Note:** If your devcontainer seems to hang after building, or if `git` complains about missing user name and email, you can manually run `./.devcontainer/boot-check.sh` to apply `.env` variables to your environment. +> **Note:** If your devcontainer seems to hang after building, or if `git` complains about missing user name and email, you can manually run `./scripts/start-container.sh` to apply `.env` variables and verify hooks. ### 4. Build Something Great Start developing! Use the universal `Makefile` targets: -| Command | Purpose | -| ------------ | ----------------------------- | -| `make help` | Show all available targets | -| `make setup` | Install deps & configure hooks| -| `make dev` | Start the development server | -| `make test` | Run the test suite | -| `make build` | Create a production build | -| `make lint` | Run code formatting & linting | -| `make clean` | Remove build artifacts | +| Command | Purpose | +| ------------ | ------------------------------ | +| `make help` | Show all available targets | +| `make setup` | Install deps & configure hooks | +| `make dev` | Start the development server | +| `make test` | Run the test suite | +| `make build` | Create a production build | +| `make lint` | Run code formatting & linting | +| `make clean` | Remove build artifacts | --- ## 📚 Key Files to Know -| File | What It Does | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`AGENTS.md`** | Instructions for AI assistants — coding standards, workflow rules, and architectural philosophy. | -| **`Makefile`** | Maps your stack-specific commands to universal targets. Update this once you choose your tech stack. | -| **`.env.example`** | Lists all required environment variables. Copy to `.env` and fill in your values. | -| **`CODEOWNERS`** | Defines who must approve PRs for critical paths (CI, ADRs, Devcontainer). | -| **`CONTRIBUTING.md`** | How to contribute: branch naming, conventional commits, ADR workflow, and PR process. | -| **`SECURITY.md`** | How to report vulnerabilities. Replace `[SECURITY_EMAIL]` with your contact. | +| File | What It Does | +| --------------------- | ---------------------------------------------------------------------------------------------------- | +| **`AGENTS.md`** | Instructions for AI assistants — coding standards, workflow rules, and architectural philosophy. | +| **`Makefile`** | Maps your stack-specific commands to universal targets. Update this once you choose your tech stack. | +| **`.env.example`** | Lists all required environment variables. Copy to `.env` and fill in your values. | +| **`CODEOWNERS`** | Defines who must approve PRs for critical paths (CI, ADRs, Devcontainer). | +| **`CONTRIBUTING.md`** | How to contribute: branch naming, conventional commits, ADR workflow, and PR process. | +| **`SECURITY.md`** | How to report vulnerabilities. Replace `[SECURITY_EMAIL]` with your contact. | --- diff --git a/templates/SECURITY.md b/templates/SECURITY.md index b1c4914..5d1acf1 100644 --- a/templates/SECURITY.md +++ b/templates/SECURITY.md @@ -23,9 +23,9 @@ Include as much of the following information as possible: ## Supported Versions -| Version | Supported | -| ------- | ------------------ | -| Latest | ✅ Yes | +| Version | Supported | +| ------- | --------- | +| Latest | ✅ Yes | ## Security Measures in This Project diff --git a/templates/scripts/setup-env.sh b/templates/scripts/setup-env.sh old mode 100644 new mode 100755 index d1944df..15a4137 --- a/templates/scripts/setup-env.sh +++ b/templates/scripts/setup-env.sh @@ -13,25 +13,23 @@ if [ ! -f .env ]; then fi echo "Setting up environment variables..." -read -p "Enter your Git Name: " GIT_NAME -read -p "Enter your Git Email: " GIT_EMAIL +read -rp "Enter your Git Name: " GIT_NAME +read -rp "Enter your Git Email: " GIT_EMAIL echo "" echo "Optional: SSH Public Key for commit signing." echo "If you use 1Password as your SSH agent, you can copy the public key string directly." echo "(e.g., ssh-ed25519 AAAAC3Nz...)" -read -p "Enter your SSH Public Key (press Enter to skip): " SSH_PUBLIC_KEY +read -rp "Enter your SSH Public Key (press Enter to skip): " SSH_PUBLIC_KEY echo "" echo "Optional: The Gemini API Key is used by the Gemini CLI inside this Devcontainer." echo "You can get an API key from: https://aistudio.google.com/app/apikey" -read -p "Enter your Gemini API Key (press Enter to skip): " GEMINI_API_KEY +read -rp "Enter your Gemini API Key (press Enter to skip): " GEMINI_API_KEY echo "" -echo "Optional: The GitHub Token is used by the GitHub CLI and automations inside the Devcontainer." -echo "You can get a Fine-grained PAT from: https://github.com/settings/tokens?type=beta" -echo "It needs 'Pull Requests: Read-only' and 'Contents: Read-only' access to relevant repositories." -read -p "Enter your GitHub Token (press Enter to skip): " GITHUB_TOKEN +echo "Optional: Authenticate with GitHub CLI for automations inside the Devcontainer." +echo "To authenticate, you can run: gh auth login" # Portable sed: works on both macOS (BSD sed) and Linux (GNU sed) portable_sed() { @@ -74,9 +72,7 @@ if [ -n "$GEMINI_API_KEY" ]; then update_env "GEMINI_API_KEY" "$GEMINI_API_KEY" fi -if [ -n "$GITHUB_TOKEN" ]; then - update_env "GITHUB_TOKEN" "$GITHUB_TOKEN" -fi + # Update the LICENSE file if it exists if [ -f "LICENSE" ] && [ -n "$GIT_NAME" ]; then diff --git a/templates/scripts/setup-gemini.sh b/templates/scripts/setup-gemini.sh old mode 100644 new mode 100755 index b17fc03..6c74282 --- a/templates/scripts/setup-gemini.sh +++ b/templates/scripts/setup-gemini.sh @@ -2,7 +2,11 @@ set -euo pipefail # Install Gemini CLI globally -echo "Installing Gemini CLI..." -npm install -g @google/gemini-cli +if command -v gemini &> /dev/null; then + echo "Gemini CLI is already installed." +else + echo "Installing Gemini CLI..." + npm install -g @google/gemini-cli +fi echo "✅ Gemini CLI setup complete! Run 'gemini' to start." diff --git a/templates/scripts/start-container.sh b/templates/scripts/start-container.sh new file mode 100755 index 0000000..940fa80 --- /dev/null +++ b/templates/scripts/start-container.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -euo pipefail + +# Change to the repository root relative to the script's location +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +echo "🚀 Starting Antigravity Devcontainer environment..." + +# 1. Check existing environment variables and apply Git configuration +echo "Checking environment variables..." +bash ./.devcontainer/boot-check.sh + +# 2. Configure Git hooks via Makefile +echo "Ensuring Git hooks are configured..." +make setup + +echo "✅ Container startup complete." diff --git a/templates/scripts/troubleshooting.sh b/templates/scripts/troubleshooting.sh new file mode 100755 index 0000000..3b89574 --- /dev/null +++ b/templates/scripts/troubleshooting.sh @@ -0,0 +1,84 @@ +#!/bin/bash +set -u + +echo "🔍 Starting Devcontainer Troubleshooting..." +echo "----------------------------------------" + +# Change to the repository root relative to the script's location +cd "$(dirname "${BASH_SOURCE[0]}")/.." || exit + +ISSUE_FOUND=0 + +# 1. Check for .env file +echo "Checking for .env file..." +if [ ! -f .env ]; then + echo "❌ Error: .env file is missing." + if [ -f .env.example ]; then + echo " -> .env.example found. Creating .env from template..." + cp .env.example .env + echo " ✅ .env created. Please run './scripts/setup-env.sh' to populate it." + else + echo " ❌ Error: .env.example is also missing. Cannot create .env block automatically." + ISSUE_FOUND=1 + fi +else + # Basic check to see if .env has been filled out (checking for placeholder values or empty critical values) + if grep -q "YOUR_GIT_NAME_HERE" .env || grep -q "YOUR_GIT_EMAIL_HERE" .env; then + echo "⚠️ Warning: .env file contains placeholder values." + echo " -> Please run './scripts/setup-env.sh' to configure your environment variables." + ISSUE_FOUND=1 + else + echo "✅ .env file found and appears to be configured." + fi +fi +echo "----------------------------------------" + +# 2. Check script permissions +echo "Checking script permissions..." +PERM_ISSUE=0 +for script in scripts/*.sh templates/scripts/*.sh; do + if [ -f "$script" ]; then + if [ ! -x "$script" ]; then + echo "❌ Error: $script is missing execute permissions." + PERM_ISSUE=1 + fi + fi +done + +if [ $PERM_ISSUE -eq 1 ]; then + echo " -> Attempting to fix permissions..." + chmod +x scripts/*.sh templates/scripts/*.sh 2>/dev/null || true + echo " ✅ Added execute permissions to scripts." +else + echo "✅ All scripts have correct execute permissions." +fi +echo "----------------------------------------" + +# 3. Check for specific dependencies (e.g., Make, Git) +echo "Checking dependencies..." +if ! command -v make &> /dev/null; then + echo "❌ Error: 'make' is not installed." + echo " -> Please ensure your Devcontainer has the necessary build tools." + ISSUE_FOUND=1 +else + echo "✅ 'make' is installed." +fi + +if ! command -v git &> /dev/null; then + echo "❌ Error: 'git' is not installed." + echo " -> Git is required for this Devcontainer." + ISSUE_FOUND=1 +else + echo "✅ 'git' is installed." +fi +echo "----------------------------------------" + +# Final summary +if [ $ISSUE_FOUND -eq 1 ]; then + echo "⚠️ Troubleshooting complete, but some issues require your attention." + echo " Please review the warnings and errors above." + exit 1 +else + echo "🚀 Troubleshooting complete. Everything looks good!" + exit 0 +fi