Skip to content

Bump Meziantou.Analyzer from 3.0.312 to 3.0.315 - #1

Closed
dependabot[bot] wants to merge 40 commits into
mainfrom
dependabot/nuget/Meziantou.Analyzer-3.0.315
Closed

dependabot[bot] wants to merge 40 commits into
mainfrom
dependabot/nuget/Meziantou.Analyzer-3.0.315

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 20, 2026

Copy link
Copy Markdown

Updated Meziantou.Analyzer from 3.0.312 to 3.0.315.

Release notes

Sourced from Meziantou.Analyzer's releases.

3.0.315

NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.315

What's Changed

Full Changelog: meziantou/Meziantou.Analyzer@3.0.314...3.0.315

3.0.314

NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.314

What's Changed

Full Changelog: meziantou/Meziantou.Analyzer@3.0.313...3.0.314

3.0.313

NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.313

What's Changed

Full Changelog: meziantou/Meziantou.Analyzer@3.0.312...3.0.313

Commits viewable in compare view.

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

MartinQuiri and others added 30 commits October 18, 2026 22:24
… infraestructura segura

- Kumquat.Core: formatos, detección por bytes mágicos, grafo de capacidades
  con Dijkstra acotado, servicio de conversión con publicación atómica y JobRunner.
- Kumquat.Infrastructure: ProcessRunner (ArgumentList + Job Object con límite
  de memoria y kill-on-close), TempWorkspaceFactory, SafeExtractor anti Zip Slip.
- Calidad: analizadores como error, BannedApiAnalyzers, CPM, lock files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ración por arista

- tools/engines.json + fetch-engines.ps1: descarga verificada por SHA-256 y SOURCE.txt (oferta GPL).
- FfmpegConverter: perfiles H.264/VP9/Opus/LAME, rutas file: + protocol_whitelist, progreso vía -progress.
- VipsConverter: capacidades detectadas en runtime, autorot, animación GIF/WebP, caché desactivada
  (evitaba que libvips retuviera los archivos del usuario).
- 204 aristas verificadas con corpus sintético (lavfi) y ffprobe.
- Line endings LF en todo el repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… y app

- WheelWindow: ventana en capas pre-registrada con RegisterDragDrop y estacionada
  fuera de pantalla; nunca toma el foco; render GDI+ con DPI por monitor.
- DropTarget (COM generado): CF_HDROP vía vtable, nunca responde MOVE.
- GlobalInputHook en hilo propio + DragGestureTracker puro (Shift/Ctrl/BloqMayús/clic derecho).
- TrayIcon con menú y notificaciones; BatchNotifier agrupa por drop.
- Kumquat.Hosting: composición DI compartida, Serilog local.
- Tests unitarios de geometría, orden, gesto y efectos; E2E con arrastre OLE real
  (requiere escritorio interactivo).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SE y documentación

- kumquat convert/targets/formats/engines.
- ConversionPolicy: el grafo ya no ofrece destinos sin sentido (PNG→MP3 vía GIF/MP4).
- Solución con plataformas x64 y ARM64 reales; ambos nativos de libvips (lock files estables).
- Workflows con acciones fijadas por SHA, Dependabot, plantillas de issues/PR.
- README, CONTRIBUTING (DCO), SECURITY, CODE_OF_CONDUCT, THIRD-PARTY-NOTICES, ARCHITECTURE,
  guía de pruebas manuales; REUSE 3.3 conforme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…flow de tags

- TFM net10.0-windows: elimina la proyección WinRT (~53 MB) que no se usaba.
- Solo se empaquetan los binarios de FFmpeg necesarios (sin include/lib/doc/ffplay).
- PublishTrimmed sin advertencias IL: zip de 93 MB, arranque ~275 ms, ~40 MB en reposo.
- CLI renombrada a kumquat-cli: 'kumquat.exe' pisaba a 'Kumquat.exe' (Windows no distingue mayúsculas).
- tools/publish.ps1 con smoke test de motores y SHA-256; release.yml con paso SignPath preparado.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- La CLI recortada pisaba el runtime recortado de la app al compartir carpeta (MissingMethodException).
  Ahora va en cli\ y EngineLocator encuentra los motores del paquete desde ahí.
