---
name: step-init
description: Initialize GitFlow configuration and branches
next_step: null
---

# Step: INIT - Initialize GitFlow

## YOUR TASK:

Set up GitFlow configuration with bare repository, worktrees, and branches.

**ULTRA THINK before creating configuration.**

---

## MANDATORY QUESTIONS

**⛔ ALWAYS ask these 3 questions, even if values can be auto-detected.**
**⛔ ALWAYS detect workspace context (step 2) to show sibling projects.**

| Question | Variable | Auto-detect from |
|----------|----------|------------------|
| Repository URL | `{REPO_URL}` | `git remote get-url origin` |
| Root folder | `{ROOT_FOLDER}` | Parent of current directory |
| Project name | `{PROJECT_NAME}` | Repo name from URL or folder |

**Multi-project principle:** Each repository has its OWN independent GitFlow config. Step 2 scans for sibling projects to provide context, not to share configuration.

**⛔ FOLLOW-UP RULE:** When a user selects a "Custom..." option (custom name, custom path, custom URL), that selection is just a CHOICE, not the actual value. You MUST immediately ask a follow-up question to capture the actual value. Never proceed with a blank or default value.

---

## EXECUTION SEQUENCE:

### 1. Detect Environment (for defaults only)

```bash
# PLATFORM DETECTION (required for correct path handling on WSL/Windows/macOS/Linux)
if [ -f /proc/version ] && grep -qi "microsoft\|wsl" /proc/version 2>/dev/null; then
  GF_PLATFORM="wsl"; GF_SHELL="bash"
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "mingw"* ]] || [[ "$OSTYPE" == "cygwin" ]]; then
  GF_PLATFORM="windows"; GF_SHELL="gitbash"
elif [[ -n "$WINDIR" ]] || [[ -n "$SystemRoot" ]]; then
  GF_PLATFORM="windows"; GF_SHELL="powershell"
elif [[ "$OSTYPE" == "darwin"* ]]; then
  GF_PLATFORM="macos"; GF_SHELL="zsh"
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
  GF_PLATFORM="linux"; GF_SHELL="bash"
else
  GF_PLATFORM="unknown"; GF_SHELL="bash"
fi
echo "Platform: $GF_PLATFORM ($GF_SHELL)"

# Check if we're in a git repository
IS_GIT_REPO=$(git rev-parse --git-dir 2>/dev/null && echo "true" || echo "false")

# Auto-detect values for defaults (will be confirmed by user)
DETECTED_URL=$(git remote get-url origin 2>/dev/null || echo "")
DETECTED_FOLDER=$(dirname "$(pwd)")
DETECTED_NAME=$(basename -s .git "$DETECTED_URL" 2>/dev/null || basename "$(pwd)")

# Detect git provider
if [[ "$DETECTED_URL" == *"github.com"* ]]; then
  GIT_PROVIDER="github"
elif [[ "$DETECTED_URL" == *"dev.azure.com"* ]]; then
  GIT_PROVIDER="azuredevops"
else
  GIT_PROVIDER="unknown"
fi

# Check if already initialized
ALREADY_INITIALIZED=$([ -f ".claude/gitflow/config.json" ] && echo "true" || echo "false")
```

### 2. Detect Workspace (multi-project context)

**Scan the parent directory for sibling projects already using GitFlow:**

```bash
WORKSPACE_DIR=$(dirname "$(pwd)")
SIBLING_PROJECTS=()

for dir in "$WORKSPACE_DIR"/*/; do
  [ -d "$dir/.bare" ] || [ -d "$dir/01-Main" ] || [ -d "$dir/02-Develop" ] && {
    PROJECT_NAME_SIBLING=$(basename "$dir")
    SIBLING_PROJECTS+=("$PROJECT_NAME_SIBLING")
  }
done
```

**Display workspace context:**

```
┌─────────────────────────────────────────────────────────────┐
│  WORKSPACE: {WORKSPACE_DIR}                                  │
├─────────────────────────────────────────────────────────────┤
│  Each project has its OWN independent GitFlow configuration. │
│  This init configures only: {DETECTED_NAME}                  │
├─────────────────────────────────────────────────────────────┤
{if SIBLING_PROJECTS not empty}
│  Existing GitFlow projects:                                  │
│  {for each SIBLING} ✅ {SIBLING_NAME}/                       │
│     ├── .bare/  01-Main/  02-Develop/                        │
│     └── features/  releases/  hotfixes/                      │
│  {end for}                                                   │
│                                                              │
│  New project to initialize:                                  │
│  ⬜ {DETECTED_NAME}/                                         │
│     └── (same structure will be created)                     │
{else}
│  No existing GitFlow projects detected.                      │
│  This will be the first project in this workspace.           │
{endif}
└─────────────────────────────────────────────────────────────┘
```

