Skip to content
Merged
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
12 changes: 11 additions & 1 deletion .github/workflows/repo-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,21 @@ on:
pull_request:

jobs:
structure:
structure-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Check repo structure
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
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<p align="center">
<img src="assets/architecture.png" alt="dev-bootstrap installation architecture" width="500">
Expand All @@ -87,14 +95,14 @@ One line. Paste it in PowerShell. Walk away. Come back to a fully 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

Expand Down
18 changes: 9 additions & 9 deletions bootstrap.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
149 changes: 149 additions & 0 deletions macos/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -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 <file> <line>
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"
9 changes: 9 additions & 0 deletions macos/zshrc.snippet.sh
Original file line number Diff line number Diff line change
@@ -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
125 changes: 125 additions & 0 deletions prompts/chatgpt-setup.md
Original file line number Diff line number Diff line change
@@ -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.
```
Loading