danceflow-stemlab 1.3.0__tar.gz → 1.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/MANIFEST.in +3 -0
  2. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/PKG-INFO +10 -2
  3. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/README.md +7 -0
  4. danceflow_stemlab-1.3.2/docs/branding/README.md +11 -0
  5. danceflow_stemlab-1.3.2/docs/branding/logo-monochrome.svg +6 -0
  6. danceflow_stemlab-1.3.2/docs/branding/logo.png +0 -0
  7. danceflow_stemlab-1.3.2/docs/branding/logo.svg +6 -0
  8. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/docs/codex-publishing.md +7 -0
  9. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/mcp-registry/server.json +4 -4
  10. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/.codex-plugin/plugin.json +3 -3
  11. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/README.md +4 -0
  12. danceflow_stemlab-1.3.2/plugins/stemlab/branding/logo-monochrome.svg +6 -0
  13. danceflow_stemlab-1.3.2/plugins/stemlab/branding/logo.png +0 -0
  14. danceflow_stemlab-1.3.2/plugins/stemlab/branding/logo.svg +6 -0
  15. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/plugin.json +3 -3
  16. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/pyproject.toml +5 -1
  17. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/build_codex_plugin.py +8 -1
  18. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/prepare_codex_marketplace.py +2 -1
  19. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/publish_mcp_registry.py +2 -0
  20. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/PKG-INFO +10 -2
  21. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/SOURCES.txt +7 -0
  22. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/__init__.py +1 -1
  23. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_package.py +3 -0
  24. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_release.py +16 -0
  25. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/.agents/plugins/marketplace.json +0 -0
  26. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/.github/workflows/codex-plugin.yml +0 -0
  27. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/.github/workflows/release.yml +0 -0
  28. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/LICENSE +0 -0
  29. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/docs/codex-plugin.md +0 -0
  30. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/docs/cue-alignment.md +0 -0
  31. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/docs/evidence-models.md +0 -0
  32. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/docs/midi.md +0 -0
  33. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/.mcp.json +0 -0
  34. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/mcp.json +0 -0
  35. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/skills/stemlab/SKILL.md +0 -0
  36. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/plugins/stemlab/skills/stemlab/references/tools.md +0 -0
  37. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/benchmark_evidence_corpus.py +0 -0
  38. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/capture_loop_workflow.py +0 -0
  39. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/check_codex_timeline.py +0 -0
  40. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/loop_demo.py +0 -0
  41. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/scripts/smoke_midi.py +0 -0
  42. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/setup.cfg +0 -0
  43. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/dependency_links.txt +0 -0
  44. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/entry_points.txt +0 -0
  45. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/requires.txt +0 -0
  46. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/danceflow_stemlab.egg-info/top_level.txt +0 -0
  47. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/__main__.py +0 -0
  48. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/__init__.py +0 -0
  49. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/evidence/__init__.py +0 -0
  50. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/evidence/adapters.py +0 -0
  51. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/evidence/registry.py +0 -0
  52. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/evidence/runner.py +0 -0
  53. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/evidence/worker.py +0 -0
  54. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/harmony.py +0 -0
  55. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/loops.py +0 -0
  56. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/lyrics.py +0 -0
  57. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/__init__.py +0 -0
  58. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/adapters.py +0 -0
  59. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/artifacts.py +0 -0
  60. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/registry.py +0 -0
  61. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/runner.py +0 -0
  62. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/midi/worker.py +0 -0
  63. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/registry.py +0 -0
  64. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/rhythm.py +0 -0
  65. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/runner.py +0 -0
  66. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/semantic_audio.py +0 -0
  67. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/semantic_text.py +0 -0
  68. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/song_map.py +0 -0
  69. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/sonic.py +0 -0
  70. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/structure.py +0 -0
  71. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/tempo_regimes.py +0 -0
  72. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/analysis/transcription.py +0 -0
  73. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/audio.py +0 -0
  74. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/__init__.py +0 -0
  75. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/base.py +0 -0
  76. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/beatnet.py +0 -0
  77. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/beatthis.py +0 -0
  78. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/beattransformer.py +0 -0
  79. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/beats/common.py +0 -0
  80. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/bootstrap.py +0 -0
  81. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/branding.py +0 -0
  82. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/canonical.py +0 -0
  83. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/cli.py +0 -0
  84. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/__init__.py +0 -0
  85. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/__main__.py +0 -0
  86. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/bridge.py +0 -0
  87. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/jobs.py +0 -0
  88. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/paths.py +0 -0
  89. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/server.py +0 -0
  90. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/tasks.py +0 -0
  91. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/timeline.py +0 -0
  92. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/codex/worker.py +0 -0
  93. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/cue_cli.py +0 -0
  94. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/cues.py +0 -0
  95. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/lyric_lrc.py +0 -0
  96. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/manifest.py +0 -0
  97. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/models.py +0 -0
  98. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/pipeline.py +0 -0
  99. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/__init__.py +0 -0
  100. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/base.py +0 -0
  101. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/bsroformer.py +0 -0
  102. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/common.py +0 -0
  103. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/demucs.py +0 -0
  104. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/openunmix.py +0 -0
  105. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/separators/scnet.py +0 -0
  106. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/server.py +0 -0
  107. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/sonic_visualiser.py +0 -0
  108. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/spectrogram.py +0 -0
  109. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/spectrogram_repair.py +0 -0
  110. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/speech.py +0 -0
  111. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/types.py +0 -0
  112. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/util.py +0 -0
  113. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/vamp.py +0 -0
  114. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/vamp_runtime.py +0 -0
  115. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/app.js +0 -0
  116. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/arcadians-cover.jpg +0 -0
  117. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/arcadians-reference.json +0 -0
  118. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/index.html +0 -0
  119. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/style.css +0 -0
  120. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/web/timeline.css +0 -0
  121. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/webui.py +0 -0
  122. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/src/stemlab/word_alignment.py +0 -0
  123. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_analysis_registry.py +0 -0
  124. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_arcadians_fixture.py +0 -0
  125. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_audio_normalization.py +0 -0
  126. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_beat_consensus.py +0 -0
  127. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_beat_this_bootstrap.py +0 -0
  128. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_beatnet_bootstrap.py +0 -0
  129. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_beatnet_compat.py +0 -0
  130. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_branding.py +0 -0
  131. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_bsroformer_adapter.py +0 -0
  132. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_canonical.py +0 -0
  133. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_canonical_extended.py +0 -0
  134. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_bridge.py +0 -0
  135. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_jobs.py +0 -0
  136. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_protocol.py +0 -0
  137. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_codex_timeline.py +0 -0
  138. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_cue_integration.py +0 -0
  139. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_cues.py +0 -0
  140. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_deep_harmony.py +0 -0
  141. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_deep_lyrics.py +0 -0
  142. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_deep_sonic_rhythm.py +0 -0
  143. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_distribution_identity.py +0 -0
  144. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_docker_contract.py +0 -0
  145. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_evidence_models.py +0 -0
  146. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_loop_integration.py +0 -0
  147. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_loops.py +0 -0
  148. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_lyric_lrc.py +0 -0
  149. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_manifest.py +0 -0
  150. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_midi_adapters.py +0 -0
  151. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_midi_extraction.py +0 -0
  152. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_midi_integration.py +0 -0
  153. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_midi_registry.py +0 -0
  154. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_models.py +0 -0
  155. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_repository_hygiene.py +0 -0
  156. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_server.py +0 -0
  157. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_song_map.py +0 -0
  158. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_sonic_visualiser.py +0 -0
  159. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_sonic_visualiser_workspace.py +0 -0
  160. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_spectrogram.py +0 -0
  161. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_speech_repetition.py +0 -0
  162. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_vamp.py +0 -0
  163. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_vamp_runtime.py +0 -0
  164. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_web_frontend.py +0 -0
  165. {danceflow_stemlab-1.3.0 → danceflow_stemlab-1.3.2}/tests/test_word_alignment.py +0 -0