- Al cerrar, el contenedor DI se liberaba de forma síncrona con un IAsyncDisposable (crash al salir).
- Kumquat.exe --smoke-test: publish.ps1 arranca la app de verdad antes de empaquetar.
- Notificación al iniciar: la app no tiene ventana y parecía no abrir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…racción en el log

- El hook global ve el botón soltado antes que el bucle OLE de la fuente: la rueda se ocultaba
  y el drop caía en el escritorio. Ahora espera hasta 600 ms solo si hay un sector resaltado;
  en el centro o fuera se cierra al instante (antes se veía 'cargando').
- WheelController.Trace: cada paso del gesto queda en el log (sin registrar teclas).
- Validado a mano en el escritorio real: PNG -> JPG, AVIF y GIF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…as herramientas y acciones

- WheelLayout multianillo: centro=cancelar, anillo interior=convertir, medio=herramientas,
  exterior=acciones; anillos vacíos se ocultan; color de resaltado por anillo; etiquetas que
  se ajustan al espacio real (dos líneas, fuente reducida antes que cortar palabras).
- Herramientas (ITool/ToolService, salida "foto (comprimido).jpg" con publicación atómica
  compartida con las conversiones): comprimir/rotar/reducir/sin metadatos (libvips),
  comprimir video, quitar audio, normalizar (FFmpeg).
- Acciones: copiar ruta (portapapeles nativo), ver en carpeta, terminal aquí.
- JobRunner genérico (JobRequest). CLI: tools / apply.
- Bugs encontrados por los tests: loudnorm dejaba el audio a 192 kHz (WMA fallaba, WAV/FLAC
  4x más pesados); rotar y las fotos de celular con orientación EXIF fallaban con imágenes
  grandes ("out of order read") por abrir siempre en acceso secuencial.
- Vista previa de la rueda generada por test en docs/images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…os; copiar/mover a

- Motores nuevos con hash fijado: qpdf 12.4.2 (Apache-2.0) y MuPDF 1.28.5 (AGPL-3.0).
- PDF: unir, dividir en páginas, comprimir (submuestreo de imágenes con mutool clean),
  rotar, páginas a JPG; imágenes -> PDF con mutool create (los JPEG se incrustan sin
  recodificar: 440 KB en vez de 12 MB) y orientación EXIF aplicada.
- Conversiones nuevas: imagen -> PDF, PDF -> TXT (error claro si es un escaneo sin texto),
  EPUB -> PDF/TXT.
- Imagen: voltear, blanco y negro, máx. 1920 px. Video: rotar, fotograma, unir (escala al
  primer clip y rellena silencio si falta audio). Audio: unir.
- Comprimidos: ZIP de archivos y carpetas; extraer ZIP/RAR/7z/TAR/GZIP con SharpCompress
  bajo las mismas defensas (Zip Slip, bombas); GZIP con GZipStream y detección de .tar.gz.
- Herramientas que combinan varios archivos (orden natural de nombres) y salidas en carpeta.
- Acciones: copiar a… / mover a… con el selector de carpetas nativo (abierto fuera del Drop
  para no congelar al Explorador); nunca sobrescribe.
- Bugs encontrados por tests: SharpCompress lanzaba excepciones no capturadas con archivos
  dañados; la CLI aplicaba de a uno las herramientas que combinan; binarios de tests
  desactualizados por mezclar bin/ y bin/x64/ (ahora una sola carpeta de salida).
- 504 tests pasan (10 omitidos: muestras HEIC/7z/RAR sin generador libre).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…itor de metadatos

- Herramientas con parámetros (ToolParameter: texto, contraseña, tiempo, páginas, campos
  personalizados) con valores iniciales leídos del archivo y validación por la herramienta.
- Ventana de opciones en WPF con tema Fluent (claro/oscuro del sistema), validación en vivo y
  "solo se envía lo que cambió" en los campos de texto (metadatos de varios archivos a la vez).
- Recortar audio/video (corte exacto), extraer páginas, proteger (AES-256) y desbloquear PDF
  (la contraseña viaja en un archivo de argumentos temporal, no en la línea de comandos).