**Key principle:** GitFlow is **per-repository**. Each project has its own `config.json`, its own worktree structure, and its own version history. Projects do not share configuration.

### 3. Handle Existing Configuration

**If `ALREADY_INITIALIZED` = true:**

Display current configuration and ask what to do:

```yaml
AskUserQuestion:
  - header: "Existing"
    question: "GitFlow is already initialized. Current config will be shown. What do you want to do?"
    options:
      - label: "Reconfigure (Recommended)"
        description: "Review and update all settings"
      - label: "Repair"
        description: "Fix missing directories only"
      - label: "View only"
        description: "Display current config and exit"
      - label: "Cancel"
        description: "Exit without changes"
    multiSelect: false
```

**Handle choices:**
- **Reconfigure**: Continue to step 4 (will ask all questions again)
- **Repair**: Check directories, fix missing ones, exit
- **View only**: Display config, exit
- **Cancel**: Exit immediately

### 4. MANDATORY: Ask Repository URL

**⛔ ALWAYS ask, even if URL was detected:**

```yaml
AskUserQuestion:
  - header: "Repository"
    question: "Repository URL? (detected: {DETECTED_URL})"
    options:
      - label: "Use detected URL (Recommended)"
        description: "{DETECTED_URL}"
      - label: "Enter GitHub URL"
        description: "https://github.com/org/repo.git"
      - label: "Enter Azure DevOps URL"
        description: "https://dev.azure.com/org/project/_git/repo"
      - label: "Local only (no remote)"
        description: "Initialize without remote (limited features)"
    multiSelect: false
```

**⛔ FOLLOW-UP: If user selects "Enter GitHub URL" or "Enter Azure DevOps URL":**

The selected option is just a choice, NOT the actual URL. You MUST ask a follow-up question:

```yaml
AskUserQuestion:
  - header: "URL"
    question: "Enter the repository URL:"
    options:
      - label: "https://github.com/org/repo.git"
        description: "Example GitHub format"
      - label: "https://dev.azure.com/org/project/_git/repo"
        description: "Example Azure DevOps format"
    multiSelect: false
```

The user will type the actual URL via "Other". Then:
- Validate format
- Update `{REPO_URL}` and `{GIT_PROVIDER}`

### 5. MANDATORY: Ask Root Folder

**⛔ ALWAYS ask where to create THIS project's structure:**

**If sibling projects exist, show where it fits:**

```
{WORKSPACE_DIR}/
├── SmartStack.app/    ✅ (gitflow)
├── SmartStack.mcp/    ✅ (gitflow)
├── SmartStack.cli/    ✅ (gitflow)
└── NewProject/        ← THIS PROJECT
    ├── .bare/
    ├── 01-Main/
    ├── 02-Develop/
    ├── features/
    ├── releases/
    └── hotfixes/
```

```yaml
AskUserQuestion:
  - header: "Location"
    question: "Root folder for THIS project? (worktrees will be created here)"
    options:
      - label: "Use parent folder (Recommended)"
        description: "{DETECTED_FOLDER}/ - consistent with {#SIBLING_PROJECTS} sibling project(s)"
      - label: "Use current folder"
        description: "$(pwd)/ - Will create subfolders here"
      - label: "Custom path"
        description: "Specify a different location"
    multiSelect: false
```

**⛔ FOLLOW-UP: If user selects "Custom path":**

You MUST ask a follow-up question to get the actual path:

```yaml
AskUserQuestion:
  - header: "Path"
    question: "Enter the full path for the project root folder:"
    options:
      - label: "{DETECTED_FOLDER}/"
        description: "Parent of current directory"
      - label: "{WORKSPACE_DIR}/"
        description: "Workspace root"
    multiSelect: false
```

The user will type the actual path via "Other". Validate the path exists or can be created.

**Explain the structure that will be created for this project:**

```
{ROOT_FOLDER}/
├── .bare/                 # Git bare repository (this repo only)
├── 01-Main/               # Worktree: main branch
├── 02-Develop/            # Worktree: develop branch
├── features/              # Feature branch worktrees
├── releases/              # Release branch worktrees
└── hotfixes/              # Hotfix branch worktrees
```

### 6. MANDATORY: Ask Project Name

**⛔ ALWAYS ask to confirm project name:**

```yaml
AskUserQuestion:
  - header: "Project"
    question: "Project name? (detected: {DETECTED_NAME})"
    options:
      - label: "Use detected name (Recommended)"
        description: "Project: {DETECTED_NAME}"
      - label: "Custom name"
        description: "Specify a different project name"
    multiSelect: false
```

