diff --git a/.claude/commands/rename.md b/.claude/commands/rename.md new file mode 100644 index 0000000..4dbaf67 --- /dev/null +++ b/.claude/commands/rename.md @@ -0,0 +1,4 @@ +--- +description: Renombra esta terminal/Claude (se muestra como título en FleetView) +--- +rename: $ARGUMENTS diff --git a/.claude/hooks/goal_autogen.sh b/.claude/hooks/goal_autogen.sh index d9e8990..9c17a12 100755 --- a/.claude/hooks/goal_autogen.sh +++ b/.claude/hooks/goal_autogen.sh @@ -20,7 +20,7 @@ ASK="$HOME/fn_registry/python/functions/core/ask_llm.py" P=$(printf '%s' "$PROMPT" | tail -c 2000) [ -z "$P" ] && exit 0 -SYS="Dado el PRIMER mensaje de un usuario a un asistente de codigo en una terminal, infiere un OBJETIVO breve de la tarea (maximo 8 palabras, en espanol, sin comillas) y un DoD breve (definition of done: condicion concreta de 'terminado', maximo 8 palabras, en espanol). Responde SOLO un objeto JSON en una sola linea, sin markdown ni texto extra: {\"goal\":\"...\",\"dod\":\"...\"}. Si el mensaje es un saludo, charla trivial o no describe ninguna tarea, responde exactamente {}." +SYS="Dado el PRIMER mensaje de un usuario a un asistente de codigo en una terminal, infiere un OBJETIVO breve de la tarea (maximo 8 palabras, en espanol, sin comillas), un DoD breve (definition of done: condicion concreta de 'terminado', maximo 8 palabras, en espanol) y EXACTAMENTE 3 EMOJIS que representen visualmente la tarea (3 emojis pegados, sin espacios ni texto entre ellos). Responde SOLO un objeto JSON en una sola linea, sin markdown ni texto extra: {\"goal\":\"...\",\"dod\":\"...\",\"emojis\":\"🔭✨🌌\"}. Si el mensaje es un saludo, charla trivial o no describe ninguna tarea, responde exactamente {}." RAW=$("$PY" "$ASK" --system "$SYS" "$P" 2>/dev/null) [ -z "$RAW" ] && exit 0 @@ -31,14 +31,15 @@ JSON=$(printf '%s' "$RAW" | tr '\n' ' ' | grep -o '{[^{}]*}' | head -1) GOAL=$(printf '%s' "$JSON" | jq -r '.goal // ""' 2>/dev/null) DOD=$(printf '%s' "$JSON" | jq -r '.dod // ""' 2>/dev/null) +EMOJIS=$(printf '%s' "$JSON" | jq -r '.emojis // ""' 2>/dev/null) [ -z "$GOAL" ] && exit 0 # Carrera: si entre tanto se creo el archivo, no pisar. [ -f "$F" ] && exit 0 TMP="${F}.tmp.$$" -if jq -n --arg g "$GOAL" --arg d "$DOD" --arg p "$P" \ - '{goal:$g, phase:"planificando", history:["planificando"], prompts:[$p]} | if $d != "" then .dod=$d else . end' > "$TMP" 2>/dev/null; then +if jq -n --arg g "$GOAL" --arg d "$DOD" --arg e "$EMOJIS" --arg p "$P" \ + '{goal:$g, phase:"planificando", history:["planificando"], prompts:[$p]} | (if $d != "" then .dod=$d else . end) | (if $e != "" then .emojis=$e else . end)' > "$TMP" 2>/dev/null; then mv "$TMP" "$F" else rm -f "$TMP" diff --git a/.claude/hooks/goal_tracker.sh b/.claude/hooks/goal_tracker.sh index 3dc867a..25d5514 100755 --- a/.claude/hooks/goal_tracker.sh +++ b/.claude/hooks/goal_tracker.sh @@ -52,6 +52,28 @@ if [ -n "$GOAL_LINE" ]; then block "🎯 Objetivo fijado: ${NEWGOAL}" fi +# --- /rename o rename: (nombre manual de la terminal) --- +RENAME_LINE=$(printf '%s' "$PROMPT" | grep -ioE '^[[:space:]]*(/rename|rename[[:space:]]*:)[[:space:]]*.+' | head -1) +if [ -n "$RENAME_LINE" ]; then + NEWNAME=$(printf '%s' "$RENAME_LINE" | sed -E 's#^[[:space:]]*(/rename|rename[[:space:]]*:)[[:space:]]*##; s/[[:space:]]+$//') + case "$NEWNAME" in + -|clear|none|borrar|quitar|reset) + if [ -f "$F" ]; then + TMP="${F}.tmp.$$"; jq 'del(.rename)' "$F" > "$TMP" 2>/dev/null && mv "$TMP" "$F" + fi + block "🏷️ Nombre de la terminal borrado." ;; + esac + if [ -f "$F" ]; then + TMP="${F}.tmp.$$" + jq --arg n "$NEWNAME" '.rename=$n' "$F" > "$TMP" 2>/dev/null && mv "$TMP" "$F" + else + # Sin objetivo aun: crear el archivo minimo con el rename. + TMP="${F}.tmp.$$" + jq -n --arg n "$NEWNAME" '{rename:$n, phase:"planificando", prompts:[]}' > "$TMP" 2>/dev/null && mv "$TMP" "$F" + fi + block "🏷️ Terminal renombrada: ${NEWNAME}" +fi + # --- dod: --- DOD_LINE=$(printf '%s' "$PROMPT" | grep -ioE '^[[:space:]]*dod[[:space:]]*:[[:space:]]*.+' | head -1) if [ -n "$DOD_LINE" ]; then diff --git a/.claude/settings.json b/.claude/settings.json index 039a906..4a9b84d 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -4,14 +4,18 @@ "Edit(~/.claude/**)", "Write(~/.claude/**)", "Edit(.claude/**)", - "Write(.claude/**)" + "Write(.claude/**)", + "Bash(CGO_ENABLED=1 go test *)", + "Bash(sqlite3 *)", + "Read(//home/enmanuel/.claude/**)" ], "deny": [ "Edit(~/.claude/.git/**)", "Write(~/.claude/.git/**)", "Edit(.git/**)", "Write(.git/**)" - ] + ], + "defaultMode": "dontAsk" }, "hooks": { "UserPromptSubmit": [ @@ -73,8 +77,14 @@ } } }, + "language": "Español", "effortLevel": "xhigh", + "voice": { + "enabled": true, + "mode": "hold" + }, "skipDangerousModePermissionPrompt": true, "preferredNotifChannel": "notifications_disabled", - "agentPushNotifEnabled": false + "agentPushNotifEnabled": false, + "voiceEnabled": true } diff --git a/.claude/statusline.sh b/.claude/statusline.sh index 76e1913..9628240 100755 --- a/.claude/statusline.sh +++ b/.claude/statusline.sh @@ -45,6 +45,25 @@ if [ "$CONTEXT_PCT" -eq 0 ] && [ "$CONTEXT_USED" -gt 0 ]; then CONTEXT_PCT=$(echo "scale=0; $CONTEXT_USED * 100 / $CONTEXT_TOTAL" | bc) fi +# Persistir el contexto por sesión en un sidecar para que fleetview (y otras +# herramientas) puedan mostrarlo sin tener este stdin. El statusline se re-ejecuta +# cada pocos segundos, así que el dato se mantiene fresco mientras la sesión vive. +if [ -n "$SESSION_ID" ]; then + RTDIR="$HOME/.claude/runtime" + mkdir -p "$RTDIR" 2>/dev/null + RTF="$RTDIR/${SESSION_ID}.json" + RTMP="${RTF}.tmp.$$" + if jq -n \ + --argjson pct "${CONTEXT_PCT:-0}" \ + --argjson used "${CONTEXT_USED:-0}" \ + --argjson total "${CONTEXT_TOTAL:-200000}" \ + '{ctx_pct:$pct, ctx_used:$used, ctx_total:$total}' > "$RTMP" 2>/dev/null; then + mv "$RTMP" "$RTF" 2>/dev/null + else + rm -f "$RTMP" 2>/dev/null + fi +fi + # Costos TOTAL_COST=$(echo "$INPUT" | jq -r '.cost.total_cost_usd // 0' | xargs printf "%.3f") SESSION_DURATION=$(echo "$INPUT" | jq -r '.cost.total_duration_ms // 0')