fantasy-claude 1.0.3 → 1.0.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.0.4
package/cli.sh CHANGED
@@ -1,7 +1,15 @@
1
1
  #!/bin/bash
2
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2
+ SOURCE="${BASH_SOURCE[0]}"
3
+ while [ -L "$SOURCE" ]; do
4
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
5
+ SOURCE="$(readlink "$SOURCE")"
6
+ [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
7
+ done
8
+ SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
9
+ # shellcheck source=lib/python.sh
10
+ source "$SCRIPT_DIR/lib/python.sh"
3
11
  case "${1:-}" in
4
12
  install) exec bash "$SCRIPT_DIR/install.sh" ;;
5
13
  --version) cat "$SCRIPT_DIR/VERSION" ;;
6
- *) exec python3 "$SCRIPT_DIR/configure.py" ;;
14
+ *) exec $PYTHON_BIN "$SCRIPT_DIR/configure.py" ;;
7
15
  esac
package/config.json CHANGED
@@ -12,6 +12,11 @@
12
12
  "context-pct",
13
13
  "burn-rate",
14
14
  "session-cost"
15
+ ],
16
+ [
17
+ "streak",
18
+ "usage-5h",
19
+ "reset-time"
15
20
  ]
16
21
  ],
17
22
  "element_settings": {
@@ -67,10 +72,10 @@
67
72
  "color": null
68
73
  },
69
74
  "usage-5h": {
70
- "emoji": false,
75
+ "emoji": true,
71
76
  "label": true,
72
- "color": "green",
73
- "bar": "multi"
77
+ "color": null,
78
+ "bar": "off"
74
79
  },
75
80
  "model": {
76
81
  "emoji": true,
package/configure.sh CHANGED
@@ -2,4 +2,5 @@
2
2
  # Thin wrapper — launches the interactive TUI configurator
3
3
  set -euo pipefail
4
4
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
- exec python3 "$REPO_DIR/configure.py" "$@"
5
+ source "$REPO_DIR/lib/python.sh"
6
+ exec $PYTHON_BIN "$REPO_DIR/configure.py" "$@"
@@ -1,7 +1,8 @@
1
1
  #!/bin/bash
2
2
  # Notification hook for auth_success events
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../lib/python.sh"
3
4
  input=$(cat)
4
- msg=$(echo "$input" | python3 -c "
5
+ msg=$(echo "$input" | $PYTHON_BIN -c "
5
6
  import sys, json
6
7
  try:
7
8
  print(json.load(sys.stdin).get('message', 'Authentication succeeded'))
@@ -1,7 +1,8 @@
1
1
  #!/bin/bash
2
2
  # Notification hook for elicitation_dialog events
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../lib/python.sh"
3
4
  input=$(cat)
4
- msg=$(echo "$input" | python3 -c "
5
+ msg=$(echo "$input" | $PYTHON_BIN -c "
5
6
  import sys, json
6
7
  try:
7
8
  print(json.load(sys.stdin).get('message', 'Claude has a question'))
@@ -1,7 +1,8 @@
1
1
  #!/bin/bash
2
2
  # Notification hook for permission_prompt events
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../lib/python.sh"
3
4
  input=$(cat)
4
- msg=$(echo "$input" | python3 -c "
5
+ msg=$(echo "$input" | $PYTHON_BIN -c "
5
6
  import sys, json
6
7
  try:
7
8
  print(json.load(sys.stdin).get('message', 'Claude needs your permission'))
package/hooks/notify.sh CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/bin/bash
2
2
  # Hook script for notifications when Claude Code needs user input.
3
3
  # Uses iTerm2 OSC 9 escape sequence on macOS, notify-send on Linux.
4
+ source "$(dirname "${BASH_SOURCE[0]}")/../lib/python.sh"
4
5
 
5
6
  input=$(cat)
6
7
 
7
8
  # Build notification message with emoji prefix based on type
8
- message=$(echo "$input" | python3 -c "
9
+ message=$(echo "$input" | $PYTHON_BIN -c "
9
10
  import sys, json
10
11
  try:
11
12
  d = json.load(sys.stdin)
package/hooks/sounds.sh CHANGED
@@ -2,12 +2,13 @@
2
2
  # Hook script for sound events — reads config.json and plays the configured sound
3
3
 
4
4
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ source "$REPO_DIR/lib/python.sh"
5
6
  CONFIG="$REPO_DIR/config.json"
6
7
 
7
8
  input=$(cat)
8
9
 
9
10
  # Determine event type and whether it's an error
10
- hook_event=$(echo "$input" | python3 -c "
11
+ hook_event=$(echo "$input" | $PYTHON_BIN -c "
11
12
  import sys, json
12
13
  try:
13
14
  d = json.load(sys.stdin)
@@ -25,7 +26,7 @@ except:
25
26
 
26
27
  [ -z "$hook_event" ] && exit 0
27
28
 
28
- sound_name=$(python3 -c "
29
+ sound_name=$($PYTHON_BIN -c "
29
30
  import json
30
31
  with open('$CONFIG') as f:
31
32
  d = json.load(f)
package/install.sh CHANGED
@@ -8,6 +8,30 @@ SETTINGS="$CLAUDE_DIR/settings.json"
8
8
  VERSION=$(cat "$REPO_DIR/VERSION" 2>/dev/null || echo "unknown")
9
9
  echo "Installing claude-hooks v$VERSION from $REPO_DIR"
10
10
 
11
+ detect_python() {
12
+ local candidates=("python3.13" "python3.12" "python3.11" "python3.10" "python3.9" "python3.8" "python3.7" "python3.6" "python3" "python")
13
+ for candidate in "${candidates[@]}"; do
14
+ if command -v "$candidate" &>/dev/null; then
15
+ local ver
16
+ ver=$("$candidate" -c "import sys; v=sys.version_info; print(v.major*100+v.minor)" 2>/dev/null)
17
+ if [ -n "$ver" ] && [ "$ver" -ge 306 ]; then
18
+ command -v "$candidate"
19
+ return 0
20
+ fi
21
+ fi
22
+ done
23
+ return 1
24
+ }
25
+
26
+ echo "Detecting Python 3.6+..."
27
+ PYTHON_PATH=$(detect_python) || {
28
+ echo "ERROR: Python 3.6+ not found."
29
+ echo "Install Python 3 from https://www.python.org/downloads/ and re-run install.sh"
30
+ exit 1
31
+ }
32
+ echo "Using Python: $PYTHON_PATH ($("$PYTHON_PATH" --version))"
33
+ echo "$PYTHON_PATH" > "$REPO_DIR/.python_bin"
34
+
11
35
  # Make all scripts executable
12
36
  chmod +x "$REPO_DIR/statusline/statusline.sh"
13
37
  chmod +x "$REPO_DIR/statusline/elements/"*.sh
@@ -25,7 +49,7 @@ if [ ! -f "$SETTINGS" ]; then
25
49
  echo "{}" > "$SETTINGS"
26
50
  fi
27
51
 
28
- python3 - <<EOF
52
+ "$PYTHON_PATH" - <<EOF
29
53
  import json
30
54
 
31
55
  settings_path = "$SETTINGS"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fantasy-claude",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Statusline and sound hooks for Claude Code",
5
5
  "bin": {
6
6
  "fantasy-claude": "./cli.sh",
@@ -21,5 +21,8 @@
21
21
  "repository": {
22
22
  "type": "git",
23
23
  "url": "https://github.com/itsAlfantasy/fantasy-claude"
24
+ },
25
+ "dependencies": {
26
+ "fantasy-claude": "^1.0.3"
24
27
  }
25
28
  }
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  # Context window usage % from the most recent Claude Code session JSONL
3
- python3 - << 'PYEOF'
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
4
+ $PYTHON_BIN - << 'PYEOF'
4
5
  import glob, json, os, sys
5
6
 
6
7
  CLAUDE_DIR = os.path.expanduser("~/.claude/projects")
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
3
- python3 - "$REPO_DIR/config.json" << 'PYEOF'
3
+ source "$REPO_DIR/lib/python.sh"
4
+ $PYTHON_BIN - "$REPO_DIR/config.json" << 'PYEOF'
4
5
  import os, json, sys
5
6
 
6
7
  basename_only = False
@@ -1,5 +1,6 @@
1
1
  #!/bin/bash
2
- python3 - << 'PYEOF'
2
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
3
+ $PYTHON_BIN - << 'PYEOF'
3
4
  import glob, os, json
4
5
  claude_dir = os.path.expanduser('~/.claude/projects')
5
6
  files = glob.glob(f'{claude_dir}/**/*.jsonl', recursive=True)
@@ -1,5 +1,6 @@
1
1
  #!/bin/bash
2
- python3 - << 'PYEOF'
2
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
3
+ $PYTHON_BIN - << 'PYEOF'
3
4
  from datetime import date
4
5
  import hashlib
5
6
  LINE1 = [
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  # Current Claude model from the most recent session JSONL
3
- python3 - << 'PYEOF'
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
4
+ $PYTHON_BIN - << 'PYEOF'
4
5
  import glob, json, os, re, sys
5
6
 
6
7
  CLAUDE_DIR = os.path.expanduser("~/.claude/projects")
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
3
- python3 - "$REPO_DIR/config.json" << 'PYEOF'
3
+ source "$REPO_DIR/lib/python.sh"
4
+ $PYTHON_BIN - "$REPO_DIR/config.json" << 'PYEOF'
4
5
  import json, sys
5
6
  from datetime import datetime
6
7
 
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
3
- python3 - "$REPO_DIR/config.json" << 'PYEOF'
3
+ source "$REPO_DIR/lib/python.sh"
4
+ $PYTHON_BIN - "$REPO_DIR/config.json" << 'PYEOF'
4
5
  import json, sys
5
6
  from datetime import date
6
7
 
@@ -1,9 +1,10 @@
1
1
  #!/bin/bash
2
2
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
3
+ source "$REPO_DIR/lib/python.sh"
3
4
  POMO_FILE="/tmp/pomodoro_$(id -u)"
4
5
 
5
6
  _get_duration() {
6
- python3 - "$REPO_DIR/config.json" << 'PYEOF'
7
+ $PYTHON_BIN - "$REPO_DIR/config.json" << 'PYEOF'
7
8
  import json, sys
8
9
  try:
9
10
  with open(sys.argv[1]) as f:
@@ -1,7 +1,8 @@
1
1
  #!/bin/bash
2
2
  # Estimated session cost from token counts in the active JSONL
3
3
  # Uses Sonnet 4.6 pricing: $3/MTok in, $15/MTok out, $3.75/MTok cache-write, $0.30/MTok cache-read
4
- python3 - << 'PYEOF'
4
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
5
+ $PYTHON_BIN - << 'PYEOF'
5
6
  import glob, json, os, sys
6
7
 
7
8
  CLAUDE_DIR = os.path.expanduser("~/.claude/projects")
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  # Duration of the current Claude Code session from its JSONL
3
- python3 - << 'PYEOF'
3
+ source "$(dirname "${BASH_SOURCE[0]}")/../../lib/python.sh"
4
+ $PYTHON_BIN - << 'PYEOF'
4
5
  import glob, json, os, sys
5
6
  from datetime import datetime, timezone
6
7
 
@@ -1,6 +1,7 @@
1
1
  #!/bin/bash
2
2
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
3
- python3 - "$REPO_DIR/config.json" << 'PYEOF'
3
+ source "$REPO_DIR/lib/python.sh"
4
+ $PYTHON_BIN - "$REPO_DIR/config.json" << 'PYEOF'
4
5
  import glob, os, json, sys
5
6
  from datetime import date, timedelta
6
7
 
@@ -2,6 +2,7 @@
2
2
  # Main statusline script — reads config.json and composes the status line
3
3
 
4
4
  REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ source "$REPO_DIR/lib/python.sh"
5
6
  CONFIG="$REPO_DIR/config.json"
6
7
  ELEMENTS_DIR="$REPO_DIR/statusline/elements"
7
8
 
@@ -102,7 +103,7 @@ while IFS= read -r raw_line; do
102
103
  current_parts+=("$formatted")
103
104
  fi
104
105
  fi
105
- done < <(python3 -c "
106
+ done < <($PYTHON_BIN -c "
106
107
  import json, sys
107
108
  EMOJIS = {
108
109
  'battery': '\U0001f50b',