Round 511-520: Game engines, audio/video, 3D/CAD, GIS, scientific computing, data viz, typesetting (200 commands)

ober

9bc100860ba84f545c624a600c4b02e55d630ad0

diff --git a/docs/jemacs-vs-emacs.md b/docs/jemacs-vs-emacs.md
index 6acd7db..63c20ce 100644
--- a/docs/jemacs-vs-emacs.md
+++ b/docs/jemacs-vs-emacs.md
@@ -4583,6 +4583,256 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features 
 | ebib-import-file | :orange_circle: | Import file into Ebib |
 | ebib-push-citation | :orange_circle: | Push Ebib citation to buffer |
 
+### Round 520 — Typst, Texinfo, Groff, LilyPond
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `typst-compile` | :orange_circle: Scaffolded | Typst: compile document |
+| `typst-watch` | :orange_circle: Scaffolded | Typst: watch mode |
+| `typst-init` | :orange_circle: Scaffolded | Typst: initialize project |
+| `typst-package` | :orange_circle: Scaffolded | Typst: packages |
+| `typst-query` | :orange_circle: Scaffolded | Typst: query document |
+| `texinfo-compile` | :orange_circle: Scaffolded | Texinfo: compile |
+| `texinfo-html` | :orange_circle: Scaffolded | Texinfo: to HTML |
+| `texinfo-pdf` | :orange_circle: Scaffolded | Texinfo: to PDF |
+| `texinfo-info` | :orange_circle: Scaffolded | Texinfo: to Info |
+| `texinfo-xml` | :orange_circle: Scaffolded | Texinfo: to XML |
+| `groff-compile` | :orange_circle: Scaffolded | Groff: compile document |
+| `groff-man` | :orange_circle: Scaffolded | Groff: man macro |
+| `groff-ms` | :orange_circle: Scaffolded | Groff: ms macro |
+| `groff-mm` | :orange_circle: Scaffolded | Groff: mm macro |
+| `groff-pdf` | :orange_circle: Scaffolded | Groff: to PDF |
+| `lilypond-compile` | :orange_circle: Scaffolded | LilyPond: compile score |
+| `lilypond-midi` | :orange_circle: Scaffolded | LilyPond: MIDI output |
+| `lilypond-pdf` | :orange_circle: Scaffolded | LilyPond: PDF output |
+| `lilypond-svg` | :orange_circle: Scaffolded | LilyPond: SVG output |
+| `lilypond-preview` | :orange_circle: Scaffolded | LilyPond: preview |
+
+### Round 519 — Maxima, LaTeX ext, Pandoc ext, AsciiDoc
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `maxima-solve` | :orange_circle: Scaffolded | Maxima: solve equation |
+| `maxima-simplify` | :orange_circle: Scaffolded | Maxima: simplify |
+| `maxima-integrate` | :orange_circle: Scaffolded | Maxima: integrate |
+| `maxima-plot` | :orange_circle: Scaffolded | Maxima: plot |
+| `maxima-diff` | :orange_circle: Scaffolded | Maxima: differentiate |
+| `latex-compile` | :orange_circle: Scaffolded | LaTeX: compile document |
+| `latex-bibtex` | :orange_circle: Scaffolded | LaTeX: BibTeX |
+| `latex-glossary` | :orange_circle: Scaffolded | LaTeX: glossary |
+| `latex-index` | :orange_circle: Scaffolded | LaTeX: index |
+| `latex-clean` | :orange_circle: Scaffolded | LaTeX: clean aux files |
+| `pandoc-convert` | :orange_circle: Scaffolded | Pandoc: convert document |
+| `pandoc-template` | :orange_circle: Scaffolded | Pandoc: templates |
+| `pandoc-filter` | :orange_circle: Scaffolded | Pandoc: filters |
+| `pandoc-metadata` | :orange_circle: Scaffolded | Pandoc: metadata |
+| `pandoc-defaults` | :orange_circle: Scaffolded | Pandoc: defaults file |
+| `asciidoc-convert` | :orange_circle: Scaffolded | AsciiDoc: convert |
+| `asciidoc-pdf` | :orange_circle: Scaffolded | AsciiDoc: to PDF |
+| `asciidoc-html` | :orange_circle: Scaffolded | AsciiDoc: to HTML |
+| `asciidoc-docbook` | :orange_circle: Scaffolded | AsciiDoc: to DocBook |
+| `asciidoc-manpage` | :orange_circle: Scaffolded | AsciiDoc: to manpage |
+
+### Round 518 — Jupyter ext, JupyterLab ext, RStudio, Octave
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `jupyter-notebook` | :orange_circle: Scaffolded | Jupyter: open notebook |
+| `jupyter-kernel` | :orange_circle: Scaffolded | Jupyter: kernel management |
+| `jupyter-convert` | :orange_circle: Scaffolded | Jupyter: convert notebook |
+| `jupyter-trust` | :orange_circle: Scaffolded | Jupyter: trust notebook |
+| `jupyter-extension` | :orange_circle: Scaffolded | Jupyter: extensions |
+| `jupyterlab-build` | :orange_circle: Scaffolded | JupyterLab: build |
+| `jupyterlab-extension` | :orange_circle: Scaffolded | JupyterLab: extensions |
+| `jupyterlab-theme` | :orange_circle: Scaffolded | JupyterLab: themes |
+| `jupyterlab-workspace` | :orange_circle: Scaffolded | JupyterLab: workspaces |
+| `jupyterlab-config` | :orange_circle: Scaffolded | JupyterLab: configuration |
+| `rstudio-project` | :orange_circle: Scaffolded | RStudio: project |
+| `rstudio-connect` | :orange_circle: Scaffolded | RStudio: Connect publish |
+| `rstudio-publish` | :orange_circle: Scaffolded | RStudio: publish |
+| `rstudio-package` | :orange_circle: Scaffolded | RStudio: package tools |
+| `rstudio-shiny` | :orange_circle: Scaffolded | RStudio: Shiny app |
+| `octave-eval` | :orange_circle: Scaffolded | Octave: evaluate |
+| `octave-plot` | :orange_circle: Scaffolded | Octave: plot |
+| `octave-load` | :orange_circle: Scaffolded | Octave: load data |
+| `octave-save` | :orange_circle: Scaffolded | Octave: save data |
+| `octave-package` | :orange_circle: Scaffolded | Octave: packages |
+
+### Round 517 — Bokeh, Gnuplot ext, ParaView, VTK
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `bokeh-figure` | :orange_circle: Scaffolded | Bokeh: figure |
+| `bokeh-plot` | :orange_circle: Scaffolded | Bokeh: plot |
+| `bokeh-server` | :orange_circle: Scaffolded | Bokeh: server |
+| `bokeh-export` | :orange_circle: Scaffolded | Bokeh: export |
+| `bokeh-widget` | :orange_circle: Scaffolded | Bokeh: widgets |
+| `gnuplot-plot` | :orange_circle: Scaffolded | Gnuplot: plot data |
+| `gnuplot-set` | :orange_circle: Scaffolded | Gnuplot: set options |
+| `gnuplot-fit` | :orange_circle: Scaffolded | Gnuplot: curve fitting |
+| `gnuplot-terminal` | :orange_circle: Scaffolded | Gnuplot: terminal type |
+| `gnuplot-multiplot` | :orange_circle: Scaffolded | Gnuplot: multiplot |
+| `paraview-open` | :orange_circle: Scaffolded | ParaView: open data |
+| `paraview-filter` | :orange_circle: Scaffolded | ParaView: apply filter |
+| `paraview-render` | :orange_circle: Scaffolded | ParaView: render |
+| `paraview-export` | :orange_circle: Scaffolded | ParaView: export |
+| `paraview-animate` | :orange_circle: Scaffolded | ParaView: animation |
+| `vtk-reader` | :orange_circle: Scaffolded | VTK: data reader |
+| `vtk-filter` | :orange_circle: Scaffolded | VTK: filter pipeline |
+| `vtk-mapper` | :orange_circle: Scaffolded | VTK: mapper |
+| `vtk-render` | :orange_circle: Scaffolded | VTK: render window |
+| `vtk-export` | :orange_circle: Scaffolded | VTK: export scene |
+
+### Round 516 — Pandas ext, Matplotlib ext, Seaborn, Plotly
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `pandas-dataframe` | :orange_circle: Scaffolded | Pandas: DataFrame operations |
+| `pandas-merge` | :orange_circle: Scaffolded | Pandas: merge/join |
+| `pandas-groupby` | :orange_circle: Scaffolded | Pandas: group by |
+| `pandas-pivot` | :orange_circle: Scaffolded | Pandas: pivot table |
+| `pandas-io` | :orange_circle: Scaffolded | Pandas: I/O operations |
+| `matplotlib-plot` | :orange_circle: Scaffolded | Matplotlib: create plot |
+| `matplotlib-figure` | :orange_circle: Scaffolded | Matplotlib: figure management |
+| `matplotlib-axis` | :orange_circle: Scaffolded | Matplotlib: axis config |
+| `matplotlib-style` | :orange_circle: Scaffolded | Matplotlib: style sheets |
+| `matplotlib-save` | :orange_circle: Scaffolded | Matplotlib: save figure |
+| `seaborn-heatmap` | :orange_circle: Scaffolded | Seaborn: heatmap |
+| `seaborn-scatter` | :orange_circle: Scaffolded | Seaborn: scatter plot |
+| `seaborn-bar` | :orange_circle: Scaffolded | Seaborn: bar plot |
+| `seaborn-violin` | :orange_circle: Scaffolded | Seaborn: violin plot |
+| `seaborn-pair` | :orange_circle: Scaffolded | Seaborn: pair plot |
+| `plotly-chart` | :orange_circle: Scaffolded | Plotly: chart |
+| `plotly-scatter` | :orange_circle: Scaffolded | Plotly: scatter |
+| `plotly-bar` | :orange_circle: Scaffolded | Plotly: bar chart |
+| `plotly-layout` | :orange_circle: Scaffolded | Plotly: layout |
+| `plotly-export` | :orange_circle: Scaffolded | Plotly: export |
+
+### Round 515 — ogr2ogr, PROJ, NumPy ext, SciPy ext
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `ogr2ogr-convert` | :orange_circle: Scaffolded | ogr2ogr: convert format |
+| `ogr2ogr-info` | :orange_circle: Scaffolded | ogr2ogr: layer info |
+| `ogr2ogr-clip` | :orange_circle: Scaffolded | ogr2ogr: clip geometry |
+| `ogr2ogr-reproject` | :orange_circle: Scaffolded | ogr2ogr: reproject |
+| `ogr2ogr-sql` | :orange_circle: Scaffolded | ogr2ogr: SQL query |
+| `proj-transform` | :orange_circle: Scaffolded | PROJ: transform coordinates |
+| `proj-info` | :orange_circle: Scaffolded | PROJ: CRS info |
+| `proj-factors` | :orange_circle: Scaffolded | PROJ: projection factors |
+| `proj-geod` | :orange_circle: Scaffolded | PROJ: geodesic calculations |
+| `proj-crs` | :orange_circle: Scaffolded | PROJ: CRS database |
+| `numpy-array` | :orange_circle: Scaffolded | NumPy: array operations |
+| `numpy-linalg` | :orange_circle: Scaffolded | NumPy: linear algebra |
+| `numpy-fft` | :orange_circle: Scaffolded | NumPy: FFT |
+| `numpy-random` | :orange_circle: Scaffolded | NumPy: random |
+| `numpy-einsum` | :orange_circle: Scaffolded | NumPy: einsum |
+| `scipy-optimize` | :orange_circle: Scaffolded | SciPy: optimize |
+| `scipy-integrate` | :orange_circle: Scaffolded | SciPy: integrate |
+| `scipy-interpolate` | :orange_circle: Scaffolded | SciPy: interpolate |
+| `scipy-signal` | :orange_circle: Scaffolded | SciPy: signal processing |
+| `scipy-sparse` | :orange_circle: Scaffolded | SciPy: sparse matrices |
+
+### Round 514 — FreeCAD, KiCad, QGIS, GDAL
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `freecad-macro` | :orange_circle: Scaffolded | FreeCAD: run macro |
+| `freecad-export` | :orange_circle: Scaffolded | FreeCAD: export model |
+| `freecad-mesh` | :orange_circle: Scaffolded | FreeCAD: mesh tools |
+| `freecad-assembly` | :orange_circle: Scaffolded | FreeCAD: assembly |
+| `freecad-sketch` | :orange_circle: Scaffolded | FreeCAD: sketcher |
+| `kicad-schematic` | :orange_circle: Scaffolded | KiCad: schematic editor |
+| `kicad-pcb` | :orange_circle: Scaffolded | KiCad: PCB layout |
+| `kicad-library` | :orange_circle: Scaffolded | KiCad: library manager |
+| `kicad-gerber` | :orange_circle: Scaffolded | KiCad: Gerber export |
+| `kicad-bom` | :orange_circle: Scaffolded | KiCad: BOM generator |
+| `qgis-layer` | :orange_circle: Scaffolded | QGIS: layer management |
+| `qgis-process` | :orange_circle: Scaffolded | QGIS: processing tools |
+| `qgis-plugin` | :orange_circle: Scaffolded | QGIS: plugin manager |
+| `qgis-export` | :orange_circle: Scaffolded | QGIS: export map |
+| `qgis-style` | :orange_circle: Scaffolded | QGIS: style manager |
+| `gdal-translate` | :orange_circle: Scaffolded | GDAL: translate raster |
+| `gdal-warp` | :orange_circle: Scaffolded | GDAL: warp raster |
+| `gdal-info` | :orange_circle: Scaffolded | GDAL: raster info |
+| `gdal-merge` | :orange_circle: Scaffolded | GDAL: merge rasters |
+| `gdal-calc` | :orange_circle: Scaffolded | GDAL: raster calculator |
+
+### Round 513 — LAME, Opus, Blender ext, OpenSCAD
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `lame-encode` | :orange_circle: Scaffolded | LAME: encode MP3 |
+| `lame-decode` | :orange_circle: Scaffolded | LAME: decode MP3 |
+| `lame-tag` | :orange_circle: Scaffolded | LAME: ID3 tags |
+| `lame-quality` | :orange_circle: Scaffolded | LAME: quality settings |
+| `lame-preset` | :orange_circle: Scaffolded | LAME: encoding preset |
+| `opus-encode` | :orange_circle: Scaffolded | Opus: encode audio |
+| `opus-decode` | :orange_circle: Scaffolded | Opus: decode audio |
+| `opus-info` | :orange_circle: Scaffolded | Opus: file info |
+| `opus-header` | :orange_circle: Scaffolded | Opus: header info |
+| `opus-comment` | :orange_circle: Scaffolded | Opus: comments |
+| `blender-render` | :orange_circle: Scaffolded | Blender: render scene |
+| `blender-script` | :orange_circle: Scaffolded | Blender: run script |
+| `blender-export` | :orange_circle: Scaffolded | Blender: export model |
+| `blender-import` | :orange_circle: Scaffolded | Blender: import model |
+| `blender-batch` | :orange_circle: Scaffolded | Blender: batch render |
+| `openscad-render` | :orange_circle: Scaffolded | OpenSCAD: render model |
+| `openscad-export` | :orange_circle: Scaffolded | OpenSCAD: export STL |
+| `openscad-preview` | :orange_circle: Scaffolded | OpenSCAD: preview |
+| `openscad-library` | :orange_circle: Scaffolded | OpenSCAD: library |
+| `openscad-customize` | :orange_circle: Scaffolded | OpenSCAD: customizer |
+
+### Round 512 — SFML, FFmpeg ext, SoX, Audacity
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `sfml-window` | :orange_circle: Scaffolded | SFML: window |
+| `sfml-render` | :orange_circle: Scaffolded | SFML: render |
+| `sfml-audio` | :orange_circle: Scaffolded | SFML: audio |
+| `sfml-network` | :orange_circle: Scaffolded | SFML: network |
+| `sfml-shader` | :orange_circle: Scaffolded | SFML: shader |
+| `ffmpeg-convert` | :orange_circle: Scaffolded | FFmpeg: convert format |
+| `ffmpeg-stream` | :orange_circle: Scaffolded | FFmpeg: stream media |
+| `ffmpeg-filter` | :orange_circle: Scaffolded | FFmpeg: apply filter |
+| `ffmpeg-probe` | :orange_circle: Scaffolded | FFmpeg: probe file |
+| `ffmpeg-record` | :orange_circle: Scaffolded | FFmpeg: record |
+| `sox-convert` | :orange_circle: Scaffolded | SoX: convert audio |
+| `sox-effect` | :orange_circle: Scaffolded | SoX: apply effect |
+| `sox-trim` | :orange_circle: Scaffolded | SoX: trim audio |
+| `sox-mix` | :orange_circle: Scaffolded | SoX: mix audio |
+| `sox-stat` | :orange_circle: Scaffolded | SoX: audio statistics |
+| `audacity-import` | :orange_circle: Scaffolded | Audacity: import audio |
+| `audacity-export` | :orange_circle: Scaffolded | Audacity: export audio |
+| `audacity-effect` | :orange_circle: Scaffolded | Audacity: apply effect |
+| `audacity-normalize` | :orange_circle: Scaffolded | Audacity: normalize |
+| `audacity-label` | :orange_circle: Scaffolded | Audacity: labels |
+
+### Round 511 — Godot, Love2D, Raylib, SDL2
+
+| Feature | Status | Notes |
+|---------|--------|-------|
+| `godot-scene` | :orange_circle: Scaffolded | Godot: scene editor |
+| `godot-shader` | :orange_circle: Scaffolded | Godot: shader editor |
+| `godot-signal` | :orange_circle: Scaffolded | Godot: signal connections |
+| `godot-export` | :orange_circle: Scaffolded | Godot: export project |
+| `godot-debugger` | :orange_circle: Scaffolded | Godot: debugger |
+| `love2d-run` | :orange_circle: Scaffolded | Love2D: run game |
+| `love2d-conf` | :orange_circle: Scaffolded | Love2D: configuration |
+| `love2d-package` | :orange_circle: Scaffolded | Love2D: package game |
+| `love2d-debug` | :orange_circle: Scaffolded | Love2D: debug |
+| `love2d-console` | :orange_circle: Scaffolded | Love2D: console |
+| `raylib-build` | :orange_circle: Scaffolded | Raylib: build project |
+| `raylib-example` | :orange_circle: Scaffolded | Raylib: examples |
+| `raylib-shader` | :orange_circle: Scaffolded | Raylib: shader |
+| `raylib-texture` | :orange_circle: Scaffolded | Raylib: texture |
+| `raylib-audio` | :orange_circle: Scaffolded | Raylib: audio |
+| `sdl2-init` | :orange_circle: Scaffolded | SDL2: initialize |
+| `sdl2-window` | :orange_circle: Scaffolded | SDL2: window management |
+| `sdl2-render` | :orange_circle: Scaffolded | SDL2: renderer |
+| `sdl2-event` | :orange_circle: Scaffolded | SDL2: event handling |
+| `sdl2-mixer` | :orange_circle: Scaffolded | SDL2: audio mixer |
+
 ### Round 510 — Lmod, Singularity, Apptainer, Charliecloud
 
 | Feature | Status | Notes |
