kicad-sch-api 0.4.0__tar.gz → 0.4.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.

Potentially problematic release.


This version of kicad-sch-api might be problematic. Click here for more details.

Files changed (166) hide show
  1. kicad_sch_api-0.4.2/.claude/commands/dev/publish-pypi.md +711 -0
  2. kicad_sch_api-0.4.2/CHANGELOG.md +101 -0
  3. {kicad_sch_api-0.4.0/kicad_sch_api.egg-info → kicad_sch_api-0.4.2}/PKG-INFO +17 -9
  4. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/README.md +15 -7
  5. kicad_sch_api-0.4.2/examples/kicad_cli_exports.py +176 -0
  6. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/__init__.py +2 -2
  7. kicad_sch_api-0.4.2/kicad_sch_api/cli/__init__.py +45 -0
  8. kicad_sch_api-0.4.2/kicad_sch_api/cli/base.py +302 -0
  9. kicad_sch_api-0.4.2/kicad_sch_api/cli/bom.py +164 -0
  10. kicad_sch_api-0.4.2/kicad_sch_api/cli/erc.py +229 -0
  11. kicad_sch_api-0.4.2/kicad_sch_api/cli/export_docs.py +289 -0
  12. kicad_sch_api-0.4.2/kicad_sch_api/cli/netlist.py +94 -0
  13. kicad_sch_api-0.4.2/kicad_sch_api/cli/types.py +43 -0
  14. kicad_sch_api-0.4.2/kicad_sch_api/core/collections/__init__.py +5 -0
  15. kicad_sch_api-0.4.2/kicad_sch_api/core/collections/base.py +248 -0
  16. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/component_bounds.py +5 -0
  17. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/components.py +142 -47
  18. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/config.py +85 -3
  19. kicad_sch_api-0.4.2/kicad_sch_api/core/factories/__init__.py +5 -0
  20. kicad_sch_api-0.4.2/kicad_sch_api/core/factories/element_factory.py +276 -0
  21. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/formatter.py +22 -5
  22. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/junctions.py +26 -75
  23. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/labels.py +28 -52
  24. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/file_io.py +3 -2
  25. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/metadata.py +6 -5
  26. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/validation.py +3 -2
  27. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/wire.py +7 -1
  28. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/nets.py +38 -43
  29. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/no_connects.py +29 -53
  30. kicad_sch_api-0.4.2/kicad_sch_api/core/parser.py +661 -0
  31. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/schematic.py +211 -148
  32. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/texts.py +28 -55
  33. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/types.py +59 -18
  34. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/wires.py +27 -75
  35. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/__init__.py +22 -0
  36. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/graphics_parser.py +564 -0
  37. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/label_parser.py +194 -0
  38. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/library_parser.py +165 -0
  39. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/metadata_parser.py +58 -0
  40. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/sheet_parser.py +352 -0
  41. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/symbol_parser.py +313 -0
  42. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/text_parser.py +250 -0
  43. kicad_sch_api-0.4.2/kicad_sch_api/parsers/elements/wire_parser.py +242 -0
  44. kicad_sch_api-0.4.2/kicad_sch_api/parsers/utils.py +80 -0
  45. kicad_sch_api-0.4.2/kicad_sch_api/validation/__init__.py +25 -0
  46. kicad_sch_api-0.4.2/kicad_sch_api/validation/erc.py +171 -0
  47. kicad_sch_api-0.4.2/kicad_sch_api/validation/erc_models.py +203 -0
  48. kicad_sch_api-0.4.2/kicad_sch_api/validation/pin_matrix.py +243 -0
  49. kicad_sch_api-0.4.2/kicad_sch_api/validation/validators.py +391 -0
  50. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2/kicad_sch_api.egg-info}/PKG-INFO +17 -9
  51. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api.egg-info/SOURCES.txt +28 -7
  52. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/pyproject.toml +2 -2
  53. kicad_sch_api-0.4.2/tests/test_cli_integration.py +248 -0
  54. kicad_sch_api-0.4.0/.claude/commands/dev/publish-pypi.md +0 -358
  55. kicad_sch_api-0.4.0/CHANGELOG.md +0 -184
  56. kicad_sch_api-0.4.0/kicad_sch_api/core/manhattan_routing.py +0 -430
  57. kicad_sch_api-0.4.0/kicad_sch_api/core/parser.py +0 -2351
  58. kicad_sch_api-0.4.0/kicad_sch_api/core/simple_manhattan.py +0 -228
  59. kicad_sch_api-0.4.0/kicad_sch_api/core/wire_routing.py +0 -380
  60. kicad_sch_api-0.4.0/kicad_sch_api/parsers/label_parser.py +0 -254
  61. kicad_sch_api-0.4.0/kicad_sch_api/parsers/symbol_parser.py +0 -222
  62. kicad_sch_api-0.4.0/kicad_sch_api/parsers/wire_parser.py +0 -99
  63. kicad_sch_api-0.4.0/tests/test_manhattan_routing.py +0 -255
  64. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/dev/dead-code-analysis.md +0 -0
  65. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/dev/review-implementation.md +0 -0
  66. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/dev/run-tests.md +0 -0
  67. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/dev/update-and-commit.md +0 -0
  68. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/dev/update-memory-bank.md +0 -0
  69. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/.claude/commands/test/run-reference-tests.md +0 -0
  70. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/LICENSE +0 -0
  71. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/MANIFEST.in +0 -0
  72. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/advanced_usage.py +0 -0
  73. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/basic_usage.py +0 -0
  74. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/mcp_basic_example.py +0 -0
  75. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/mcp_integration.py +0 -0
  76. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/parser_demo.py +0 -0
  77. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/pin_to_pin_wiring_demo.py +0 -0
  78. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/simple_circuit_with_pin_wiring.py +0 -0
  79. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/examples/simple_two_resistor_routing.py +0 -0
  80. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/cli.py +0 -0
  81. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/__init__.py +0 -0
  82. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/base.py +0 -0
  83. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/components.py +0 -0
  84. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/junctions.py +0 -0
  85. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/labels.py +0 -0
  86. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/collections/wires.py +0 -0
  87. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/__init__.py +0 -0
  88. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/geometry.py +0 -0
  89. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/ic_manager.py +0 -0
  90. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/__init__.py +0 -0
  91. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/format_sync.py +0 -0
  92. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/graphics.py +0 -0
  93. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/sheet.py +0 -0
  94. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/managers/text_elements.py +0 -0
  95. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/core/pin_utils.py +0 -0
  96. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/discovery/__init__.py +0 -0
  97. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/discovery/search_index.py +0 -0
  98. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/geometry/__init__.py +0 -0
  99. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/geometry/font_metrics.py +0 -0
  100. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/geometry/symbol_bbox.py +0 -0
  101. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/interfaces/__init__.py +0 -0
  102. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/interfaces/parser.py +0 -0
  103. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/interfaces/repository.py +0 -0
  104. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/interfaces/resolver.py +0 -0
  105. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/library/__init__.py +0 -0
  106. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/library/cache.py +0 -0
  107. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/parsers/__init__.py +0 -0
  108. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/parsers/base.py +0 -0
  109. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/parsers/registry.py +0 -0
  110. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/py.typed +0 -0
  111. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/symbols/__init__.py +0 -0
  112. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/symbols/cache.py +0 -0
  113. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/symbols/resolver.py +0 -0
  114. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/symbols/validators.py +0 -0
  115. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/utils/__init__.py +0 -0
  116. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api/utils/validation.py +0 -0
  117. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api.egg-info/dependency_links.txt +0 -0
  118. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api.egg-info/entry_points.txt +0 -0
  119. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api.egg-info/requires.txt +0 -0
  120. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/kicad_sch_api.egg-info/top_level.txt +0 -0
  121. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/setup.cfg +0 -0
  122. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/README.md +0 -0
  123. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/blank_schematic/blank_schematic.kicad_pro +0 -0
  124. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/blank_schematic/blank_schematic.kicad_sch +0 -0
  125. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/multi_unit_7400/multi_unit_7400.kicad_pro +0 -0
  126. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/multi_unit_7400/multi_unit_7400.kicad_sch +0 -0
  127. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/power_symbols/power_symbols.kicad_pro +0 -0
  128. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/power_symbols/power_symbols.kicad_sch +0 -0
  129. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/resistor_divider/resistor_divider.kicad_pro +0 -0
  130. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/resistor_divider/resistor_divider.kicad_sch +0 -0
  131. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/sch_title/sch_title.kicad_pro +0 -0
  132. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/sch_title/sch_title.kicad_sch +0 -0
  133. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_extended_component/single_extended_component.kicad_pro +0 -0
  134. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_extended_component/single_extended_component.kicad_sch +0 -0
  135. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_hierarchical_sheet/single_hierarchical_sheet.kicad_pro +0 -0
  136. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_hierarchical_sheet/single_hierarchical_sheet.kicad_sch +0 -0
  137. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_hierarchical_sheet/subcircuit1.kicad_sch +0 -0
  138. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_label/single_label.kicad_pro +0 -0
  139. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_label/single_label.kicad_sch +0 -0
  140. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_label_hierarchical/single_label_hierarchical.kicad_pro +0 -0
  141. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_label_hierarchical/single_label_hierarchical.kicad_sch +0 -0
  142. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_resistor/single_resistor.kicad_pro +0 -0
  143. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_resistor/single_resistor.kicad_sch +0 -0
  144. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_text/single_text.kicad_pro +0 -0
  145. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_text/single_text.kicad_sch +0 -0
  146. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_text_box/single_text_box.kicad_pro +0 -0
  147. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_text_box/single_text_box.kicad_sch +0 -0
  148. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_wire/single_wire.kicad_pro +0 -0
  149. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/single_wire/single_wire.kicad_sch +0 -0
  150. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/two_resistors/two_resistors.kicad_pro +0 -0
  151. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/reference_tests/reference_kicad_projects/two_resistors/two_resistors.kicad_sch +0 -0
  152. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_bounding_box_rectangles.py +0 -0
  153. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_component_removal.py +0 -0
  154. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_element_removal.py +0 -0
  155. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_geometry.py +0 -0
  156. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_grid_snapping.py +0 -0
  157. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_image_support.py +0 -0
  158. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_issue_13_public_properties.py +0 -0
  159. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_kicad_validation.py +0 -0
  160. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_parse_reference_rectangles.py +0 -0
  161. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_pin_positioning.py +0 -0
  162. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_pin_to_pin_wiring.py +0 -0
  163. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_rectangle.py +0 -0
  164. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_rectangle_roundtrip.py +0 -0
  165. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_removal_against_references.py +0 -0
  166. {kicad_sch_api-0.4.0 → kicad_sch_api-0.4.2}/tests/test_wire_operations.py +0 -0
@@ -0,0 +1,711 @@
1
+ # PyPI Release Command - kicad-sch-api
2
+
3
+ ## Usage
4
+ ```bash
5
+ /publish-pypi <version> [--test-only] [--check-only]
6
+ ```
7
+
8
+ **⚠️ CRITICAL: Version number is MANDATORY - command will fail if not provided!**
9
+
10
+ ## Description
11
+ Complete PyPI release pipeline - from testing to tagging to publishing. This command handles version management, git operations, comprehensive testing, and PyPI publication.
12
+
13
+ ## Parameters
14
+ - `version` - **REQUIRED** Version number (e.g., "0.4.1", "1.0.0", "0.5.0-beta.1")
15
+ - `--test-only`: Publish to Test PyPI only (for validation)
16
+ - `--check-only`: Run all checks without publishing
17
+
18
+ ## What This Command Does
19
+
20
+ This command automates the complete release process:
21
+
22
+ ### 1. Pre-Release Validation
23
+ - **Check branch status** - Ensure we're on main branch
24
+ - **Validate version format** - Semantic versioning check
25
+ - **Check for uncommitted changes** - Ensure clean working directory
26
+ - **Sync with remote** - Fetch latest changes from origin
27
+ - **Version conflict check** - Ensure version doesn't already exist on PyPI or git tags
28
+
29
+ ### 2. Version Management
30
+ - **Update pyproject.toml** - Set new version number
31
+ - **Commit version changes** - Clean commit for version bump
32
+ - **Show version comparison** - Display current vs new version
33
+
34
+ ### 3. Testing and Validation
35
+ - **Run full test suite** - All tests must pass
36
+ - **Code quality checks** - Black, isort, mypy, flake8
37
+ - **Format preservation tests** - Critical for KiCAD compatibility
38
+ - **Build package** - Create wheel and sdist
39
+ - **Test installation** - Verify package installs correctly
40
+ - **Import validation** - Ensure package imports work
41
+
42
+ ### 4. Git Operations
43
+ - **Create release tag** - Tag commit with version number
44
+ - **Push release tag** - Push tag to origin
45
+ - **Create GitHub release** - Generate release notes and publish
46
+
47
+ ### 5. PyPI Publication
48
+ - **Build distributions** - Create wheel and sdist
49
+ - **Upload to PyPI** - Publish to registry
50
+ - **Verify upload** - Check package is available
51
+
52
+ ### 6. Post-Release Verification
53
+ - **Test installation from PyPI** - Verify package works
54
+ - **Display release summary** - Show URLs and next steps
55
+
56
+ ## Implementation
57
+
58
+ ```bash
59
+ #!/bin/bash
60
+ set -e # Exit on error
61
+
62
+ # CRITICAL: Always require version number as parameter
63
+ if [ -z "$1" ]; then
64
+ echo "❌ ERROR: Version number is required!"
65
+ echo "Usage: /publish-pypi <version> [--test-only] [--check-only]"
66
+ echo "Example: /publish-pypi 0.4.1"
67
+ echo "Example: /publish-pypi 0.5.0"
68
+ echo "Example: /publish-pypi 1.0.0-beta.1"
69
+ exit 1
70
+ fi
71
+
72
+ version="$1"
73
+ shift # Remove version from arguments
74
+
75
+ # Parse flags
76
+ TEST_ONLY=false
77
+ CHECK_ONLY=false
78
+
79
+ while [[ $# -gt 0 ]]; do
80
+ case $1 in
81
+ --test-only)
82
+ TEST_ONLY=true
83
+ shift
84
+ ;;
85
+ --check-only)
86
+ CHECK_ONLY=true
87
+ shift
88
+ ;;
89
+ *)
90
+ echo "Unknown option: $1"
91
+ exit 1
92
+ ;;
93
+ esac
94
+ done
95
+
96
+ echo "🎯 Starting release process for kicad-sch-api version: $version"
97
+ echo "================================================================"
98
+
99
+ # 1. Pre-flight checks and branch management
100
+ echo "🔍 Running pre-flight checks..."
101
+
102
+ # Fetch latest changes from remote
103
+ echo "🔄 Fetching latest changes from origin..."
104
+ git fetch origin
105
+
106
+ # Ensure clean working directory
107
+ if [ -n "$(git status --porcelain)" ]; then
108
+ echo "❌ Uncommitted changes found. Commit or stash first."
109
+ exit 1
110
+ fi
111
+
112
+ # Check current branch
113
+ current_branch=$(git branch --show-current)
114
+ if [[ "$current_branch" != "main" ]]; then
115
+ echo "⚠️ Warning: Not on main branch (currently on '$current_branch')"
116
+ read -p "Continue? (y/N): " -n 1 -r
117
+ echo ""
118
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
119
+ exit 1
120
+ fi
121
+ fi
122
+
123
+ # Validate version format (semantic versioning)
124
+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
125
+ echo "❌ Invalid version format. Use semantic versioning (e.g., 0.4.1, 1.0.0)"
126
+ echo "Provided: $version"
127
+ exit 1
128
+ fi
129
+
130
+ # Show current version for comparison
131
+ current_version=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
132
+ echo "📊 Current version: $current_version"
133
+ echo "📊 New version: $version"
134
+ echo ""
135
+ read -p "🤔 Confirm release version $version? (y/N): " -n 1 -r
136
+ echo ""
137
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
138
+ echo "❌ Release cancelled. Please specify the correct version."
139
+ exit 1
140
+ fi
141
+
142
+ # Check if version already exists on PyPI
143
+ echo "🔍 Checking if version already exists on PyPI..."
144
+ if pip index versions kicad-sch-api 2>/dev/null | grep -q "kicad-sch-api ($version)"; then
145
+ echo "❌ Version $version already exists on PyPI"
146
+ exit 1
147
+ fi
148
+
149
+ # Check if git tag already exists
150
+ if git rev-parse "v$version" >/dev/null 2>&1; then
151
+ echo "❌ Git tag v$version already exists"
152
+ exit 1
153
+ fi
154
+
155
+ # Ensure main is up-to-date with origin
156
+ echo "🔄 Ensuring main is up-to-date..."
157
+ git pull origin main || {
158
+ echo "❌ Failed to pull latest main"
159
+ exit 1
160
+ }
161
+
162
+ # Install build dependencies
163
+ echo "📥 Installing build dependencies..."
164
+ uv pip install build twine --quiet
165
+
166
+ # 2. Version update
167
+ echo "📝 Updating version to $version..."
168
+
169
+ # Update pyproject.toml
170
+ sed -i.bak "s/^version = .*/version = \"$version\"/" pyproject.toml
171
+ rm -f pyproject.toml.bak
172
+
173
+ # Check if changes were made
174
+ if ! git diff --quiet pyproject.toml; then
175
+ git add pyproject.toml
176
+ git commit -m "🔖 Bump version to $version"
177
+ echo "✅ Version updated and committed"
178
+ else
179
+ echo "ℹ️ Version already up to date"
180
+ fi
181
+
182
+ # 3. Code quality checks
183
+ echo "🎨 Checking code quality..."
184
+
185
+ # Format check
186
+ echo " - Checking code formatting..."
187
+ if ! uv run black --check kicad_sch_api/ tests/ --quiet 2>/dev/null; then
188
+ echo "❌ Code not formatted. Run: uv run black kicad_sch_api/ tests/"
189
+ exit 1
190
+ fi
191
+
192
+ # Import sort check
193
+ echo " - Checking import sorting..."
194
+ if ! uv run isort --check-only kicad_sch_api/ tests/ --quiet 2>/dev/null; then
195
+ echo "❌ Imports not sorted. Run: uv run isort kicad_sch_api/ tests/"
196
+ exit 1
197
+ fi
198
+
199
+ # Type checking
200
+ echo " - Running type checks..."
201
+ uv run mypy kicad_sch_api/ --ignore-missing-imports --quiet 2>/dev/null || {
202
+ echo "⚠️ Type checking issues found (non-blocking)"
203
+ }
204
+
205
+ echo "✅ Code quality checks passed"
206
+
207
+ # 4. Comprehensive testing
208
+ echo "🧪 Running comprehensive test suite..."
209
+
210
+ # Core tests - format preservation is critical for KiCAD compatibility
211
+ echo " - Running unit tests..."
212
+ if ! uv run pytest tests/ -v --tb=short -q; then
213
+ echo "❌ Tests failed"
214
+ exit 1
215
+ fi
216
+
217
+ # Format preservation tests (CRITICAL for KiCAD compatibility)
218
+ echo " - Running format preservation tests..."
219
+ if ! uv run pytest tests/reference_tests/ -v --tb=short -q 2>/dev/null; then
220
+ echo "⚠️ Format preservation tests not found or failed"
221
+ fi
222
+
223
+ # Import validation
224
+ echo " - Testing imports..."
225
+ if ! uv run python -c "import kicad_sch_api; print('✅ Import successful')" 2>/dev/null; then
226
+ echo "❌ Import test failed"
227
+ exit 1
228
+ fi
229
+
230
+ echo "✅ All tests passed"
231
+
232
+ # 5. Build package
233
+ echo "🏗️ Building package..."
234
+
235
+ # Clean previous builds
236
+ rm -rf build/ dist/ *.egg-info/ kicad_sch_api.egg-info/
237
+
238
+ # Build
239
+ if ! python -m build; then
240
+ echo "❌ Package build failed"
241
+ exit 1
242
+ fi
243
+
244
+ echo "✅ Package built successfully"
245
+
246
+ # 6. Package validation
247
+ echo "📋 Validating package..."
248
+
249
+ # Check package integrity
250
+ if ! twine check dist/*; then
251
+ echo "❌ Package validation failed"
252
+ exit 1
253
+ fi
254
+
255
+ # Test installation in clean environment
256
+ echo "🧪 Testing package installation in isolated environment..."
257
+ TEMP_VENV=$(mktemp -d)
258
+ python -m venv "$TEMP_VENV"
259
+ source "$TEMP_VENV/bin/activate"
260
+
261
+ if ! pip install dist/*.whl --quiet; then
262
+ echo "❌ Package installation failed"
263
+ deactivate
264
+ rm -rf "$TEMP_VENV"
265
+ exit 1
266
+ fi
267
+
268
+ if ! python -c "import kicad_sch_api; print('✅ Package import successful')"; then
269
+ echo "❌ Package import failed"
270
+ deactivate
271
+ rm -rf "$TEMP_VENV"
272
+ exit 1
273
+ fi
274
+
275
+ deactivate
276
+ rm -rf "$TEMP_VENV"
277
+
278
+ echo "✅ Package validation complete"
279
+
280
+ # 7. Exit if check-only
281
+ if [[ "$CHECK_ONLY" == "true" ]]; then
282
+ echo ""
283
+ echo "================================================"
284
+ echo "✅ All pre-publication checks passed"
285
+ echo "================================================"
286
+ echo "📦 Package ready for publication"
287
+ echo "📊 Version: $version"
288
+ echo "🏷️ Next step: Run without --check-only to publish"
289
+ exit 0
290
+ fi
291
+
292
+ # 8. Git tagging and GitHub release
293
+ echo "🏷️ Creating git tag and GitHub release..."
294
+
295
+ # Verify we're on main branch for tagging
296
+ current_branch_for_tag=$(git branch --show-current)
297
+ if [[ "$current_branch_for_tag" != "main" ]]; then
298
+ echo "❌ Must be on main branch for release tagging"
299
+ echo "💡 Switch to main branch and re-run this command"
300
+ exit 1
301
+ fi
302
+
303
+ # Generate release notes from commits since last tag
304
+ last_tag=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
305
+ if [ -n "$last_tag" ]; then
306
+ echo "📋 Generating release notes since $last_tag..."
307
+ release_notes=$(git log --pretty=format:"- %s (%h)" "$last_tag"..HEAD)
308
+ else
309
+ echo "📋 Generating release notes for initial release..."
310
+ release_notes=$(git log --pretty=format:"- %s (%h)" --max-count=10)
311
+ fi
312
+
313
+ # Create git tag
314
+ echo "🏷️ Creating git tag v$version..."
315
+ git tag -a "v$version" -m "🚀 Release version $version
316
+
317
+ Features and changes in this release:
318
+ $release_notes
319
+
320
+ Full changelog: https://github.com/circuit-synth/kicad-sch-api/compare/${last_tag}...v$version"
321
+
322
+ # Push tag to origin
323
+ echo "📤 Pushing release tag to origin..."
324
+ git push origin "v$version" || {
325
+ echo "❌ Failed to push release tag"
326
+ exit 1
327
+ }
328
+
329
+ echo "✅ Tagged and pushed v$version"
330
+
331
+ # Create GitHub release using gh CLI
332
+ if command -v gh >/dev/null 2>&1; then
333
+ echo "📝 Creating GitHub release..."
334
+
335
+ gh release create "v$version" \
336
+ --title "🚀 Release v$version" \
337
+ --notes "## What's Changed
338
+
339
+ $release_notes
340
+
341
+ ## Installation
342
+
343
+ \`\`\`bash
344
+ pip install kicad-sch-api==$version
345
+ # or
346
+ uv add kicad-sch-api==$version
347
+ \`\`\`
348
+
349
+ ## PyPI Package
350
+ 📦 https://pypi.org/project/kicad-sch-api/$version/
351
+
352
+ **Full Changelog**: https://github.com/circuit-synth/kicad-sch-api/compare/${last_tag}...v$version" \
353
+ --latest || {
354
+ echo "⚠️ GitHub release creation failed (continuing with PyPI release)"
355
+ }
356
+
357
+ echo "✅ GitHub release created"
358
+ else
359
+ echo "⚠️ GitHub CLI (gh) not found - skipping GitHub release creation"
360
+ echo "💡 Install with: brew install gh"
361
+ echo "📝 Manual release notes:"
362
+ echo "$release_notes"
363
+ fi
364
+
365
+ # 9. Publish to PyPI
366
+ echo ""
367
+ echo "🚀 Publishing to PyPI..."
368
+
369
+ if [[ "$TEST_ONLY" == "true" ]]; then
370
+ # Publish to Test PyPI
371
+ echo "📡 Publishing to Test PyPI..."
372
+
373
+ # Use environment variable or .pypirc
374
+ if [[ -n "$TEST_PYPI_API_TOKEN" ]]; then
375
+ twine upload --repository testpypi dist/* --username __token__ --password "$TEST_PYPI_API_TOKEN"
376
+ else
377
+ echo "ℹ️ Using .pypirc credentials for Test PyPI..."
378
+ twine upload --repository testpypi dist/*
379
+ fi
380
+
381
+ if [[ $? -eq 0 ]]; then
382
+ echo "✅ Successfully published to Test PyPI"
383
+ echo "🔗 View at: https://test.pypi.org/project/kicad-sch-api/"
384
+ echo "📥 Test install: pip install --index-url https://test.pypi.org/simple/ kicad-sch-api"
385
+ else
386
+ echo "❌ Test PyPI publication failed"
387
+ exit 1
388
+ fi
389
+
390
+ else
391
+ # Publish to production PyPI
392
+ echo "📡 Publishing to Production PyPI..."
393
+
394
+ # Final confirmation
395
+ echo ""
396
+ echo "⚠️ WARNING: Publishing to PRODUCTION PyPI"
397
+ echo "This action cannot be undone for this version."
398
+ echo "Version: $version"
399
+ read -p "Continue? (y/N): " -n 1 -r confirm
400
+ echo ""
401
+
402
+ if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
403
+ echo "❌ Publication cancelled"
404
+ # Clean up git tag since we're not publishing
405
+ git tag -d "v$version" 2>/dev/null
406
+ git push origin ":refs/tags/v$version" 2>/dev/null
407
+ exit 1
408
+ fi
409
+
410
+ # Use environment variable or .pypirc
411
+ if [[ -n "$PYPI_API_TOKEN" ]]; then
412
+ twine upload dist/* --username __token__ --password "$PYPI_API_TOKEN"
413
+ else
414
+ echo "ℹ️ Using .pypirc credentials for PyPI..."
415
+ twine upload dist/*
416
+ fi
417
+
418
+ if [[ $? -eq 0 ]]; then
419
+ echo ""
420
+ echo "🎉 Successfully published to PyPI!"
421
+ echo "🔗 View at: https://pypi.org/project/kicad-sch-api/$version/"
422
+ echo "📥 Install: pip install kicad-sch-api==$version"
423
+ else
424
+ echo "❌ PyPI publication failed"
425
+ exit 1
426
+ fi
427
+ fi
428
+
429
+ # 10. Post-release verification
430
+ echo ""
431
+ echo "⏳ Waiting for PyPI propagation (30 seconds)..."
432
+ sleep 30
433
+
434
+ # Verify package is available on PyPI
435
+ echo "🔍 Verifying package on PyPI..."
436
+ package_info=$(pip index versions kicad-sch-api 2>/dev/null || echo "not found")
437
+ if [[ "$package_info" == *"$version"* ]]; then
438
+ echo "✅ Package verified on PyPI"
439
+ else
440
+ echo "⚠️ Package not yet visible on PyPI (may take a few minutes)"
441
+ fi
442
+
443
+ # Test installation from PyPI in clean environment (production only)
444
+ if [[ "$TEST_ONLY" == "false" ]]; then
445
+ echo "🧪 Testing installation from PyPI..."
446
+ temp_dir=$(mktemp -d)
447
+ cd "$temp_dir"
448
+ python -m venv test_env
449
+ source test_env/bin/activate
450
+
451
+ pip install kicad-sch-api==$version --quiet && \
452
+ python -c "import kicad_sch_api; print(f'✅ Installed version: {kicad_sch_api.__version__ if hasattr(kicad_sch_api, \"__version__\") else \"unknown\"}')" || \
453
+ echo "⚠️ Installation test from PyPI failed (package may still be propagating)"
454
+
455
+ deactivate
456
+ cd - >/dev/null
457
+ rm -rf "$temp_dir"
458
+ fi
459
+
460
+ # Final summary
461
+ echo ""
462
+ echo "================================================================"
463
+ echo "🎉 Release v$version Complete!"
464
+ echo "================================================================"
465
+ echo "📊 Release Summary:"
466
+ echo " 📦 PyPI: https://pypi.org/project/kicad-sch-api/$version/"
467
+ echo " 🏷️ Git Tag: v$version"
468
+ echo " 📋 GitHub: https://github.com/circuit-synth/kicad-sch-api/releases/tag/v$version"
469
+ echo ""
470
+ echo "✅ Publication process completed successfully"
471
+ ```
472
+
473
+ ## Usage Examples
474
+
475
+ ### Recommended Workflow
476
+
477
+ ```bash
478
+ # 1. First, check that everything is ready (dry run)
479
+ /publish-pypi 0.4.1 --check-only
480
+
481
+ # 2. Test on Test PyPI first (HIGHLY RECOMMENDED)
482
+ /publish-pypi 0.4.1 --test-only
483
+
484
+ # 3. Verify Test PyPI installation works
485
+ pip install --index-url https://test.pypi.org/simple/ kicad-sch-api==0.4.1
486
+
487
+ # 4. If everything looks good, publish to production PyPI
488
+ /publish-pypi 0.4.1
489
+ ```
490
+
491
+ ### Other Examples
492
+
493
+ ```bash
494
+ # Release a patch version
495
+ /publish-pypi 0.4.1
496
+
497
+ # Release a minor version
498
+ /publish-pypi 0.5.0
499
+
500
+ # Release a major version
501
+ /publish-pypi 1.0.0
502
+
503
+ # Release a beta version
504
+ /publish-pypi 1.0.0-beta.1
505
+
506
+ # Release a release candidate
507
+ /publish-pypi 1.0.0-rc.1
508
+ ```
509
+
510
+ ## Authentication Methods
511
+
512
+ ### Method 1: Environment Variables (Recommended for CI)
513
+
514
+ #### For Test PyPI
515
+ ```bash
516
+ export TEST_PYPI_API_TOKEN=pypi-your_test_token_here
517
+ ```
518
+
519
+ #### For Production PyPI
520
+ ```bash
521
+ export PYPI_API_TOKEN=pypi-your_production_token_here
522
+ ```
523
+
524
+ ### Method 2: .pypirc File (Recommended for Local Development)
525
+
526
+ Create `~/.pypirc` with your API tokens:
527
+
528
+ ```ini
529
+ [distutils]
530
+ index-servers =
531
+ pypi
532
+ testpypi
533
+
534
+ [pypi]
535
+ repository = https://upload.pypi.org/legacy/
536
+ username = __token__
537
+ password = pypi-your_production_token_here
538
+
539
+ [testpypi]
540
+ repository = https://test.pypi.org/legacy/
541
+ username = __token__
542
+ password = pypi-your_test_token_here
543
+ ```
544
+
545
+ **Using .pypirc:**
546
+ ```bash
547
+ # Publish to Test PyPI using .pypirc
548
+ twine upload --repository testpypi dist/*
549
+
550
+ # Publish to Production PyPI using .pypirc
551
+ twine upload --repository pypi dist/*
552
+
553
+ # Or use the default (production PyPI)
554
+ twine upload dist/*
555
+ ```
556
+
557
+ **Security Notes:**
558
+ - Set proper file permissions: `chmod 600 ~/.pypirc`
559
+ - Never commit `.pypirc` to version control
560
+ - Environment variables take precedence over `.pypirc`
561
+ - Use scoped API tokens (project-specific) instead of global tokens
562
+
563
+ ## Prerequisites
564
+
565
+ Before running this command, ensure you have:
566
+
567
+ 1. **PyPI account** with API token configured
568
+ 2. **Git credentials** set up for pushing
569
+ 3. **GitHub CLI (gh)** installed and authenticated (for GitHub releases)
570
+ 4. **Clean working directory** (no uncommitted changes)
571
+ 5. **Main branch** checked out (for production releases)
572
+
573
+ ### Setup GitHub CLI
574
+ ```bash
575
+ # Install GitHub CLI
576
+ brew install gh
577
+
578
+ # Authenticate with GitHub
579
+ gh auth login
580
+
581
+ # Verify authentication
582
+ gh auth status
583
+ ```
584
+
585
+ ## Version Numbering Strategy
586
+
587
+ This project follows **Semantic Versioning** (semver.org):
588
+
589
+ - **MAJOR.MINOR.PATCH** (e.g., 0.4.1)
590
+ - **MAJOR**: Breaking API changes
591
+ - **MINOR**: New features, backward compatible
592
+ - **PATCH**: Bug fixes, backward compatible
593
+
594
+ **For pre-1.0 versions (0.x.y):**
595
+ - Minor version bumps may include breaking changes
596
+ - Communicate clearly in release notes
597
+ - Move to v1.0.0 when API is stable
598
+
599
+ **Examples:**
600
+ - `0.4.0 → 0.4.1` - Bug fixes, small improvements
601
+ - `0.4.1 → 0.5.0` - New features (bus support, netlist generation)
602
+ - `0.5.0 → 1.0.0` - API stable, production ready
603
+
604
+ ## What Gets Released
605
+
606
+ The release process creates:
607
+ - **Python package** - Wheel and source distribution on PyPI
608
+ - **Git tag** - Version tag on main branch (e.g., `v0.4.1`)
609
+ - **GitHub release** - Auto-generated release notes
610
+ - **Documentation** - All examples and docs included in package
611
+
612
+ ## Safety Features
613
+
614
+ This enhanced command includes:
615
+
616
+ ✅ **Mandatory version parameter** - Prevents accidental releases
617
+ ✅ **Version conflict detection** - Checks PyPI and git tags
618
+ ✅ **Semantic versioning validation** - Ensures proper version format
619
+ ✅ **Clean working directory check** - No uncommitted changes
620
+ ✅ **Main branch enforcement** - Production releases only from main
621
+ ✅ **Comprehensive testing** - Unit tests, format preservation, imports
622
+ ✅ **Package validation** - Twine checks, installation tests
623
+ ✅ **Automatic git tagging** - Creates and pushes version tags
624
+ ✅ **GitHub release creation** - Auto-generated release notes
625
+ ✅ **Post-release verification** - Tests installation from PyPI
626
+
627
+ ## Troubleshooting
628
+
629
+ ### Common Issues
630
+
631
+ **Version already exists:**
632
+ ```bash
633
+ ❌ Version 0.4.1 already exists on PyPI
634
+ # Solution: Increment version number (you cannot overwrite PyPI versions)
635
+ /publish-pypi 0.4.2
636
+ ```
637
+
638
+ **Git tag already exists:**
639
+ ```bash
640
+ ❌ Git tag v0.4.1 already exists
641
+ # Solution: Delete tag or use new version
642
+ git tag -d v0.4.1 # Delete local tag
643
+ git push origin :refs/tags/v0.4.1 # Delete remote tag
644
+ ```
645
+
646
+ **Not on main branch:**
647
+ ```bash
648
+ ⚠️ Warning: Not on main branch (currently on 'develop')
649
+ # Solution: Switch to main or force continue
650
+ git checkout main
651
+ git pull origin main
652
+ ```
653
+
654
+ **Tests failing:**
655
+ ```bash
656
+ ❌ Tests failed
657
+ # Solution: Fix failing tests before publishing
658
+ uv run pytest tests/ -v
659
+ ```
660
+
661
+ **GitHub CLI not found:**
662
+ ```bash
663
+ ⚠️ GitHub CLI (gh) not found - skipping GitHub release creation
664
+ # Solution: Install gh (optional, not required for PyPI)
665
+ brew install gh
666
+ gh auth login
667
+ ```
668
+
669
+ ### Rollback Procedure
670
+
671
+ If something goes wrong after publishing:
672
+
673
+ ```bash
674
+ # 1. Yank the bad release from PyPI (prevents new installations)
675
+ pip install twine
676
+ twine yank kicad-sch-api --version BAD_VERSION
677
+
678
+ # 2. Delete the git tag (optional)
679
+ git tag -d vBAD_VERSION
680
+ git push origin :refs/tags/vBAD_VERSION
681
+
682
+ # 3. Delete the GitHub release (optional)
683
+ gh release delete vBAD_VERSION
684
+
685
+ # 4. Fix the issues and release a new patch version
686
+ /publish-pypi NEW_VERSION
687
+ ```
688
+
689
+ ## Comparison with Previous Version
690
+
691
+ ### Old Command (Issue #2-4)
692
+ ❌ No version parameter
693
+ ❌ No git tagging
694
+ ❌ No GitHub releases
695
+ ❌ No version conflict detection
696
+ ❌ Manual version management
697
+
698
+ ### Enhanced Command (This Version)
699
+ ✅ Mandatory version parameter
700
+ ✅ Automatic git tagging
701
+ ✅ GitHub release creation
702
+ ✅ Version conflict detection
703
+ ✅ Automatic version updates
704
+ ✅ Comprehensive validation
705
+ ✅ Post-release verification
706
+
707
+ This addresses **GitHub Issues #2, #3, and #4** by preventing version confusion and ensuring proper release workflow.
708
+
709
+ ---
710
+
711
+ **This command provides a complete, automated PyPI release pipeline with comprehensive validation and safety checks, ensuring every release is properly tagged, tested, and documented.**