**⛔ FOLLOW-UP: If user selects "Custom name":**

You MUST ask a follow-up question to get the actual name:

```yaml
AskUserQuestion:
  - header: "Name"
    question: "Enter the project name:"
    options:
      - label: "{DETECTED_NAME}"
        description: "Detected from repository"
      - label: "{DETECTED_NAME}-v2"
        description: "Variant of detected name"
    multiSelect: false
```

The user will type the actual name via "Other". Use this raw input for step 6b.

### 6b. Normalize Project Name (INTELLIGENT)

**⛔ ALWAYS normalize, even if user chose the detected name.**

See [references/init-name-normalization.md](../references/init-name-normalization.md) for the full 5-step process:
1. Parse input into words (split on separators + camelCase)
2. Language detection and spell check (ask user if typos found)
3. Generate all name variants (PascalCase.Dot, PascalCase, kebab-case, snake_case)
4. Ask user to choose PRIMARY format
5. Store all derived names in `PROJECT_VARIANTS`

### 7. Ask Worktree Mode

```yaml
AskUserQuestion:
  - header: "Worktrees"
    question: "How should worktrees be organized?"
    options:
      - label: "Organized (Recommended)"
        description: "01-Main, 02-Develop, features/, releases/, hotfixes/"
      - label: "Simple"
        description: "main/, develop/, features/, releases/, hotfixes/"
      - label: "Disabled"
        description: "No worktrees, use git checkout (not recommended)"
    multiSelect: false
```

### 8. Create Directory Structure

**⛔ CRITICAL: Use ABSOLUTE PATHS for ALL operations. NEVER use `cd` (it does not persist between Bash calls).**
**⛔ Use `git -C <path>` or `GIT_DIR=<path>` instead of `cd` + `git`.**

**Path normalization for WSL:**
```bash
# If on WSL, translate Windows paths to /mnt/ format
# normalize_path_for_platform() from _shared.md handles this
# Example: D:/projects/MyApp → /mnt/d/projects/MyApp
PROJECT_BASE="{ROOT_FOLDER}"  # Must be already normalized for current platform
```

**⛔ Create the COMPLETE structure with absolute paths:**

```bash
PROJECT_BASE="{ROOT_FOLDER}"

# Create subdirectories (absolute paths)
mkdir -p "$PROJECT_BASE/features" "$PROJECT_BASE/releases" "$PROJECT_BASE/hotfixes"

# Create bare repository if not exists (absolute path, no cd)
if [ ! -d "$PROJECT_BASE/.bare" ]; then
  git clone --bare "{REPO_URL}" "$PROJECT_BASE/.bare"

  # Configure bare repo for worktrees (using git -C, no cd)
  git -C "$PROJECT_BASE/.bare" config core.bare false
  git -C "$PROJECT_BASE/.bare" config core.worktree ..
fi

# Create .git pseudo-file pointing to .bare
echo "gitdir: ./.bare" > "$PROJECT_BASE/.git"

# Organized mode: numbered main folders (absolute paths, GIT_DIR instead of cd)
if [ "$WORKTREE_MODE" = "organized" ]; then
  [ ! -d "$PROJECT_BASE/01-Main" ] && \
    GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/01-Main" main

  [ ! -d "$PROJECT_BASE/02-Develop" ] && \
    GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/02-Develop" develop
fi

# Simple mode: named folders (absolute paths)
if [ "$WORKTREE_MODE" = "simple" ]; then
  [ ! -d "$PROJECT_BASE/main" ] && \
    GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/main" main

  [ ! -d "$PROJECT_BASE/develop" ] && \
    GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/develop" develop
fi

# Create gitflow config directory (absolute paths)
DEVELOP_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "02-Develop" || echo "develop")
mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/plans"
mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/logs"
mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/cache"
mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/backup"
```

### 9. Create Configuration

**Write `.claude/gitflow/config.json` in develop worktree.**

See [references/init-config-template.md](../references/init-config-template.md) for:
- Full config.json v2.1.0 template (platform, workspace, repository, git, worktrees, versioning, efcore, workflow, language)
- Path storage convention (`normalize_path_for_storage()` format)

**⛔ IMPORTANT:** Store paths using Windows-style format (`D:/path/to/folder`). The `read_gitflow_config()` in `_shared.md` translates to platform format at read time.

### 10. Detect Version

**⛔ Use absolute paths with `git -C`, no `cd`.**