diff --git a/src/jerboa-emacs/editor-extra-final.ss b/src/jerboa-emacs/editor-extra-final.ss
index fe8f52c..da48df2 100644
--- a/src/jerboa-emacs/editor-extra-final.ss
+++ b/src/jerboa-emacs/editor-extra-final.ss
@@ -33122,3 +33122,409 @@
 (def (cmd-charliecloud-list app)
   (let* ((echo (app-state-echo app)))
     (echo-message! echo "Charliecloud: list images")))
+
+;; Round 512: SFML, FFmpeg ext, SoX, Audacity (20 commands)
+(def (cmd-sfml-window app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SFML: window")))
+
+(def (cmd-sfml-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SFML: render")))
+
+(def (cmd-sfml-audio app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SFML: audio")))
+
+(def (cmd-sfml-network app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SFML: network")))
+
+(def (cmd-sfml-shader app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SFML: shader")))
+
+(def (cmd-ffmpeg-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FFmpeg: convert format")))
+
+(def (cmd-ffmpeg-stream app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FFmpeg: stream media")))
+
+(def (cmd-ffmpeg-filter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FFmpeg: apply filter")))
+
+(def (cmd-ffmpeg-probe app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FFmpeg: probe file")))
+
+(def (cmd-ffmpeg-record app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FFmpeg: record")))
+
+(def (cmd-sox-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SoX: convert audio")))
+
+(def (cmd-sox-effect app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SoX: apply effect")))
+
+(def (cmd-sox-trim app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SoX: trim audio")))
+
+(def (cmd-sox-mix app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SoX: mix audio")))
+
+(def (cmd-sox-stat app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SoX: audio statistics")))
+
+(def (cmd-audacity-import app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Audacity: import audio")))
+
+(def (cmd-audacity-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Audacity: export audio")))
+
+(def (cmd-audacity-effect app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Audacity: apply effect")))
+
+(def (cmd-audacity-normalize app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Audacity: normalize")))
+
+(def (cmd-audacity-label app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Audacity: labels")))
+
+;; Round 514: FreeCAD, KiCad, QGIS, GDAL (20 commands)
+(def (cmd-freecad-macro app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FreeCAD: run macro")))
+
+(def (cmd-freecad-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FreeCAD: export model")))
+
+(def (cmd-freecad-mesh app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FreeCAD: mesh tools")))
+
+(def (cmd-freecad-assembly app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FreeCAD: assembly")))
+
+(def (cmd-freecad-sketch app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "FreeCAD: sketcher")))
+
+(def (cmd-kicad-schematic app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "KiCad: schematic editor")))
+
+(def (cmd-kicad-pcb app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "KiCad: PCB layout")))
+
+(def (cmd-kicad-library app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "KiCad: library manager")))
+
+(def (cmd-kicad-gerber app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "KiCad: Gerber export")))
+
+(def (cmd-kicad-bom app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "KiCad: BOM generator")))
+
+(def (cmd-qgis-layer app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "QGIS: layer management")))
+
+(def (cmd-qgis-process app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "QGIS: processing tools")))
+
+(def (cmd-qgis-plugin app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "QGIS: plugin manager")))
+
+(def (cmd-qgis-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "QGIS: export map")))
+
+(def (cmd-qgis-style app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "QGIS: style manager")))
+
+(def (cmd-gdal-translate app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "GDAL: translate raster")))
+
+(def (cmd-gdal-warp app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "GDAL: warp raster")))
+
+(def (cmd-gdal-info app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "GDAL: raster info")))
+
+(def (cmd-gdal-merge app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "GDAL: merge rasters")))
+
+(def (cmd-gdal-calc app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "GDAL: raster calculator")))
+
+;; Round 515 batch 2: NumPy ext, SciPy ext (10 commands)
+(def (cmd-numpy-array app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "NumPy: array operations")))
+
+(def (cmd-numpy-linalg app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "NumPy: linear algebra")))
+
+(def (cmd-numpy-fft app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "NumPy: FFT")))
+
+(def (cmd-numpy-random app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "NumPy: random")))
+
+(def (cmd-numpy-einsum app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "NumPy: einsum")))
+
+(def (cmd-scipy-optimize app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SciPy: optimize")))
+
+(def (cmd-scipy-integrate app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SciPy: integrate")))
+
+(def (cmd-scipy-interpolate app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SciPy: interpolate")))
+
+(def (cmd-scipy-signal app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SciPy: signal processing")))
+
+(def (cmd-scipy-sparse app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SciPy: sparse matrices")))
+
+;; Round 517: Bokeh, Gnuplot ext, ParaView, VTK (20 commands)
+(def (cmd-bokeh-figure app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Bokeh: figure")))
+
+(def (cmd-bokeh-plot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Bokeh: plot")))
+
+(def (cmd-bokeh-server app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Bokeh: server")))
+
+(def (cmd-bokeh-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Bokeh: export")))
+
+(def (cmd-bokeh-widget app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Bokeh: widgets")))
+
+(def (cmd-gnuplot-plot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Gnuplot: plot data")))
+
+(def (cmd-gnuplot-set app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Gnuplot: set options")))
+
+(def (cmd-gnuplot-fit app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Gnuplot: curve fitting")))
+
+(def (cmd-gnuplot-terminal app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Gnuplot: terminal type")))
+
+(def (cmd-gnuplot-multiplot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Gnuplot: multiplot")))
+
+(def (cmd-paraview-open app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ParaView: open data")))
+
+(def (cmd-paraview-filter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ParaView: apply filter")))
+
+(def (cmd-paraview-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ParaView: render")))
+
+(def (cmd-paraview-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ParaView: export")))
+
+(def (cmd-paraview-animate app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ParaView: animation")))
+
+(def (cmd-vtk-reader app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "VTK: data reader")))
+
+(def (cmd-vtk-filter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "VTK: filter pipeline")))
+
+(def (cmd-vtk-mapper app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "VTK: mapper")))
+
+(def (cmd-vtk-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "VTK: render window")))
+
+(def (cmd-vtk-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "VTK: export scene")))
+
+;; Round 519: Maxima, LaTeX ext, Pandoc ext, AsciiDoc (20 commands)
+(def (cmd-maxima-solve app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Maxima: solve equation")))
+
+(def (cmd-maxima-simplify app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Maxima: simplify")))
+
+(def (cmd-maxima-integrate app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Maxima: integrate")))
+
+(def (cmd-maxima-plot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Maxima: plot")))
+
+(def (cmd-maxima-diff app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Maxima: differentiate")))
+
+(def (cmd-latex-compile app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LaTeX: compile document")))
+
+(def (cmd-latex-bibtex app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LaTeX: BibTeX")))
+
+(def (cmd-latex-glossary app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LaTeX: glossary")))
+
+(def (cmd-latex-index app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LaTeX: index")))
+
+(def (cmd-latex-clean app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LaTeX: clean aux files")))
+
+(def (cmd-pandoc-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandoc: convert document")))
+
+(def (cmd-pandoc-template app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandoc: templates")))
+
+(def (cmd-pandoc-filter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandoc: filters")))
+
+(def (cmd-pandoc-metadata app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandoc: metadata")))
+
+(def (cmd-pandoc-defaults app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandoc: defaults file")))
+
+(def (cmd-asciidoc-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "AsciiDoc: convert")))
+
+(def (cmd-asciidoc-pdf app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "AsciiDoc: to PDF")))
+
+(def (cmd-asciidoc-html app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "AsciiDoc: to HTML")))
+
+(def (cmd-asciidoc-docbook app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "AsciiDoc: to DocBook")))
+
+(def (cmd-asciidoc-manpage app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "AsciiDoc: to manpage")))
+
+;; Round 520 batch 2: Groff, LilyPond (10 commands)
+(def (cmd-groff-compile app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Groff: compile document")))
+
+(def (cmd-groff-man app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Groff: man macro")))
+
+(def (cmd-groff-ms app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Groff: ms macro")))
+
+(def (cmd-groff-mm app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Groff: mm macro")))
+
+(def (cmd-groff-pdf app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Groff: to PDF")))
+
+(def (cmd-lilypond-compile app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LilyPond: compile score")))
+
+(def (cmd-lilypond-midi app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LilyPond: MIDI output")))
+
+(def (cmd-lilypond-pdf app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LilyPond: PDF output")))
+
+(def (cmd-lilypond-svg app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LilyPond: SVG output")))
+
+(def (cmd-lilypond-preview app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LilyPond: preview")))
diff --git a/src/jerboa-emacs/editor-extra-modes.ss b/src/jerboa-emacs/editor-extra-modes.ss
index 18c2422..596879c 100644
--- a/src/jerboa-emacs/editor-extra-modes.ss
+++ b/src/jerboa-emacs/editor-extra-modes.ss
@@ -32346,3 +32346,409 @@
 (def (cmd-singularity-pull app)
   (let* ((echo (app-state-echo app)))
     (echo-message! echo "Singularity: pull image")))
+
+;; Round 511: Godot, Love2D, Raylib, SDL2 (20 commands)
+(def (cmd-godot-scene app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Godot: scene editor")))
+
+(def (cmd-godot-shader app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Godot: shader editor")))
+
+(def (cmd-godot-signal app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Godot: signal connections")))
+
+(def (cmd-godot-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Godot: export project")))
+
+(def (cmd-godot-debugger app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Godot: debugger")))
+
+(def (cmd-love2d-run app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Love2D: run game")))
+
+(def (cmd-love2d-conf app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Love2D: configuration")))
+
+(def (cmd-love2d-package app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Love2D: package game")))
+
+(def (cmd-love2d-debug app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Love2D: debug")))
+
+(def (cmd-love2d-console app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Love2D: console")))
+
+(def (cmd-raylib-build app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Raylib: build project")))
+
+(def (cmd-raylib-example app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Raylib: examples")))
+
+(def (cmd-raylib-shader app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Raylib: shader")))
+
+(def (cmd-raylib-texture app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Raylib: texture")))
+
+(def (cmd-raylib-audio app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Raylib: audio")))
+
+(def (cmd-sdl2-init app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SDL2: initialize")))
+
+(def (cmd-sdl2-window app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SDL2: window management")))
+
+(def (cmd-sdl2-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SDL2: renderer")))
+
+(def (cmd-sdl2-event app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SDL2: event handling")))
+
+(def (cmd-sdl2-mixer app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "SDL2: audio mixer")))
+
+;; Round 513: LAME, Opus, Blender ext, OpenSCAD (20 commands)
+(def (cmd-lame-encode app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LAME: encode MP3")))
+
+(def (cmd-lame-decode app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LAME: decode MP3")))
+
+(def (cmd-lame-tag app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LAME: ID3 tags")))
+
+(def (cmd-lame-quality app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LAME: quality settings")))
+
+(def (cmd-lame-preset app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "LAME: encoding preset")))
+
+(def (cmd-opus-encode app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Opus: encode audio")))
+
+(def (cmd-opus-decode app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Opus: decode audio")))
+
+(def (cmd-opus-info app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Opus: file info")))
+
+(def (cmd-opus-header app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Opus: header info")))
+
+(def (cmd-opus-comment app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Opus: comments")))
+
+(def (cmd-blender-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Blender: render scene")))
+
+(def (cmd-blender-script app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Blender: run script")))
+
+(def (cmd-blender-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Blender: export model")))
+
+(def (cmd-blender-import app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Blender: import model")))
+
+(def (cmd-blender-batch app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Blender: batch render")))
+
+(def (cmd-openscad-render app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "OpenSCAD: render model")))
+
+(def (cmd-openscad-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "OpenSCAD: export STL")))
+
+(def (cmd-openscad-preview app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "OpenSCAD: preview")))
+
+(def (cmd-openscad-library app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "OpenSCAD: library")))
+
+(def (cmd-openscad-customize app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "OpenSCAD: customizer")))
+
+;; Round 515 batch 1: ogr2ogr, PROJ (10 commands)
+(def (cmd-ogr2ogr-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ogr2ogr: convert format")))
+
+(def (cmd-ogr2ogr-info app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ogr2ogr: layer info")))
+
+(def (cmd-ogr2ogr-clip app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ogr2ogr: clip geometry")))
+
+(def (cmd-ogr2ogr-reproject app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ogr2ogr: reproject")))
+
+(def (cmd-ogr2ogr-sql app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "ogr2ogr: SQL query")))
+
+(def (cmd-proj-transform app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "PROJ: transform coordinates")))
+
+(def (cmd-proj-info app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "PROJ: CRS info")))
+
+(def (cmd-proj-factors app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "PROJ: projection factors")))
+
+(def (cmd-proj-geod app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "PROJ: geodesic calculations")))
+
+(def (cmd-proj-crs app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "PROJ: CRS database")))
+
+;; Round 516: Pandas ext, Matplotlib ext, Seaborn, Plotly (20 commands)
+(def (cmd-pandas-dataframe app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandas: DataFrame operations")))
+
+(def (cmd-pandas-merge app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandas: merge/join")))
+
+(def (cmd-pandas-groupby app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandas: group by")))
+
+(def (cmd-pandas-pivot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandas: pivot table")))
+
+(def (cmd-pandas-io app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Pandas: I/O operations")))
+
+(def (cmd-matplotlib-plot app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Matplotlib: create plot")))
+
+(def (cmd-matplotlib-figure app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Matplotlib: figure management")))
+
+(def (cmd-matplotlib-axis app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Matplotlib: axis config")))
+
+(def (cmd-matplotlib-style app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Matplotlib: style sheets")))
+
+(def (cmd-matplotlib-save app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Matplotlib: save figure")))
+
+(def (cmd-seaborn-heatmap app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Seaborn: heatmap")))
+
+(def (cmd-seaborn-scatter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Seaborn: scatter plot")))
+
+(def (cmd-seaborn-bar app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Seaborn: bar plot")))
+
+(def (cmd-seaborn-violin app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Seaborn: violin plot")))
+
+(def (cmd-seaborn-pair app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Seaborn: pair plot")))
+
+(def (cmd-plotly-chart app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Plotly: chart")))
+
+(def (cmd-plotly-scatter app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Plotly: scatter")))
+
+(def (cmd-plotly-bar app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Plotly: bar chart")))
+
+(def (cmd-plotly-layout app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Plotly: layout")))
+
+(def (cmd-plotly-export app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Plotly: export")))
+
+;; Round 518: Jupyter ext, JupyterLab ext, RStudio, Octave (20 commands)
+(def (cmd-jupyter-notebook app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Jupyter: open notebook")))
+
+(def (cmd-jupyter-kernel app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Jupyter: kernel management")))
+
+(def (cmd-jupyter-convert app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Jupyter: convert notebook")))
+
+(def (cmd-jupyter-trust app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Jupyter: trust notebook")))
+
+(def (cmd-jupyter-extension app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "Jupyter: extensions")))
+
+(def (cmd-jupyterlab-build app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "JupyterLab: build")))
+
+(def (cmd-jupyterlab-extension app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "JupyterLab: extensions")))
+
+(def (cmd-jupyterlab-theme app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "JupyterLab: themes")))
+
+(def (cmd-jupyterlab-workspace app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "JupyterLab: workspaces")))
+
+(def (cmd-jupyterlab-config app)
+  (let* ((echo (app-state-echo app)))
+    (echo-message! echo "JupyterLab: configuration")))