$npx -y skills add Soul-Brews-Studio/arra-oracle-skills-cli --skill incubateClone or create repos for active development — the right hand of /learn. Use when user says "incubate [repo]", "work on [repo]", "clone for dev", or wants to set up a dev workflow. Do NOT trigger for study/exploration (use /learn), finding projects (use /trace), or session mining
| 1 | # /incubate — Active Development Workflow |
| 2 | |
| 3 | Clone or create repos for active development → set up branches, make changes, push PRs. |
| 4 | |
| 5 | > "/learn reads the book. /incubate writes the next chapter." |
| 6 | |
| 7 | ## Usage |
| 8 | |
| 9 | ``` |
| 10 | /incubate [url] # Clone via ghq, symlink, ready for dev |
| 11 | /incubate [slug] # Use slug from ψ/memory/slugs.yaml |
| 12 | /incubate [repo-name] # Finds in ghq or creates with default org |
| 13 | /incubate [url] --flash "fix desc" # Issue → branch → fix → PR → offload |
| 14 | /incubate [url] --contribute # Fork if needed → branch per feature → PRs |
| 15 | /incubate --status # List all active ψ/incubate/ with git status |
| 16 | /incubate --status --include-offloaded # Also list offloaded entries from .origins (#280) |
| 17 | /incubate --offload [slug] # Remove symlink, keep ghq clone |
| 18 | /incubate --offload [slug] --purge # Also drop entry from .origins manifest (#280) |
| 19 | /incubate --init # Restore all origins after git clone |
| 20 | ``` |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## Workflow Modes |
| 25 | |
| 26 | | Flag | Scope | Duration | Cleanup | |
| 27 | |------|-------|----------|---------| |
| 28 | | (default) | Long-term dev | Weeks/months | Manual offload | |
| 29 | | `--flash` | Single fix | Minutes | Issue → PR → auto-offload + purge | |
| 30 | | `--contribute` | Multi-feature | Days/weeks | Offload when all PRs done | |
| 31 | | `--status` | Query | — | Read-only listing | |
| 32 | | `--offload` | Cleanup | — | Remove symlink (keep ghq) | |
| 33 | |
| 34 | ``` |
| 35 | incubate → Long-term dev (manual cleanup) |
| 36 | ↓ |
| 37 | --contribute → Push → offload (keep ghq) |
| 38 | ↓ |
| 39 | --flash → Issue → Branch → PR → offload → purge (complete cycle) |
| 40 | ``` |
| 41 | |
| 42 | --- |
| 43 | |
| 44 | ## Directory Structure |
| 45 | |
| 46 | ``` |
| 47 | ψ/incubate/ |
| 48 | ├── .origins # Manifest of incubated repos (committed) |
| 49 | └── OWNER/ |
| 50 | └── REPO/ |
| 51 | ├── origin # Symlink to ghq source (gitignored) |
| 52 | └── REPO.md # Hub file — tracks incubation sessions (committed) |
| 53 | ``` |
| 54 | |
| 55 | **Offload source, keep hub:** |
| 56 | ```bash |
| 57 | unlink ψ/incubate/OWNER/REPO/origin # Remove symlink |
| 58 | # ghq clone preserved for future use |
| 59 | # Hub file (REPO.md) remains in ψ/incubate/OWNER/REPO/ |
| 60 | ``` |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ## /incubate --init |
| 65 | |
| 66 | Restore all origins after cloning (like `git submodule init`): |
| 67 | |
| 68 | ```bash |
| 69 | ROOT="$(pwd)" |
| 70 | while read repo; do |
| 71 | OWNER=$(dirname "$repo") |
| 72 | REPO=$(basename "$repo") |
| 73 | ghq get -u "https://github.com/$repo" |
| 74 | mkdir -p "$ROOT/ψ/incubate/$OWNER/$REPO" |
| 75 | ln -sf "$(ghq root)/github.com/$repo" "$ROOT/ψ/incubate/$OWNER/$REPO/origin" |
| 76 | echo "✓ Restored: $repo" |
| 77 | done < "$ROOT/ψ/incubate/.origins" |
| 78 | ``` |
| 79 | |
| 80 | --- |
| 81 | |
| 82 | ## Step 0: Detect Input Type + Resolve Path |
| 83 | |
| 84 | **CRITICAL: Capture ABSOLUTE paths first:** |
| 85 | ```bash |
| 86 | date "+🕐 %H:%M %Z (%A %d %B %Y)" && ROOT="$(pwd)" |
| 87 | echo "Incubating from: $ROOT" |
| 88 | ``` |
| 89 | |
| 90 | ### If URL (http* or owner/repo format) |
| 91 | |
| 92 | Clone or create, symlink origin, update manifest: |
| 93 | |
| 94 | ```bash |
| 95 | # Replace [URL] with actual URL |
| 96 | URL="[URL]" |
| 97 | ROOT="$(pwd)" |
| 98 | OWNER=$(echo "$URL" | sed -E 's|.*github.com/([^/]+)/.*|\1|') |
| 99 | REPO=$(echo "$URL" | sed -E 's|.*/([^/]+)(\.git)?$|\1|') |
| 100 | SLUG="$OWNER/$REPO" |
| 101 | |
| 102 | # Auto-stash unstaged changes in source clone before pulling (#279). |
| 103 | # `ghq get -u` runs `git pull` under the hood and aborts on dirty trees, |
| 104 | # stranding the ritual. Detect + stash with a clear log + restore hint. |
| 105 | GHQ_ROOT_PRECHECK=$(ghq root 2>/dev/null) |
| 106 | SOURCE_PRECHECK="$GHQ_ROOT_PRECHECK/github.com/$SLUG" |
| 107 | if [ -d "$SOURCE_PRECHECK/.git" ]; then |
| 108 | if [ -n "$(git -C "$SOURCE_PRECHECK" status --porcelain 2>/dev/null)" ]; then |
| 109 | STASH_NAME="pre-incubate-$(date +%Y-%m-%d)" |
| 110 | echo "⚠️ Source clone has uncommitted changes — auto-stashing as '$STASH_NAME'" |
| 111 | git -C "$SOURCE_PRECHECK" stash push -u -m "$STASH_NAME" |
| 112 | echo " (run \`git -C $SOURCE_PRECHECK stash pop\` to restore)" |
| 113 | fi |
| 114 | fi |
| 115 | |
| 116 | # Check if repo exists on GitHub |
| 117 | if gh repo view "$SLUG" --json name &>/dev/null; then |
| 118 | ghq get -u "https://github.com/$SLUG" |
| 119 | else |
| 120 | echo "Repo not found — creating private repo..." |
| 121 | gh repo create "$SLUG" --private --clone=false |
| 122 | ghq get "https://github.com/$SLUG" |
| 123 | GHQ_ROOT=$(ghq root) |
| 124 | LOCAL="$GHQ_ROOT/github.com/$SLUG" |
| 125 | if [ ! -f "$LOCAL/README.md" ]; then |
| 126 | echo "# $REPO" > "$LOCAL/README.md" |
| 127 | git -C "$LOCAL" add README.md |
| 128 | git -C "$LOCAL" commit -m "Initial commit" |
| 129 | git -C "$LOCAL" push origin main 2>/dev/null || git -C "$LOCAL" push origin master |
| 130 | fi |
| 131 | fi |
| 132 | |
| 133 | GHQ_ROOT=$(ghq root) |
| 134 | mkdir -p "$ROOT/ψ/incubate/$OWNER/$REPO" |
| 135 | ln -sf "$GHQ_ROOT/github.com/$OWNER/$REPO" "$ROOT/ψ/incubate/$OWNER/$REPO/origin" |
| 136 | |
| 137 | # Auto-add gitignore pattern if missing (#250) |
| 138 | GITIGNORE="$ROOT/.gitignore" |
| 139 | if [ -f "$GITIGNORE |