```bash
DEVELOP_FULL_PATH="$PROJECT_BASE/$DEVELOP_DIR"

# Priority: csproj > Directory.Build.props > package.json > VERSION > tag
VERSION=$(grep -oP '<Version>\K[^<]+' "$DEVELOP_FULL_PATH"/*.csproj 2>/dev/null | head -1)
[ -z "$VERSION" ] && VERSION=$(grep -oP '<Version>\K[^<]+' "$DEVELOP_FULL_PATH/Directory.Build.props" 2>/dev/null)
[ -z "$VERSION" ] && VERSION=$(grep -oP '"version":\s*"\K[^"]+' "$DEVELOP_FULL_PATH/package.json" 2>/dev/null)
[ -z "$VERSION" ] && VERSION=$(cat "$DEVELOP_FULL_PATH/VERSION" 2>/dev/null)
[ -z "$VERSION" ] && VERSION=$(git -C "$DEVELOP_FULL_PATH" describe --tags --abbrev=0 2>/dev/null | sed 's/^v//')
[ -z "$VERSION" ] && VERSION="0.1.0"
```

### 10b. Post-Init Validation

**⛔ MANDATORY: Verify the structure was created correctly.**

See [references/init-config-template.md](../references/init-config-template.md) — Section "Post-Init Validation" for the full bash validation script.

Checks: .bare/HEAD, worktree branches (main/develop), features/releases/hotfixes dirs, .claude/gitflow/ dir.

### 11. Summary

```
╔══════════════════════════════════════════════════════════════════╗
║                    GITFLOW INITIALIZED                            ║
╠══════════════════════════════════════════════════════════════════╣
║  Project:    {PROJECT_NAME}                                       ║
║  Root:       {ROOT_FOLDER}                                        ║
║  Remote:     {REPO_URL}                                           ║
║  Provider:   {GIT_PROVIDER}                                       ║
║  Platform:   {GF_PLATFORM} ({GF_SHELL})                           ║
║  Version:    {VERSION}                                            ║
║  Config:     v2.1.0                                               ║
╠══════════════════════════════════════════════════════════════════╣
║  Structure:                                                        ║
║  ├── .bare/           (git bare repository)                       ║
║  ├── 01-Main/         (main branch)         ✅                    ║
║  ├── 02-Develop/      (develop branch)      ✅                    ║
║  ├── features/        (feature worktrees)   ✅                    ║
║  ├── releases/        (release worktrees)   ✅                    ║
║  └── hotfixes/        (hotfix worktrees)    ✅                    ║
╠══════════════════════════════════════════════════════════════════╣
║  Validation: {ERRORS == 0 ? "ALL CHECKS PASSED" : "errors"}      ║
╠══════════════════════════════════════════════════════════════════╣
{if SIBLING_PROJECTS not empty}
║  Workspace: {WORKSPACE_DIR}                                       ║
║  GitFlow projects: {#SIBLING_PROJECTS + 1} (including this one)   ║
╠══════════════════════════════════════════════════════════════════╣
{endif}
║  Config: 02-Develop/.claude/gitflow/config.json                   ║
╠══════════════════════════════════════════════════════════════════╣
║  NEXT: cd 02-Develop && /gitflow -f <feature-name>                ║
╚══════════════════════════════════════════════════════════════════╝
```

---

## VALIDATION CHECKLIST:

Before completing init, verify:

- [ ] Repository URL confirmed by user
- [ ] Root folder confirmed by user
- [ ] Project name confirmed by user
- [ ] .bare/ directory exists
- [ ] 01-Main/ worktree exists and is on main branch
- [ ] 02-Develop/ worktree exists and is on develop branch
- [ ] features/, releases/, hotfixes/ directories exist
- [ ] .claude/gitflow/config.json created in develop worktree

---

## ERROR HANDLING:

| Error | Solution |
|-------|----------|
| Clone fails | Check URL, network, credentials |
| Worktree exists | Skip or offer to recreate |
| Permission denied | Check folder permissions |
| Branch missing | Create from default branch |

---

## SUCCESS CRITERIA:

- ✅ All 3 mandatory questions asked
- ✅ Complete folder structure created
- ✅ Both main and develop worktrees functional
- ✅ Configuration file created
- ✅ User can navigate to 02-Develop and start working

## NEXT STEP:

Init is standalone. User should `cd 02-Develop` then run `/gitflow -f <feature-name>`.

---

## WORKSPACE MODE (`--workspace`)

When called with `init --workspace`, batch-initialize all repos in a workspace.

See [references/init-config-template.md](../references/init-config-template.md) — Section "Workspace Mode" for the full execution sequence:
1. Ask workspace directory
2. Detect or ask for repos
3. Create `.smartstack-workspace.json`
4. Loop Steps 1-10b per repo with workspace defaults
5. Display global summary
