Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 38 additions & 34 deletions .claude/status_lines/status_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@

import json
import os
import sys
import subprocess
from pathlib import Path
import sys
from datetime import datetime
from pathlib import Path

try:
sys.stdin.reconfigure(encoding="utf-8", errors="replace")
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
try:
from dotenv import load_dotenv

load_dotenv()
except ImportError:
pass # dotenv is optional
Expand All @@ -25,41 +32,41 @@ def log_status_line(input_data, status_line_output):
# Ensure logs directory exists
log_dir = Path("logs")
log_dir.mkdir(parents=True, exist_ok=True)
log_file = log_dir / 'status_line.json'
log_file = log_dir / "status_line.json"

# Read existing log data or initialize empty list
if log_file.exists():
with open(log_file, 'r') as f:
with open(log_file, "r") as f:
try:
log_data = json.load(f)
except (json.JSONDecodeError, ValueError):
log_data = []
else:
log_data = []

# Create log entry with input data and generated output
log_entry = {
"timestamp": datetime.now().isoformat(),
"input_data": input_data,
"status_line_output": status_line_output
"status_line_output": status_line_output,
}

# Append the log entry
log_data.append(log_entry)

# Write back to file with formatting
with open(log_file, 'w') as f:
with open(log_file, "w") as f:
json.dump(log_data, f, indent=2)


