python: publish nimblebrain-synapse (the Synapse server SDK) to PyPI#30
Open
mgoldsborough wants to merge 2 commits into
Open
python: publish nimblebrain-synapse (the Synapse server SDK) to PyPI#30mgoldsborough wants to merge 2 commits into
mgoldsborough wants to merge 2 commits into
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Python
SynapseUIserver descriptor (the server half that registers a cross-hostui://component from a FastMCP server) shipped only as in-repo source plus vendored copies. Vendoring drifts — bassethound's copy already forked (deadskybridge_mime/mcpui_mimeparams, 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(importnimblebrain_synapse). PyPI has no scopes and thesynapse-*namespace is contested (Vertexsynapse,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/synapsescope, and it reads as the umbrella Python Synapse package —SynapseUIis its first export; future pieces land in the same package. TheSynapseUIclass andwindow.SynapseUIclient global are unchanged.Packaging —
[project.urls]+ classifiers; wheel builds clean and includes the vendored client IIFE (verified: packages undernimblebrain_synapse/, metadata namenimblebrain-synapse,from nimblebrain_synapse import SynapseUIimports).Independent versioning — versions on its own line, not lockstep with
@nimblebrain/synapse(npm). Newpython/CHANGELOG.md, a__client_version__provenance pin (which npm build the bundled IIFE came from), and a README compatibility table:nimblebrain-synapse@nimblebrain/synapse)2026-01-26· MCP Apps (SEP-1865) · OpenAI Apps SDKCI gate — adds a
pythonjob (ruff check+ruff format --check+pytest, viauv); previously the package was ungated beyond the IIFE freshness diff.Release —
publish-python.ymlonnimblebrain-synapse-v*tags (distinct from npm'sv*): tag/version match,uv build, PyPI trusted publishing (OIDC, no token), and a GitHub Release frompython/CHANGELOG.md.One-time setup before the first tag
PyPI trusted publishing needs a publisher registered on PyPI (like the npm
npmenvironment already configured): repoNimbleBrainInc/synapse, workflowpublish-python.yml, environmentpypi, projectnimblebrain-synapse(register as a pending publisher since it doesn't exist yet — the name is confirmed available). Until thenverifyruns; onlypublishneeds it.Verification
ruff check/ruff format --check/pytestgreen (15 passed).uv buildproduces sdist + wheel undernimblebrain_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", deletingsrc/bassethound/synapse_ui/and importing fromnimblebrain_synapse— permanently retiring the drift. bassethound passes no custom mimes, so it's a behavior-identical swap.