- Metadatos:
  - Fotos: XMP + campos XP de Windows (Unicode) + EXIF ASCII solo si no hay tildes; en JPEG
    se reemplazan solo los bloques APP1: los datos de imagen quedan idénticos byte a byte.
  - PDF: diccionario Info vía script de mutool run, campos personalizados; se quita el XMP del
    catálogo (los lectores lo priorizan y mostrarían el valor viejo).
  - Audio/video: -c copy sin recodificar; OGG/Opus en la pista, AIFF con ID3, WAV/AVI sin
    campos personalizados (RIFF INFO no los admite).
  - Word/Excel/PowerPoint: docProps/core.xml.
- Anillo de herramientas hasta 10 sectores (un PDF tiene 10 herramientas).
- CLI: apply ... --set clave=valor.
- Bugs encontrados: el lector de etiquetas perdía mayúsculas; el SDK de WPF compilaba la librería
  de diálogos como ARM64 (último RID) y fallaba al cargarla en x64; la solución sin plataforma
  elegía ARM64 por orden alfabético (ahora x64 por defecto); errores "password" de mutool no se
  detectaban por mirar solo la última línea.
- 581 tests pasan (10 omitidos: muestras HEIC/7z/RAR sin generador libre).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rílicas con vista previa

- Nueva librería Kumquat.Design (sin UI): íconos Phosphor (MIT) con su id lógico, intérprete
  de trazados SVG (arcos y cuadráticas a Béziers, W3C F.6) para dibujarlos igual en GDI+ y WPF,
  paleta por familia (PDF rojo, imagen verde, video índigo, audio rosa...) y tipografía Inter (OFL).
- Rueda: disco de vidrio translúcido con borde de luz y sombra, sectores con esquinas redondeadas
  y separación pareja (geometría exacta, sin doble alfa), ícono + texto en herramientas y acciones,
  logo en el centro.
- Ventana de opciones: acrílico de Windows 11, contenido bajo la barra de título, encabezado con
  el ícono de la herramienta, botones en píldora, Inter.
- Vista previa (PreviewService, en segundo plano, carpeta temporal propia):
  - PDF: miniaturas (mutool draw); en "Extraer páginas" se eligen con un clic, sincronizado con
    el campo de texto (PageRanges.Expand/Describe).
  - Video: reproductor + tira de fotogramas (ffmpeg tile) con asas para el tramo a recortar;
    al mover un asa se ve ese fotograma; reproducir respeta el tramo.
  - Audio: forma de onda (showwavespic) coloreada dentro del tramo, con reproducción.
  - Fotos: miniatura con libvips.
- Ícono de la app y de la bandeja desde el logo (.ico 16–256 px generado por
  tools/build-design-assets.py, que también genera IconPaths.g.cs).
- Bug encontrado por el smoke test del empaquetado: LoadIconWithScaleDown no existe sin Common
  Controls 6; se usa LoadImageW y hay un test que carga el ícono real.
- 623 tests (613 pasan, 10 omitidos: muestras HEIC/7z/RAR sin generador libre); REUSE conforme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in arrastrar

- ExplorerSelection: lee la selección del Explorador en primer plano (pestaña activa en
  Windows 11, o el escritorio) con las interfaces documentadas del shell: IShellWindows →
  IShellBrowser → IShellView.GetItemObject(SVGIO_SELECTION) → IDataObject, reutilizando el
  lector de CF_HDROP del drop.
- Modo clic de la rueda: el hook informa el movimiento solo mientras la rueda está abierta en
  este modo; clic en un sector aplica, en el centro/fuera o Esc cancela. El modo arrastre no cambia.
- Atajo global con RegisterHotKey (MOD_NOREPEAT), activable desde el menú del ícono; aviso si
  no hay nada seleccionado o si otra app ya usa el atajo.
- Tests: modo clic del tracker; E2E que abre el Explorador con un archivo seleccionado y lo lee.
- Arreglo: el E2E de arrastre apuntaba a un radio de la rueda de un solo anillo (desde la rueda
  de 3 anillos caía en el anillo equivocado).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fotograma con vista previa

- Reproductor propio (FfmpegPlayback): FFmpeg decodifica el video a BGRA y el audio a PCM, que
  suena por waveOut (WaveOutPlayer, API de Windows sin componentes opcionales). El reloj es el
  audio que ya sonó; los fotogramas atrasados se descartan. Se ve y se oye cualquier formato que
  Kumquat acepte (MKV, WebM, OGG, Opus, FLAC...), sin depender de MediaElement / Media Player.