@@ -1,5 +1,6 @@
1
1
  include .agents/plugins/marketplace.json
2
2
  recursive-include plugins/stemlab *.json *.md
3
+ recursive-include plugins/stemlab/branding *.svg *.png
3
4
  include plugins/stemlab/.mcp.json
4
5
  include plugins/stemlab/.codex-plugin/plugin.json
5
6
  include scripts/build_codex_plugin.py
@@ -18,3 +19,5 @@ include scripts/smoke_midi.py
18
19
  include docs/cue-alignment.md
19
20
  include docs/evidence-models.md
20
21
  include scripts/benchmark_evidence_corpus.py
22
+
23
+ recursive-include docs/branding *.svg *.png *.md
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: danceflow-stemlab
3
- Version: 1.3.0
4
- Summary: Local, evidence-led music analysis for stems, timing, structure, harmony, lyrics, and loopable sections for Shorts
3
+ Version: 1.3.2
4
+ Summary: Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
5
5
  Author: Kieran Simkin
6
6
  Maintainer: Kieran Simkin
7
7
  License-Expression: MIT
8
+ Project-URL: DanceFlow ecosystem, https://kieransimkin.co.uk/danceflow/
8
9
  Project-URL: Homepage, https://kieransimkin.co.uk/
9
10
  Project-URL: My Songs portfolio, https://kieransimkin.co.uk/my-songs/
