gator-command 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gator_command/__init__.py +2 -0
- gator_command/cli.py +137 -0
- gator_command/scripts/crawler.py +633 -0
- gator_command/scripts/dashboard/dashboard.css +982 -0
- gator_command/scripts/dashboard/dashboard.html +84 -0
- gator_command/scripts/dashboard/dashboard.js +419 -0
- gator_command/scripts/dashboard/views/audit.js +270 -0
- gator_command/scripts/dashboard/views/fleet.js +307 -0
- gator_command/scripts/dashboard/views/repo.js +599 -0
- gator_command/scripts/dashboard/views/settings.js +173 -0
- gator_command/scripts/dashboard/views/updates.js +308 -0
- gator_command/scripts/enforcer-prompt.md +22 -0
- gator_command/scripts/extract-claude-sessions.py +489 -0
- gator_command/scripts/extract-codex-sessions.py +477 -0
- gator_command/scripts/extract-gemini-sessions.py +410 -0
- gator_command/scripts/gator-audit.py +956 -0
- gator_command/scripts/gator-charter-draft.py +919 -0
- gator_command/scripts/gator-charter-lint.py +427 -0
- gator_command/scripts/gator-charter-verify.py +606 -0
- gator_command/scripts/gator-dashboard.py +1271 -0
- gator_command/scripts/gator-deploy.py +916 -0
- gator_command/scripts/gator-drift.py +569 -0
- gator_command/scripts/gator-enforce.py +82 -0
- gator_command/scripts/gator-fleet-intel.py +460 -0
- gator_command/scripts/gator-fleet-report.py +615 -0
- gator_command/scripts/gator-init-command-post.py +315 -0
- gator_command/scripts/gator-init.py +434 -0
- gator_command/scripts/gator-machine-id.py +153 -0
- gator_command/scripts/gator-policy-status.py +631 -0
- gator_command/scripts/gator-pulse.py +459 -0
- gator_command/scripts/gator-repo-status.py +649 -0
- gator_command/scripts/gator-session-common.py +372 -0
- gator_command/scripts/gator-session-sink.py +831 -0
- gator_command/scripts/gator-sessions.py +1244 -0
- gator_command/scripts/gator-update.py +615 -0
- gator_command/scripts/gator-version.py +38 -0
- gator_command/scripts/gator_core.py +489 -0
- gator_command/scripts/gator_remote.py +381 -0
- gator_command/scripts/gator_runtime.py +142 -0
- gator_command/scripts/gatorize-actions.sh +989 -0
- gator_command/scripts/gatorize-lib.sh +166 -0
- gator_command/scripts/gatorize-post.sh +394 -0
- gator_command/scripts/gatorize.py +1163 -0
- gator_command/scripts/gatorize.sh +185 -0
- gator_command/scripts/generate_markdown.py +212 -0
- gator_command/scripts/generate_wiki.py +424 -0
- gator_command/scripts/graph_health.py +780 -0
- gator_command/scripts/memex-lint.py +286 -0
- gator_command/scripts/memex-lint.sh +205 -0
- gator_command/scripts/memex.py +1472 -0
- gator_command/scripts/memex_formatters.py +191 -0
- gator_command/scripts/memex_state.py +236 -0
- gator_command/scripts/spawn.py +650 -0
- gator_command/templates/gator-starter/blueprints/README.md +32 -0
- gator_command/templates/gator-starter/charterignore +53 -0
- gator_command/templates/gator-starter/charters/README.md +178 -0
- gator_command/templates/gator-starter/charters/_template.md +31 -0
- gator_command/templates/gator-starter/commands/commit.md +33 -0
- gator_command/templates/gator-starter/commands/init.md +11 -0
- gator_command/templates/gator-starter/commands/update.md +5 -0
- gator_command/templates/gator-starter/constitution.md +165 -0
- gator_command/templates/gator-starter/field-guides/README.md +25 -0
- gator_command/templates/gator-starter/gator-start-up.md +119 -0
- gator_command/templates/gator-starter/procedures/charter-alignment.md +83 -0
- gator_command/templates/gator-starter/procedures/enforcer-review.md +317 -0
- gator_command/templates/gator-starter/procedures/field-guide-generation.md +176 -0
- gator_command/templates/gator-starter/procedures/knowledge-capture.md +57 -0
- gator_command/templates/gator-starter/procedures/significance-check.md +69 -0
- gator_command/templates/gator-starter/reference-notes/concierge-responses.md +535 -0
- gator_command/templates/gator-starter/reference-notes/dangerous-patterns.md +91 -0
- gator_command/templates/gator-starter/reference-notes/dashboard-operations.md +22 -0
- gator_command/templates/gator-starter/reference-notes/enforcer-configuration.md +232 -0
- gator_command/templates/gator-starter/reference-notes/example-project.md +289 -0
- gator_command/templates/gator-starter/reference-notes/failure-modes-and-self-correction.md +72 -0
- gator_command/templates/gator-starter/reference-notes/git-workflow.md +60 -0
- gator_command/templates/gator-starter/reference-notes/identity-and-ownership.md +37 -0
- gator_command/templates/gator-starter/reference-notes/refactor-approach.md +155 -0
- gator_command/templates/gator-starter/reference-notes/what-gator-requires-from-a-model.md +108 -0
- gator_command/templates/gator-starter/reference-notes/why-navigation-coding-feels-different.md +99 -0
- gator_command/templates/gator-starter/reference-notes/workflow-profiles.md +155 -0
- gator_command/templates/gator-starter/scripts/__pycache__/enforcer-review.cpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/__pycache__/gator-approve.cpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/__pycache__/gator-init.cpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/__pycache__/gator-pre-commit.cpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/__pycache__/gator-update.cpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/enforcer-prompt.md +55 -0
- gator_command/templates/gator-starter/scripts/enforcer-review.py +1551 -0
- gator_command/templates/gator-starter/scripts/gator-approve.py +139 -0
- gator_command/templates/gator-starter/scripts/gator-enforce.py +82 -0
- gator_command/templates/gator-starter/scripts/gator-init.py +434 -0
- gator_command/templates/gator-starter/scripts/gator-pre-commit.py +2670 -0
- gator_command/templates/gator-starter/scripts/gator-pulse.py +459 -0
- gator_command/templates/gator-starter/scripts/gator-update.py +615 -0
- gator_command/templates/gator-starter/scripts/gator-version.py +38 -0
- gator_command/templates/gator-starter/scripts/gator_core.py +487 -0
- gator_command/templates/gator-starter/scripts/hooks/__pycache__/commit-msgcpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/hooks/__pycache__/post-commitcpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/hooks/__pycache__/pre-commitcpython-313.pyc +0 -0
- gator_command/templates/gator-starter/scripts/hooks/commit-msg +5 -0
- gator_command/templates/gator-starter/scripts/hooks/post-commit +7 -0
- gator_command/templates/gator-starter/scripts/hooks/pre-commit +5 -0
- gator_command/templates/gator-starter/sessions/.gitignore +7 -0
- gator_command/templates/gator-starter/vault/.gitkeep +0 -0
- gator_command/templates/gator-starter/whiteboard.md +5 -0
- gator_command-1.0.0.dist-info/METADATA +122 -0
- gator_command-1.0.0.dist-info/RECORD +110 -0
- gator_command-1.0.0.dist-info/WHEEL +5 -0
- gator_command-1.0.0.dist-info/entry_points.txt +2 -0
- gator_command-1.0.0.dist-info/licenses/LICENSE +21 -0
- gator_command-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# gatorize-actions.sh — Scenario action functions for gatorize.sh
|
|
3
|
+
#
|
|
4
|
+
# Sourced by gatorize.sh. Not a standalone script.
|
|
5
|
+
# Requires: gatorize-lib.sh (for log_step, confirm, detect_*, write_gator_version, etc.)
|
|
6
|
+
# Requires: TEMPLATES, GATOR_BRANCH, GATOR_GEN, TODAY (set by gatorize.sh)
|
|
7
|
+
#
|
|
8
|
+
# Contains: git init, feature branch, hook installation, fresh install,
|
|
9
|
+
# stub writing, upgrade, morph, dual-structure handling.
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# Action: Git Init (Scenario 1)
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
action_git_init() {
|
|
16
|
+
local target="$1"
|
|
17
|
+
log_blank
|
|
18
|
+
echo " No git repository found in $target."
|
|
19
|
+
echo " Gator requires git — the entire governance model depends on commit history,"
|
|
20
|
+
echo " branching, and audit trails. Gator cannot function without it."
|
|
21
|
+
log_blank
|
|
22
|
+
|
|
23
|
+
if ! confirm "Initialize a git repo now?" "Y"; then
|
|
24
|
+
echo " Aborted. Initialize a git repo in $target and re-run gatorize.sh."
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Preflight: check git identity
|
|
29
|
+
local git_user git_email
|
|
30
|
+
git_user=$(git config user.name 2>/dev/null || true)
|
|
31
|
+
git_email=$(git config user.email 2>/dev/null || true)
|
|
32
|
+
if [ -z "$git_user" ] || [ -z "$git_email" ]; then
|
|
33
|
+
log_blank
|
|
34
|
+
echo " Git identity not configured. Git requires user.name and user.email to commit."
|
|
35
|
+
echo " Run these commands first, then re-run gatorize.sh:"
|
|
36
|
+
log_blank
|
|
37
|
+
echo " git config --global user.name \"Your Name\""
|
|
38
|
+
echo " git config --global user.email \"you@example.com\""
|
|
39
|
+
log_blank
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
(
|
|
44
|
+
cd "$target"
|
|
45
|
+
git init
|
|
46
|
+
local default_branch
|
|
47
|
+
default_branch=$(git branch --show-current 2>/dev/null || echo "master")
|
|
48
|
+
if [ "$default_branch" != "main" ]; then
|
|
49
|
+
git branch -M main 2>/dev/null || true
|
|
50
|
+
fi
|
|
51
|
+
# Check for files beyond .git itself
|
|
52
|
+
if [ -n "$(ls -A 2>/dev/null | grep -v '^\.git$')" ]; then
|
|
53
|
+
git add -A
|
|
54
|
+
git commit -m "Initial commit (pre-Gator)"
|
|
55
|
+
else
|
|
56
|
+
git commit --allow-empty -m "Initial commit (pre-Gator)"
|
|
57
|
+
fi
|
|
58
|
+
git branch dev
|
|
59
|
+
git checkout -b "$GATOR_BRANCH"
|
|
60
|
+
)
|
|
61
|
+
log_blank
|
|
62
|
+
log_step "Git initialized. Branches: main, dev, $GATOR_BRANCH (current)."
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# =============================================================================
|
|
66
|
+
# Action: Feature Branch (mandatory for all git scenarios)
|
|
67
|
+
# =============================================================================
|
|
68
|
+
|
|
69
|
+
action_feature_branch() {
|
|
70
|
+
local target="$1"
|
|
71
|
+
|
|
72
|
+
# Check for uncommitted changes
|
|
73
|
+
local dirty current_branch
|
|
74
|
+
dirty=$(cd "$target" && git status --porcelain 2>/dev/null | head -1)
|
|
75
|
+
current_branch=$(cd "$target" && git branch --show-current 2>/dev/null)
|
|
76
|
+
|
|
77
|
+
if [ -n "$dirty" ]; then
|
|
78
|
+
log_blank
|
|
79
|
+
echo " Warning: uncommitted changes detected in $target."
|
|
80
|
+
echo " Strongly recommend committing or stashing before gatorizing."
|
|
81
|
+
log_blank
|
|
82
|
+
echo " Options:"
|
|
83
|
+
echo " [c] Continue anyway (changes will mix with Gator install)"
|
|
84
|
+
echo " [a] Abort — commit your changes first, then re-run"
|
|
85
|
+
log_blank
|
|
86
|
+
read -rp " Choice [c/a]: " dirty_choice
|
|
87
|
+
if [[ "$dirty_choice" =~ ^[Aa]$ ]]; then
|
|
88
|
+
echo " Aborted. Commit your changes and re-run gatorize.sh."
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Handle existing gator-install branch BEFORE branch selection
|
|
94
|
+
if (cd "$target" && git rev-parse --verify "$GATOR_BRANCH" >/dev/null 2>&1); then
|
|
95
|
+
log_blank
|
|
96
|
+
echo " Branch '$GATOR_BRANCH' already exists (prior install attempt?)."
|
|
97
|
+
log_blank
|
|
98
|
+
echo " [1] Delete and start fresh (recommended)"
|
|
99
|
+
echo " [2] Continue on existing branch"
|
|
100
|
+
echo " [x] Cancel installation"
|
|
101
|
+
log_blank
|
|
102
|
+
read -rp " Choice [1/2/x]: " branch_choice
|
|
103
|
+
case "$branch_choice" in
|
|
104
|
+
1)
|
|
105
|
+
(cd "$target" && git checkout dev 2>/dev/null || git checkout main 2>/dev/null)
|
|
106
|
+
(cd "$target" && git branch -D "$GATOR_BRANCH" 2>/dev/null)
|
|
107
|
+
log_step "Deleted old '$GATOR_BRANCH' branch."
|
|
108
|
+
;;
|
|
109
|
+
[xX])
|
|
110
|
+
echo " Installation cancelled."
|
|
111
|
+
exit 0
|
|
112
|
+
;;
|
|
113
|
+
*)
|
|
114
|
+
log_step "Continuing on existing '$GATOR_BRANCH' branch."
|
|
115
|
+
;;
|
|
116
|
+
esac
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
log_blank
|
|
120
|
+
echo " Gator installs on a feature branch ('$GATOR_BRANCH') for safety."
|
|
121
|
+
echo " This keeps the install reversible — delete the branch if anything goes wrong,"
|
|
122
|
+
echo " merge to dev when you're happy."
|
|
123
|
+
log_blank
|
|
124
|
+
|
|
125
|
+
# Get list of local branches (excluding gator-install itself)
|
|
126
|
+
local branches=()
|
|
127
|
+
while IFS= read -r branch; do
|
|
128
|
+
branch="${branch#\* }" # strip the * from current branch
|
|
129
|
+
branch="${branch#"${branch%%[! ]*}"}" # strip ALL leading spaces
|
|
130
|
+
[ "$branch" = "$GATOR_BRANCH" ] && continue # don't list gator-install as a source
|
|
131
|
+
branches+=("$branch")
|
|
132
|
+
done < <(cd "$target" && git branch 2>/dev/null)
|
|
133
|
+
|
|
134
|
+
if [ ${#branches[@]} -eq 0 ]; then
|
|
135
|
+
log_step "No branches found (empty repo?). Installing on current state."
|
|
136
|
+
(
|
|
137
|
+
cd "$target"
|
|
138
|
+
git checkout -b "$GATOR_BRANCH" 2>/dev/null || git checkout "$GATOR_BRANCH"
|
|
139
|
+
)
|
|
140
|
+
return
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
local source_branch=""
|
|
144
|
+
|
|
145
|
+
if [ ${#branches[@]} -eq 1 ]; then
|
|
146
|
+
source_branch="${branches[0]}"
|
|
147
|
+
echo " Only one branch available: $source_branch"
|
|
148
|
+
echo " '$GATOR_BRANCH' will branch from '$source_branch'."
|
|
149
|
+
log_blank
|
|
150
|
+
if ! confirm "Proceed?" "Y"; then
|
|
151
|
+
echo " Aborted."
|
|
152
|
+
exit 0
|
|
153
|
+
fi
|
|
154
|
+
else
|
|
155
|
+
echo " Available branches:"
|
|
156
|
+
log_blank
|
|
157
|
+
for i in "${!branches[@]}"; do
|
|
158
|
+
local marker=" "
|
|
159
|
+
if [ "${branches[$i]}" = "$current_branch" ]; then
|
|
160
|
+
marker="* "
|
|
161
|
+
fi
|
|
162
|
+
echo " [$((i+1))] ${marker}${branches[$i]}"
|
|
163
|
+
done
|
|
164
|
+
log_blank
|
|
165
|
+
read -rp " Which branch should '$GATOR_BRANCH' branch from? [1-${#branches[@]}]: " source_choice
|
|
166
|
+
|
|
167
|
+
if [[ "$source_choice" =~ ^[0-9]+$ ]] && [ "$source_choice" -ge 1 ] && [ "$source_choice" -le ${#branches[@]} ]; then
|
|
168
|
+
source_branch="${branches[$((source_choice-1))]}"
|
|
169
|
+
else
|
|
170
|
+
source_branch="$current_branch"
|
|
171
|
+
echo " Invalid choice. Branching from '$current_branch'."
|
|
172
|
+
fi
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
(
|
|
176
|
+
cd "$target"
|
|
177
|
+
git checkout "$source_branch" 2>/dev/null
|
|
178
|
+
# Ensure dev exists
|
|
179
|
+
if ! git rev-parse --verify dev >/dev/null 2>&1; then
|
|
180
|
+
git branch dev 2>/dev/null || true
|
|
181
|
+
log_step "Created 'dev' branch."
|
|
182
|
+
fi
|
|
183
|
+
# Create or switch to gator-install (already handled above if it existed)
|
|
184
|
+
if git rev-parse --verify "$GATOR_BRANCH" >/dev/null 2>&1; then
|
|
185
|
+
git checkout "$GATOR_BRANCH"
|
|
186
|
+
else
|
|
187
|
+
git checkout -b "$GATOR_BRANCH"
|
|
188
|
+
fi
|
|
189
|
+
)
|
|
190
|
+
log_step "On '$GATOR_BRANCH' (from '$source_branch')."
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# =============================================================================
|
|
194
|
+
# Action: Install git hooks (pre-commit + commit-msg)
|
|
195
|
+
# =============================================================================
|
|
196
|
+
|
|
197
|
+
is_windows_shell() {
|
|
198
|
+
case "$(uname -s 2>/dev/null)" in
|
|
199
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
200
|
+
return 0
|
|
201
|
+
;;
|
|
202
|
+
*)
|
|
203
|
+
return 1
|
|
204
|
+
;;
|
|
205
|
+
esac
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
write_windows_hook() {
|
|
209
|
+
local dest="$1"
|
|
210
|
+
local hook_name="$2"
|
|
211
|
+
local py_path
|
|
212
|
+
py_path=$(python -c "import sys; print(sys.executable.replace('\\\\', '/'))" 2>/dev/null)
|
|
213
|
+
[ -n "$py_path" ] || return 1
|
|
214
|
+
|
|
215
|
+
case "$hook_name" in
|
|
216
|
+
pre-commit)
|
|
217
|
+
cat > "$dest" <<EOF
|
|
218
|
+
#!$py_path
|
|
219
|
+
import subprocess
|
|
220
|
+
import sys
|
|
221
|
+
|
|
222
|
+
raise SystemExit(
|
|
223
|
+
subprocess.call(["python", ".gator/scripts/gator-pre-commit.py", "--phase", "validate"])
|
|
224
|
+
)
|
|
225
|
+
EOF
|
|
226
|
+
;;
|
|
227
|
+
commit-msg)
|
|
228
|
+
cat > "$dest" <<EOF
|
|
229
|
+
#!$py_path
|
|
230
|
+
import subprocess
|
|
231
|
+
import sys
|
|
232
|
+
|
|
233
|
+
raise SystemExit(
|
|
234
|
+
subprocess.call(["python", ".gator/scripts/gator-pre-commit.py", "--phase", "trailers", *sys.argv[1:]])
|
|
235
|
+
)
|
|
236
|
+
EOF
|
|
237
|
+
;;
|
|
238
|
+
post-commit)
|
|
239
|
+
cat > "$dest" <<EOF
|
|
240
|
+
#!$py_path
|
|
241
|
+
import subprocess
|
|
242
|
+
|
|
243
|
+
raise SystemExit(
|
|
244
|
+
subprocess.call(["python", ".gator/scripts/gator-pre-commit.py", "--phase", "cleanup"])
|
|
245
|
+
)
|
|
246
|
+
EOF
|
|
247
|
+
;;
|
|
248
|
+
*)
|
|
249
|
+
return 1
|
|
250
|
+
;;
|
|
251
|
+
esac
|
|
252
|
+
|
|
253
|
+
chmod +x "$dest"
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
install_hooks() {
|
|
257
|
+
local target="$1"
|
|
258
|
+
local hooks_dir="$target/.git/hooks"
|
|
259
|
+
|
|
260
|
+
# Only install if .git exists (it should — we're on a branch)
|
|
261
|
+
if [ ! -d "$target/.git" ]; then
|
|
262
|
+
return
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
mkdir -p "$hooks_dir"
|
|
266
|
+
|
|
267
|
+
local installed=0
|
|
268
|
+
local backed_up=0
|
|
269
|
+
|
|
270
|
+
for hook_name in pre-commit commit-msg post-commit; do
|
|
271
|
+
local src="$TEMPLATES/scripts/hooks/$hook_name"
|
|
272
|
+
local dest="$hooks_dir/$hook_name"
|
|
273
|
+
|
|
274
|
+
[ -f "$src" ] || continue
|
|
275
|
+
|
|
276
|
+
if [ -f "$dest" ]; then
|
|
277
|
+
# Check if it's already a Gator hook (idempotent)
|
|
278
|
+
if grep -q "Gator" "$dest" 2>/dev/null; then
|
|
279
|
+
cp "$src" "$dest"
|
|
280
|
+
chmod +x "$dest"
|
|
281
|
+
installed=$((installed + 1))
|
|
282
|
+
continue
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
# Existing non-Gator hook — back up and replace
|
|
286
|
+
local backup="$dest.pre-gator"
|
|
287
|
+
if [ ! -f "$backup" ]; then
|
|
288
|
+
cp "$dest" "$backup"
|
|
289
|
+
backed_up=$((backed_up + 1))
|
|
290
|
+
log_step "Backed up existing $hook_name hook → $hook_name.pre-gator"
|
|
291
|
+
fi
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
if is_windows_shell && write_windows_hook "$dest" "$hook_name"; then
|
|
295
|
+
:
|
|
296
|
+
else
|
|
297
|
+
cp "$src" "$dest"
|
|
298
|
+
chmod +x "$dest"
|
|
299
|
+
fi
|
|
300
|
+
installed=$((installed + 1))
|
|
301
|
+
done
|
|
302
|
+
|
|
303
|
+
if [ "$backed_up" -gt 0 ]; then
|
|
304
|
+
log_step "Git hooks: $installed installed, $backed_up existing hooks backed up"
|
|
305
|
+
log_step "Your original hooks are preserved as .pre-gator files in .git/hooks/"
|
|
306
|
+
else
|
|
307
|
+
log_step "Git hooks installed (pre-commit + commit-msg + post-commit)"
|
|
308
|
+
fi
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
# =============================================================================
|
|
312
|
+
# Action: Install .gator/ (fresh, from templates)
|
|
313
|
+
# =============================================================================
|
|
314
|
+
|
|
315
|
+
action_install_gator() {
|
|
316
|
+
local target="$1"
|
|
317
|
+
|
|
318
|
+
log_step "Installing .gator/ into $target ..."
|
|
319
|
+
|
|
320
|
+
# Create directory structure
|
|
321
|
+
mkdir -p "$target/.gator/charters" "$target/.gator/blueprints" \
|
|
322
|
+
"$target/.gator/reference-notes" \
|
|
323
|
+
"$target/.gator/procedures" "$target/.gator/scripts" \
|
|
324
|
+
"$target/.gator/threads" "$target/.gator/artifacts" \
|
|
325
|
+
"$target/.gator/vault" "$target/.gator/policies" \
|
|
326
|
+
"$target/.gator/sessions"
|
|
327
|
+
|
|
328
|
+
# Copy constitution, startup guide
|
|
329
|
+
cp "$TEMPLATES/constitution.md" "$target/.gator/"
|
|
330
|
+
cp "$TEMPLATES/gator-start-up.md" "$target/.gator/"
|
|
331
|
+
|
|
332
|
+
# Copy charters scaffolding
|
|
333
|
+
cp "$TEMPLATES/charters/README.md" "$target/.gator/charters/"
|
|
334
|
+
cp "$TEMPLATES/charters/_template.md" "$target/.gator/charters/"
|
|
335
|
+
|
|
336
|
+
# Copy blueprints scaffolding
|
|
337
|
+
cp "$TEMPLATES/blueprints/README.md" "$target/.gator/blueprints/" 2>/dev/null || true
|
|
338
|
+
|
|
339
|
+
# Copy reference notes
|
|
340
|
+
cp "$TEMPLATES/reference-notes/"*.md "$target/.gator/reference-notes/"
|
|
341
|
+
|
|
342
|
+
# Copy procedures
|
|
343
|
+
cp "$TEMPLATES/procedures/"*.md "$target/.gator/procedures/"
|
|
344
|
+
|
|
345
|
+
# Copy sessions gitignore (keeps _active/ out of git)
|
|
346
|
+
if [ -f "$TEMPLATES/sessions/.gitignore" ]; then
|
|
347
|
+
cp "$TEMPLATES/sessions/.gitignore" "$target/.gator/sessions/"
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
# Copy scripts (top-level files)
|
|
351
|
+
cp "$TEMPLATES/scripts/"* "$target/.gator/scripts/" 2>/dev/null || true
|
|
352
|
+
|
|
353
|
+
# Copy nested script directories (e.g., scripts/hooks/)
|
|
354
|
+
for subdir in "$TEMPLATES/scripts/"*/; do
|
|
355
|
+
[ -d "$subdir" ] || continue
|
|
356
|
+
local dirname
|
|
357
|
+
dirname=$(basename "$subdir")
|
|
358
|
+
mkdir -p "$target/.gator/scripts/$dirname"
|
|
359
|
+
cp "$subdir"* "$target/.gator/scripts/$dirname/" 2>/dev/null || true
|
|
360
|
+
done
|
|
361
|
+
|
|
362
|
+
# Install slash commands (vendor-neutral source, Claude Code destination)
|
|
363
|
+
if [ -d "$TEMPLATES/commands" ]; then
|
|
364
|
+
mkdir -p "$target/.claude/commands"
|
|
365
|
+
for cmd_file in "$TEMPLATES/commands/"*.md; do
|
|
366
|
+
[ -f "$cmd_file" ] || continue
|
|
367
|
+
local cmd_name
|
|
368
|
+
cmd_name=$(basename "$cmd_file")
|
|
369
|
+
local cmd_dest="$target/.claude/commands/$cmd_name"
|
|
370
|
+
|
|
371
|
+
if [ -f "$cmd_dest" ]; then
|
|
372
|
+
# Check if it's already a Gator command (idempotent)
|
|
373
|
+
if grep -qi "gator\|constitution\|charter" "$cmd_dest" 2>/dev/null; then
|
|
374
|
+
cp "$cmd_file" "$cmd_dest"
|
|
375
|
+
continue
|
|
376
|
+
fi
|
|
377
|
+
# Existing non-Gator command — back up
|
|
378
|
+
local cmd_backup="$cmd_dest.pre-gator"
|
|
379
|
+
if [ ! -f "$cmd_backup" ]; then
|
|
380
|
+
cp "$cmd_dest" "$cmd_backup"
|
|
381
|
+
log_step "Backed up existing slash command $cmd_name → $cmd_name.pre-gator"
|
|
382
|
+
fi
|
|
383
|
+
fi
|
|
384
|
+
|
|
385
|
+
cp "$cmd_file" "$cmd_dest"
|
|
386
|
+
done
|
|
387
|
+
fi
|
|
388
|
+
|
|
389
|
+
# .gitkeep for empty dirs
|
|
390
|
+
touch "$target/.gator/threads/.gitkeep"
|
|
391
|
+
touch "$target/.gator/artifacts/.gitkeep"
|
|
392
|
+
touch "$target/.gator/vault/.gitkeep"
|
|
393
|
+
|
|
394
|
+
# Install git hooks (pre-commit + commit-msg)
|
|
395
|
+
install_hooks "$target"
|
|
396
|
+
|
|
397
|
+
# Write stubs for content files
|
|
398
|
+
write_stubs "$target"
|
|
399
|
+
|
|
400
|
+
# Write version marker
|
|
401
|
+
write_gator_version "$target" "install"
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
write_stubs() {
|
|
405
|
+
local target="$1"
|
|
406
|
+
|
|
407
|
+
cat > "$target/.gator/mission.md" << 'STUB'
|
|
408
|
+
# Mission
|
|
409
|
+
|
|
410
|
+
## What We're Building
|
|
411
|
+
|
|
412
|
+
[What is this project? One paragraph.]
|
|
413
|
+
|
|
414
|
+
## Why It Exists
|
|
415
|
+
|
|
416
|
+
[What problem does it solve? Who is it for?]
|
|
417
|
+
|
|
418
|
+
## What Success Looks Like
|
|
419
|
+
|
|
420
|
+
[How do you know when it's working?]
|
|
421
|
+
STUB
|
|
422
|
+
|
|
423
|
+
cat > "$target/.gator/roadmap.md" << 'STUB'
|
|
424
|
+
# Roadmap
|
|
425
|
+
|
|
426
|
+
[Priority-ordered. Updated as items complete or priorities shift.]
|
|
427
|
+
|
|
428
|
+
[Status key: Done · Building · Designed · Considering · Deferred]
|
|
429
|
+
|
|
430
|
+
| # | Feature | Status | Next step |
|
|
431
|
+
|---|---------|--------|-----------|
|
|
432
|
+
| 1 | | | |
|
|
433
|
+
| 2 | | | |
|
|
434
|
+
| 3 | | | |
|
|
435
|
+
STUB
|
|
436
|
+
|
|
437
|
+
cat > "$target/.gator/inbox.md" << 'STUB'
|
|
438
|
+
# Inbox
|
|
439
|
+
|
|
440
|
+
[Drop anything here. No formatting needed. The agent triages at session open.]
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
STUB
|
|
445
|
+
|
|
446
|
+
cat > "$target/.gator/commit_draft.md" << 'STUB'
|
|
447
|
+
---
|
|
448
|
+
message: ""
|
|
449
|
+
change-type:
|
|
450
|
+
significance:
|
|
451
|
+
decision-tags: []
|
|
452
|
+
agent:
|
|
453
|
+
architect:
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
# Session Change Log
|
|
457
|
+
|
|
458
|
+
STUB
|
|
459
|
+
|
|
460
|
+
cat > "$target/.gator/whiteboard.md" << 'STUB'
|
|
461
|
+
# Whiteboard
|
|
462
|
+
|
|
463
|
+
Review log. Enforcer findings land here with timestamps. The Architect and agent review together, then act.
|
|
464
|
+
|
|
465
|
+
When this file exceeds 100 lines, archive older reviews to `artifacts/review-log.md` and keep the most recent 2–3.
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
STUB
|
|
470
|
+
|
|
471
|
+
# Lint allowlist and commit issues — empty by default
|
|
472
|
+
echo '[]' > "$target/.gator/lint-allow.json"
|
|
473
|
+
printf "# Commit Issues\n\nNo findings.\n" > "$target/.gator/commit_issues.md"
|
|
474
|
+
|
|
475
|
+
# Enforcement config — strict by default
|
|
476
|
+
if [ ! -f "$target/.gator/config.json" ]; then
|
|
477
|
+
printf '{\n "enforcement_level": "strict"\n}\n' > "$target/.gator/config.json"
|
|
478
|
+
fi
|
|
479
|
+
|
|
480
|
+
cat > "$target/.gator/patterns.md" << 'STUB'
|
|
481
|
+
# Patterns
|
|
482
|
+
|
|
483
|
+
Recurring rhythms, obligations, schedules. Updated as patterns emerge.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
STUB
|
|
488
|
+
|
|
489
|
+
cat > "$target/.gator/charters/INDEX.md" << 'STUB'
|
|
490
|
+
# Charter Index
|
|
491
|
+
|
|
492
|
+
**Always read first:** [Cross-Cutting](cross-cutting.md) (when it exists)
|
|
493
|
+
|
|
494
|
+
| If you're changing... | Read these charters |
|
|
495
|
+
|---|---|
|
|
496
|
+
| | |
|
|
497
|
+
STUB
|
|
498
|
+
|
|
499
|
+
cat > "$target/.gator/issues.md" << 'STUB'
|
|
500
|
+
# Issues
|
|
501
|
+
|
|
502
|
+
Active bugs, blockers, and known fragilities. Checked at session open.
|
|
503
|
+
|
|
504
|
+
**Status key**: Open · Working · Resolved
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
STUB
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
# =============================================================================
|
|
512
|
+
# Template overlay (used by upgrade and morph)
|
|
513
|
+
# =============================================================================
|
|
514
|
+
|
|
515
|
+
# Overlay template files into a directory WITHOUT deleting existing extras.
|
|
516
|
+
# Template files overwrite same-named files; files that exist only in the
|
|
517
|
+
# target directory are left untouched.
|
|
518
|
+
overlay_templates() {
|
|
519
|
+
local src_dir="$1" dest_dir="$2"
|
|
520
|
+
[ -d "$src_dir" ] || return 0
|
|
521
|
+
mkdir -p "$dest_dir"
|
|
522
|
+
local count=0
|
|
523
|
+
for f in "$src_dir"/*; do
|
|
524
|
+
[ -f "$f" ] || continue
|
|
525
|
+
cp "$f" "$dest_dir/"
|
|
526
|
+
count=$((count + 1))
|
|
527
|
+
done
|
|
528
|
+
echo "$count"
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
# =============================================================================
|
|
532
|
+
# Action: Upgrade existing .gator/ (Scenario 3)
|
|
533
|
+
# =============================================================================
|
|
534
|
+
|
|
535
|
+
action_upgrade_gator() {
|
|
536
|
+
local target="$1"
|
|
537
|
+
|
|
538
|
+
# --- Detect generation ---
|
|
539
|
+
local gen
|
|
540
|
+
gen=$(detect_gator_generation "$target")
|
|
541
|
+
|
|
542
|
+
local subcase
|
|
543
|
+
if [ "$gen" -eq 0 ]; then
|
|
544
|
+
subcase="3a"
|
|
545
|
+
elif [ "$gen" -lt "$GATOR_GEN" ]; then
|
|
546
|
+
subcase="3b"
|
|
547
|
+
else
|
|
548
|
+
subcase="3c"
|
|
549
|
+
fi
|
|
550
|
+
|
|
551
|
+
log_blank
|
|
552
|
+
case "$subcase" in
|
|
553
|
+
3a)
|
|
554
|
+
echo " Pre-gatorize.sh install detected (generation 0)."
|
|
555
|
+
echo " No thin link, no registry entry, no outbox."
|
|
556
|
+
echo " Upgrade will add these and refresh templates while preserving all"
|
|
557
|
+
echo " your content — charters, mission, threads, reference-notes, scripts."
|
|
558
|
+
echo ""
|
|
559
|
+
echo " Note: your existing reference-notes and scripts may include files"
|
|
560
|
+
echo " not in the current template. These will be kept intact."
|
|
561
|
+
;;
|
|
562
|
+
3b)
|
|
563
|
+
echo " Earlier gatorize.sh install detected (generation $gen → $GATOR_GEN)."
|
|
564
|
+
echo " Upgrade will refresh templates while preserving all your content."
|
|
565
|
+
;;
|
|
566
|
+
3c)
|
|
567
|
+
echo " Current generation ($gen). Refreshing templates to latest versions."
|
|
568
|
+
;;
|
|
569
|
+
esac
|
|
570
|
+
log_blank
|
|
571
|
+
|
|
572
|
+
if has_gator_knowledge "$target"; then
|
|
573
|
+
echo " Existing .gator/ has project knowledge (charters, threads, mission, etc.)."
|
|
574
|
+
echo " All content will be preserved."
|
|
575
|
+
log_blank
|
|
576
|
+
if ! confirm "Proceed with upgrade?" "Y"; then
|
|
577
|
+
echo " Aborted."
|
|
578
|
+
exit 0
|
|
579
|
+
fi
|
|
580
|
+
fi
|
|
581
|
+
|
|
582
|
+
# --- Ensure all directories exist (older versions may be missing some) ---
|
|
583
|
+
mkdir -p "$target/.gator/charters" "$target/.gator/blueprints" \
|
|
584
|
+
"$target/.gator/reference-notes" \
|
|
585
|
+
"$target/.gator/procedures" "$target/.gator/scripts" \
|
|
586
|
+
"$target/.gator/threads" "$target/.gator/artifacts" \
|
|
587
|
+
"$target/.gator/vault" "$target/.gator/policies" \
|
|
588
|
+
"$target/.gator/sessions"
|
|
589
|
+
|
|
590
|
+
# --- Refresh template-derived files ---
|
|
591
|
+
# Sessions gitignore (keeps _active/ out of git)
|
|
592
|
+
if [ -f "$TEMPLATES/sessions/.gitignore" ]; then
|
|
593
|
+
cp "$TEMPLATES/sessions/.gitignore" "$target/.gator/sessions/"
|
|
594
|
+
fi
|
|
595
|
+
|
|
596
|
+
# Constitution and startup guide: always overwrite (these are authoritative)
|
|
597
|
+
cp "$TEMPLATES/constitution.md" "$target/.gator/"
|
|
598
|
+
cp "$TEMPLATES/gator-start-up.md" "$target/.gator/"
|
|
599
|
+
log_step "Refreshed constitution.md, gator-start-up.md"
|
|
600
|
+
|
|
601
|
+
# Charter scaffolding: overwrite templates, preserve user charters
|
|
602
|
+
cp "$TEMPLATES/charters/README.md" "$target/.gator/charters/"
|
|
603
|
+
cp "$TEMPLATES/charters/_template.md" "$target/.gator/charters/"
|
|
604
|
+
cp "$TEMPLATES/blueprints/README.md" "$target/.gator/blueprints/" 2>/dev/null || true
|
|
605
|
+
log_step "Refreshed charter and blueprint templates"
|
|
606
|
+
|
|
607
|
+
# Reference-notes: OVERLAY
|
|
608
|
+
local rn_refreshed
|
|
609
|
+
rn_refreshed=$(overlay_templates "$TEMPLATES/reference-notes" "$target/.gator/reference-notes")
|
|
610
|
+
local rn_total
|
|
611
|
+
rn_total=$(find "$target/.gator/reference-notes" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
612
|
+
log_step "Reference-notes: $rn_refreshed template files refreshed, $rn_total total (extras preserved)"
|
|
613
|
+
|
|
614
|
+
# Procedures: OVERLAY
|
|
615
|
+
local proc_refreshed
|
|
616
|
+
proc_refreshed=$(overlay_templates "$TEMPLATES/procedures" "$target/.gator/procedures")
|
|
617
|
+
local proc_total
|
|
618
|
+
proc_total=$(find "$target/.gator/procedures" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
619
|
+
log_step "Procedures: $proc_refreshed template files refreshed, $proc_total total (extras preserved)"
|
|
620
|
+
|
|
621
|
+
# Scripts: OVERLAY (top-level files)
|
|
622
|
+
local script_refreshed=0
|
|
623
|
+
for f in "$TEMPLATES/scripts/"*; do
|
|
624
|
+
[ -f "$f" ] || continue
|
|
625
|
+
cp "$f" "$target/.gator/scripts/"
|
|
626
|
+
script_refreshed=$((script_refreshed + 1))
|
|
627
|
+
done 2>/dev/null || true
|
|
628
|
+
|
|
629
|
+
# Scripts: nested directories (e.g., scripts/hooks/)
|
|
630
|
+
for subdir in "$TEMPLATES/scripts/"*/; do
|
|
631
|
+
[ -d "$subdir" ] || continue
|
|
632
|
+
local dirname
|
|
633
|
+
dirname=$(basename "$subdir")
|
|
634
|
+
mkdir -p "$target/.gator/scripts/$dirname"
|
|
635
|
+
for f in "$subdir"*; do
|
|
636
|
+
[ -f "$f" ] || continue
|
|
637
|
+
cp "$f" "$target/.gator/scripts/$dirname/"
|
|
638
|
+
script_refreshed=$((script_refreshed + 1))
|
|
639
|
+
done
|
|
640
|
+
done 2>/dev/null || true
|
|
641
|
+
|
|
642
|
+
local script_total
|
|
643
|
+
script_total=$(find "$target/.gator/scripts" -type f 2>/dev/null | wc -l | tr -d ' ')
|
|
644
|
+
log_step "Scripts: $script_refreshed template files refreshed, $script_total total (extras preserved)"
|
|
645
|
+
|
|
646
|
+
# --- Content files: create stubs only if missing ---
|
|
647
|
+
for stub_file in mission.md roadmap.md inbox.md commit_draft.md whiteboard.md \
|
|
648
|
+
patterns.md issues.md; do
|
|
649
|
+
if [ ! -f "$target/.gator/$stub_file" ]; then
|
|
650
|
+
case "$stub_file" in
|
|
651
|
+
mission.md) echo "# Mission" > "$target/.gator/$stub_file" ;;
|
|
652
|
+
roadmap.md) echo "# Roadmap" > "$target/.gator/$stub_file" ;;
|
|
653
|
+
inbox.md) printf "# Inbox\n\n---\n\n" > "$target/.gator/$stub_file" ;;
|
|
654
|
+
commit_draft.md) cat > "$target/.gator/$stub_file" << 'CDSTUB'
|
|
655
|
+
---
|
|
656
|
+
message: ""
|
|
657
|
+
change-type:
|
|
658
|
+
significance:
|
|
659
|
+
decision-tags: []
|
|
660
|
+
agent:
|
|
661
|
+
architect:
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
# Session Change Log
|
|
665
|
+
|
|
666
|
+
CDSTUB
|
|
667
|
+
;;
|
|
668
|
+
whiteboard.md) echo "# Whiteboard" > "$target/.gator/$stub_file" ;;
|
|
669
|
+
patterns.md) printf "# Patterns\n\n---\n\n" > "$target/.gator/$stub_file" ;;
|
|
670
|
+
issues.md) printf "# Issues\n\n---\n\n" > "$target/.gator/$stub_file" ;;
|
|
671
|
+
esac
|
|
672
|
+
log_step "Created missing stub: $stub_file"
|
|
673
|
+
fi
|
|
674
|
+
done
|
|
675
|
+
|
|
676
|
+
# Identity: create only if missing
|
|
677
|
+
if [ ! -f "$target/.gator/identity.md" ]; then
|
|
678
|
+
echo "# Identity" > "$target/.gator/identity.md"
|
|
679
|
+
log_step "Created missing stub: identity.md"
|
|
680
|
+
fi
|
|
681
|
+
|
|
682
|
+
# Charter INDEX: create only if missing
|
|
683
|
+
if [ ! -f "$target/.gator/charters/INDEX.md" ]; then
|
|
684
|
+
cat > "$target/.gator/charters/INDEX.md" << 'STUB'
|
|
685
|
+
# Charter Index
|
|
686
|
+
|
|
687
|
+
**Always read first:** [Cross-Cutting](cross-cutting.md) (when it exists)
|
|
688
|
+
|
|
689
|
+
| If you're changing... | Read these charters |
|
|
690
|
+
|---|---|
|
|
691
|
+
| | |
|
|
692
|
+
STUB
|
|
693
|
+
log_step "Created missing charters/INDEX.md"
|
|
694
|
+
fi
|
|
695
|
+
|
|
696
|
+
# Enforcement config: create only if missing (preserves user changes)
|
|
697
|
+
if [ ! -f "$target/.gator/config.json" ]; then
|
|
698
|
+
printf '{\n "enforcement_level": "strict"\n}\n' > "$target/.gator/config.json"
|
|
699
|
+
log_step "Created config.json (enforcement: strict)"
|
|
700
|
+
fi
|
|
701
|
+
|
|
702
|
+
# --- .gitkeep for empty dirs ---
|
|
703
|
+
[ -z "$(ls -A "$target/.gator/threads" 2>/dev/null)" ] && \
|
|
704
|
+
touch "$target/.gator/threads/.gitkeep"
|
|
705
|
+
[ -z "$(ls -A "$target/.gator/artifacts" 2>/dev/null)" ] && \
|
|
706
|
+
touch "$target/.gator/artifacts/.gitkeep"
|
|
707
|
+
|
|
708
|
+
# --- Install/refresh git hooks ---
|
|
709
|
+
install_hooks "$target"
|
|
710
|
+
|
|
711
|
+
# --- Write version marker ---
|
|
712
|
+
write_gator_version "$target" "upgrade"
|
|
713
|
+
|
|
714
|
+
log_blank
|
|
715
|
+
log_step "Upgraded .gator/ (gen $gen → $GATOR_GEN) — templates refreshed, content preserved."
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
# =============================================================================
|
|
719
|
+
# Action: Morph memex → gator (Scenario 4)
|
|
720
|
+
# =============================================================================
|
|
721
|
+
|
|
722
|
+
action_morph_memex() {
|
|
723
|
+
local target="$1"
|
|
724
|
+
|
|
725
|
+
detect_legacy_memex "$target"
|
|
726
|
+
|
|
727
|
+
log_blank
|
|
728
|
+
echo " Legacy memex structure detected:"
|
|
729
|
+
$HAS_MEMEX_DIR && echo " memex/ (content layer)"
|
|
730
|
+
$HAS_DOT_MEMEX_DIR && echo " .memex/ (system layer)"
|
|
731
|
+
$HAS_ROOT_CONSTITUTION && echo " constitution.md (root)"
|
|
732
|
+
$HAS_ROOT_CONSTITUTION_CORE && echo " constitution-core.md (root)"
|
|
733
|
+
log_blank
|
|
734
|
+
echo " Gatorize will morph this into .gator/ structure:"
|
|
735
|
+
echo " 1. Rename legacy dirs to *.pre-gator/ (preserves history, easy rollback)"
|
|
736
|
+
echo " 2. Install fresh .gator/ from templates"
|
|
737
|
+
echo " 3. Copy your content (mission, threads, artifacts, etc.) into .gator/"
|
|
738
|
+
echo " 4. Archive root constitution files"
|
|
739
|
+
echo " 5. Leave pre-gator dirs on this branch for review"
|
|
740
|
+
log_blank
|
|
741
|
+
if ! confirm "Proceed with morph?" "Y"; then
|
|
742
|
+
echo " Aborted."
|
|
743
|
+
exit 0
|
|
744
|
+
fi
|
|
745
|
+
|
|
746
|
+
# --- Step 1: Rename legacy dirs using git mv where possible ---
|
|
747
|
+
|
|
748
|
+
(
|
|
749
|
+
cd "$target"
|
|
750
|
+
if $HAS_MEMEX_DIR; then
|
|
751
|
+
if [ -d "memex.pre-gator" ]; then
|
|
752
|
+
echo " memex.pre-gator/ already exists — skipping rename"
|
|
753
|
+
else
|
|
754
|
+
git mv "memex" "memex.pre-gator" 2>/dev/null || \
|
|
755
|
+
mv "memex" "memex.pre-gator"
|
|
756
|
+
log_step "Renamed memex/ → memex.pre-gator/"
|
|
757
|
+
fi
|
|
758
|
+
fi
|
|
759
|
+
if $HAS_DOT_MEMEX_DIR; then
|
|
760
|
+
if [ -d ".memex.pre-gator" ]; then
|
|
761
|
+
echo " .memex.pre-gator/ already exists — skipping rename"
|
|
762
|
+
else
|
|
763
|
+
git mv ".memex" ".memex.pre-gator" 2>/dev/null || \
|
|
764
|
+
mv ".memex" ".memex.pre-gator"
|
|
765
|
+
log_step "Renamed .memex/ → .memex.pre-gator/"
|
|
766
|
+
fi
|
|
767
|
+
fi
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
# --- Step 2: Install .gator/ skeleton (or upgrade existing) ---
|
|
771
|
+
|
|
772
|
+
if [ -d "$target/.gator" ]; then
|
|
773
|
+
log_step "Existing .gator/ found — upgrading templates, preserving content."
|
|
774
|
+
action_upgrade_gator "$target"
|
|
775
|
+
else
|
|
776
|
+
action_install_gator "$target"
|
|
777
|
+
fi
|
|
778
|
+
|
|
779
|
+
# --- Step 3: Overlay content from memex.pre-gator/ ---
|
|
780
|
+
|
|
781
|
+
local src="$target/memex.pre-gator"
|
|
782
|
+
|
|
783
|
+
if [ -d "$src" ]; then
|
|
784
|
+
log_step "Migrating content from memex.pre-gator/ into .gator/ ..."
|
|
785
|
+
|
|
786
|
+
# Direct-copy content files (overwrite stubs)
|
|
787
|
+
for f in mission.md roadmap.md identity.md inbox.md issues.md \
|
|
788
|
+
commit_draft.md whiteboard.md friction.md audit-tracker.md; do
|
|
789
|
+
if [ -f "$src/$f" ]; then
|
|
790
|
+
cp "$src/$f" "$target/.gator/$f"
|
|
791
|
+
log_step " Migrated $f"
|
|
792
|
+
fi
|
|
793
|
+
done
|
|
794
|
+
|
|
795
|
+
# patterns — could be a file or a directory
|
|
796
|
+
if [ -d "$src/patterns" ]; then
|
|
797
|
+
mkdir -p "$target/.gator/patterns"
|
|
798
|
+
cp -r "$src/patterns/"* "$target/.gator/patterns/" 2>/dev/null || true
|
|
799
|
+
log_step " Migrated patterns/"
|
|
800
|
+
elif [ -f "$src/patterns.md" ]; then
|
|
801
|
+
cp "$src/patterns.md" "$target/.gator/patterns.md"
|
|
802
|
+
log_step " Migrated patterns.md"
|
|
803
|
+
fi
|
|
804
|
+
|
|
805
|
+
# active-threads → .gator/threads/ (demoted to reference tier)
|
|
806
|
+
if [ -d "$src/active-threads" ]; then
|
|
807
|
+
local at_count=0
|
|
808
|
+
for f in "$src/active-threads/"*.md; do
|
|
809
|
+
[ -f "$f" ] || continue
|
|
810
|
+
local basename_f
|
|
811
|
+
basename_f=$(basename "$f")
|
|
812
|
+
[ "$basename_f" = "_TEMPLATE.md" ] && continue
|
|
813
|
+
[ "$basename_f" = "_template.md" ] && continue
|
|
814
|
+
if [ -f "$target/.gator/threads/$basename_f" ]; then
|
|
815
|
+
cp "$f" "$target/.gator/threads/${basename_f%.md}-legacy.md"
|
|
816
|
+
else
|
|
817
|
+
cp "$f" "$target/.gator/threads/$basename_f"
|
|
818
|
+
fi
|
|
819
|
+
at_count=$((at_count + 1))
|
|
820
|
+
done
|
|
821
|
+
[ "$at_count" -gt 0 ] && log_step " Migrated $at_count active threads → threads/ (demoted)"
|
|
822
|
+
fi
|
|
823
|
+
|
|
824
|
+
# threads → .gator/threads/ (merge)
|
|
825
|
+
if [ -d "$src/threads" ]; then
|
|
826
|
+
local t_count=0
|
|
827
|
+
for f in "$src/threads/"*.md; do
|
|
828
|
+
[ -f "$f" ] || continue
|
|
829
|
+
local basename_f
|
|
830
|
+
basename_f=$(basename "$f")
|
|
831
|
+
if [ -f "$target/.gator/threads/$basename_f" ]; then
|
|
832
|
+
cp "$f" "$target/.gator/threads/${basename_f%.md}-legacy.md"
|
|
833
|
+
else
|
|
834
|
+
cp "$f" "$target/.gator/threads/$basename_f"
|
|
835
|
+
fi
|
|
836
|
+
t_count=$((t_count + 1))
|
|
837
|
+
done
|
|
838
|
+
[ "$t_count" -gt 0 ] && log_step " Migrated $t_count threads"
|
|
839
|
+
fi
|
|
840
|
+
|
|
841
|
+
# artifacts
|
|
842
|
+
if [ -d "$src/artifacts" ]; then
|
|
843
|
+
local a_count=0
|
|
844
|
+
for f in "$src/artifacts/"*.md; do
|
|
845
|
+
[ -f "$f" ] || continue
|
|
846
|
+
cp "$f" "$target/.gator/artifacts/"
|
|
847
|
+
a_count=$((a_count + 1))
|
|
848
|
+
done
|
|
849
|
+
[ "$a_count" -gt 0 ] && log_step " Migrated $a_count artifacts"
|
|
850
|
+
fi
|
|
851
|
+
|
|
852
|
+
# charters — preserve user charters, gator templates already installed
|
|
853
|
+
if [ -d "$src/charters" ]; then
|
|
854
|
+
local c_count=0
|
|
855
|
+
for f in "$src/charters/"*.md; do
|
|
856
|
+
[ -f "$f" ] || continue
|
|
857
|
+
local basename_f
|
|
858
|
+
basename_f=$(basename "$f")
|
|
859
|
+
case "$basename_f" in
|
|
860
|
+
_template.md|README.md) continue ;;
|
|
861
|
+
esac
|
|
862
|
+
cp "$f" "$target/.gator/charters/$basename_f"
|
|
863
|
+
c_count=$((c_count + 1))
|
|
864
|
+
done
|
|
865
|
+
[ "$c_count" -gt 0 ] && log_step " Migrated $c_count charters"
|
|
866
|
+
fi
|
|
867
|
+
|
|
868
|
+
# vault
|
|
869
|
+
if [ -d "$src/vault" ] && [ -n "$(ls -A "$src/vault" 2>/dev/null)" ]; then
|
|
870
|
+
cp -r "$src/vault/"* "$target/.gator/vault/" 2>/dev/null || true
|
|
871
|
+
log_step " Migrated vault/"
|
|
872
|
+
fi
|
|
873
|
+
|
|
874
|
+
# reference-notes — legacy notes may conflict with template notes
|
|
875
|
+
if [ -d "$src/reference-notes" ]; then
|
|
876
|
+
local rn_count=0 rn_conflict=0
|
|
877
|
+
for f in "$src/reference-notes/"*.md; do
|
|
878
|
+
[ -f "$f" ] || continue
|
|
879
|
+
local basename_f
|
|
880
|
+
basename_f=$(basename "$f")
|
|
881
|
+
if [ -f "$target/.gator/reference-notes/$basename_f" ]; then
|
|
882
|
+
if ! diff -q "$f" "$target/.gator/reference-notes/$basename_f" >/dev/null 2>&1; then
|
|
883
|
+
cp "$f" "$target/.gator/reference-notes/${basename_f%.md}-project.md"
|
|
884
|
+
rn_conflict=$((rn_conflict + 1))
|
|
885
|
+
fi
|
|
886
|
+
else
|
|
887
|
+
cp "$f" "$target/.gator/reference-notes/$basename_f"
|
|
888
|
+
rn_count=$((rn_count + 1))
|
|
889
|
+
fi
|
|
890
|
+
done
|
|
891
|
+
[ "$rn_count" -gt 0 ] && log_step " Migrated $rn_count reference notes"
|
|
892
|
+
[ "$rn_conflict" -gt 0 ] && log_step " Preserved $rn_conflict conflicting notes with -project suffix"
|
|
893
|
+
fi
|
|
894
|
+
fi
|
|
895
|
+
|
|
896
|
+
# --- Step 4: Overlay from .memex.pre-gator/ ---
|
|
897
|
+
|
|
898
|
+
local dotsrc="$target/.memex.pre-gator"
|
|
899
|
+
|
|
900
|
+
if [ -d "$dotsrc" ]; then
|
|
901
|
+
log_step "Migrating system layer from .memex.pre-gator/ ..."
|
|
902
|
+
|
|
903
|
+
if [ -f "$dotsrc/roles.yaml" ]; then
|
|
904
|
+
cp "$dotsrc/roles.yaml" "$target/.gator/roles.yaml"
|
|
905
|
+
log_step " Migrated roles.yaml"
|
|
906
|
+
fi
|
|
907
|
+
|
|
908
|
+
if [ -d "$dotsrc/policies" ]; then
|
|
909
|
+
mkdir -p "$target/.gator/policies"
|
|
910
|
+
cp "$dotsrc/policies/"*.md "$target/.gator/policies/" 2>/dev/null || true
|
|
911
|
+
log_step " Migrated policies/"
|
|
912
|
+
fi
|
|
913
|
+
|
|
914
|
+
log_step " Skipped .memex/scripts/ (gator provides its own)"
|
|
915
|
+
fi
|
|
916
|
+
|
|
917
|
+
# --- Step 5: Archive root constitution files ---
|
|
918
|
+
|
|
919
|
+
(
|
|
920
|
+
cd "$target"
|
|
921
|
+
if $HAS_ROOT_CONSTITUTION && [ -f "constitution.md" ]; then
|
|
922
|
+
git mv "constitution.md" ".gator/legacy-constitution.md" 2>/dev/null || \
|
|
923
|
+
mv "constitution.md" ".gator/legacy-constitution.md"
|
|
924
|
+
log_step "Archived constitution.md → .gator/legacy-constitution.md"
|
|
925
|
+
fi
|
|
926
|
+
if $HAS_ROOT_CONSTITUTION_CORE && [ -f "constitution-core.md" ]; then
|
|
927
|
+
git mv "constitution-core.md" ".gator/legacy-constitution-core.md" 2>/dev/null || \
|
|
928
|
+
mv "constitution-core.md" ".gator/legacy-constitution-core.md"
|
|
929
|
+
log_step "Archived constitution-core.md → .gator/legacy-constitution-core.md"
|
|
930
|
+
fi
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
# Remove .gitkeep from dirs that now have content
|
|
934
|
+
[ -n "$(find "$target/.gator/threads" -name "*.md" 2>/dev/null)" ] && \
|
|
935
|
+
rm -f "$target/.gator/threads/.gitkeep"
|
|
936
|
+
[ -n "$(find "$target/.gator/artifacts" -name "*.md" 2>/dev/null)" ] && \
|
|
937
|
+
rm -f "$target/.gator/artifacts/.gitkeep"
|
|
938
|
+
|
|
939
|
+
# Write version marker
|
|
940
|
+
write_gator_version "$target" "morph"
|
|
941
|
+
|
|
942
|
+
log_blank
|
|
943
|
+
log_step "Morph complete. Pre-gator directories preserved for review:"
|
|
944
|
+
$HAS_MEMEX_DIR && log_step " memex.pre-gator/ — your original content"
|
|
945
|
+
$HAS_DOT_MEMEX_DIR && log_step " .memex.pre-gator/ — your original system layer"
|
|
946
|
+
log_step "Review .gator/, then delete pre-gator dirs when satisfied."
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
# =============================================================================
|
|
950
|
+
# Action: Handle dual memex + gator (Scenario 5)
|
|
951
|
+
# =============================================================================
|
|
952
|
+
|
|
953
|
+
action_warn_dual() {
|
|
954
|
+
local target="$1"
|
|
955
|
+
|
|
956
|
+
detect_legacy_memex "$target"
|
|
957
|
+
|
|
958
|
+
log_blank
|
|
959
|
+
echo " Both memex and gator structures found in $target."
|
|
960
|
+
echo " This is ambiguous — could be a partial migration or manual setup."
|
|
961
|
+
log_blank
|
|
962
|
+
echo " Legacy memex:"
|
|
963
|
+
$HAS_MEMEX_DIR && echo " memex/"
|
|
964
|
+
$HAS_DOT_MEMEX_DIR && echo " .memex/"
|
|
965
|
+
$HAS_ROOT_CONSTITUTION && echo " constitution.md (root)"
|
|
966
|
+
$HAS_ROOT_CONSTITUTION_CORE && echo " constitution-core.md (root)"
|
|
967
|
+
echo " Gator:"
|
|
968
|
+
echo " .gator/"
|
|
969
|
+
log_blank
|
|
970
|
+
echo " Options:"
|
|
971
|
+
echo " [m] Morph — fold memex content into existing .gator/ (recommended)"
|
|
972
|
+
echo " [u] Upgrade — refresh .gator/ templates, ignore memex dirs"
|
|
973
|
+
echo " [a] Abort — inspect manually first"
|
|
974
|
+
log_blank
|
|
975
|
+
read -rp " Choice [m/u/a]: " dual_choice
|
|
976
|
+
|
|
977
|
+
case "$dual_choice" in
|
|
978
|
+
[Mm])
|
|
979
|
+
action_morph_memex "$target"
|
|
980
|
+
;;
|
|
981
|
+
[Uu])
|
|
982
|
+
action_upgrade_gator "$target"
|
|
983
|
+
;;
|
|
984
|
+
*)
|
|
985
|
+
echo " Aborted. Inspect the repo manually and re-run when ready."
|
|
986
|
+
exit 0
|
|
987
|
+
;;
|
|
988
|
+
esac
|
|
989
|
+
}
|