- Fotograma exacto al mover asas o el cabezal (solo se atiende el último pedido: nunca hay más
  de un FFmpeg a la vez).
- Fotograma: nuevo parámetro "Instante" (por defecto la mitad del video) con modo de línea de
  tiempo "instante": se elige con un clic, arrastrando o pausando la reproducción.
- Recortar y Fotograma usan -ss antes de la entrada: saltan directo al instante (antes se
  decodificaba desde el principio; lento en videos largos) y siguen siendo exactos.
- ProcessRunner: lectura binaria de stdout y prioridad normal para procesos interactivos.
- Arreglo en JobRunner: "en cola" se notificaba después de encolar, y un trabajo instantáneo podía
  avisar "terminado" antes; el seguimiento del lote quedaba esperando. Test de regresión que falla
  sin el arreglo.
- Tests: reproductor (fotograma exacto, tiempo real, pausa, solo audio MP3/OGG/FLAC) y la ventana
  real en el hilo de la app (reproducir avanza y muestra fotogramas; elegir instante actualiza el campo).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Entrada para archivos y carpetas registrada por usuario (HKCU, sin administrador), con el logo;
  se corrige sola si se mueve la carpeta y se quita desde el menú del ícono o con --unregister.
- El Explorador lanza "Kumquat.exe --wheel archivo": si Kumquat ya corre, la ruta se le pasa por
  WM_COPYDATA (con firma propia) y el proceso sale; si no, arranca y abre la rueda.
- El Explorador lanza un proceso por archivo: los pedidos se juntan 250 ms y, si son parte de la
  selección del Explorador, se usa la selección completa. La rueda se abre una vez, en modo clic.
- En Windows 11 aparece en "Mostrar más opciones"; el menú nuevo exige paquete firmado.
- Tests: registro en una rama de prueba del registro (comillas: rutas con espacios no se parten),
  quitar sin error si no estaba, y pedidos entre procesos que llegan a la ventana de la rueda.
- README: corregido un párrafo que había quedado partido.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Píldora del mismo vidrio, centrada y pegada bajo la rueda: "PNG · 2,4 MB", "3 JPG · 12 MB",
  "3 archivos · …" si se mezclan formatos, "Carpeta". El formato sale del contenido, no de la extensión.
- El lienzo crece hacia abajo solo lo necesario: el centro de la rueda sigue bajo el cursor.
- FileSizeText: tamaños como el Explorador (base 1024, un decimal bajo 10), con la cultura del usuario.
- La etiqueta es una ayuda: si leer el tamaño falla, la rueda se abre igual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… estilo WPF por hilo

- dotnet sln add le puso mapeos de plataforma a Kumquat.Design y la solución sin plataforma elige
  ARM64: la DLL quedaba ARM64 y un proceso x64 no la cargaba (FileNotFoundException al arrancar).
  No llegaba al paquete publicado (se compila por proyecto), pero rompía dotnet build + dotnet test.
  Ahora es IL puro (AnyCPU) y ArquitecturaTests verifica que toda librería de Kumquat lo sea.
- El estilo de los botones en píldora era un Style estático: pertenece al hilo que lo crea y
  compartirlo entre hilos de UI fallaba (se vio con tests en paralelo). Ahora uno por hilo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…scribir, con tests

- WheelSession: toda la lógica (arrastre + drop, espera del drop, modo clic del atajo y del menú
  contextual, recolección de pedidos) sin Win32, sobre IWheelSurface. WheelController queda como
  adaptador de hooks, OLE, atajo y WM_COPYDATA. 15 tests con superficie falsa y geometría real
  (antes 0 % de cobertura automática).
- StagedOutput: tests de la promesa central — nombre ocupado, carrera por el nombre (otro proceso
  crea el archivo entre la elección y la publicación: no se pisa), carrera que no termina, motor
  que falla a la mitad, cancelación y salida de carpeta; sin restos .kumquat-*.
- Errores inesperados al generar la vista previa, reproducir o leer fotogramas: se registran en el
  log (DialogDiagnostics) y la ventana vuelve a un estado usable. Test con una vista previa que falla.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compilar la solución o un proyecto dejaba variantes x64/AnyCPU/ARM64 mezcladas en la carpeta de
salida compartida (así una librería ARM64 llegó a un proceso x64). Directory.Build.targets fija
PlatformTarget=AnyCPU para toda librería; la arquitectura la decide el ejecutable.
El commit anterior se hizo con este test fallando: el script no frenaba ante errores (ya frena).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… reproductor, atajo, menú)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n y PDF escaneado)

- Tesseract 5.5.3 sin binarios oficiales para Windows: se compila desde el código con vcpkg
  (tools/build-tesseract.ps1, baseline fijado, estático y solo Release); fetch-engines lo invoca.
  Modelos tessdata_best (español + inglés) verificados por SHA-256.
- Herramientas: Extraer texto (imagen → TXT), PDF buscable (imagen → PDF con texto invisible) y
  Reconocer texto (PDF escaneado → PDF buscable).
- PDF: solo se reconocen las páginas sin texto; las demás quedan originales (vectoriales). Páginas
  a 300 ppp → JPEG → Tesseract en paralelo → qpdf reemplaza solo esas (argumentos por archivo).
- Imágenes: JPEG/PNG/TIFF/BMP/GIF/WebP pasan tal cual (el PDF no engorda); HEIC, AVIF, SVG (a 300
  ppp) o fotos con rotación EXIF se normalizan. Fotos que dicen 72 ppp se tratan como 300.
- Anillo de herramientas hasta 12; "Comprimir en ZIP" pasa a "Crear ZIP" y una palabra que no
  entra ni achicada va en una línea con "…" (GDI+ la partía a la mitad).
- CI: compila Tesseract con caché; el proyecto E2E aceptaba mal --coverage (código 5) y habría
  hecho fallar el primer CI; ArquitecturaTests excluye ejecutables.
- Tests: unión de páginas para qpdf, umbral de texto, imagen → texto con tildes y eñes, PDF
  buscable, imagen sin texto, PDF mixto (solo la página escaneada) y PDF que ya tiene texto.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… probar con el motor real

- fetch-engines fallaba en modo estricto al preguntar 'build' a motores que no lo tienen: habría
  roto el empaquetado y CI.
- Los formatos de salida de Tesseract son configs de tessdata: sin configs/pdf el PDF buscable
  fallaba ("Can't open pdf"). Se copian pdf y txt; la fuente invisible ya viene en el ejecutable.
- Marca .version: Set-Content -NoNewline no la escribía en Windows PowerShell 5.1 (sin error).
- Sin el modelo osd (no se usa con --psm 3): 10 MB menos.
- Tests: se exige reconocer palabras de diccionario; "Kumquat" lo lee "Kumaquat" (limitación
  real del OCR con nombres inventados), las tildes y eñes salen exactas.
- THIRD-PARTY-NOTICES: Tesseract, tessdata_best y las 16 bibliotecas enlazadas estáticamente.
- Verificado con el paquete publicado: la prueba de arranque exige tesseract=ok y la CLI publicada
  reconoce texto (TXT y PDF buscable).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Nuevo E2E: archivo seleccionado en el Explorador → Ctrl+Alt+K → clic en el sector norte →
  aparece el JPG y el original queda intacto (mouse y teclado reales).
- Lo que costó y queda documentado en el test:
  - Al arrancar, el aviso de la bandeja deja el foco en Shell_TrayWnd y Windows no deja que otro
    proceso lo tome: se activa el Explorador pulsando Alt antes de SetForegroundWindow.
  - Con imágenes, explorer /select no deja nada seleccionado (recarga la vista con la plantilla de
    Imágenes): se selecciona con IShellView.SelectItem, como un clic. Un clic en la barra de título
    no sirve (en Windows 11 es la barra de pestañas).
- IShellView.SelectItem con su firma real; diagnóstico del shell en los mensajes de error del E2E.
- Los E2E corren en serie (xunit.runner.json): comparten mouse, teclado y la instancia única.
- 4/4 E2E y 686 tests (0 errores).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CommandPalette: como Spotlight. Encabezado con el archivo (formato y tamaño), cuadro de búsqueda,
  lista con el ícono y el color de cada acción y su grupo; ↑↓ eligen (con vuelta), Enter aplica,
  Esc o un clic afuera cierran; también se elige con el mouse. Vidrio acrílico, Inter.
