-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreflight.sh
More file actions
executable file
·189 lines (157 loc) · 6.09 KB
/
preflight.sh
File metadata and controls
executable file
·189 lines (157 loc) · 6.09 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
#!/usr/bin/env bash
# scripts/preflight.sh — environment & dependency check for llm-wiki-bootstrap.
#
# Purpose:
# Verify hard requirements are present, report which optional shell tools
# the host has, and detect installed AI runtimes. Helps users see whether
# /wiki-extract's primary handlers will run first-try or fall back to
# LLM-vision / failed-sidecar.
#
# Usage:
# ./scripts/preflight.sh
#
# Exit codes:
# 0 — all hard requirements met (optional tools may be missing)
# 1 — at least one hard requirement missing
#
# Idempotent. Safe to re-run. Writes nothing to disk.
set -euo pipefail
# Resolve repo root so the script works from any directory.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# TTY-aware colors. Plain output when piped or redirected.
if [ -t 1 ]; then
RED=$'\033[31m'
YELLOW=$'\033[33m'
GREEN=$'\033[32m'
DIM=$'\033[2m'
RESET=$'\033[0m'
else
RED=
YELLOW=
GREEN=
DIM=
RESET=
fi
# Platform-aware install command for hints (shared helper; default first so a
# missing helper never breaks the script).
INSTALL_CMD="<your-package-manager> install"
[ -f "$SCRIPT_DIR/lib/platform-hint.sh" ] && . "$SCRIPT_DIR/lib/platform-hint.sh"
# State tracking
hard_failures=0
have_pdftotext=no
have_pandoc=no
have_xlsx2csv=no
have_python_docx=no
have_python_openpyxl=no
have_npx=no
have_ai_tool=no
# Helpers
have() { command -v "$1" >/dev/null 2>&1; }
ok() { printf "%s✓%s %-15s — %s\n" "$GREEN" "$RESET" "$1" "$2"; }
warn() { printf "%s⚠%s %-15s — %s\n" "$YELLOW" "$RESET" "$1" "$2"; }
fail() { printf "%s✗%s %-15s — %s\n" "$RED" "$RESET" "$1" "$2"; hard_failures=$((hard_failures + 1)); }
echo "llm-wiki-bootstrap preflight"
echo "============================"
echo
echo "${DIM}Hard requirements:${RESET}"
# bash itself (we wouldn't be running otherwise, but report the version)
ok "bash" "present (${BASH_VERSION:-unknown})"
# awk
if have awk; then ok "awk" "present"
else fail "awk" "missing — required by scripts/body-hash.sh (install: ${INSTALL_CMD} gawk)"; fi
# openssl
if have openssl; then ok "openssl" "present"
else fail "openssl" "missing — required by scripts/body-hash.sh (install: ${INSTALL_CMD} openssl)"; fi
# git
if have git; then ok "git" "present"
else fail "git" "missing — required (install: ${INSTALL_CMD} git)"; fi
# raw/ permissions
if [ -d "$REPO_ROOT/raw" ]; then
if [ -w "$REPO_ROOT/raw" ]; then ok "raw/ write" "OK"
else fail "raw/ write" "no write permission on raw/ (fix: chmod u+w \"$REPO_ROOT/raw\")"; fi
else
warn "raw/" "directory missing — run mkdir raw, or /wiki-init in your AI tool"
fi
# wiki/ permissions
if [ -d "$REPO_ROOT/wiki" ]; then
if [ -w "$REPO_ROOT/wiki" ]; then ok "wiki/ write" "OK"
else fail "wiki/ write" "no write permission on wiki/ (fix: chmod u+w \"$REPO_ROOT/wiki\")"; fi
else
warn "wiki/" "directory missing — run mkdir wiki, or /wiki-init in your AI tool"
fi
echo
echo "${DIM}Recommended optional tools (enable shell-first extraction):${RESET}"
# pdftotext
if have pdftotext; then ok "pdftotext" "present — PDF primary handler"; have_pdftotext=yes
else warn "pdftotext" "missing — PDF will fall back to LLM-vision (install: ${INSTALL_CMD} poppler)"; fi
# pandoc
if have pandoc; then ok "pandoc" "present — DOCX primary handler"; have_pandoc=yes
else warn "pandoc" "missing — DOCX will try python-docx, then fail (install: ${INSTALL_CMD} pandoc)"; fi
# xlsx2csv
if have xlsx2csv; then ok "xlsx2csv" "present — XLSX primary handler"; have_xlsx2csv=yes
else warn "xlsx2csv" "missing — XLSX will try openpyxl, then fail (install: pip install xlsx2csv)"; fi
# python3 + modules
if have python3; then
ok "python3" "present"
if python3 -c "import docx" >/dev/null 2>&1; then
ok "python-docx" "present — DOCX fallback ready"; have_python_docx=yes
else
warn "python-docx" "missing (install: pip install python-docx)"
fi
if python3 -c "import openpyxl" >/dev/null 2>&1; then
ok "openpyxl" "present — XLSX fallback ready"; have_python_openpyxl=yes
else
warn "openpyxl" "missing (install: pip install openpyxl)"
fi
else
warn "python3" "missing — DOCX/XLSX fallbacks unavailable (install: ${INSTALL_CMD} python3)"
fi
# npx — only needed for the optional MCP server (scripts/mcp-server.sh).
if have npx; then ok "npx" "present — MCP server can be launched (scripts/mcp-server.sh)"; have_npx=yes
else warn "npx" "missing — optional, blocks scripts/mcp-server.sh only (install Node ≥18 from https://nodejs.org)"; fi
echo
echo "${DIM}AI runtimes on PATH:${RESET}"
for tool in claude cursor code copilot gemini; do
if have "$tool"; then ok "$tool" "present"; have_ai_tool=yes; fi
done
if [ "$have_ai_tool" = "no" ]; then
warn "(none)" "no supported AI tool found on PATH — install one of Claude Code, Cursor, VSCode, Copilot CLI, or Gemini CLI."
fi
echo
# Exit on hard failures before printing the summary.
if [ "$hard_failures" -gt 0 ]; then
printf "%sNot ready.%s %d hard requirement(s) missing. Install them before running any /wiki-* command.\n" \
"$RED" "$RESET" "$hard_failures"
exit 1
fi
# Compose extraction-coverage summary.
full="URL, plain text, CSV, image"
partial=""
degraded=""
if [ "$have_pdftotext" = "yes" ]; then
full="${full}, PDF"
else
degraded="${degraded}, PDF (LLM-vision fallback)"
fi
if [ "$have_pandoc" = "yes" ]; then
full="${full}, DOCX"
elif [ "$have_python_docx" = "yes" ]; then
partial="${partial}, DOCX (python-docx fallback)"
else
degraded="${degraded}, DOCX (will produce extraction_status: failed sidecar)"
fi
if [ "$have_xlsx2csv" = "yes" ]; then
full="${full}, XLSX"
elif [ "$have_python_openpyxl" = "yes" ]; then
partial="${partial}, XLSX (openpyxl fallback)"
else
degraded="${degraded}, XLSX (will produce extraction_status: failed sidecar)"
fi
# Strip leading ", " from partial / degraded before printing.
partial="${partial#, }"
degraded="${degraded#, }"
printf "%sReady.%s Full first-try: %s.\n" "$GREEN" "$RESET" "$full"
[ -n "$partial" ] && printf "%sPartial:%s %s.\n" "$YELLOW" "$RESET" "$partial"
[ -n "$degraded" ] && printf "%sDegraded:%s %s.\n" "$YELLOW" "$RESET" "$degraded"
exit 0