golem-cc 0.2.3 → 0.2.5
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.
- package/bin/golem +507 -0
- package/package.json +1 -1
package/bin/golem
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# golem run build Run autonomous build loop
|
|
12
12
|
# golem simplify [path] Run code simplifier
|
|
13
13
|
# golem status Show project status
|
|
14
|
+
# golem doctor Check installation health
|
|
14
15
|
#
|
|
15
16
|
set -euo pipefail
|
|
16
17
|
|
|
@@ -115,6 +116,119 @@ get_version() {
|
|
|
115
116
|
fi
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
# Update checker - checks npm registry for newer version with caching
|
|
120
|
+
# Cache file: ~/.golem/.update-check (JSON format)
|
|
121
|
+
# Returns: latest version if update available, empty string otherwise
|
|
122
|
+
check_for_update() {
|
|
123
|
+
local current_version="$1"
|
|
124
|
+
local cache_file="$HOME/.golem/.update-check"
|
|
125
|
+
local cache_max_age=86400 # 24 hours in seconds
|
|
126
|
+
local timeout_secs=3
|
|
127
|
+
local npm_registry="https://registry.npmjs.org/golem-cc/latest"
|
|
128
|
+
|
|
129
|
+
# Skip if current version is unknown
|
|
130
|
+
[[ "$current_version" == "unknown" ]] && return
|
|
131
|
+
|
|
132
|
+
# Check cache first
|
|
133
|
+
if [[ -f "$cache_file" ]]; then
|
|
134
|
+
local cache_time=""
|
|
135
|
+
local cached_version=""
|
|
136
|
+
|
|
137
|
+
if command -v jq &>/dev/null; then
|
|
138
|
+
cache_time=$(jq -r '.checked // 0' "$cache_file" 2>/dev/null)
|
|
139
|
+
cached_version=$(jq -r '.version // ""' "$cache_file" 2>/dev/null)
|
|
140
|
+
else
|
|
141
|
+
# Parse JSON without jq
|
|
142
|
+
cache_time=$(grep -o '"checked"[[:space:]]*:[[:space:]]*[0-9]*' "$cache_file" 2>/dev/null | grep -o '[0-9]*$')
|
|
143
|
+
cached_version=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$cache_file" 2>/dev/null | sed 's/.*"\([^"]*\)"$/\1/')
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
local now
|
|
147
|
+
now=$(date +%s)
|
|
148
|
+
local age=$((now - ${cache_time:-0}))
|
|
149
|
+
|
|
150
|
+
# Use cached result if still fresh
|
|
151
|
+
if [[ $age -lt $cache_max_age ]] && [[ -n "$cached_version" ]]; then
|
|
152
|
+
# Compare versions - only output if update available
|
|
153
|
+
if version_gt "$cached_version" "$current_version"; then
|
|
154
|
+
echo "$cached_version"
|
|
155
|
+
fi
|
|
156
|
+
return
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# Fetch latest version from npm registry (with timeout, background-friendly)
|
|
161
|
+
local latest_version=""
|
|
162
|
+
local response=""
|
|
163
|
+
|
|
164
|
+
# Use curl with timeout (available on all Unix systems)
|
|
165
|
+
if command -v curl &>/dev/null; then
|
|
166
|
+
response=$(curl -s --max-time "$timeout_secs" "$npm_registry" 2>/dev/null) || return
|
|
167
|
+
elif command -v wget &>/dev/null; then
|
|
168
|
+
response=$(wget -q -O - --timeout="$timeout_secs" "$npm_registry" 2>/dev/null) || return
|
|
169
|
+
else
|
|
170
|
+
# No curl or wget available
|
|
171
|
+
return
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Parse version from response
|
|
175
|
+
if [[ -n "$response" ]]; then
|
|
176
|
+
if command -v jq &>/dev/null; then
|
|
177
|
+
latest_version=$(echo "$response" | jq -r '.version // ""' 2>/dev/null)
|
|
178
|
+
else
|
|
179
|
+
latest_version=$(echo "$response" | grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/')
|
|
180
|
+
fi
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Update cache (create directory if needed)
|
|
184
|
+
if [[ -n "$latest_version" ]]; then
|
|
185
|
+
mkdir -p "$(dirname "$cache_file")"
|
|
186
|
+
local now
|
|
187
|
+
now=$(date +%s)
|
|
188
|
+
cat > "$cache_file" << EOF
|
|
189
|
+
{"version":"$latest_version","checked":$now}
|
|
190
|
+
EOF
|
|
191
|
+
|
|
192
|
+
# Compare versions and output if update available
|
|
193
|
+
if version_gt "$latest_version" "$current_version"; then
|
|
194
|
+
echo "$latest_version"
|
|
195
|
+
fi
|
|
196
|
+
fi
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Compare two semver versions - returns 0 if v1 > v2
|
|
200
|
+
version_gt() {
|
|
201
|
+
local v1="$1"
|
|
202
|
+
local v2="$2"
|
|
203
|
+
|
|
204
|
+
# Use sort -V if available (GNU coreutils)
|
|
205
|
+
if printf '%s\n' "$v1" "$v2" | sort -V &>/dev/null; then
|
|
206
|
+
local highest
|
|
207
|
+
highest=$(printf '%s\n' "$v1" "$v2" | sort -V | tail -1)
|
|
208
|
+
[[ "$highest" == "$v1" ]] && [[ "$v1" != "$v2" ]]
|
|
209
|
+
return $?
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
# Fallback: simple numeric comparison for x.y.z format
|
|
213
|
+
local v1_major v1_minor v1_patch
|
|
214
|
+
local v2_major v2_minor v2_patch
|
|
215
|
+
|
|
216
|
+
IFS='.' read -r v1_major v1_minor v1_patch <<< "$v1"
|
|
217
|
+
IFS='.' read -r v2_major v2_minor v2_patch <<< "$v2"
|
|
218
|
+
|
|
219
|
+
# Default to 0 if empty
|
|
220
|
+
v1_major=${v1_major:-0}; v1_minor=${v1_minor:-0}; v1_patch=${v1_patch:-0}
|
|
221
|
+
v2_major=${v2_major:-0}; v2_minor=${v2_minor:-0}; v2_patch=${v2_patch:-0}
|
|
222
|
+
|
|
223
|
+
# Compare major.minor.patch
|
|
224
|
+
if [[ $v1_major -gt $v2_major ]]; then return 0; fi
|
|
225
|
+
if [[ $v1_major -lt $v2_major ]]; then return 1; fi
|
|
226
|
+
if [[ $v1_minor -gt $v2_minor ]]; then return 0; fi
|
|
227
|
+
if [[ $v1_minor -lt $v2_minor ]]; then return 1; fi
|
|
228
|
+
if [[ $v1_patch -gt $v2_patch ]]; then return 0; fi
|
|
229
|
+
return 1
|
|
230
|
+
}
|
|
231
|
+
|
|
118
232
|
# Audit logging
|
|
119
233
|
log_event() {
|
|
120
234
|
local event="$1"
|
|
@@ -192,6 +306,10 @@ print_usage() {
|
|
|
192
306
|
echo " simplify [path] Run code simplifier"
|
|
193
307
|
echo " status Show project status"
|
|
194
308
|
echo " status --check Exit 0 if complete, 1 if incomplete, 2 if no plan"
|
|
309
|
+
echo " status --skip-update-check Skip checking for updates"
|
|
310
|
+
echo " doctor Check installation health"
|
|
311
|
+
echo " doctor --fix Auto-fix detected issues"
|
|
312
|
+
echo " doctor --json Output results as JSON (for CI/scripting)"
|
|
195
313
|
echo ""
|
|
196
314
|
echo -e "${BLUE}Options:${NC}"
|
|
197
315
|
echo " --init Initialize golem in current project"
|
|
@@ -681,8 +799,376 @@ cmd_simplify() {
|
|
|
681
799
|
fi
|
|
682
800
|
}
|
|
683
801
|
|
|
802
|
+
# Doctor command - verify installation health
|
|
803
|
+
cmd_doctor() {
|
|
804
|
+
local all_passed=true
|
|
805
|
+
local fix_mode=false
|
|
806
|
+
local json_mode=false
|
|
807
|
+
local fixes_applied=0
|
|
808
|
+
local fixes_available=0
|
|
809
|
+
|
|
810
|
+
# JSON output accumulator (array of check results)
|
|
811
|
+
local json_checks=()
|
|
812
|
+
|
|
813
|
+
# Parse options
|
|
814
|
+
while [[ $# -gt 0 ]]; do
|
|
815
|
+
case $1 in
|
|
816
|
+
--fix)
|
|
817
|
+
fix_mode=true
|
|
818
|
+
shift
|
|
819
|
+
;;
|
|
820
|
+
--json)
|
|
821
|
+
json_mode=true
|
|
822
|
+
shift
|
|
823
|
+
;;
|
|
824
|
+
*)
|
|
825
|
+
shift
|
|
826
|
+
;;
|
|
827
|
+
esac
|
|
828
|
+
done
|
|
829
|
+
|
|
830
|
+
if [[ "$json_mode" == "false" ]]; then
|
|
831
|
+
print_banner
|
|
832
|
+
header_box "DOCTOR" "$BLUE"
|
|
833
|
+
echo ""
|
|
834
|
+
if [[ "$fix_mode" == "true" ]]; then
|
|
835
|
+
echo -e " ${DIM}Checking installation health (auto-fix enabled)...${NC}"
|
|
836
|
+
else
|
|
837
|
+
echo -e " ${DIM}Checking golem installation health...${NC}"
|
|
838
|
+
fi
|
|
839
|
+
echo ""
|
|
840
|
+
fi
|
|
841
|
+
|
|
842
|
+
# Track check results for summary
|
|
843
|
+
local checks_passed=0
|
|
844
|
+
local checks_failed=0
|
|
845
|
+
|
|
846
|
+
# Helper: prompt user to apply a fix (or auto-apply in fix mode)
|
|
847
|
+
# Always returns 0 to avoid triggering set -e
|
|
848
|
+
apply_fix() {
|
|
849
|
+
local description="$1"
|
|
850
|
+
local fix_cmd="$2"
|
|
851
|
+
|
|
852
|
+
fixes_available=$((fixes_available + 1))
|
|
853
|
+
|
|
854
|
+
if [[ "$fix_mode" == "true" ]]; then
|
|
855
|
+
# Auto-fix mode: apply without prompting
|
|
856
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${CYAN}→ Applying fix: $description${NC}"
|
|
857
|
+
if eval "$fix_cmd" 2>/dev/null; then
|
|
858
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${GREEN}✓ Fixed${NC}"
|
|
859
|
+
fixes_applied=$((fixes_applied + 1))
|
|
860
|
+
else
|
|
861
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${RED}✗ Fix failed${NC}"
|
|
862
|
+
fi
|
|
863
|
+
else
|
|
864
|
+
# Interactive mode: prompt user (only if stdin is a terminal and not json mode)
|
|
865
|
+
if [[ -t 0 ]] && [[ "$json_mode" == "false" ]]; then
|
|
866
|
+
echo -ne " ${YELLOW}Fix this? [y/N]${NC} "
|
|
867
|
+
local response=""
|
|
868
|
+
read -r response
|
|
869
|
+
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
870
|
+
echo -e " ${CYAN}→ Applying fix: $description${NC}"
|
|
871
|
+
if eval "$fix_cmd" 2>/dev/null; then
|
|
872
|
+
echo -e " ${GREEN}✓ Fixed${NC}"
|
|
873
|
+
fixes_applied=$((fixes_applied + 1))
|
|
874
|
+
else
|
|
875
|
+
echo -e " ${RED}✗ Fix failed${NC}"
|
|
876
|
+
fi
|
|
877
|
+
else
|
|
878
|
+
echo -e " ${DIM}Skipped${NC}"
|
|
879
|
+
fi
|
|
880
|
+
elif [[ "$json_mode" == "false" ]]; then
|
|
881
|
+
# Non-interactive: just show the hint
|
|
882
|
+
echo -e " ${DIM}Fix: $description${NC}"
|
|
883
|
+
fi
|
|
884
|
+
fi
|
|
885
|
+
return 0 # Always return 0 to continue script execution
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
# Helper function to run a check with optional auto-fix
|
|
889
|
+
# Always returns 0 to avoid triggering set -e; tracks failures internally
|
|
890
|
+
run_check() {
|
|
891
|
+
local name="$1"
|
|
892
|
+
local check_cmd="$2"
|
|
893
|
+
local fix_hint="$3"
|
|
894
|
+
local fix_cmd="${4:-}"
|
|
895
|
+
local check_status="pass"
|
|
896
|
+
local fixed=false
|
|
897
|
+
|
|
898
|
+
if eval "$check_cmd" 2>/dev/null; then
|
|
899
|
+
[[ "$json_mode" == "false" ]] && status_line "✓" "$GREEN" "$name"
|
|
900
|
+
checks_passed=$((checks_passed + 1))
|
|
901
|
+
check_status="pass"
|
|
902
|
+
else
|
|
903
|
+
[[ "$json_mode" == "false" ]] && status_line "✗" "$RED" "$name"
|
|
904
|
+
checks_failed=$((checks_failed + 1))
|
|
905
|
+
all_passed=false
|
|
906
|
+
check_status="fail"
|
|
907
|
+
|
|
908
|
+
# Attempt to fix if fix_cmd is provided
|
|
909
|
+
if [[ -n "$fix_cmd" ]]; then
|
|
910
|
+
apply_fix "$fix_hint" "$fix_cmd"
|
|
911
|
+
# Re-check after fix attempt
|
|
912
|
+
if eval "$check_cmd" 2>/dev/null; then
|
|
913
|
+
checks_passed=$((checks_passed + 1))
|
|
914
|
+
checks_failed=$((checks_failed - 1))
|
|
915
|
+
check_status="fixed"
|
|
916
|
+
fixed=true
|
|
917
|
+
fi
|
|
918
|
+
elif [[ -n "$fix_hint" ]] && [[ "$json_mode" == "false" ]]; then
|
|
919
|
+
echo -e " ${DIM}Fix: $fix_hint${NC}"
|
|
920
|
+
fi
|
|
921
|
+
fi
|
|
922
|
+
|
|
923
|
+
# Add to JSON checks array
|
|
924
|
+
local fix_available="false"
|
|
925
|
+
[[ -n "$fix_cmd" ]] && fix_available="true"
|
|
926
|
+
local escaped_name="${name//\"/\\\"}"
|
|
927
|
+
local escaped_hint="${fix_hint//\"/\\\"}"
|
|
928
|
+
json_checks+=("{\"name\":\"$escaped_name\",\"status\":\"$check_status\",\"fixable\":$fix_available,\"fix_hint\":\"$escaped_hint\"}")
|
|
929
|
+
|
|
930
|
+
return 0 # Always return 0 to continue script execution
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
# === Global Installation Checks ===
|
|
934
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Global Installation (~/.golem/)${NC}"
|
|
935
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
936
|
+
|
|
937
|
+
# Check ~/.golem directory exists
|
|
938
|
+
run_check "~/.golem/ directory exists" \
|
|
939
|
+
"[[ -d \"$HOME/.golem\" ]]" \
|
|
940
|
+
"Create directory" \
|
|
941
|
+
"mkdir -p \"$HOME/.golem\""
|
|
942
|
+
|
|
943
|
+
# Check ~/.golem/bin/golem exists and is executable
|
|
944
|
+
run_check "~/.golem/bin/golem is executable" \
|
|
945
|
+
"[[ -x \"$HOME/.golem/bin/golem\" ]]" \
|
|
946
|
+
"Fix permissions" \
|
|
947
|
+
"[[ -f \"$HOME/.golem/bin/golem\" ]] && chmod +x \"$HOME/.golem/bin/golem\""
|
|
948
|
+
|
|
949
|
+
# Check ~/.golem/bin/render-md.cjs exists
|
|
950
|
+
run_check "~/.golem/bin/render-md.cjs exists" \
|
|
951
|
+
"[[ -f \"$HOME/.golem/bin/render-md.cjs\" ]]" \
|
|
952
|
+
"npx golem-cc (reinstall)" \
|
|
953
|
+
""
|
|
954
|
+
|
|
955
|
+
# Check ~/.golem/golem/prompts directory
|
|
956
|
+
run_check "~/.golem/golem/prompts/ exists" \
|
|
957
|
+
"[[ -d \"$HOME/.golem/golem/prompts\" ]]" \
|
|
958
|
+
"Create directory" \
|
|
959
|
+
"mkdir -p \"$HOME/.golem/golem/prompts\""
|
|
960
|
+
|
|
961
|
+
# Check ~/.golem/golem/agents directory
|
|
962
|
+
run_check "~/.golem/golem/agents/ exists" \
|
|
963
|
+
"[[ -d \"$HOME/.golem/golem/agents\" ]]" \
|
|
964
|
+
"Create directory" \
|
|
965
|
+
"mkdir -p \"$HOME/.golem/golem/agents\""
|
|
966
|
+
|
|
967
|
+
# Check VERSION file
|
|
968
|
+
run_check "~/.golem/VERSION file exists" \
|
|
969
|
+
"[[ -f \"$HOME/.golem/VERSION\" ]]" \
|
|
970
|
+
"npx golem-cc (reinstall)" \
|
|
971
|
+
""
|
|
972
|
+
|
|
973
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
974
|
+
|
|
975
|
+
# === Claude Code Integration Checks ===
|
|
976
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Claude Code Integration (~/.claude/)${NC}"
|
|
977
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
978
|
+
|
|
979
|
+
# Check ~/.claude/golem directory
|
|
980
|
+
run_check "~/.claude/golem/ directory exists" \
|
|
981
|
+
"[[ -d \"$HOME/.claude/golem\" ]]" \
|
|
982
|
+
"Create directory" \
|
|
983
|
+
"mkdir -p \"$HOME/.claude/golem\""
|
|
984
|
+
|
|
985
|
+
# Check ~/.claude/commands/golem directory with slash commands
|
|
986
|
+
run_check "~/.claude/commands/golem/ exists" \
|
|
987
|
+
"[[ -d \"$HOME/.claude/commands/golem\" ]]" \
|
|
988
|
+
"Create directory" \
|
|
989
|
+
"mkdir -p \"$HOME/.claude/commands/golem\""
|
|
990
|
+
|
|
991
|
+
# Check for key slash command files
|
|
992
|
+
run_check "Slash commands installed (build.md)" \
|
|
993
|
+
"[[ -f \"$HOME/.claude/commands/golem/build.md\" ]]" \
|
|
994
|
+
"npx golem-cc (reinstall)" \
|
|
995
|
+
""
|
|
996
|
+
|
|
997
|
+
# Check ~/.claude/golem/prompts directory
|
|
998
|
+
run_check "~/.claude/golem/prompts/ exists" \
|
|
999
|
+
"[[ -d \"$HOME/.claude/golem/prompts\" ]]" \
|
|
1000
|
+
"Create directory" \
|
|
1001
|
+
"mkdir -p \"$HOME/.claude/golem/prompts\""
|
|
1002
|
+
|
|
1003
|
+
# Check ~/.claude/golem/agents directory
|
|
1004
|
+
run_check "~/.claude/golem/agents/ exists" \
|
|
1005
|
+
"[[ -d \"$HOME/.claude/golem/agents\" ]]" \
|
|
1006
|
+
"Create directory" \
|
|
1007
|
+
"mkdir -p \"$HOME/.claude/golem/agents\""
|
|
1008
|
+
|
|
1009
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1010
|
+
|
|
1011
|
+
# === Shell Integration Checks ===
|
|
1012
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Shell Integration${NC}"
|
|
1013
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1014
|
+
|
|
1015
|
+
# Determine user's shell and config file
|
|
1016
|
+
local user_shell
|
|
1017
|
+
user_shell=$(basename "${SHELL:-/bin/bash}")
|
|
1018
|
+
local shell_config=""
|
|
1019
|
+
case "$user_shell" in
|
|
1020
|
+
zsh) shell_config="$HOME/.zshrc" ;;
|
|
1021
|
+
bash)
|
|
1022
|
+
if [[ -f "$HOME/.bash_profile" ]]; then
|
|
1023
|
+
shell_config="$HOME/.bash_profile"
|
|
1024
|
+
else
|
|
1025
|
+
shell_config="$HOME/.bashrc"
|
|
1026
|
+
fi
|
|
1027
|
+
;;
|
|
1028
|
+
*) shell_config="$HOME/.profile" ;;
|
|
1029
|
+
esac
|
|
1030
|
+
|
|
1031
|
+
# Check if golem is in PATH (the function/alias should work)
|
|
1032
|
+
run_check "golem command available in PATH" \
|
|
1033
|
+
"command -v golem &>/dev/null" \
|
|
1034
|
+
"Add PATH to $shell_config" \
|
|
1035
|
+
"grep -q '.golem/bin' \"$shell_config\" 2>/dev/null || echo 'export PATH=\"\$HOME/.golem/bin:\$PATH\"' >> \"$shell_config\""
|
|
1036
|
+
|
|
1037
|
+
# Check shell config files for golem setup
|
|
1038
|
+
local shell_config_found=false
|
|
1039
|
+
local shell_configs=("$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile")
|
|
1040
|
+
for config in "${shell_configs[@]}"; do
|
|
1041
|
+
if [[ -f "$config" ]] && grep -q "golem" "$config" 2>/dev/null; then
|
|
1042
|
+
shell_config_found=true
|
|
1043
|
+
break
|
|
1044
|
+
fi
|
|
1045
|
+
done
|
|
1046
|
+
run_check "Shell config contains golem setup" \
|
|
1047
|
+
"$shell_config_found" \
|
|
1048
|
+
"Add PATH to $shell_config" \
|
|
1049
|
+
"grep -q '.golem/bin' \"$shell_config\" 2>/dev/null || echo 'export PATH=\"\$HOME/.golem/bin:\$PATH\"' >> \"$shell_config\""
|
|
1050
|
+
|
|
1051
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1052
|
+
|
|
1053
|
+
# === Optional Checks ===
|
|
1054
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Optional Dependencies${NC}"
|
|
1055
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1056
|
+
|
|
1057
|
+
# Check if Claude Code CLI is installed
|
|
1058
|
+
if command -v claude &>/dev/null; then
|
|
1059
|
+
local claude_version
|
|
1060
|
+
claude_version=$(claude --version 2>/dev/null | head -1 || echo "unknown")
|
|
1061
|
+
[[ "$json_mode" == "false" ]] && status_line "✓" "$GREEN" "Claude Code CLI installed ($claude_version)"
|
|
1062
|
+
checks_passed=$((checks_passed + 1))
|
|
1063
|
+
json_checks+=("{\"name\":\"Claude Code CLI installed\",\"status\":\"pass\",\"fixable\":false,\"fix_hint\":\"npm install -g @anthropic-ai/claude-code\",\"version\":\"$claude_version\"}")
|
|
1064
|
+
else
|
|
1065
|
+
[[ "$json_mode" == "false" ]] && status_line "◦" "$YELLOW" "Claude Code CLI not found (required for golem)"
|
|
1066
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${DIM}Install: npm install -g @anthropic-ai/claude-code${NC}"
|
|
1067
|
+
# This is critical, so count as failure
|
|
1068
|
+
checks_failed=$((checks_failed + 1))
|
|
1069
|
+
all_passed=false
|
|
1070
|
+
json_checks+=("{\"name\":\"Claude Code CLI installed\",\"status\":\"fail\",\"fixable\":false,\"fix_hint\":\"npm install -g @anthropic-ai/claude-code\"}")
|
|
1071
|
+
fi
|
|
1072
|
+
|
|
1073
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1074
|
+
|
|
1075
|
+
# === Project-Level Checks (if in a golem project) ===
|
|
1076
|
+
if [[ -d ".golem" ]]; then
|
|
1077
|
+
[[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Project-Level (.golem/)${NC}"
|
|
1078
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1079
|
+
|
|
1080
|
+
run_check ".golem/ directory exists" \
|
|
1081
|
+
"[[ -d \".golem\" ]]" \
|
|
1082
|
+
"Create directory" \
|
|
1083
|
+
"mkdir -p .golem"
|
|
1084
|
+
|
|
1085
|
+
run_check ".golem/AGENTS.md exists" \
|
|
1086
|
+
"[[ -f \".golem/AGENTS.md\" ]]" \
|
|
1087
|
+
"Run golem --init" \
|
|
1088
|
+
""
|
|
1089
|
+
|
|
1090
|
+
run_check ".golem/specs/ directory exists" \
|
|
1091
|
+
"[[ -d \".golem/specs\" ]]" \
|
|
1092
|
+
"Create directory" \
|
|
1093
|
+
"mkdir -p .golem/specs"
|
|
1094
|
+
|
|
1095
|
+
run_check ".golem/prompts/ directory exists" \
|
|
1096
|
+
"[[ -d \".golem/prompts\" ]]" \
|
|
1097
|
+
"Create directory" \
|
|
1098
|
+
"mkdir -p .golem/prompts"
|
|
1099
|
+
|
|
1100
|
+
run_check ".golem/agents/ directory exists" \
|
|
1101
|
+
"[[ -d \".golem/agents\" ]]" \
|
|
1102
|
+
"Create directory" \
|
|
1103
|
+
"mkdir -p .golem/agents"
|
|
1104
|
+
|
|
1105
|
+
[[ "$json_mode" == "false" ]] && echo ""
|
|
1106
|
+
fi
|
|
1107
|
+
|
|
1108
|
+
# === Summary ===
|
|
1109
|
+
local total=$((checks_passed + checks_failed))
|
|
1110
|
+
local version
|
|
1111
|
+
version=$(get_version)
|
|
1112
|
+
|
|
1113
|
+
# JSON output mode
|
|
1114
|
+
if [[ "$json_mode" == "true" ]]; then
|
|
1115
|
+
local json_checks_str
|
|
1116
|
+
json_checks_str=$(IFS=,; echo "${json_checks[*]}")
|
|
1117
|
+
local success="true"
|
|
1118
|
+
[[ $checks_failed -gt 0 ]] && success="false"
|
|
1119
|
+
|
|
1120
|
+
cat <<EOF
|
|
1121
|
+
{
|
|
1122
|
+
"success": $success,
|
|
1123
|
+
"version": "$version",
|
|
1124
|
+
"checks_passed": $checks_passed,
|
|
1125
|
+
"checks_failed": $checks_failed,
|
|
1126
|
+
"checks_total": $total,
|
|
1127
|
+
"fixes_applied": $fixes_applied,
|
|
1128
|
+
"fixes_available": $fixes_available,
|
|
1129
|
+
"checks": [$json_checks_str]
|
|
1130
|
+
}
|
|
1131
|
+
EOF
|
|
1132
|
+
if [[ $checks_failed -eq 0 ]]; then
|
|
1133
|
+
exit 0
|
|
1134
|
+
else
|
|
1135
|
+
exit 1
|
|
1136
|
+
fi
|
|
1137
|
+
fi
|
|
1138
|
+
|
|
1139
|
+
hr "━" "$CYAN"
|
|
1140
|
+
echo ""
|
|
1141
|
+
|
|
1142
|
+
# Show fixes applied if any
|
|
1143
|
+
if [[ $fixes_applied -gt 0 ]]; then
|
|
1144
|
+
status_line "⚡" "$CYAN" "$fixes_applied fix(es) applied"
|
|
1145
|
+
fi
|
|
1146
|
+
|
|
1147
|
+
# Recalculate pass status (fixes may have resolved issues)
|
|
1148
|
+
if [[ $checks_failed -eq 0 ]]; then
|
|
1149
|
+
status_line "✓" "$GREEN" "All checks passed ($checks_passed/$total)"
|
|
1150
|
+
echo ""
|
|
1151
|
+
if [[ $fixes_applied -gt 0 ]]; then
|
|
1152
|
+
echo -e " ${DIM}Note: You may need to restart your shell for PATH changes${NC}"
|
|
1153
|
+
echo ""
|
|
1154
|
+
fi
|
|
1155
|
+
exit 0
|
|
1156
|
+
else
|
|
1157
|
+
status_line "✗" "$RED" "$checks_failed check(s) failed ($checks_passed/$total passed)"
|
|
1158
|
+
echo ""
|
|
1159
|
+
if [[ "$fix_mode" == "false" ]] && [[ $fixes_available -gt 0 ]]; then
|
|
1160
|
+
echo -e " ${DIM}Run 'golem doctor --fix' to auto-fix issues${NC}"
|
|
1161
|
+
else
|
|
1162
|
+
echo -e " ${DIM}Run 'npx golem-cc' to reinstall golem${NC}"
|
|
1163
|
+
fi
|
|
1164
|
+
echo ""
|
|
1165
|
+
exit 1
|
|
1166
|
+
fi
|
|
1167
|
+
}
|
|
1168
|
+
|
|
684
1169
|
cmd_status() {
|
|
685
1170
|
local check_only=false
|
|
1171
|
+
local skip_update_check=false
|
|
686
1172
|
|
|
687
1173
|
# Parse options
|
|
688
1174
|
while [[ $# -gt 0 ]]; do
|
|
@@ -691,6 +1177,10 @@ cmd_status() {
|
|
|
691
1177
|
check_only=true
|
|
692
1178
|
shift
|
|
693
1179
|
;;
|
|
1180
|
+
--skip-update-check)
|
|
1181
|
+
skip_update_check=true
|
|
1182
|
+
shift
|
|
1183
|
+
;;
|
|
694
1184
|
*)
|
|
695
1185
|
shift
|
|
696
1186
|
;;
|
|
@@ -750,6 +1240,19 @@ cmd_status() {
|
|
|
750
1240
|
done || echo -e " ${DIM}No commits yet${NC}"
|
|
751
1241
|
fi
|
|
752
1242
|
echo ""
|
|
1243
|
+
|
|
1244
|
+
# Check for updates (non-blocking, cached)
|
|
1245
|
+
if [[ "$skip_update_check" == "false" ]]; then
|
|
1246
|
+
local current_version
|
|
1247
|
+
current_version=$(get_version)
|
|
1248
|
+
local latest_version
|
|
1249
|
+
latest_version=$(check_for_update "$current_version")
|
|
1250
|
+
|
|
1251
|
+
if [[ -n "$latest_version" ]]; then
|
|
1252
|
+
echo -e " ${YELLOW}Update available:${NC} ${DIM}$current_version${NC} → ${GREEN}$latest_version${NC} ${DIM}(run: npx golem-cc)${NC}"
|
|
1253
|
+
echo ""
|
|
1254
|
+
fi
|
|
1255
|
+
fi
|
|
753
1256
|
}
|
|
754
1257
|
|
|
755
1258
|
# Main entry point
|
|
@@ -783,6 +1286,10 @@ main() {
|
|
|
783
1286
|
shift
|
|
784
1287
|
cmd_status "$@"
|
|
785
1288
|
;;
|
|
1289
|
+
doctor)
|
|
1290
|
+
shift
|
|
1291
|
+
cmd_doctor "$@"
|
|
1292
|
+
;;
|
|
786
1293
|
"")
|
|
787
1294
|
# No command - just launch claude
|
|
788
1295
|
claude
|