Cross-platform compile mode ships everywhere, plus a self-percolating release pipeline

Big engineering week — 168 commits and 67 releases across the stack, most of it plumbing that makes the next set of features possible. Here’s the rundown, organized by what actually matters.

Full analyzer compile now works cross-platform

The headline: compiled-analyzer mode is now live on Windows, Linux, and macOS, and it’s wired into the Python package end-to-end.

Getting there meant chasing down a string of real platform bugs in the engine itself:

  • Linux/macOS were missing a HINSTANCE typedef and compiled-RUN dispatch entirely — now enabled on both (NLP-ENGINE-516).
  • macOS had a nasty bug where << was picking the bool overload instead of the string one for RSSTR/RSNAME/RSKB* emits — fixed by casting to _TCHAR* (NLP-ENGINE-519).
  • .dylib vs .so extensions are now handled correctly when loading compiled analyzers and KBs on macOS (NLP-ENGINE-517).
  • Fixed an empty run-tree bug in macOS codegen, and made sure the run/ output directory actually exists before analyzer-pass codegen tries to write into it.
  • make_dir/rm_dir now properly implemented on Linux and macOS (NLP-ENGINE-526), and rundir creation switched to std::filesystem::create_directory (NLP-ENGINE-527).

On top of that, compile-mode support landed in the Python, TypeScript, and VS Code packages this week:

  • py-package-nlpengine gained compile() and a new cloud_compile() that does an end-to-end analyzer build via the dispatcher service — plus wheels now build for Python 3.13.
  • The core python package (v2.0.1) and ts-nlp-engine (v2.0.1, its first real release) both got compile-mode added to NLPEngine.
  • vscode-nlp now stages the compiled .so/.dylib into bin/ on Linux/macOS so cloud-compile mode works from the editor.

If you’ve been wanting to compile analyzers instead of just interpreting them, this is the week that got real across the board.

Release percolation: less manual bumping, more auto-flow

I spent real time this week making releases percolate automatically instead of me manually bumping seven repos by hand. package-analyzers was extracted into its own submodule, and py-package-nlpengine now has a listener that auto-bumps and auto-publishes whenever analyzers move, replacing the old PR-based flow and the nightly cron with something event-driven. There’s now a documented cross-repo percolation map (parse-en-us → analyzer-templates → package-analyzers → downstream) so it’s clear what triggers what. Also cleaned up a genuinely annoying bug where the analyzers submodule wasn’t being checked out before zipping, leaving visualtext.zip empty on some builds — fixed on both macOS and Linux paths.

Lite specials

Added _xVAR("attribute") as a new match-list special in NLP++ lite — lets a rule pull an attribute value directly off a matched node. Small but useful for anyone doing conceptual-grammar work that needs quick attribute access mid-match.

Smaller fixes worth knowing about

  • NLP_ENGINE::close() is now idempotent (NLP-ENGINE-523) — calling it twice won’t blow up, which also fixed a Windows tempdir cleanup PermissionError in the Python bindings.
  • Bounded _stprintf writes into MAXPATH buffers (NLP-ENGINE-521) — a real overflow risk closed.
  • Fixed the VS multi-config generator post-build copy for test-nlp (NLP-ENGINE-522).

Releases

nlp-engine went from v3.1.44 all the way to v3.1.57 this week, with matching builds on Windows/Linux/macOS repos riding along automatically. py-package-nlpengine climbed to v2.0.8. Both python and ts-nlp-engine cut their v2.0.1/first releases with compile support.

Next

With compile mode now solid cross-platform, I want to spend some time actually using it on bigger analyzer chains and see where the rough edges are — and get a proper writeup together on cloud_compile() for anyone who wants to try it.