-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·236 lines (212 loc) · 10.5 KB
/
Copy pathsetup.sh
File metadata and controls
executable file
·236 lines (212 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#!/usr/bin/env bash
#
# ai-dev-kit - set up a project for AI-assisted development across
# Claude Code (Claude), OpenAI Codex (GPT), and GitHub Copilot (any model).
#
# Usage: ./setup.sh [TARGET_DIR] [options]
#
set -euo pipefail
ADK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export ADK_ROOT
# ---- defaults -------------------------------------------------------------
TARGET_DIR="$(pwd)"
ASSUME_YES=""; QUIET=""; DRY_RUN=""
AGENTS_ARG=""
CLAUDE_MODEL="claude-opus-4-8"
CODEX_MODEL="gpt-5.5"
CODEX_REASONING="high"
WANT_SUPERPOWERS_ARG="ask" # ask | yes | no
NO_GRAPHIFY=""
GITIGNORE_GENERATED=""
NO_GITIGNORE=""
ON_CONFLICT="prompt" # prompt | backup | skip | overwrite
WANT_GREP_MCP=""; WANT_JOURNAL=""; WANT_HOOKS=""; WANT_PROCESS_HOOKS=""; NO_EXTRAS=""
SUPERPOWERS_REPO="https://github.com/obra/superpowers"
SUPERPOWERS_MARKETPLACE="obra/superpowers-marketplace"
usage() {
cat <<'EOF'
ai-dev-kit setup
Usage: ./setup.sh [TARGET_DIR] [options]
TARGET_DIR Project to configure (default: current directory)
Options:
--agents=LIST Comma list of: claude,codex,copilot (default: prompt)
--claude-model=NAME Default Claude model (default: claude-opus-4-8)
--codex-model=NAME Default Codex/GPT model (default: gpt-5.5)
--codex-reasoning=LEVEL Codex reasoning effort (default: high)
--superpowers Install Superpowers without asking
--no-superpowers Never install Superpowers
--no-graphify Skip graphify install + graph build
--gitignore Add the generated files to .gitignore (keep them local)
--no-gitignore Don't add generated files to .gitignore (and don't prompt)
--on-conflict=POLICY When a file you already have collides: prompt | backup |
skip | overwrite (default: prompt; --yes treats it as backup)
--with-grep Add Grep MCP (search ~1M public repos for usage)
--with-journal Add private-journal MCP (cross-session memory)
--with-hooks Add Claude guardrail hooks (deny secrets/dangerous cmds)
--with-process-hooks Enforce the delivery process (Claude): block prod edits
without a defended plan; refuse to stop on a red build
--with-all-extras Enable all of the optional tools above
--no-extras Don't prompt for optional tools
-y, --yes Non-interactive; accept all defaults
--quiet Reduce log output
--dry-run Print planned actions; write/install nothing
-h, --help Show this help
EOF
}
# ---- arg parsing ----------------------------------------------------------
while [ $# -gt 0 ]; do
case "$1" in
--agents=*) AGENTS_ARG="${1#*=}" ;;
--claude-model=*) CLAUDE_MODEL="${1#*=}" ;;
--codex-model=*) CODEX_MODEL="${1#*=}" ;;
--codex-reasoning=*) CODEX_REASONING="${1#*=}" ;;
--superpowers) WANT_SUPERPOWERS_ARG="yes" ;;
--no-superpowers) WANT_SUPERPOWERS_ARG="no" ;;
--no-graphify) NO_GRAPHIFY=1 ;;
--gitignore) GITIGNORE_GENERATED=1 ;;
--no-gitignore) NO_GITIGNORE=1 ;;
--on-conflict=*) ON_CONFLICT="${1#*=}" ;;
--with-grep) WANT_GREP_MCP=1 ;;
--with-journal) WANT_JOURNAL=1 ;;
--with-hooks) WANT_HOOKS=1 ;;
--with-process-hooks) WANT_PROCESS_HOOKS=1 ;;
--with-all-extras) WANT_GREP_MCP=1; WANT_JOURNAL=1; WANT_HOOKS=1; WANT_PROCESS_HOOKS=1 ;;
--no-extras) NO_EXTRAS=1 ;;
-y|--yes) ASSUME_YES=1 ;;
--quiet) QUIET=1 ;;
--dry-run) DRY_RUN=1 ;;
-h|--help) usage; exit 0 ;;
-*) echo "Unknown option: $1" >&2; usage; exit 2 ;;
*) TARGET_DIR="$1" ;;
esac
shift
done
# ---- source libraries -----------------------------------------------------
for f in log detect prompt idempotent toolinfo mcp \
configure_claude configure_codex configure_copilot \
install_graphify install_journal scaffold; do
# shellcheck source=/dev/null
. "$ADK_ROOT/lib/$f.sh"
done
export ASSUME_YES QUIET DRY_RUN CLAUDE_MODEL CODEX_MODEL CODEX_REASONING \
GITIGNORE_GENERATED ON_CONFLICT SUPERPOWERS_REPO SUPERPOWERS_MARKETPLACE \
WANT_GREP_MCP WANT_JOURNAL WANT_HOOKS WANT_PROCESS_HOOKS
case "$ON_CONFLICT" in
prompt|backup|skip|overwrite) ;;
*) die "Invalid --on-conflict='$ON_CONFLICT' (use: prompt | backup | skip | overwrite)" ;;
esac
# ---- selection helpers ----------------------------------------------------
choose_agents() {
EN_CLAUDE=""; EN_CODEX=""; EN_COPILOT=""
if [ -n "$AGENTS_ARG" ]; then
case ",$AGENTS_ARG," in *,claude,*) EN_CLAUDE=1 ;; esac
case ",$AGENTS_ARG," in *,codex,*) EN_CODEX=1 ;; esac
case ",$AGENTS_ARG," in *,copilot,*) EN_COPILOT=1 ;; esac
else
confirm "Enable Claude Code (Claude models)?" y && EN_CLAUDE=1 || true
confirm "Enable OpenAI Codex (GPT models)?" y && EN_CODEX=1 || true
confirm "Enable GitHub Copilot (cloud agent)?" y && EN_COPILOT=1 || true
fi
export EN_CLAUDE EN_CODEX EN_COPILOT
}
decide_superpowers() {
case "$WANT_SUPERPOWERS_ARG" in
yes) WANT_SUPERPOWERS=1 ;;
no) WANT_SUPERPOWERS="" ;;
ask)
if confirm "Install Superpowers (skills/methodology) from $SUPERPOWERS_REPO?" y; then
WANT_SUPERPOWERS=1
else
WANT_SUPERPOWERS=""
fi ;;
esac
export WANT_SUPERPOWERS
}
decide_gitignore() {
if [ -z "${GITIGNORE_GENERATED:-}" ] && [ -z "${NO_GITIGNORE:-}" ]; then
if confirm "Add the generated files to .gitignore (keep them out of version control)?" n; then
GITIGNORE_GENERATED=1
fi
fi
export GITIGNORE_GENERATED
}
decide_extras() {
local have="${WANT_GREP_MCP:-}${WANT_JOURNAL:-}${WANT_HOOKS:-}${WANT_PROCESS_HOOKS:-}"
if [ -z "$have" ] && [ -z "$NO_EXTRAS" ] && [ -z "$ASSUME_YES" ]; then
if confirm "Set up optional tools (Grep MCP, private-journal, guardrail/process hooks)?" n; then
confirm " Grep MCP - search ~1M public repos for usage?" y && WANT_GREP_MCP=1 || true
confirm " private-journal - cross-session memory?" n && WANT_JOURNAL=1 || true
[ -n "${EN_CLAUDE:-}" ] && { confirm " Claude guardrail hooks - deny secrets/dangerous cmds?" y && WANT_HOOKS=1 || true; }
[ -n "${EN_CLAUDE:-}" ] && { confirm " Delivery-process hooks - enforce defended plans / green builds?" n && WANT_PROCESS_HOOKS=1 || true; }
fi
fi
export WANT_GREP_MCP WANT_JOURNAL WANT_HOOKS WANT_PROCESS_HOOKS
}
print_summary() {
log_step "Done"
log_info "Target: $TARGET_DIR"
log_info "Agents: ${EN_CLAUDE:+Claude }${EN_CODEX:+Codex }${EN_COPILOT:+Copilot}"
[ -n "${GITIGNORE_GENERATED:-}" ] && log_info "Mode: local — generated files were added to .gitignore."
if [ -n "${WANT_GREP_MCP:-}${WANT_JOURNAL:-}${WANT_HOOKS:-}${WANT_PROCESS_HOOKS:-}" ]; then
log_info "Optional tools:${WANT_GREP_MCP:+ grep-mcp}${WANT_JOURNAL:+ journal}${WANT_HOOKS:+ hooks}${WANT_PROCESS_HOOKS:+ process-hooks}"
[ -n "${WANT_GREP_MCP:-}${WANT_JOURNAL:-}" ] && log_dim "MCP servers were added to your agent config(s) — restart/reload the agent to load them."
fi
# Plugin tools can't be installed by a script (no headless install) — say so here
# instead of letting users expect them from --with-all-extras.
if [ -n "${EN_CLAUDE:-}" ] && [ ! -d "$HOME/.claude/plugins/cache/ponytail" ]; then
echo
log_info "Plugin tools (one-time, inside the agent — a script can't install these):"
log_dim "ponytail (minimal-code skill): in Claude Code send these as two separate prompts, then restart:"
log_dim " /plugin marketplace add DietrichGebert/ponytail"
log_dim " /plugin install ponytail@ponytail"
[ -n "${EN_CODEX:-}" ] && log_dim "Codex CLI: codex plugin marketplace add DietrichGebert/ponytail && codex plugin install ponytail@ponytail"
fi
echo
log_info "Next steps:"
log_dim "1. Edit AGENTS.md - your single source of truth for all three agents."
log_dim "2. Fill in the Standards section of AGENTS.md (code/commit/PR rules, tools, tests)."
[ -n "${EN_CODEX:-}" ] && log_dim "3. Codex: open the project once and 'trust' it so .codex/config.toml loads."
[ -n "${EN_COPILOT:-}" ] && log_dim "4. Copilot: pick the model in the task model-picker; commit copilot-setup-steps.yml to the DEFAULT branch."
log_dim "5. Keep the graph fresh after edits: graphify update ."
echo
log_dim "To undo everything ai-dev-kit added here: $ADK_ROOT/uninstall.sh \"$TARGET_DIR\""
}
# ---- main -----------------------------------------------------------------
main() {
[ -d "$TARGET_DIR" ] || die "Target directory not found: $TARGET_DIR"
TARGET_DIR="$(cd "$TARGET_DIR" && pwd)"; export TARGET_DIR
detect_os; detect_arch; detect_pkg_mgr
log_step "ai-dev-kit -> $TARGET_DIR (${ADK_OS}/${ADK_ARCH}, pkg=${ADK_PKG})"
is_dry && log_warn "DRY RUN - no installs or file writes will happen."
choose_agents
[ -n "${EN_CLAUDE:-}${EN_CODEX:-}${EN_COPILOT:-}" ] || die "No agents selected; nothing to do."
# Models are NOT prompted for (a free-text answer is easy to fumble with a y/n reflex).
# They come from defaults or --claude-model= / --codex-model=; the chosen value is logged below.
[ -n "${EN_CLAUDE:-}" ] && log_dim "Claude model: $CLAUDE_MODEL (change with --claude-model=NAME)"
[ -n "${EN_CODEX:-}" ] && log_dim "Codex model: $CODEX_MODEL (change with --codex-model=NAME)"
decide_superpowers
decide_gitignore
decide_extras
if [ -n "${EN_CLAUDE:-}" ]; then
if is_dry; then log_info "[dry] configure Claude Code (superpowers=${WANT_SUPERPOWERS:-no})"; else configure_claude; fi
fi
if [ -n "${EN_CODEX:-}" ]; then
if is_dry; then log_info "[dry] configure Codex (superpowers=${WANT_SUPERPOWERS:-no})"; else configure_codex; fi
fi
if [ -n "${EN_COPILOT:-}" ]; then
if is_dry; then log_info "[dry] configure Copilot (superpowers=${WANT_SUPERPOWERS:-no})"; else configure_copilot; fi
fi
if [ -z "$NO_GRAPHIFY" ]; then
if is_dry; then log_info "[dry] install graphify + build graph"; else install_graphify; fi
fi
if [ -n "${WANT_JOURNAL:-}" ]; then
if is_dry; then log_info "[dry] build private-journal-mcp"; else install_journal || true; fi
fi
if is_dry; then
log_info "[dry] scaffold AGENTS.md + per-agent config + slash commands${WANT_GREP_MCP:+ + Grep MCP}${WANT_JOURNAL:+ + journal MCP}${WANT_HOOKS:+ + hooks}"
else
scaffold_project
fi
print_summary
}
main