From 62d4bce14432a06915d80797eec9ea45cd592de8 Mon Sep 17 00:00:00 2001 From: Ossie Irondi Date: Wed, 4 Feb 2026 21:49:24 -0600 Subject: [PATCH 1/3] Add macOS bootstrap + structure checks --- .github/workflows/repo-health.yml | 12 ++- README.md | 10 +- macos/bootstrap.sh | 149 ++++++++++++++++++++++++++++++ macos/zshrc.snippet.sh | 9 ++ scripts/check-structure.ps1 | 3 + scripts/check-structure.sh | 31 +++++++ 6 files changed, 212 insertions(+), 2 deletions(-) create mode 100755 macos/bootstrap.sh create mode 100644 macos/zshrc.snippet.sh create mode 100755 scripts/check-structure.sh diff --git a/.github/workflows/repo-health.yml b/.github/workflows/repo-health.yml index 2d868ac..00c8174 100644 --- a/.github/workflows/repo-health.yml +++ b/.github/workflows/repo-health.yml @@ -5,7 +5,7 @@ on: pull_request: jobs: - structure: + structure-windows: runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -13,3 +13,13 @@ jobs: shell: pwsh run: | ./scripts/check-structure.ps1 + + structure-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Check repo structure + shell: bash + run: | + bash scripts/check-structure.sh + bash -n macos/bootstrap.sh diff --git a/README.md b/README.md index a12cbcd..cfa38b1 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,19 @@ So we built it. ## The Solution +### Windows + ```powershell irm https://raw.githubusercontent.com/Jarvis-AojDevStuio/dev-bootstrap/main/bootstrap.ps1 | iex ``` -One line. Paste it in PowerShell. Walk away. Come back to a fully configured development machine. +### macOS + +```bash +curl -fsSL https://raw.githubusercontent.com/Jarvis-AojDevStuio/dev-bootstrap/main/macos/bootstrap.sh | bash +``` + +One command. Paste it in your terminal. Walk away. Come back to a configured development machine.

dev-bootstrap installation architecture diff --git a/macos/bootstrap.sh b/macos/bootstrap.sh new file mode 100755 index 0000000..941b5a7 --- /dev/null +++ b/macos/bootstrap.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +set -euo pipefail + +# macOS bootstrap entrypoint +# Installs: Xcode CLT, Homebrew, git, curl, fnm (Node), uv (Python), bun, Claude Code, Codex CLI + +MARKER_BEGIN="# ---- dev-bootstrap (macos) ----" +MARKER_END="# ------------------------------" + +log() { + printf "\n== %s ==\n" "$1" +} + +require_cmd() { + command -v "$1" >/dev/null 2>&1 || { + echo "Missing command: $1" >&2 + return 1 + } +} + +ensure_line_in_file_once() { + # Usage: ensure_line_in_file_once + local file="$1" + local line="$2" + mkdir -p "$(dirname "$file")" + touch "$file" + if ! grep -Fqs "$line" "$file"; then + printf "\n%s\n" "$line" >> "$file" + fi +} + +ensure_snippet_in_zshrc_once() { + local zshrc="$HOME/.zshrc" + local snippet_file="$1" + + touch "$zshrc" + + if grep -Fqs "$MARKER_BEGIN" "$zshrc"; then + return 0 + fi + + { + echo + echo "$MARKER_BEGIN" + cat "$snippet_file" + echo "$MARKER_END" + } >> "$zshrc" +} + +log "Preflight: Xcode Command Line Tools" +if ! xcode-select -p >/dev/null 2>&1; then + echo "Xcode Command Line Tools not found. Triggering install..." + xcode-select --install || true + echo "Waiting for Command Line Tools installation to complete..." + # Poll until installed (user must complete GUI prompt) + until xcode-select -p >/dev/null 2>&1; do + sleep 5 + done +fi + +log "Homebrew" +if ! command -v brew >/dev/null 2>&1; then + echo "Homebrew not found. Installing..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +fi + +# Initialize brew in future shells (idempotent) +if [[ -x /opt/homebrew/bin/brew ]]; then + ensure_line_in_file_once "$HOME/.zprofile" 'eval "$(/opt/homebrew/bin/brew shellenv)"' + eval "$(/opt/homebrew/bin/brew shellenv)" +elif [[ -x /usr/local/bin/brew ]]; then + ensure_line_in_file_once "$HOME/.zprofile" 'eval "$(/usr/local/bin/brew shellenv)"' + eval "$(/usr/local/bin/brew shellenv)" +else + # If brew is installed somewhere else, just require it and continue. + require_cmd brew +fi + +log "Base tools (git, curl)" +# Idempotent: brew will verify or install. +brew list git >/dev/null 2>&1 || brew install git +brew list curl >/dev/null 2>&1 || brew install curl + +log "Node via fnm" +brew list fnm >/dev/null 2>&1 || brew install fnm + +# Ensure fnm activation + PATH in zsh +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +SNIPPET="$REPO_ROOT/macos/zshrc.snippet.sh" +require_cmd fnm +ensure_snippet_in_zshrc_once "$SNIPPET" + +# Activate fnm in current shell +# shellcheck disable=SC2046 +if fnm env --use-on-cd >/dev/null 2>&1; then + eval "$(fnm env --use-on-cd)" +fi + +fnm install --lts +fnm default lts-latest +require_cmd node +require_cmd npm +node -v +npm -v + +log "Python via uv" +if ! command -v uv >/dev/null 2>&1; then + curl -LsSf https://astral.sh/uv/install.sh | sh +fi + +# Ensure PATH contains uv default install location +# (actual PATH injection is handled by zsh snippet as well) +require_cmd uv +uv --version +uv python install 3.12 +uv python pin 3.12 +require_cmd python +python --version + +log "Bun" +if ! command -v bun >/dev/null 2>&1; then + curl -fsSL https://bun.com/install | bash +fi +require_cmd bun +bun --version + +log "Claude Code" +if ! command -v claude >/dev/null 2>&1; then + # Per official docs for macOS/Linux + curl -fsSL https://claude.ai/install.sh | bash +fi +if command -v claude >/dev/null 2>&1; then + claude --version || true +else + echo "Claude Code installed, but 'claude' is not on PATH yet. Open a new terminal and try: claude --version" >&2 +fi + +log "Codex CLI" +# Requires npm from the fnm-managed node. +npm list -g --depth=0 @openai/codex >/dev/null 2>&1 || npm install -g @openai/codex +require_cmd codex +codex --version + +log "Finish" +echo "Open a NEW terminal so .zprofile/.zshrc changes load." +echo "Then run (interactive auth):" +echo " - claude" +echo " - codex" diff --git a/macos/zshrc.snippet.sh b/macos/zshrc.snippet.sh new file mode 100644 index 0000000..e982167 --- /dev/null +++ b/macos/zshrc.snippet.sh @@ -0,0 +1,9 @@ +# Minimal PATH + fnm activation for dev-bootstrap (macOS) + +# Ensure common installer bins are on PATH +export PATH="$HOME/.local/bin:$HOME/.bun/bin:$PATH" + +# fnm (Node manager) +if command -v fnm >/dev/null 2>&1; then + eval "$(fnm env --use-on-cd)" +fi diff --git a/scripts/check-structure.ps1 b/scripts/check-structure.ps1 index b5ec625..3e5dd9a 100644 --- a/scripts/check-structure.ps1 +++ b/scripts/check-structure.ps1 @@ -8,7 +8,10 @@ $requiredPaths = @( 'LICENSE', 'bootstrap.ps1', 'wsl/setup.sh', + 'macos/bootstrap.sh', + 'macos/zshrc.snippet.sh', 'scripts/check-structure.ps1', + 'scripts/check-structure.sh', '.github/workflows/repo-health.yml' ) diff --git a/scripts/check-structure.sh b/scripts/check-structure.sh new file mode 100755 index 0000000..809a215 --- /dev/null +++ b/scripts/check-structure.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail + +required_paths=( + "README.md" + "LICENSE" + "bootstrap.ps1" + "wsl/setup.sh" + "macos/bootstrap.sh" + "macos/zshrc.snippet.sh" + "scripts/check-structure.ps1" + "scripts/check-structure.sh" + ".github/workflows/repo-health.yml" +) + +missing=() +for p in "${required_paths[@]}"; do + if [[ ! -e "$p" ]]; then + missing+=("$p") + fi +done + +if (( ${#missing[@]} > 0 )); then + echo "Missing required paths:" >&2 + for m in "${missing[@]}"; do + echo " - $m" >&2 + done + exit 1 +fi + +echo "OK: repo structure looks correct." From d24ad9b21ea4d665d8f93a747f6c92fab5de96d8 Mon Sep 17 00:00:00 2001 From: Ossie Irondi Date: Mon, 9 Feb 2026 13:23:15 -0600 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=94=A7=20fix:=20Replace=20irm|iex=20i?= =?UTF-8?q?nstallers=20with=20winget/npm=20for=20proxy=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch uv, Bun, and Claude Code installation from irm|iex (Invoke-RestMethod piped to Invoke-Expression) to winget and npm. Corporate proxies like Zscaler commonly block the irm|iex pattern, causing silent install failures. Update README to reflect new installation sources. Co-Authored-By: Claude Opus 4.6 --- README.md | 8 ++++---- bootstrap.ps1 | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cfa38b1..407b0c2 100644 --- a/README.md +++ b/README.md @@ -95,14 +95,14 @@ One command. Paste it in your terminal. Walk away. Come back to a configured dev | **fnm** | Latest | Node version manager | [github.com/Schniz/fnm](https://github.com/Schniz/fnm) via winget | | **Node.js** | LTS | JavaScript runtime | Installed via fnm | | **npm** | Bundled | Package manager | Comes with Node.js | -| **uv** | Latest | Python toolchain | [astral.sh/uv](https://docs.astral.sh/uv/) | +| **uv** | Latest | Python toolchain | [astral-sh.uv](https://docs.astral.sh/uv/) via winget | | **Python** | 3.12 (pinned) | Python runtime | Installed via uv | -| **Bun** | Latest | Fast JS runtime | [bun.sh](https://bun.sh/docs/installation) | -| **Claude Code** | Latest | Anthropic AI CLI | [claude.ai](https://code.claude.com/docs/en/setup) | +| **Bun** | Latest | Fast JS runtime | [Oven-sh.Bun](https://bun.sh) via winget | +| **Claude Code** | Latest | Anthropic AI CLI | [@anthropic-ai/claude-code](https://www.npmjs.com/package/@anthropic-ai/claude-code) via npm | | **Codex CLI** | Latest | OpenAI code assistant | [openai.com](https://developers.openai.com/codex/cli) | | **WSL2** | Latest | Linux on Windows | [Microsoft](https://learn.microsoft.com/en-us/windows/wsl/install) *(optional)* | -> Every tool is installed from its **official canonical source**. No third-party mirrors. No mystery binaries. All sources documented inline in `bootstrap.ps1`. +> Every tool is installed from its **official canonical source** via winget or npm — avoiding `irm|iex` patterns that corporate proxies (Zscaler, etc.) often block. No third-party mirrors. No mystery binaries. All sources documented inline in `bootstrap.ps1`. ## How It Works diff --git a/bootstrap.ps1 b/bootstrap.ps1 index 7f57db4..7456ac6 100644 --- a/bootstrap.ps1 +++ b/bootstrap.ps1 @@ -3,9 +3,9 @@ Windows-first bootstrap. Canonical sources: - WSL: https://learn.microsoft.com/en-us/windows/wsl/install -- uv: https://docs.astral.sh/uv/getting-started/installation/ -- Bun: https://bun.com/docs/installation -- Claude Code: https://code.claude.com/docs/en/setup +- uv: https://github.com/microsoft/winget-pkgs (astral-sh.uv) +- Bun: https://github.com/microsoft/winget-pkgs (Oven-sh.Bun) +- Claude Code: https://www.npmjs.com/package/@anthropic-ai/claude-code - Codex CLI: https://developers.openai.com/codex/cli - Git for Windows: https://git-scm.com/download/win - winget: https://learn.microsoft.com/en-us/windows/package-manager/winget/ @@ -126,8 +126,8 @@ node --version 2>$null | Out-Host npm --version 2>$null | Out-Host Section "Python via uv (includes Python management)" -# Official uv PowerShell install: https://docs.astral.sh/uv/getting-started/installation/ -powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +# winget avoids Zscaler/corporate-proxy blocks on irm|iex pattern +WinGetInstall "astral-sh.uv" RefreshPath Need "uv" "If this is your first run, open a new PowerShell window and rerun so PATH updates apply." uv --version 2>$null | Out-Host @@ -137,15 +137,15 @@ Need "python" "If this is your first run, open a new PowerShell window and rerun python --version 2>$null | Out-Host Section "Bun" -# Official Bun PowerShell install: https://bun.com/docs/installation -powershell -c "irm bun.sh/install.ps1 | iex" +# winget avoids Zscaler/corporate-proxy blocks on irm|iex pattern +WinGetInstall "Oven-sh.Bun" RefreshPath Need "bun" "If this is your first run, open a new PowerShell window and rerun so PATH updates apply." bun --version 2>$null | Out-Host Section "Claude Code" -# Official setup docs: https://code.claude.com/docs/en/setup -irm https://claude.ai/install.ps1 | iex +# npm avoids Zscaler/corporate-proxy blocks on irm|iex pattern +npm install -g @anthropic-ai/claude-code RefreshPath Need "claude" "If this is your first run, open a new PowerShell window and rerun so PATH updates apply." claude --version 2>$null | Out-Host From 0b1a1614656b4131e62412f31ffcffea614c3be9 Mon Sep 17 00:00:00 2001 From: Ossie Irondi Date: Mon, 9 Feb 2026 15:05:11 -0600 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20feat(prompts):=20Add=20ChatGPT?= =?UTF-8?q?=20custom=20instructions=20builder=20prompt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an interactive interview-style prompt that generates personalized ChatGPT custom instructions and an "About Me" profile. Users paste the prompt into ChatGPT and answer 11 questions to receive optimized instruction blocks. Co-Authored-By: AOJDevStudio --- prompts/chatgpt-setup.md | 125 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 prompts/chatgpt-setup.md diff --git a/prompts/chatgpt-setup.md b/prompts/chatgpt-setup.md new file mode 100644 index 0000000..a04f946 --- /dev/null +++ b/prompts/chatgpt-setup.md @@ -0,0 +1,125 @@ +# ChatGPT Custom Instructions Builder + +> **How to use:** Paste the prompt below into a new ChatGPT conversation. +> The AI will interview you one question at a time, then generate two blocks: +> 1. **Custom Instructions** — paste into ChatGPT Settings > Custom Instructions +> 2. **About Me** — a longer profile you can reuse anywhere + +--- + +## Prompt + +```text +You are an AI "Instruction Builder." Well-structured custom instructions help ChatGPT give consistently better, more personalized responses tailored to your work. Your job is to interview me and then generate TWO final blocks: + +1) CUSTOM INSTRUCTIONS (short, optimized for ChatGPT's ~1,500 character limit) +2) ABOUT ME (longer profile/context, no character limit) + +## Process Rules + +- Ask questions ONE at a time, in the numbered order below. +- Ask only what you need to fill the template; stop as soon as you have enough. +- If I answer vaguely, ask a single follow-up only when genuinely required. +- If I say "skip" or "N/A", move to the next question without follow-up. +- After question 11, say "Interview complete! Here are your custom blocks:" then output ONLY the two final blocks, each in its own code block. +- Use placeholders like [NOT PROVIDED] ONLY if I refuse to answer a required field. + +## Interview Questions (ask one at a time, in this exact order) + +1) What assistant name/persona should I use? (e.g., Jarvis, Nova, Sage) +2) What is your name? +3) Your role/title? +4) Your location (city/state/country)? +5) List 3 core values (comma-separated). +6) One-sentence mission statement? (skip if unsure) +7) Your industry + what you do (1-2 sentences). +8) Your primary tools/stack (list the main ones). +9) Your technical level: beginner, intermediate, or advanced? +10) Any email/document style rules? (e.g., "always use bullet points", "formal tone") +11) Do you want contact info included in ABOUT ME? If yes, provide any of: website, email, phone, linkedin, company, address. + +## Output Requirements + +CUSTOM INSTRUCTIONS must fit within ~1,500 characters and include ALL of the following: + +- Assistant name/persona line: "Your name is [ASSISTANT_NAME]. Refer to yourself as [ASSISTANT_NAME]." +- Decision rule (this is critical — put it near the top): + - Config/troubleshooting: THE OPTION — single best fix, minimal steps, no alternatives unless asked + - Exploratory/strategy: 2-4 options with tradeoffs + your recommendation +- Clarifying questions only when truly ambiguous +- Response format tags (always use these labels): + - SUMMARY: (one-line answer) + - ACTIONS: (steps to take) + - RESULTS: (code or final output, always in a code block) + - For complex/exploratory topics, also add: + - ANALYSIS: (deeper breakdown) + - NEXT: (recommended next steps) +- Code/text rule: any extracted or provided text goes in a code block; code always goes under RESULTS. +- Web/citations rule: do not browse for simple troubleshooting; browse + cite URLs for time-sensitive or uncertain facts. +- Risk rule: flag moderate risk with WARNING and high risk/irreversible actions with DANGER. + +ABOUT ME must include: +- Name, role/title, location +- Core values (3) +- Mission statement +- Work context (industry, responsibilities, tools/stack, technical level) +- Communication preferences (email/doc rules, plus the same decision rule above) +- Optional contact fields (only if provided) + +## Example Output + +Here is an example of what the TWO final blocks should look like. Adapt the content based on the user's actual interview answers. + +CUSTOM INSTRUCTIONS example: + +Your name is Jarvis. Refer to yourself as Jarvis. + +Decision rule: +- Config/troubleshooting: Give THE OPTION. Single best fix, minimal steps. No alternatives unless I ask. +- Exploratory/strategy: Give 2-4 options with tradeoffs, then your recommendation. + +Only ask clarifying questions when genuinely ambiguous. + +Format every response with: +SUMMARY: one-line answer +ACTIONS: numbered steps to take +RESULTS: code or final output (always in a code block) + +For complex or exploratory topics, add: +ANALYSIS: deeper breakdown of the problem +NEXT: recommended next steps + +Rules: +- Any extracted text or code goes in a code block. Code always under RESULTS. +- Do not browse the web for simple troubleshooting. Browse + cite URLs for time-sensitive or uncertain facts. +- Flag moderate risk with WARNING. Flag high risk or irreversible actions with DANGER. +- Keep responses concise and actionable. I prefer direct answers over lengthy explanations. + +ABOUT ME example: + +Name: Alex Chen +Role: Senior DevOps Engineer +Location: Austin, TX + +Core Values: Automation, Reliability, Continuous Learning + +Mission: Eliminate toil through infrastructure-as-code so teams can focus on building products. + +Work Context: +- Industry: SaaS / Cloud Infrastructure +- Responsibilities: CI/CD pipelines, Kubernetes clusters, monitoring, incident response +- Tools/Stack: Terraform, AWS, Kubernetes, GitHub Actions, Python, Go +- Technical Level: Advanced + +Communication Preferences: +- Emails: concise, bullet points, action items at top +- Documents: headers + short paragraphs, no filler +- Decision rule: single best option for troubleshooting, options with tradeoffs for strategy + +Contact: +- GitHub: github.com/alexchen +- LinkedIn: linkedin.com/in/alexchen +- Company: Acme Cloud Inc. + +Start now with Question 1. +```