- CommandSearch (Core): sin tildes, prefijo, inicio de palabra ("ext pag"), palabras clave
  ("jpeg", "achicar", "consola") y letras en orden desde 3; a igual puntaje, el orden de la rueda.
- Ctrl+Alt+K y el menú contextual abren el buscador; la rueda queda para arrastrar con el mouse.
- Primer plano: el proceso que lanza el Explorador le cede el permiso a la instancia
  (AllowSetForegroundWindow) para que el buscador reciba el teclado.
- Tests: búsqueda (19), buscador (10, con vista previa clara/oscura en docs/images), sesión (el
  atajo y el menú abren el buscador, el arrastre sigue con la rueda) y E2E de punta a punta:
  Ctrl+Alt+K → "jpg" + Enter y clic derecho (Kumquat.exe --wheel) → "jpg" + Enter.
- E2E de arrastre robusto: si el clic sintético no llega a la ventana de origen (no hay arrastre
  OLE) se reintenta y, si persiste, el mensaje dice que es el arnés. 3 corridas seguidas 5/5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Mismo vidrio que las demás ventanas: gesto de la rueda (2×2), atajo Ctrl+Alt+K, entrada del
  clic derecho, carpeta para archivos sin carpeta (Escritorio por defecto; Cambiar… / Usar el
  Escritorio) e iniciar con Windows (desactivado por defecto).
- El menú del ícono queda en Configuración…, registros, licencias y salir.
- Autostart en la clave Run del usuario (sin administrador); se corrige si se mueve la carpeta.
- Una carpeta elegida que ya no existe vuelve al Escritorio.
- Tests: valores sin cambios, cambiar gesto y carpeta, vistas previas clara y oscura, inicio con
  Windows en una rama de prueba del registro, carpeta inexistente.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…na web

- VirtualDrops: sin CF_HDROP, lee los nombres de FileGroupDescriptorW en DragEnter (los anillos
  salen de la extensión) y recién en Drop copia FileContents (HGLOBAL o IStream) a una carpeta
  temporal: el contenido solo existe durante el drop y copiarlo antes trabaría al programa de origen.
- Seguridad: nombres sin carpetas ni ..\, caracteres inválidos reemplazados; máximo 64 elementos y
  4 GiB; si la copia falla se cancela el drop sin romper el arrastre.
- Los resultados van a la carpeta de Configuración (Escritorio por defecto); la etiqueta bajo la
  rueda lo dice ("PDF · se guarda en Escritorio") y la acción "Guardar en Escritorio" los guarda
  tal cual. Las copias se borran al terminar el lote, al cancelar o, si quedaron, al arrancar.
- Herramientas: carpeta de salida opcional (las conversiones ya la tenían).
- Buscador: si no queda al frente (el permiso de primer plano no llegó), pulsa Alt y lo vuelve a
  pedir; el E2E del clic derecho fallaba 1 de 2 veces y ahora pasa 5 de 5.
- KUMQUAT_DATA_DIR: carpeta de datos aparte (los E2E no tocan la configuración real).
- Hilos: NativeWindow tenía un diccionario estático sin protección (y el registro de clases sin
  candado); los tests que crean ventanas en paralelo lo corrompían. Ahora es seguro entre hilos.
  Los tests de ventanas WPF corren en serie: WPF no tolera cargar su tema en varios hilos a la vez.
- Tests: nombres seguros, extracción con un IDataObject real, anillos y etiqueta, carpeta de salida
  de herramientas y E2E con un arrastre OLE virtual real (6/6 E2E). Suite 10 veces seguidas: 739,
  0 errores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Motor Kumquat.Engines.Office: Microsoft Office (Word, Excel, PowerPoint) por COM en un
  PowerShell aparte, o LibreOffice headless con perfil temporal si no hay Office.
- Documentos DOCX/DOC/ODT/RTF, hojas XLSX/XLS/ODS y presentaciones PPTX/PPT/ODP → PDF;
  PDF → DOCX (Word reconstruye párrafos; LibreOffice como respaldo, más caro).
- Seguridad: macros desactivadas, solo lectura, contraseña falsa para no pedirla, una
  conversión a la vez, sobre una copia del archivo; si Office no responde se cierra solo la
  instancia que abrió Kumquat.