10
11
  Project-URL: Arcadians showcase, https://kieransimkin.co.uk/arcadians/
@@ -124,6 +125,13 @@ Dynamic: license-file
124
125
 
125
126
  # StemLab
126
127
 
128
+ [![StemLab logo](https://raw.githubusercontent.com/kieransimkin/stemlab/v1.3.2/docs/branding/logo.png)](https://kieransimkin.co.uk/danceflow/)
129
+
130
+ By **[Kieran Simkin](https://kieransimkin.co.uk/)** · [DanceFlow ecosystem](https://kieransimkin.co.uk/danceflow/) · [Vector logo and usage guide](docs/branding/README.md).
131
+
132
+ Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
133
+
134
+
127
135
  <!-- mcp-name: io.github.kieransimkin/stemlab -->
128
136
 
129
137
  > **StemLab by [Kieran Simkin](https://kieransimkin.co.uk/)** · [My Songs portfolio](https://kieransimkin.co.uk/my-songs/) · [Arcadians EPK](https://kieransimkin.co.uk/arcadians/) · [Source](https://github.com/kieransimkin/stemlab)
@@ -1,5 +1,12 @@
1
1
  # StemLab
2
2
 
3
+ [![StemLab logo](https://raw.githubusercontent.com/kieransimkin/stemlab/v1.3.2/docs/branding/logo.png)](https://kieransimkin.co.uk/danceflow/)
4
+
5
+ By **[Kieran Simkin](https://kieransimkin.co.uk/)** · [DanceFlow ecosystem](https://kieransimkin.co.uk/danceflow/) · [Vector logo and usage guide](docs/branding/README.md).
6
+
7
+ Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
8
+
9
+
3
10
  <!-- mcp-name: io.github.kieransimkin/stemlab -->
4
11
 
5
12
  > **StemLab by [Kieran Simkin](https://kieransimkin.co.uk/)** · [My Songs portfolio](https://kieransimkin.co.uk/my-songs/) · [Arcadians EPK](https://kieransimkin.co.uk/arcadians/) · [Source](https://github.com/kieransimkin/stemlab)
@@ -0,0 +1,11 @@
1
+ # StemLab visual identity
2
+
3
+ ![StemLab logo](logo.svg)
4
+
5
+ By [Kieran Simkin](https://kieransimkin.co.uk/), part of [DanceFlow](https://kieransimkin.co.uk/danceflow/).
6
+
7
+ Split waveforms: inspectable music and stem analysis.
8
+
9
+ Original vector artwork, created 8 October 2026. Shared family: 128-unit square, rounded 30-unit frame, 5.5-unit rounded strokes, plum `#171124`, mint `#bff7df`, gold `#f5ce85`. The symbol remains unique without colour. `logo.svg` is the self-contained dark badge; `logo-monochrome.svg` is a transparent dark mark for light surfaces; `logo.png` is the 256px registry/export companion. Prefer SVG for scaling and label tiny marks with the tool name. No external fonts, scripts, remote references, animation or model-generated assets.
10
+
11
+ Use the files unchanged at a square aspect ratio, with at least 8/128 of their width as clear space. The monochrome mark needs a light background. Do not imply an official association with model providers, React, WordPress or operating-system vendors. Source artwork follows this repository's licence; dependency and third-party notices retain their own terms.
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
2
+ <title id="title">StemLab logo</title>
3
+ <desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
4
+
5
+ <g fill="none" stroke="#171124" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#171124"/><circle cx="94" cy="64" r="5" fill="#171124" stroke="none"/></g>
6
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
2
+ <title id="title">StemLab logo</title>
3
+ <desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
4
+ <rect x="3" y="3" width="122" height="122" rx="30" fill="#171124"/><rect x="8" y="8" width="112" height="112" rx="25" fill="none" stroke="#f5ce85" stroke-opacity=".35" stroke-width="1.5"/>
5
+ <g fill="none" stroke="#bff7df" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#f5ce85"/><circle cx="94" cy="64" r="5" fill="#f5ce85" stroke="none"/></g>
6
+ </svg>
@@ -168,3 +168,10 @@ validation at submission. Upstream specification changes can require a new patch
168
168
  - [GitHub workflow event behaviour](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow)
169
169
 
170
170
  - [uv tool invocation, extras and version selection](https://docs.astral.sh/uv/guides/tools/)
171
+
172
+
173
+ ## Potential problems
174
+
175
+ ### MCP Registry description length
176
+
177
+ On 8 October 2026 the 1.3.1 MCP publication returned HTTP 422 with `expected length <= 100` at `body.description`. The package summary including its website URL exceeded this registry field's limit. The matching maintainer report [registry issue 1184](https://github.com/modelcontextprotocol/registry/issues/1184) and [official OpenAPI schema](https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/api/openapi.yaml), accessed 8 October 2026, confirm the 100-character bound. Use a concise registry-specific description and keep fuller capability wording in Python/package metadata. Both the builder and publisher now validate 1–100 characters locally, with empty, overlong and non-string regression cases. Do not overwrite published tags or distributions to repair a registry description; release a successor version.
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.kieransimkin/stemlab",
4
- "title": "StemLab — timing and loops for Shorts",
5
- "description": "Local music timing analysis and loopable sections for Shorts and short-form video.",
6
- "version": "1.3.0",
4
+ "title": "StemLab \u2014 timing and loops for Shorts",
5
+ "description": "Music and stem analysis, timing and loopable Shorts. https://kieransimkin.co.uk/",
6
+ "version": "1.3.2",
7
7
  "websiteUrl": "https://kieransimkin.co.uk/my-songs/",
8
8
  "repository": {
9
9
  "url": "https://github.com/kieransimkin/stemlab",
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "identifier": "danceflow-stemlab",
16
- "version": "1.3.0",
16
+ "version": "1.3.2",
17
17
  "runtimeHint": "uvx",
18
18
  "runtimeArguments": [
19
19
  {
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "stemlab",
3
- "version": "1.3.0",
4
- "description": "Local, evidence-led music analysis and loopable sections for Shorts; StemLab / DanceFlow MCP.",
3
+ "version": "1.3.2",
4
+ "description": "Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/",
5
5
  "skills": "./skills/",
6
6
  "mcpServers": "./.mcp.json",
7
7
  "interface": {
8
8
  "displayName": "StemLab",
9
9
  "shortDescription": "Local music timing and loopable sections for Shorts",
10
- "longDescription": "StemLab turns music masters into inspectable local evidence: separated stems, beat/downbeat grids, tempo regimes, structure, harmony, vocals, lyrics, sonic features and native-sample loop candidates for Shorts and other short-form videos. Its React timeline aligns playback, spectrograms, sections, lyrics and loops, while exact reports preserve provenance. StemLab is part of Kieran Simkin's DanceFlow workflow and remains standalone from WordPress DanceMoves.",
10
+ "longDescription": "StemLab turns music masters into inspectable local evidence: separated stems, beat/downbeat grids, tempo regimes, structure, harmony, vocals, lyrics, sonic features and native-sample loop candidates for Shorts and other short-form videos. Its React timeline aligns playback, spectrograms, sections, lyrics and loops, while exact reports preserve provenance. StemLab is part of Kieran Simkin's DanceFlow workflow and remains standalone from WordPress DanceMoves. Website: https://kieransimkin.co.uk/",
11
11
  "developerName": "Kieran Simkin",
12
12
  "category": "Productivity",
13
13
  "capabilities": [
@@ -1,5 +1,9 @@
1
1
  # StemLab local Codex plugin
2
2
 
3
+ [![StemLab logo](https://raw.githubusercontent.com/kieransimkin/stemlab/v1.3.1/plugins/stemlab/branding/logo.png)](https://kieransimkin.co.uk/danceflow/)
4
+
5
+ Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
6
+
3
7
  **Audio timing analysis and loopable sections for creating Shorts and other short-form videos.**
4
8
 
5
9
  StemLab by **Kieran Simkin** — https://kieransimkin.co.uk/my-songs/
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
2
+ <title id="title">StemLab logo</title>
3
+ <desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
4
+
5
+ <g fill="none" stroke="#171124" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#171124"/><circle cx="94" cy="64" r="5" fill="#171124" stroke="none"/></g>
6
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img" aria-labelledby="title desc">
2
+ <title id="title">StemLab logo</title>
3
+ <desc id="desc">Split waveforms: inspectable music and stem analysis. Original DanceFlow family mark by Kieran Simkin.</desc>
4
+ <rect x="3" y="3" width="122" height="122" rx="30" fill="#171124"/><rect x="8" y="8" width="112" height="112" rx="25" fill="none" stroke="#f5ce85" stroke-opacity=".35" stroke-width="1.5"/>
5
+ <g fill="none" stroke="#bff7df" stroke-width="5.5" stroke-linecap="round" stroke-linejoin="round"><path d="M29 44h9l5-12 8 24 7-12h12M29 64h13l6-8 7 16 6-8h9M29 84h10l7-5 8 10 7-5h9"/><path d="M80 42v44m0-22h12" stroke="#f5ce85"/><circle cx="94" cy="64" r="5" fill="#f5ce85" stroke="none"/></g>
6
+ </svg>
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "stemlab",
4
- "version": "1.3.0",
5
- "description": "Local, evidence-led music analysis and loopable sections for Shorts; StemLab / DanceFlow MCP.",
4
+ "version": "1.3.2",
5
+ "description": "Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/",
6
6
  "author": {
7
7
  "name": "Kieran Simkin",
8
8
  "url": "https://kieransimkin.co.uk/"
@@ -26,7 +26,7 @@
26
26
  "interface": {
27
27
  "displayName": "StemLab",
28
28
  "shortDescription": "Local music timing and loopable sections for Shorts",
29
- "longDescription": "StemLab turns music masters into inspectable local evidence: separated stems, beat/downbeat grids, tempo regimes, structure, harmony, vocals, lyrics, sonic features and native-sample loop candidates for Shorts and other short-form videos. Its React timeline aligns playback, spectrograms, sections, lyrics and loops, while exact reports preserve provenance. StemLab is part of Kieran Simkin's DanceFlow workflow and remains standalone from WordPress DanceMoves.",
29
+ "longDescription": "StemLab turns music masters into inspectable local evidence: separated stems, beat/downbeat grids, tempo regimes, structure, harmony, vocals, lyrics, sonic features and native-sample loop candidates for Shorts and other short-form videos. Its React timeline aligns playback, spectrograms, sections, lyrics and loops, while exact reports preserve provenance. StemLab is part of Kieran Simkin's DanceFlow workflow and remains standalone from WordPress DanceMoves. Website: https://kieransimkin.co.uk/",
30
30
  "developerName": "Kieran Simkin",
31
31
  "category": "Productivity",
32
32
  "capabilities": [
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "danceflow-stemlab"
7
7
  dynamic = ["version"]
8
- description = "Local, evidence-led music analysis for stems, timing, structure, harmony, lyrics, and loopable sections for Shorts"
8
+ description = "Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  authors = [{name = "Kieran Simkin"}]
@@ -38,6 +38,7 @@ dependencies = [
38
38
  ]
39
39
 
40
40
  [project.urls]
41
+ "DanceFlow ecosystem" = "https://kieransimkin.co.uk/danceflow/"
41
42
  Homepage = "https://kieransimkin.co.uk/"
42
43
  "My Songs portfolio" = "https://kieransimkin.co.uk/my-songs/"
43
44
  "Arcadians showcase" = "https://kieransimkin.co.uk/arcadians/"
@@ -140,3 +141,6 @@ select = ["E4", "E7", "E9", "F"]
140
141
  [tool.pytest.ini_options]
141
142
  addopts = "-q"
142
143
  pythonpath = ["src"]
144
+
145
+ [tool.setuptools.data-files]
146
+ "share/stemlab/branding" = ["docs/branding/logo.svg", "docs/branding/logo-monochrome.svg", "docs/branding/logo.png", "docs/branding/README.md"]
@@ -58,9 +58,15 @@ def registry_metadata(root: Path, version: str) -> dict:
58
58
  value = json.loads((root / "mcp-registry/server.json").read_text(encoding="utf-8"))
59
59
  if value["name"] != "io.github.kieransimkin/stemlab":
60
60
  raise ValueError("Unexpected MCP registry namespace")
61
+ if not isinstance(value.get("description"), str) or not 1 <= len(value["description"]) <= 100:
62
+ raise ValueError("MCP registry description must contain 1 to 100 characters")
61
63
  if f'mcp-name: {value["name"]} -->' not in (root / "README.md").read_text(encoding="utf-8"):
62
64
  raise ValueError("PyPI README ownership marker is missing")
63
65
  value["version"] = version
66
+ value["icons"] = [{
67
+ "src": f"https://raw.githubusercontent.com/kieransimkin/stemlab/v{version}/docs/branding/logo.png",
68
+ "mimeType": "image/png", "sizes": ["256x256"],
69
+ }]
64
70
  for package in value["packages"]:
65
71
  if package["registryType"] != "pypi" or package["identifier"] != "danceflow-stemlab":
66
72
  raise ValueError("Unexpected MCP registry package")
@@ -73,7 +79,8 @@ def build(root: Path, output: Path, release_tag: str | None = None) -> Path:
73
79
  version = package_version(root, release_tag)
74
80
  files = {p.relative_to(root).as_posix(): p.read_bytes()
75
81
  for p in (root / "plugins/stemlab").rglob("*")
76
- if p.is_file() and p.suffix in {".json", ".md"}}
82
+ if p.is_file() and (p.suffix in {".json", ".md"} or
83
+ (p.parent.name == "branding" and p.suffix in {".svg", ".png"}))}
77
84
  files[".agents/plugins/marketplace.json"] = (root / ".agents/plugins/marketplace.json").read_bytes()
78
85
  files["plugins/stemlab/LICENSE"] = (root / "LICENSE").read_bytes()
79
86
  files["plugins/stemlab/TECHNICAL-GUIDE.md"] = (root / "docs/codex-plugin.md").read_bytes()
@@ -30,7 +30,8 @@ def verified_files(archive: Path) -> dict[str, bytes]:
30
30
  p = PurePosixPath(name)
31
31
  allowed = name in {"SHA256SUMS", ".agents/plugins/marketplace.json"} or (
32
32
  name.startswith("plugins/stemlab/") and
33
- (p.suffix in {".json", ".md"} or p.name == "LICENSE"))
33
+ (p.suffix in {".json", ".md"} or p.name == "LICENSE" or
34
+ (p.parent.name == "branding" and p.suffix in {".svg", ".png"})))
34
35
  if not allowed or ".." in p.parts or p.is_absolute() or "\\" in name:
35
36
  raise ValueError("Unexpected archive path")
36
37
  files = {name: z.read(name) for name in names}
@@ -43,6 +43,8 @@ def validate_metadata(data: dict, tag: str) -> str:
43
43
  raise ValueError("Unexpected registry identity")
44
44
  if tag != f"v{version}":
45
45
  raise ValueError("Registry version does not match the release tag")
46
+ if not isinstance(data.get("description"), str) or not 1 <= len(data["description"]) <= 100:
47
+ raise ValueError("MCP registry description must contain 1 to 100 characters")
46
48
  packages = data.get("packages", [])
47
49
  if len(packages) != 1 or packages[0].get("identifier") != "danceflow-stemlab":
48
50
  raise ValueError("Unexpected package")
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: danceflow-stemlab
3
- Version: 1.3.0
4
- Summary: Local, evidence-led music analysis for stems, timing, structure, harmony, lyrics, and loopable sections for Shorts
3
+ Version: 1.3.2
4
+ Summary: Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
5
5
  Author: Kieran Simkin
6
6
  Maintainer: Kieran Simkin
7
7
  License-Expression: MIT
8
+ Project-URL: DanceFlow ecosystem, https://kieransimkin.co.uk/danceflow/
8
9
  Project-URL: Homepage, https://kieransimkin.co.uk/
9
10
  Project-URL: My Songs portfolio, https://kieransimkin.co.uk/my-songs/
10
11
  Project-URL: Arcadians showcase, https://kieransimkin.co.uk/arcadians/
@@ -124,6 +125,13 @@ Dynamic: license-file
124
125
 
125
126
  # StemLab
126
127
 
128
+ [![StemLab logo](https://raw.githubusercontent.com/kieransimkin/stemlab/v1.3.2/docs/branding/logo.png)](https://kieransimkin.co.uk/danceflow/)
129
+
130
+ By **[Kieran Simkin](https://kieransimkin.co.uk/)** · [DanceFlow ecosystem](https://kieransimkin.co.uk/danceflow/) · [Vector logo and usage guide](docs/branding/README.md).
131
+
132
+ Local music analysis for stems, timing, beats, harmony, lyrics, MIDI and loopable sections for Shorts. https://kieransimkin.co.uk/
133
+
134
+
127
135
  <!-- mcp-name: io.github.kieransimkin/stemlab -->
128
136
 
129
137
  > **StemLab by [Kieran Simkin](https://kieransimkin.co.uk/)** · [My Songs portfolio](https://kieransimkin.co.uk/my-songs/) · [Arcadians EPK](https://kieransimkin.co.uk/arcadians/) · [Source](https://github.com/kieransimkin/stemlab)
@@ -10,12 +10,19 @@ docs/codex-publishing.md
10
10
  docs/cue-alignment.md
11
11
  docs/evidence-models.md
12
12
  docs/midi.md
13
+ docs/branding/README.md
14
+ docs/branding/logo-monochrome.svg
15
+ docs/branding/logo.png
16
+ docs/branding/logo.svg
13
17
  mcp-registry/server.json
14
18
  plugins/stemlab/.mcp.json
15
19
  plugins/stemlab/README.md
16
20
  plugins/stemlab/mcp.json
17
21
  plugins/stemlab/plugin.json
18
22
  plugins/stemlab/.codex-plugin/plugin.json
23
+ plugins/stemlab/branding/logo-monochrome.svg
24
+ plugins/stemlab/branding/logo.png
25
+ plugins/stemlab/branding/logo.svg
19
26
  plugins/stemlab/skills/stemlab/SKILL.md
20
27
  plugins/stemlab/skills/stemlab/references/tools.md
21
28
  scripts/benchmark_evidence_corpus.py
@@ -7,4 +7,4 @@ Created by Kieran Simkin — https://kieransimkin.co.uk/
7
7
  Music catalogue — https://kieransimkin.co.uk/my-songs/
8
8
  """
9
9
 
10
- __version__ = "1.3.0"
10
+ __version__ = "1.3.2"
@@ -34,6 +34,9 @@ def test_archive_is_reproducible_and_has_verified_hashes(tmp_path):
34
34
  assert "plugins/stemlab/plugin.json" in z.namelist()
35
35
  assert ".agents/plugins/marketplace.json" in z.namelist()
36
36
  assert "plugins/stemlab/.codex-plugin/plugin.json" in z.namelist()
37
+ for name in ("logo.svg", "logo-monochrome.svg", "logo.png"):
38
+ member = "plugins/stemlab/branding/" + name
39
+ assert z.read(member) == (ROOT / member).read_bytes()
37
40
  for line in z.read("SHA256SUMS").decode().splitlines():
38
41
  digest, path = line.split(" ", 1)
39
42
  assert hashlib.sha256(z.read(path)).hexdigest() == digest
@@ -25,6 +25,8 @@ def test_release_tag_and_registry_version_are_tied_to_source(tmp_path):
25
25
  archive = builder.build(ROOT, tmp_path, f"v{version}")
26
26
  meta = json.loads((tmp_path / "stemlab-mcp-server.json").read_text())
27
27
  assert meta["version"] == meta["packages"][0]["version"] == version
28
+ assert meta["icons"][0]["src"] == f"https://raw.githubusercontent.com/kieransimkin/stemlab/v{version}/docs/branding/logo.png"
29
+ assert meta["icons"][0]["sizes"] == ["256x256"]
28
30
  with zipfile.ZipFile(archive) as z:
29
31
  assert json.loads(z.read("plugins/stemlab/plugin.json"))["version"] == version
30
32
  assert json.loads(z.read("plugins/stemlab/.codex-plugin/plugin.json"))["version"] == version
@@ -80,6 +82,20 @@ def test_registry_publisher_metadata_fails_before_network():
80
82
  publisher.validate_metadata(meta, "v1.2.3")
81
83
 
82
84
 
85
+ @pytest.mark.parametrize("description", ["", "x" * 101, None])
86
+ def test_registry_rejects_description_outside_published_schema(description, tmp_path):
87
+ publisher = module("publish_mcp_registry")
88
+ builder = module("build_codex_plugin")
89
+ meta = builder.registry_metadata(ROOT, "1.2.3")
90
+ meta["description"] = description
91
+ with pytest.raises(ValueError, match="1 to 100"):
92
+ publisher.validate_metadata(meta, "v1.2.3")
93
+ (tmp_path / "mcp-registry").mkdir()
94
+ (tmp_path / "mcp-registry/server.json").write_text(json.dumps(meta))
95
+ with pytest.raises(ValueError, match="1 to 100"):
96
+ builder.registry_metadata(tmp_path, "1.2.3")
97
+
98
+
83
99
  def test_publication_is_release_gated_and_dependency_ordered():
84
100
  yaml = pytest.importorskip("yaml")
85
101
  workflow = yaml.load((ROOT / ".github/workflows/release.yml").read_text(), Loader=yaml.BaseLoader)