def get_git_branch():
"""Get current git branch if in a git repository."""
try:
result = subprocess.run(
['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
["git", "rev-parse", "--abbrev-ref", "HEAD"],
capture_output=True,
text=True,
timeout=2
timeout=2,
)
if result.returncode == 0:
return result.stdout.strip()
Expand All @@ -73,15 +80,12 @@ def get_git_status():
try:
# Check if there are uncommitted changes
result = subprocess.run(
['git', 'status', '--porcelain'],
capture_output=True,
text=True,
timeout=2
["git", "status", "--porcelain"], capture_output=True, text=True, timeout=2
)
if result.returncode == 0:
changes = result.stdout.strip()
if changes:
lines = changes.split('\n')
lines = changes.split("\n")
return f"±{len(lines)}"
except Exception:
pass
Expand All @@ -91,19 +95,19 @@ def get_git_status():
def generate_status_line(input_data):
"""Generate the status line based on input data."""
parts = []

# Model display name
model_info = input_data.get('model', {})
model_name = model_info.get('display_name', 'Claude')
model_info = input_data.get("model", {})
model_name = model_info.get("display_name", "Claude")
parts.append(f"\033[36m[{model_name}]\033[0m") # Cyan color

# Current directory
workspace = input_data.get('workspace', {})
current_dir = workspace.get('current_dir', '')
workspace = input_data.get("workspace", {})
current_dir = workspace.get("current_dir", "")
if current_dir:
dir_name = os.path.basename(current_dir)
parts.append(f"\033[34m📁 {dir_name}\033[0m") # Blue color

# Git branch and status
git_branch = get_git_branch()
if git_branch:
Expand All @@ -112,32 +116,32 @@ def generate_status_line(input_data):
if git_status:
git_info += f" {git_status}"
parts.append(f"\033[32m{git_info}\033[0m") # Green color

# Version info (optional, smaller)
version = input_data.get('version', '')
version = input_data.get("version", "")
if version:
parts.append(f"\033[90mv{version}\033[0m") # Gray color

return " | ".join(parts)


def main():
try:
# Read JSON input from stdin
input_data = json.loads(sys.stdin.read())

# Generate status line
status_line = generate_status_line(input_data)

# Log the status line event
log_status_line(input_data, status_line)

# Output the status line (first line of stdout becomes the status line)
print(status_line)

# Success
sys.exit(0)

except json.JSONDecodeError:
# Handle JSON decode errors gracefully - output basic status
print("\033[31m[Claude] 📁 Unknown\033[0m")
Expand All @@ -148,5 +152,5 @@ def main():
sys.exit(0)


if __name__ == '__main__':
main()
if __name__ == "__main__":
main()
81 changes: 45 additions & 36 deletions .claude/status_lines/status_line_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
# ///

import json
import os
import sys
from pathlib import Path
from datetime import datetime
from pathlib import Path

try:
sys.stdin.reconfigure(encoding="utf-8", errors="replace")
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
try:
from dotenv import load_dotenv

load_dotenv()
except ImportError:
pass # dotenv is optional
Expand All @@ -24,47 +30,47 @@ def log_status_line(input_data, status_line_output, error_message=None):
# Ensure logs directory exists
log_dir = Path("logs")
log_dir.mkdir(parents=True, exist_ok=True)
log_file = log_dir / 'status_line.json'
log_file = log_dir / "status_line.json"

# Read existing log data or initialize empty list
if log_file.exists():
with open(log_file, 'r') as f:
with open(log_file, "r") as f:
try:
log_data = json.load(f)
except (json.JSONDecodeError, ValueError):
log_data = []
else:
log_data = []

# Create log entry with input data and generated output
log_entry = {
"timestamp": datetime.now().isoformat(),
"version": "v2",
"input_data": input_data,
"status_line_output": status_line_output,
}

if error_message:
log_entry["error"] = error_message

# Append the log entry
log_data.append(log_entry)

# Write back to file with formatting
with open(log_file, 'w') as f:
with open(log_file, "w") as f:
json.dump(log_data, f, indent=2)


def get_last_prompt(session_id):
"""Get the last prompt for the current session."""
# Use the JSON structure
session_file = Path(f".claude/data/sessions/{session_id}.json")

if not session_file.exists():
return None, f"Session file {session_file} does not exist"

try:
with open(session_file, 'r') as f:
with open(session_file, "r") as f:
session_data = json.load(f)
prompts = session_data.get("prompts", [])
if prompts:
Expand All @@ -77,73 +83,76 @@ def get_last_prompt(session_id):
def generate_status_line(input_data):
"""Generate the status line showing the last prompt."""
# Extract session ID from input data
session_id = input_data.get('session_id', 'unknown')
session_id = input_data.get("session_id", "unknown")

# Get model name for prefix
model_info = input_data.get('model', {})
model_name = model_info.get('display_name', 'Claude')
model_info = input_data.get("model", {})
model_name = model_info.get("display_name", "Claude")

# Get the last prompt
prompt, error = get_last_prompt(session_id)

if error:
# Log the error but show a default message
log_status_line(input_data, f"[{model_name}] 💭 No recent prompt", error)
return f"\033[36m[{model_name}]\033[0m \033[90m💭 No recent prompt\033[0m"

# Format the prompt for status line
# Remove newlines and excessive whitespace
prompt = ' '.join(prompt.split())
prompt = " ".join(prompt.split())

# Color coding based on prompt type
if prompt.startswith('/'):
if prompt.startswith("/"):
# Command prompt - yellow
prompt_color = "\033[33m"
icon = "⚡"
elif '?' in prompt:
elif "?" in prompt:
# Question - blue
prompt_color = "\033[34m"
icon = "❓"
elif any(word in prompt.lower() for word in ['create', 'write', 'add', 'implement', 'build']):
elif any(
word in prompt.lower()
for word in ["create", "write", "add", "implement", "build"]
):
# Creation task - green
prompt_color = "\033[32m"
icon = "💡"
elif any(word in prompt.lower() for word in ['fix', 'debug', 'error', 'issue']):
elif any(word in prompt.lower() for word in ["fix", "debug", "error", "issue"]):
# Fix/debug task - red
prompt_color = "\033[31m"
icon = "🐛"
elif any(word in prompt.lower() for word in ['refactor', 'improve', 'optimize']):
elif any(word in prompt.lower() for word in ["refactor", "improve", "optimize"]):
# Refactor task - magenta
prompt_color = "\033[35m"
icon = "♻️"
else:
# Default - white
prompt_color = "\033[37m"
icon = "💬"

# Construct the status line
status_line = f"\033[36m[{model_name}]\033[0m {icon} {prompt_color}{prompt}\033[0m"

return status_line


def main():
try:
# Read JSON input from stdin
input_data = json.loads(sys.stdin.read())

# Generate status line
status_line = generate_status_line(input_data)

# Log the status line event (without error since it's successful)
log_status_line(input_data, status_line)

# Output the status line (first line of stdout becomes the status line)
print(status_line)

# Success
sys.exit(0)

except json.JSONDecodeError:
# Handle JSON decode errors gracefully - output basic status
print("\033[31m[Claude] 💭 JSON Error\033[0m")
Expand All @@ -154,5 +163,5 @@ def main():
sys.exit(0)


if __name__ == '__main__':
main()
if __name__ == "__main__":
main()
9 changes: 7 additions & 2 deletions .claude/status_lines/status_line_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
# ///

import json
import os
import sys
from pathlib import Path
from datetime import datetime
from pathlib import Path

try:
sys.stdin.reconfigure(encoding="utf-8", errors="replace")
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
try:
from dotenv import load_dotenv

Expand Down
Loading