- Word no muestra el aviso "convertirá el PDF": se apaga solo durante la conversión y se
  restaura el valor anterior.
- Sin Office ni LibreOffice, la rueda ofrece "Instalar LibreOffice": ventana de permiso,
  winget con el paquete oficial en una consola visible y reinicio con --restarted.
- Tests con muestras reales hechas por Office (se omiten sin Office), DOC y ODP detectados.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Motor Kumquat.Engines.Calibre: ebook-convert si Calibre está instalado (App Paths o
  Calibre2), con configuración y temporales propios: no toca la biblioteca de la persona.
- EPUB, MOBI, AZW3, FB2 y DOCX → EPUB/AZW3/MOBI; MOBI, AZW3 y FB2 → PDF. EPUB → PDF sigue
  con MuPDF. Progreso leído de la salida; aviso claro para libros con DRM.
- Formatos MOBI, AZW3 (por la versión del encabezado MOBI) y FB2 detectados por contenido.
- Sin Calibre, la rueda ofrece "Instalar Calibre" (winget calibre.calibre).
- ProcessSpec.Environment: variables solo para el motor.
- Tests con Calibre real o con KUMQUAT_TEST_CALIBRE (copia extraída del MSI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Todos los textos visibles en Strings.resx (español, el idioma base) y Strings.en.resx;
  tools/build-strings.py genera Strings.g.cs con propiedades y métodos con parámetros
  nombrados (Strings.ConvertedTo(count, target)).
- Idioma en Configuración: Automático (el de Windows; si no está traducido, inglés),
  Español o English. Al cambiarlo, Kumquat se reinicia. El CLI usa el de Windows.
- Avisos con frases completas por idioma (uno / varios), sin pegar participios.
- Buscador: palabras clave en español e inglés a la vez.
- LocalizationTests: mismas claves y huecos en cada idioma, código generado al día,
  satélite en inglés y resolución del idioma. Todos los tests corren en español (CI en
  cualquier idioma). Guía para traducir en CONTRIBUTING.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- La rueda se presenta a UI Automation con un proveedor propio (WM_GETOBJECT) y anuncia
  con UiaRaiseNotificationEvent qué se arrastró, cuántas opciones hay y qué sector queda
  elegido, sin tomar el foco. Lo decide WheelSession (probado) y lo dice WheelWindow.
- Buscador: anuncia la opción elegida con su grupo y posición mientras el foco sigue en el
  cuadro de búsqueda, y cuando no hay resultados. Ventana de opciones: anuncia los errores.
- Alto contraste: la rueda usa los colores del sistema (opaca, con contorno por sector y
  la selección del sistema); las ventanas usan SystemColors y el tema de Windows, sin acrílico.
- Tests con UI Automation real (nombre, tipo y anuncio recibido por un cliente).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MartinQuiri and others added 10 commits October 20, 2026 01:45
- installer/: MSI con WiX 5 (MS-RL, sin EULA de cuota) que instala en
  %LOCALAPPDATA%\Programs\Kumquat sin administrador, con acceso en Inicio, ícono en
  "Aplicaciones instaladas", actualización encima de la versión anterior (cerrando Kumquat
  antes de tocar archivos) y desinstalación que quita menú contextual e inicio con Windows.
- --unregister también quita el inicio con Windows; --smoke-test ya no toca el registro.
- tools/build-installer.ps1 y tools/winget-manifest.ps1 (validado con winget validate).
- release.yml arma y sube los MSI y el manifiesto de winget (variable WINGET_PACKAGE_ID).
- docs/RELEASING.md: publicar, firmar con SignPath, enviar a winget y qué falta para el
  menú moderno de Windows 11 (paquete disperso firmado + manejador nativo).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- src/Kumquat.ShellExtension: IExplorerCommand en C# con Native AOT (DLL nativa); Windows la
  aloja en dllhost.exe, no en el Explorador. Abre Kumquat.exe --wheel una sola vez con todos los
  archivos (en lotes si no entran en una línea de comandos) y se oculta para lo que no es del
  disco (Panel de control, Papelera).
- packaging/sparse: paquete disperso que da identidad a la carpeta instalada.
- tools/context-menu.ps1: arma (y firma) el paquete, lo registra (-Dev con Modo de
  desarrollador) y lo quita.
- MSI: registra el paquete si viene firmado y lo quita antes de reemplazar o borrar archivos
  (así se libera la DLL sin reiniciar).
- Tests: la DLL nativa de verdad vía DllGetClassObject con un IShellItemArray real y un
  Kumquat.exe falso; CI publica la DLL antes de los tests. Probado a mano en Windows 11:
  aparece en el menú nuevo y abre el buscador.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ProgressBoard (Core, reloj inyectable): sigue los trabajos de JobRunner, aparece si algo
  dura más de 0,7 s, se va 1,5 s después de terminar y estima cuánto falta por el ritmo de
  avance (suavizado; la cuenta sigue bajando entre avisos). "Ocultar" hasta el próximo lote.
- RemainingText: "casi listo", "quedan ~12 s", "quedan ~3 min", siempre redondeando hacia arriba.
- ProgressPanel (WPF, acrílico): una fila por archivo con barra, porcentaje, tiempo y botón
  para cancelar; resumen "N en curso · M en cola" y "y N más". Nunca toma el foco ni aparece
  en la barra de tareas; se ubica sobre la barra de tareas.
- Las conversiones describían el trabajo con "a " fijo en español: ahora se traduce.
- WindowPreview compartido para las imágenes de docs; las de la rueda se escriben con reintentos.
- Probado en vivo: comprimir un video de 1 min mostró el panel al 1,3 s y estimó bien el tiempo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README (es/en): título centrado, insignias (CI, versión, licencia, Windows, .NET) y sección
  Instalar (MSI por usuario o zip portable, aviso de SmartScreen mientras no haya firma).
- docs/images/social-preview.png (1280x640) para GitHub y LinkedIn, generada con
  tools/build-social-image.py desde el logo, Inter y la captura real de la rueda.
- URL del repositorio en el instalador y en winget (MartinQuiri.Kumquat); plantillas de
  issues con enlace a vulnerabilidades privadas y a Discussions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ilencio

Windows desinstala sin avisar un hook de bajo nivel si su callback tarda (equipo muy cargado,
una pausa del recolector de basura): la rueda dejaba de responder hasta reiniciar Kumquat. Se
vio al grabar una demo mientras se codificaba video.

- HookWatchdog: si Windows registró entrada (GetLastInputInfo) que los hooks no vieron durante
  más de 1,5 s, se reinstalan (como mucho cada 5 s) y queda en el registro.
- El hilo de los hooks lo revisa cada segundo con un timer sin ventana.
- Tests: la decisión (incluido el desborde de los ticks a los 49 días) y una prueba real que
  quita los hooks como Windows y comprueba que vuelven solos (con la tecla F24).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
En portátiles, Windows 11 frena a los procesos en segundo plano (power throttling) y Kumquat,
que vive en la bandeja, siempre lo está; con el equipo cargado (o tras un programa que vacía la
memoria, como Mem Reduct) el callback del hook tardaba y Windows lo quitaba. Se desactiva el
power throttling para el proceso y el hilo de los hooks, que además pasa a prioridad alta. En
reposo Kumquat no consume CPU: no cambia la batería.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Los segundos que el panel queda a la vista después del último trabajo mostraba "0 en curso".
Se vio al grabar la demo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… se convierte

El temporal se llamaba ".kumquat-<guid>.ext" en la carpeta destino: el punto oculta archivos en
Linux, no en Windows, así que durante una conversión larga cualquiera veía aparecer un archivo
raro. Ahora el motor escribe dentro de una carpeta .kumquat-* oculta y de sistema (no se ve
aunque el Explorador muestre los ocultos) y el resultado se mueve a su nombre final: mismo
volumen (atómico) y mismos permisos que la carpeta destino. El comentario que decía que los
restos se limpiaban al arrancar no era cierto: se corrige. Se vio al grabar la demo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---
updated-dependencies:
- dependency-name: Meziantou.Analyzer
  dependency-version: 3.0.315
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code labels Oct 20, 2026
@dependabot @github

dependabot Bot commented on behalf of github Oct 20, 2026

Copy link
Copy Markdown
Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/nuget/Meziantou.Analyzer-3.0.315 branch October 20, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant