feat(goals): emojis de objetivo + /rename + sidecar de contexto para FleetView
- goal_autogen.sh: genera 3 emojis representativos del objetivo (haiku) junto al goal+DoD, guardados en goals/<id>.json. - goal_tracker.sh: comando meta /rename (y rename:) para nombrar la terminal; se guarda en goals/<id>.json .rename. - commands/rename.md: slash command /rename. - statusline.sh: persiste el % de contexto por sesion en runtime/<id>.json para que FleetView lo muestre. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
description: Renombra esta terminal/Claude (se muestra como título en FleetView)
|
||||||
|
---
|
||||||
|
rename: $ARGUMENTS
|
||||||
@@ -20,7 +20,7 @@ ASK="$HOME/fn_registry/python/functions/core/ask_llm.py"
|
|||||||
P=$(printf '%s' "$PROMPT" | tail -c 2000)
|
P=$(printf '%s' "$PROMPT" | tail -c 2000)
|
||||||
[ -z "$P" ] && exit 0
|
[ -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)
|
RAW=$("$PY" "$ASK" --system "$SYS" "$P" 2>/dev/null)
|
||||||
[ -z "$RAW" ] && exit 0
|
[ -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)
|
GOAL=$(printf '%s' "$JSON" | jq -r '.goal // ""' 2>/dev/null)
|
||||||
DOD=$(printf '%s' "$JSON" | jq -r '.dod // ""' 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
|
[ -z "$GOAL" ] && exit 0
|
||||||
|
|
||||||
# Carrera: si entre tanto se creo el archivo, no pisar.
|
# Carrera: si entre tanto se creo el archivo, no pisar.
|
||||||
[ -f "$F" ] && exit 0
|
[ -f "$F" ] && exit 0
|
||||||
|
|
||||||
TMP="${F}.tmp.$$"
|
TMP="${F}.tmp.$$"
|
||||||
if jq -n --arg g "$GOAL" --arg d "$DOD" --arg p "$P" \
|
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' > "$TMP" 2>/dev/null; then
|
'{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"
|
mv "$TMP" "$F"
|
||||||
else
|
else
|
||||||
rm -f "$TMP"
|
rm -f "$TMP"
|
||||||
|
|||||||
@@ -52,6 +52,28 @@ if [ -n "$GOAL_LINE" ]; then
|
|||||||
block "🎯 Objetivo fijado: ${NEWGOAL}"
|
block "🎯 Objetivo fijado: ${NEWGOAL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# --- /rename <texto> o rename: <texto> (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: <texto> ---
|
# --- dod: <texto> ---
|
||||||
DOD_LINE=$(printf '%s' "$PROMPT" | grep -ioE '^[[:space:]]*dod[[:space:]]*:[[:space:]]*.+' | head -1)
|
DOD_LINE=$(printf '%s' "$PROMPT" | grep -ioE '^[[:space:]]*dod[[:space:]]*:[[:space:]]*.+' | head -1)
|
||||||
if [ -n "$DOD_LINE" ]; then
|
if [ -n "$DOD_LINE" ]; then
|
||||||
|
|||||||
+13
-3
@@ -4,14 +4,18 @@
|
|||||||
"Edit(~/.claude/**)",
|
"Edit(~/.claude/**)",
|
||||||
"Write(~/.claude/**)",
|
"Write(~/.claude/**)",
|
||||||
"Edit(.claude/**)",
|
"Edit(.claude/**)",
|
||||||
"Write(.claude/**)"
|
"Write(.claude/**)",
|
||||||
|
"Bash(CGO_ENABLED=1 go test *)",
|
||||||
|
"Bash(sqlite3 *)",
|
||||||
|
"Read(//home/enmanuel/.claude/**)"
|
||||||
],
|
],
|
||||||
"deny": [
|
"deny": [
|
||||||
"Edit(~/.claude/.git/**)",
|
"Edit(~/.claude/.git/**)",
|
||||||
"Write(~/.claude/.git/**)",
|
"Write(~/.claude/.git/**)",
|
||||||
"Edit(.git/**)",
|
"Edit(.git/**)",
|
||||||
"Write(.git/**)"
|
"Write(.git/**)"
|
||||||
]
|
],
|
||||||
|
"defaultMode": "dontAsk"
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"UserPromptSubmit": [
|
"UserPromptSubmit": [
|
||||||
@@ -73,8 +77,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"language": "Español",
|
||||||
"effortLevel": "xhigh",
|
"effortLevel": "xhigh",
|
||||||
|
"voice": {
|
||||||
|
"enabled": true,
|
||||||
|
"mode": "hold"
|
||||||
|
},
|
||||||
"skipDangerousModePermissionPrompt": true,
|
"skipDangerousModePermissionPrompt": true,
|
||||||
"preferredNotifChannel": "notifications_disabled",
|
"preferredNotifChannel": "notifications_disabled",
|
||||||
"agentPushNotifEnabled": false
|
"agentPushNotifEnabled": false,
|
||||||
|
"voiceEnabled": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
CONTEXT_PCT=$(echo "scale=0; $CONTEXT_USED * 100 / $CONTEXT_TOTAL" | bc)
|
||||||
fi
|
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
|
# Costos
|
||||||
TOTAL_COST=$(echo "$INPUT" | jq -r '.cost.total_cost_usd // 0' | xargs printf "%.3f")
|
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')
|
SESSION_DURATION=$(echo "$INPUT" | jq -r '.cost.total_duration_ms // 0')
|
||||||
|
|||||||
Reference in New Issue
Block a user