2025-09-24

Cuál es la allowlist?

Desde hace unos meses estoy usando cursor, el IDE, para programar. Como parte de ese uso, cuando hablo con las IAs, las mismas intentan correr comandos. Como es peligroso, uno tiene que andar aprobando cada comando. Pero como es engorroso, es posible whitelistear comandos para que corran sin preguntar (en este momento estoy usando la versión 1.6.45 en mac). El problema es que no pude encontrar en la GUI de cursor como ver/editar dichos comandos. Así que estuve usando el chat de cursor para encontrar los comandos que whitelistié y después de un ratito los encontramos :D. 
Para ver los comandos que tengo whitelisteados tengo que correr este comando:

% sqlite3 -noheader -list "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" "SELECT je.value FROM ItemTable AS it, json_each(it.value, '$.composerState.yoloCommandAllowlist') AS je WHERE it.key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

diff

jq

grep

head

cd

git log

git diff

git show

npm audit

sed

awk

cat

echo

Seguramente si estás en una mac el mismo comando te ande a vos

dDesde hace unos meses estoy usando cursor, el IDE, para programar. Como parte de ese uso, cuando hablo con las IAs, las mismas intentan correr comandos. Como es peligroso, uno tiene que andar aprobando cada comando. 

Y haciendo esto me di cuenta que aprobé comandos complicados :/. sed y awk tienen la opción de editar archivos inline.

Para sacarlos tuve que salir de cursor y correr este comando (que reescribe toda la lista del whitelist):

% sqlite3 "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" \

"UPDATE ItemTable SET value = json_set(value, '$.composerState.yoloCommandAllowlist', json('[\"diff\",\"jq\",\"grep\",\"head\",\"cd\",\"git log\",\"git diff\",\"git show\",\"npm audit\",\"cat\",\"echo\"]')) WHERE key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';"

Y después corrí esto para ver que quedó bien:

% sqlite3 -noheader -list "$HOME/Library/Application Support/Cursor/User/globalStorage/state.vscdb" \

"SELECT je.value FROM ItemTable AS it, json_each(it.value, '$.composerState.yoloCommandAllowlist') AS je WHERE it.key='src.vs.platform.reactivestorage.browser.reactiveStorageServiceImpl.persistentStorage.applicationUser';" 

Por último pedí en el chat que corra sed para ver que está todo bien :)

Esto me lleva a ver que cursor, el IDE, está super verde y pushean features que les faltan cosas. ¡Es un peligro!

PD: Es peor! Si la allowlist está activada puede correr comandos usando redirección de shell (>) y escribir sin confirmación del usuario. Por lo tanto hay que desactivarla hasta que arreglen esto. Para hacer esto podés ir a cmd-shift-p -> Cursor Settings -> Chat -> Auto-Run -> Auto-Run Mode y setear en Ask Every Time

2025-07-01

Tuneando firefox sobre ssh

Hace un tiempo hice que Firefox corra remoto sobre X. Para eso forwardeo el X por ssh (haciendo $ ssh -X blah) Y esto anda bien para correr sobre una VM. Pero cuando probé conectarme a mi linux desde mi mac no anduvo :(. Así que primero tuve que decirle como forwardear XAuthority corriendo XAUTHORITY=$HOME/.Xauthority firefox --no-remotePero cuando quiero conectarme a otra compu en mi red wifi anda muy lento. Así que hice algunas optimizaciones.

La primera es que cuando me conecto por ssh le paso -C para que comprima los datos, porque X manda bocha de cosas para forwardear la pantalla. Y el otro seteo que sirvió para algo fue ir a about:config en firefox y bajar el frame rate seteando layout.frame_rate en 15.

Con eso puedo usar firefox más o menos. Una cosa medio molesta es que el audio sigue saliendo por los parlantes de mi linux y no encontré fácil como forwardearlo o mutearlo, pero aunque sea así es posible usar firefox forwardeado por X por mi wifi, así que ese arreglo quedará para el futuro.

2025-05-14

pingmon update

Hace un tiempo hice un script para monitorear mi conexión a internet usando ping

Le hice algunos cambios menores, y ahora muestra datos aunque no haya llenado toda la ventana.

Esta es la última versión

#!/usr/bin/env python3

import subprocess
import sys
import re

SEQ_NUMBER_RE = re.compile(r".*icmp_seq=(\d+) ttl.*")

def report(probes, count):
  if len(probes) < count:
    count = len(probes)
  return str ( count - sum(probes[-count:]) ) 

def monitor(ip):
  probes = []
  ping = subprocess.Popen(["ping", ip], stdout=subprocess.PIPE)
  stdout = ping.stdout

  stdout.readline() # Ignore first line
  line_count = 0
  last_seq_number = 0
  while True:
    line_count +=1
    line = stdout.readline().decode()
    try:
      seq_number = int( SEQ_NUMBER_RE.match(line).group(1))
    except Exception:
      print( "!!! Failed while parsing line " + line )
      seq_number = last_seq_number
    probes.extend([0] * (seq_number - last_seq_number - 1))
    probes.append(1)
    print( "(%s) 10:%s 100:%s 1000:%s 10000:%s" % (
      line_count, report(probes, 10), report(probes, 100), report(probes, 1000), report(probes, 10000)
    ) )

    probes = probes[-10000:] # Keep memory usage bounded
    last_seq_number = seq_number

def main(argv):
  monitor(argv[1])

if __name__ == '__main__':
  main(sys.argv)