Skip to content

Instantly share code, notes, and snippets.

@zeroows
Last active February 18, 2026 17:36
Show Gist options
  • Select an option

  • Save zeroows/5b86f7a38735e4719929c0e7cbbe763b to your computer and use it in GitHub Desktop.

Select an option

Save zeroows/5b86f7a38735e4719929c0e7cbbe763b to your computer and use it in GitHub Desktop.
A self-bootstrapping shell script that sets up and launches a [claude-flow] hive-mind team with Claude Code.
#!/usr/bin/env bash
##############################################################################
# Project — AiDevSquad Hive-Mind Launcher
#
# Reads the hive manifest and starts Claude Code with the team already spinning.
# Check the gist https://gist.github.com/zeroows/5b86f7a38735e4719929c0e7cbbe763b
# Usage:
# ./start-hive.sh # Start hive (interactive)
# ./start-hive.sh "add pushback notification domain" # Start hive with a task
# ./start-hive.sh --resume # Resume last session
# ./start-hive.sh --init # Initialize hive & MCP
##############################################################################
set -euo pipefail
PROJ_ROOT="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJ_ROOT"
HIVE_CONFIG="$PROJ_ROOT/hive-manifest.json"
HIVE_NAME="AiDevSquad"
INIT_MARKER="$PROJ_ROOT/.hive-initialized"
CLAUDE_MD="$PROJ_ROOT/CLAUDE.md"
# Colors
CYAN='\033[0;36m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
DIM='\033[2m'
RESET='\033[0m'
##############################################################################
# Helpers
##############################################################################
check_claude_flow() {
# Check if claude-flow is installed / reachable
if command -v claude-flow &>/dev/null; then
return 0
fi
# Also accept bunx-resolvable (npx cache)
if bunx claude-flow --version &>/dev/null; then
return 0
fi
return 1
}
install_claude_flow() {
echo -e "${CYAN}Installing claude-flow (latest)...${RESET}"
bunx claude-flow@latest init
echo -e "${GREEN}claude-flow installed.${RESET}"
}
check_hive_config() {
[[ -f "$HIVE_CONFIG" ]]
}
generate_hive_config() {
echo -e "${CYAN}Generating hive-manifest.json template...${RESET}"
cat > "$HIVE_CONFIG" <<'MANIFEST'
{
"hiveName": "AiDevSquad",
"topology": "hierarchical",
"queen": {
"name": "ProjectDirector",
"model": "opus",
"role": "Orchestrating the project development pipeline",
"config": {
"thinking": { "type": "adaptive" }
}
},
"agents": [
{
"name": "Architect",
"role": "System design: domain structure, DI patterns, messaging design, state machines, and database schema",
"model": "opus",
"tools": ["file-reader", "web-search"]
},
{
"name": "Researcher",
"role": "Research libraries, framework patterns, best practices, and shared library usage",
"model": "sonnet",
"tools": ["web-search", "file-reader"]
},
{
"name": "Coder",
"role": "Implementation: handlers, services, repositories, consumers, migrations, DTOs, and registry wiring",
"model": "sonnet",
"tools": ["file-writer", "file-reader"]
},
{
"name": "Tester",
"role": "Writing tests: unit tests, integration tests, e2e tests, and validating state transitions",
"model": "sonnet",
"tools": ["file-reader", "file-writer"]
},
{
"name": "Reviewer",
"role": "Code review: verify patterns, error handling, input validation, query correctness, and naming conventions",
"model": "sonnet",
"tools": ["file-reader"]
}
],
"config": {
"model": "sonnet",
"memory": "persistent"
}
}
MANIFEST
echo -e "${GREEN}hive-manifest.json generated at ${HIVE_CONFIG}${RESET}"
echo -e "${DIM} Edit it to customize agent roles for your project.${RESET}"
}
ensure_gitignore() {
local gitignore="$PROJ_ROOT/.gitignore"
local entries=(".swarm/*" ".hive-mind/*" ".claude-flow/*" ".hive-initialized")
# Create .gitignore if it doesn't exist
[[ -f "$gitignore" ]] || touch "$gitignore"
local added=0
for entry in "${entries[@]}"; do
if ! grep -qxF "$entry" "$gitignore"; then
echo "$entry" >> "$gitignore"
((added++))
fi
done
if [[ $added -gt 0 ]]; then
echo -e "${GREEN}Added ${added} entries to .gitignore${RESET}"
else
echo -e "${DIM} .gitignore already has hive entries — skipping.${RESET}"
fi
}
check_claude_md() {
# Exists AND is non-empty
[[ -s "$CLAUDE_MD" ]]
}
generate_claude_md() {
local file_count
file_count=$(git ls-files 2>/dev/null | wc -l | tr -d ' ')
echo -e "${CYAN}Generating CLAUDE.md for project context (${file_count} tracked files)...${RESET}"
echo -e "${DIM} This may take a moment for larger projects.${RESET}"
# Run in background with stdin detached to prevent terminal control conflicts
# Use haiku + restricted tools + limited turns for fast generation
claude -p "Analyze this project and generate a CLAUDE.md file. \
Include: project overview, tech stack, directory structure, build/test/run commands, \
coding conventions, key architectural decisions, and any domain-specific notes. \
Be concise but thorough. Output ONLY the markdown content, no fences." \
--model haiku --tools "Read,Glob,Grep" \
< /dev/null > "$CLAUDE_MD" 2>/dev/null &
local pid=$!
local spin='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local i=0
local elapsed=0
while kill -0 "$pid" 2>/dev/null; do
printf "\r ${DIM}%s %ds elapsed${RESET}" "${spin:i++%${#spin}:1}" "$elapsed"
sleep 1
((elapsed++))
done
printf "\r%-40s\r" " " # clear spinner line
wait "$pid"
local exit_code=$?
if [[ $exit_code -ne 0 ]] || [[ ! -s "$CLAUDE_MD" ]] || head -1 "$CLAUDE_MD" | grep -qi "^error:"; then
echo -e "${RED}Failed to generate CLAUDE.md (exit code: ${exit_code}).${RESET}"
[[ -s "$CLAUDE_MD" ]] && echo -e "${DIM} Output: $(head -1 "$CLAUDE_MD")${RESET}"
echo -e "${YELLOW} You can create it manually or re-run '--init' later.${RESET}"
rm -f "$CLAUDE_MD"
return 1
fi
local lines
lines=$(wc -l < "$CLAUDE_MD" | tr -d ' ')
echo -e "${GREEN}CLAUDE.md generated (${lines} lines, ${elapsed}s) at ${CLAUDE_MD}${RESET}"
}
check_mcp() {
# Check if the claude-flow MCP server is already registered
if claude mcp list 2>/dev/null | grep -q "claude-flow"; then
return 0
fi
return 1
}
setup_mcp() {
echo -e "${CYAN}Setting up claude-flow MCP server...${RESET}"
claude mcp add claude-flow -- bunx -y claude-flow mcp start
echo -e "${GREEN}MCP server 'claude-flow' registered.${RESET}"
}
do_init() {
echo -e "${CYAN}Initializing hive-mind...${RESET}"
# 0. Ensure .gitignore has hive entries
ensure_gitignore
# 1. Ensure hive-manifest.json exists
if check_hive_config; then
echo -e "${DIM} hive-manifest.json already exists — skipping.${RESET}"
else
generate_hive_config
fi
# 2. Ensure claude-flow is installed
if check_claude_flow; then
echo -e "${DIM} claude-flow already available — skipping install.${RESET}"
else
install_claude_flow
fi
# 3. Ensure MCP is configured
if check_mcp; then
echo -e "${DIM} MCP 'claude-flow' already registered — skipping.${RESET}"
else
setup_mcp
fi
# 4. Ensure CLAUDE.md exists
if check_claude_md; then
echo -e "${DIM} CLAUDE.md already exists — skipping generation.${RESET}"
else
generate_claude_md
fi
# 5. Run hive-mind init (non-interactive, hierarchical mesh with strategic queen)
bunx claude-flow hive-mind init --manifest hive-manifest.json \
--topology hierarchical --queen-type strategic --consensus byzantine \
--no-interactive
# Mark as initialized
date -u '+%Y-%m-%dT%H:%M:%SZ' > "$INIT_MARKER"
echo -e "${GREEN}Hive initialized successfully.${RESET}"
}
##############################################################################
# --init flag: initialize hive + MCP and exit
##############################################################################
if [[ "${1:-}" == "--init" ]]; then
do_init
exit 0
fi
##############################################################################
# Pre-flight: warn if not initialized or MCP missing
##############################################################################
NEEDS_INIT=false
if ! check_hive_config; then
echo -e "${YELLOW}hive-manifest.json not found — template will be generated.${RESET}"
NEEDS_INIT=true
fi
if ! check_claude_flow; then
echo -e "${YELLOW}claude-flow is not installed.${RESET}"
NEEDS_INIT=true
fi
if ! check_claude_md; then
echo -e "${YELLOW}CLAUDE.md not found — project context will be generated.${RESET}"
NEEDS_INIT=true
fi
if [[ ! -f "$INIT_MARKER" ]]; then
echo -e "${YELLOW}Hive has not been initialized yet.${RESET}"
NEEDS_INIT=true
fi
if ! check_mcp; then
echo -e "${YELLOW}MCP server 'claude-flow' is not registered.${RESET}"
NEEDS_INIT=true
fi
if [[ "$NEEDS_INIT" == true ]]; then
echo ""
read -rp "$(echo -e "${CYAN}Run initialization now? [Y/n]: ${RESET}")" REPLY
REPLY="${REPLY:-Y}"
if [[ "$REPLY" =~ ^[Yy]$ ]]; then
do_init
echo ""
else
echo -e "${YELLOW}Skipping init — some features may not work.${RESET}"
echo -e "${DIM} You can run './start-hive.sh --init' later.${RESET}"
echo ""
fi
fi
##############################################################################
# Banner
##############################################################################
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${CYAN} <Project Name> — ${HIVE_NAME} Hive-Mind${RESET}"
echo -e "${DIM} Project: $PROJ_ROOT${RESET}"
echo -e "${DIM} Branch: $(git branch --show-current)${RESET}"
echo -e "${DIM} Status: $(git status --porcelain | wc -l | tr -d ' ') uncommitted changes${RESET}"
if [[ -f "$HIVE_CONFIG" ]]; then
AGENTS=$(python3 -c "import json; d=json.load(open('$HIVE_CONFIG')); print(', '.join(a['name'] for a in d['agents']))" 2>/dev/null || echo "unknown")
TOPOLOGY=$(python3 -c "import json; print(json.load(open('$HIVE_CONFIG'))['topology'])" 2>/dev/null || echo "hierarchical")
QUEEN=$(python3 -c "import json; print(json.load(open('$HIVE_CONFIG'))['queen']['name'])" 2>/dev/null || echo "ProjectDirector")
echo -e "${DIM} Hive: ${HIVE_NAME} (${TOPOLOGY})${RESET}"
echo -e "${DIM} Queen: ${QUEEN}${RESET}"
echo -e "${DIM} Agents: ${AGENTS}${RESET}"
else
echo -e "${RED} Hive config not found at ${HIVE_CONFIG}${RESET}"
echo -e "${YELLOW} Run './start-hive.sh --init' to generate it.${RESET}"
exit 1
fi
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo ""
# --resume flag: continue the last session
if [[ "${1:-}" == "--resume" ]]; then
echo -e "${GREEN}Resuming last session...${RESET}"
echo ""
exec claude --resume
fi
# Build the startup prompt that tells Claude to spin up the hive
HIVE_JSON=$(cat "$HIVE_CONFIG")
# Load CLAUDE.md context if available
CLAUDE_MD_CONTENT=""
if [[ -f "$CLAUDE_MD" ]]; then
CLAUDE_MD_CONTENT=$(cat "$CLAUDE_MD")
fi
# Optional user task appended to the hive startup
USER_TASK="${*:-}"
TASK_INSTRUCTION=""
if [[ -n "$USER_TASK" ]]; then
TASK_INSTRUCTION="The user's task for this session is: ${USER_TASK}"
echo -e "${GREEN}Starting hive with task: ${USER_TASK}${RESET}"
else
echo -e "${GREEN}Starting hive (interactive)...${RESET}"
fi
echo ""
STARTUP_PROMPT=$(cat <<PROMPT
Start the ${HIVE_NAME} hive-mind team using this configuration:
\`\`\`json
${HIVE_JSON}
\`\`\`
Project context (from CLAUDE.md):
\`\`\`markdown
${CLAUDE_MD_CONTENT}
\`\`\`
Instructions:
1. Create the team "${HIVE_NAME}" with TeamCreate
2. Use the project context above — every agent should be aware of the stack, conventions, and key paths
3. Create tasks based on the current project needs
4. Spawn agents from the config above using the Task tool:
- Queen "${QUEEN}" acts as project director (you, the lead)
- Spawn each agent with the matching model and role from the config
- Use background mode for agents that can work independently
5. Coordinate the pipeline: Researcher and Architect first, then Coder, then Tester, then Reviewer
6. Track progress via the task list
7. Build commands: \`go build -o service .\`, \`go test ./...\`, migrations via \`./service migrate\`
8. Don\'t add co-authered and make this as a rule
9. Always make an issue, then a PR and link the issue, and the commits are consise and qroup for easy reviews (Rule).
${TASK_INSTRUCTION}
PROMPT
)
# Collapse newlines to spaces so the objective is a single-line arg
STARTUP_PROMPT_ONELINE=$(echo "$STARTUP_PROMPT" | tr '\n' ' ' | sed 's/ */ /g')
exec bunx claude-flow hive-mind spawn "$STARTUP_PROMPT_ONELINE" --claude --queen-type strategic --consensus byzantine
@zeroows
Copy link
Author

zeroows commented Feb 18, 2026



.swarm/*
.hive-mind/*
.claude-flow/*
.hive-initialized

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment