golem-cc 0.2.3 → 0.2.6

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.
Files changed (2) hide show
  1. package/bin/golem +508 -0
  2. 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,377 @@ 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
+ # Fix also exports PATH in current session so re-check succeeds
1033
+ run_check "golem command available in PATH" \
1034
+ "command -v golem &>/dev/null" \
1035
+ "Add PATH to $shell_config" \
1036
+ "grep -q '.golem/bin' \"$shell_config\" 2>/dev/null || echo 'export PATH=\"\$HOME/.golem/bin:\$PATH\"' >> \"$shell_config\"; [[ \":\$PATH:\" != *\":\$HOME/.golem/bin:\"* ]] && export PATH=\"\$HOME/.golem/bin:\$PATH\" || true"
1037
+
1038
+ # Check shell config files for golem setup
1039
+ local shell_config_found=false
1040
+ local shell_configs=("$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile")
1041
+ for config in "${shell_configs[@]}"; do
1042
+ if [[ -f "$config" ]] && grep -q "golem" "$config" 2>/dev/null; then
1043
+ shell_config_found=true
1044
+ break
1045
+ fi
1046
+ done
1047
+ run_check "Shell config contains golem setup" \
1048
+ "$shell_config_found" \
1049
+ "Add PATH to $shell_config" \
1050
+ "grep -q '.golem/bin' \"$shell_config\" 2>/dev/null || echo 'export PATH=\"\$HOME/.golem/bin:\$PATH\"' >> \"$shell_config\""
1051
+
1052
+ [[ "$json_mode" == "false" ]] && echo ""
1053
+
1054
+ # === Optional Checks ===
1055
+ [[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Optional Dependencies${NC}"
1056
+ [[ "$json_mode" == "false" ]] && echo ""
1057
+
1058
+ # Check if Claude Code CLI is installed
1059
+ if command -v claude &>/dev/null; then
1060
+ local claude_version
1061
+ claude_version=$(claude --version 2>/dev/null | head -1 || echo "unknown")
1062
+ [[ "$json_mode" == "false" ]] && status_line "✓" "$GREEN" "Claude Code CLI installed ($claude_version)"
1063
+ checks_passed=$((checks_passed + 1))
1064
+ json_checks+=("{\"name\":\"Claude Code CLI installed\",\"status\":\"pass\",\"fixable\":false,\"fix_hint\":\"npm install -g @anthropic-ai/claude-code\",\"version\":\"$claude_version\"}")
1065
+ else
1066
+ [[ "$json_mode" == "false" ]] && status_line "◦" "$YELLOW" "Claude Code CLI not found (required for golem)"
1067
+ [[ "$json_mode" == "false" ]] && echo -e " ${DIM}Install: npm install -g @anthropic-ai/claude-code${NC}"
1068
+ # This is critical, so count as failure
1069
+ checks_failed=$((checks_failed + 1))
1070
+ all_passed=false
1071
+ json_checks+=("{\"name\":\"Claude Code CLI installed\",\"status\":\"fail\",\"fixable\":false,\"fix_hint\":\"npm install -g @anthropic-ai/claude-code\"}")
1072
+ fi
1073
+
1074
+ [[ "$json_mode" == "false" ]] && echo ""
1075
+
1076
+ # === Project-Level Checks (if in a golem project) ===
1077
+ if [[ -d ".golem" ]]; then
1078
+ [[ "$json_mode" == "false" ]] && echo -e " ${BOLD}Project-Level (.golem/)${NC}"
1079
+ [[ "$json_mode" == "false" ]] && echo ""
1080
+
1081
+ run_check ".golem/ directory exists" \
1082
+ "[[ -d \".golem\" ]]" \
1083
+ "Create directory" \
1084
+ "mkdir -p .golem"
1085
+
1086
+ run_check ".golem/AGENTS.md exists" \
1087
+ "[[ -f \".golem/AGENTS.md\" ]]" \
1088
+ "Run golem --init" \
1089
+ ""
1090
+
1091
+ run_check ".golem/specs/ directory exists" \
1092
+ "[[ -d \".golem/specs\" ]]" \
1093
+ "Create directory" \
1094
+ "mkdir -p .golem/specs"
1095
+
1096
+ run_check ".golem/prompts/ directory exists" \
1097
+ "[[ -d \".golem/prompts\" ]]" \
1098
+ "Create directory" \
1099
+ "mkdir -p .golem/prompts"
1100
+
1101
+ run_check ".golem/agents/ directory exists" \
1102
+ "[[ -d \".golem/agents\" ]]" \
1103
+ "Create directory" \
1104
+ "mkdir -p .golem/agents"
1105
+
1106
+ [[ "$json_mode" == "false" ]] && echo ""
1107
+ fi
1108
+
1109
+ # === Summary ===
1110
+ local total=$((checks_passed + checks_failed))
1111
+ local version
1112
+ version=$(get_version)
1113
+
1114
+ # JSON output mode
1115
+ if [[ "$json_mode" == "true" ]]; then
1116
+ local json_checks_str
1117
+ json_checks_str=$(IFS=,; echo "${json_checks[*]}")
1118
+ local success="true"
1119
+ [[ $checks_failed -gt 0 ]] && success="false"
1120
+
1121
+ cat <<EOF
1122
+ {
1123
+ "success": $success,
1124
+ "version": "$version",
1125
+ "checks_passed": $checks_passed,
1126
+ "checks_failed": $checks_failed,
1127
+ "checks_total": $total,
1128
+ "fixes_applied": $fixes_applied,
1129
+ "fixes_available": $fixes_available,
1130
+ "checks": [$json_checks_str]
1131
+ }
1132
+ EOF
1133
+ if [[ $checks_failed -eq 0 ]]; then
1134
+ exit 0
1135
+ else
1136
+ exit 1
1137
+ fi
1138
+ fi
1139
+
1140
+ hr "━" "$CYAN"
1141
+ echo ""
1142
+
1143
+ # Show fixes applied if any
1144
+ if [[ $fixes_applied -gt 0 ]]; then
1145
+ status_line "⚡" "$CYAN" "$fixes_applied fix(es) applied"
1146
+ fi
1147
+
1148
+ # Recalculate pass status (fixes may have resolved issues)
1149
+ if [[ $checks_failed -eq 0 ]]; then
1150
+ status_line "✓" "$GREEN" "All checks passed ($checks_passed/$total)"
1151
+ echo ""
1152
+ if [[ $fixes_applied -gt 0 ]]; then
1153
+ echo -e " ${DIM}Note: You may need to restart your shell for PATH changes${NC}"
1154
+ echo ""
1155
+ fi
1156
+ exit 0
1157
+ else
1158
+ status_line "✗" "$RED" "$checks_failed check(s) failed ($checks_passed/$total passed)"
1159
+ echo ""
1160
+ if [[ "$fix_mode" == "false" ]] && [[ $fixes_available -gt 0 ]]; then
1161
+ echo -e " ${DIM}Run 'golem doctor --fix' to auto-fix issues${NC}"
1162
+ else
1163
+ echo -e " ${DIM}Run 'npx golem-cc' to reinstall golem${NC}"
1164
+ fi
1165
+ echo ""
1166
+ exit 1
1167
+ fi
1168
+ }
1169
+
684
1170
  cmd_status() {
685
1171
  local check_only=false
1172
+ local skip_update_check=false
686
1173
 
687
1174
  # Parse options
688
1175
  while [[ $# -gt 0 ]]; do
@@ -691,6 +1178,10 @@ cmd_status() {
691
1178
  check_only=true
692
1179
  shift
693
1180
  ;;
1181
+ --skip-update-check)
1182
+ skip_update_check=true
1183
+ shift
1184
+ ;;
694
1185
  *)
695
1186
  shift
696
1187
  ;;
@@ -750,6 +1241,19 @@ cmd_status() {
750
1241
  done || echo -e " ${DIM}No commits yet${NC}"
751
1242
  fi
752
1243
  echo ""
1244
+
1245
+ # Check for updates (non-blocking, cached)
1246
+ if [[ "$skip_update_check" == "false" ]]; then
1247
+ local current_version
1248
+ current_version=$(get_version)
1249
+ local latest_version
1250
+ latest_version=$(check_for_update "$current_version")
1251
+
1252
+ if [[ -n "$latest_version" ]]; then
1253
+ echo -e " ${YELLOW}Update available:${NC} ${DIM}$current_version${NC} → ${GREEN}$latest_version${NC} ${DIM}(run: npx golem-cc)${NC}"
1254
+ echo ""
1255
+ fi
1256
+ fi
753
1257
  }
754
1258
 
755
1259
  # Main entry point
@@ -783,6 +1287,10 @@ main() {
783
1287
  shift
784
1288
  cmd_status "$@"
785
1289
  ;;
1290
+ doctor)
1291
+ shift
1292
+ cmd_doctor "$@"
1293
+ ;;
786
1294
  "")
787
1295
  # No command - just launch claude
788
1296
  claude
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "golem-cc",
3
- "version": "0.2.3",
3
+ "version": "0.2.6",
4
4
  "description": "Autonomous coding loop with Claude - structured specs, ralph loop execution, code simplification",
5
5
  "bin": {
6
6
  "golem-cc": "bin/install.cjs"