Skip to content

python: publish nimblebrain-synapse (the Synapse server SDK) to PyPI#30

Open
mgoldsborough wants to merge 2 commits into
mainfrom
python-package
Open

python: publish nimblebrain-synapse (the Synapse server SDK) to PyPI#30
mgoldsborough wants to merge 2 commits into
mainfrom
python-package

Conversation

@mgoldsborough

@mgoldsborough mgoldsborough commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Why

The Python SynapseUI server descriptor (the server half that registers a cross-host ui:// component from a FastMCP server) shipped only as in-repo source plus vendored copies. Vendoring drifts — bassethound's copy already forked (dead skybridge_mime/mcpui_mime params, diverged docstrings), and every future Python bundle that renders cross-host would fork the same security-critical code (the <script>-safe XSS embed, the two-dialect _meta). We expect multiple Python bundles to render in ChatGPT + Claude + the NimbleBrain runtime, so the fix is one installable source of truth, not N copies.

What

Turns python/ into a real, publishable, independently-versioned PyPI package.

  • Name: nimblebrain-synapse (import nimblebrain_synapse). PyPI has no scopes and the synapse-* namespace is contested (Vertex synapse, matrix-synapse, synapse-mcp, synapse-sdk), so we follow the org-prefix convention (azure-*, google-cloud-*, langchain-*): a brand-owned dist root with the import aligned. It's the faithful translation of the npm @nimblebrain/synapse scope, and it reads as the umbrella Python Synapse packageSynapseUI is its first export; future pieces land in the same package. The SynapseUI class and window.SynapseUI client global are unchanged.

  • Packaging[project.urls] + classifiers; wheel builds clean and includes the vendored client IIFE (verified: packages under nimblebrain_synapse/, metadata name nimblebrain-synapse, from nimblebrain_synapse import SynapseUI imports).

  • Independent versioning — versions on its own line, not lockstep with @nimblebrain/synapse (npm). New python/CHANGELOG.md, a __client_version__ provenance pin (which npm build the bundled IIFE came from), and a README compatibility table:

    nimblebrain-synapse Bundled client (@nimblebrain/synapse) Wire protocols
    0.1.0 0.12.0 ext-apps 2026-01-26 · MCP Apps (SEP-1865) · OpenAI Apps SDK
  • CI gate — adds a python job (ruff check + ruff format --check + pytest, via uv); previously the package was ungated beyond the IIFE freshness diff.

  • Releasepublish-python.yml on nimblebrain-synapse-v* tags (distinct from npm's v*): tag/version match, uv build, PyPI trusted publishing (OIDC, no token), and a GitHub Release from python/CHANGELOG.md.

One-time setup before the first tag

PyPI trusted publishing needs a publisher registered on PyPI (like the npm npm environment already configured): repo NimbleBrainInc/synapse, workflow publish-python.yml, environment pypi, project nimblebrain-synapse (register as a pending publisher since it doesn't exist yet — the name is confirmed available). Until then verify runs; only publish needs it.

Verification

ruff check / ruff format --check / pytest green (15 passed). uv build produces sdist + wheel under nimblebrain_synapse/ with the IIFE asset and correct metadata. Import smoke test passes. Both workflows are valid YAML. No lockfile/venv/dist byproducts tracked.

Follow-up (separate PR)

PR-B converts bassethound from its vendored copy to dependencies += "nimblebrain-synapse", deleting src/bassethound/synapse_ui/ and importing from nimblebrain_synapse — permanently retiring the drift. bassethound passes no custom mimes, so it's a behavior-identical swap.

The SynapseUI server descriptor shipped only as in-repo source and vendored
copies. Vendoring drifts: bassethound's copy already forked (dead mime params,
diverged docstrings), and every future Python bundle that renders cross-host
would fork the same security-critical code (the XSS embed, the two-dialect
_meta). Make it an installable package so bundles depend on one source of truth.

- pyproject: PyPI metadata (urls, classifiers), accurate three-host description
- CHANGELOG.md: its own version line. synapse-ui versions independently of the
  npm package (different cadence, different consumers); they meet on the wire
  protocol, recorded in __client_version__ and a README compatibility table
- CI: lint + format + test the python/ package (previously ungated beyond the
  IIFE freshness diff)
- publish-python.yml: PyPI trusted publishing on synapse-ui-v* tags, mirroring
  the npm flow (tag/version match, own CHANGELOG-extracted GitHub Release)
PyPI has no scopes, and the 'synapse' namespace is contested (Vertex's synapse,
matrix-synapse, synapse-mcp, synapse-sdk). Follow the org-prefix convention
(azure-*, google-cloud-*, langchain-*): brand-owned dist root with the import
aligned. This is the faithful translation of the npm @nimblebrain/synapse scope,
and it's the umbrella Python Synapse package — SynapseUI is its first export,
future pieces land in the same package.

Rename the import package synapse_ui -> nimblebrain_synapse; dist synapse-ui ->
nimblebrain-synapse; release tag synapse-ui-v* -> nimblebrain-synapse-v*. The
SynapseUI class and window.SynapseUI client global are unchanged, as are the JS
build artifact (synapse-ui.iife.global.js) and wire-contract (synapse-ui-data)
names.
@mgoldsborough mgoldsborough changed the title python: publish synapse-ui as an independently-versioned PyPI package python: publish nimblebrain-synapse (the Synapse server SDK) to PyPI Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant