fritzkit 0.0.0-stage → 0.1.0
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.
- package/.claude-plugin/marketplace.json +12 -0
- package/.claude-plugin/plugin.json +13 -0
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/README.md +429 -2
- package/dist/cli/commands/doctor.d.ts +4 -0
- package/dist/cli/commands/doctor.js +7 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export.d.ts +17 -0
- package/dist/cli/commands/export.js +81 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/kicad.d.ts +10 -0
- package/dist/cli/commands/kicad.js +22 -0
- package/dist/cli/commands/kicad.js.map +1 -0
- package/dist/cli/commands/parts.d.ts +22 -0
- package/dist/cli/commands/parts.js +46 -0
- package/dist/cli/commands/parts.js.map +1 -0
- package/dist/cli/commands/prune.d.ts +14 -0
- package/dist/cli/commands/prune.js +67 -0
- package/dist/cli/commands/prune.js.map +1 -0
- package/dist/cli/commands/render.d.ts +24 -0
- package/dist/cli/commands/render.js +62 -0
- package/dist/cli/commands/render.js.map +1 -0
- package/dist/cli/commands/schema.d.ts +10 -0
- package/dist/cli/commands/schema.js +35 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/ui.d.ts +14 -0
- package/dist/cli/commands/ui.js +67 -0
- package/dist/cli/commands/ui.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +24 -0
- package/dist/cli/commands/validate.js +91 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/context.d.ts +81 -0
- package/dist/cli/context.js +139 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +21 -0
- package/dist/cli/program.js +158 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/raster.d.ts +4 -0
- package/dist/cli/raster.js +9 -0
- package/dist/cli/raster.js.map +1 -0
- package/dist/core/compile/breadboard-util.d.ts +12 -0
- package/dist/core/compile/breadboard-util.js +107 -0
- package/dist/core/compile/breadboard-util.js.map +1 -0
- package/dist/core/compile/breadboard.d.ts +60 -0
- package/dist/core/compile/breadboard.js +513 -0
- package/dist/core/compile/breadboard.js.map +1 -0
- package/dist/core/compile/fzp.d.ts +12 -0
- package/dist/core/compile/fzp.js +183 -0
- package/dist/core/compile/fzp.js.map +1 -0
- package/dist/core/compile/icon.d.ts +17 -0
- package/dist/core/compile/icon.js +27 -0
- package/dist/core/compile/icon.js.map +1 -0
- package/dist/core/compile/index.d.ts +4 -0
- package/dist/core/compile/index.js +62 -0
- package/dist/core/compile/index.js.map +1 -0
- package/dist/core/compile/pcb.d.ts +39 -0
- package/dist/core/compile/pcb.js +164 -0
- package/dist/core/compile/pcb.js.map +1 -0
- package/dist/core/compile/schematic.d.ts +69 -0
- package/dist/core/compile/schematic.js +240 -0
- package/dist/core/compile/schematic.js.map +1 -0
- package/dist/core/compile/style.d.ts +52 -0
- package/dist/core/compile/style.js +72 -0
- package/dist/core/compile/style.js.map +1 -0
- package/dist/core/compile/types.d.ts +50 -0
- package/dist/core/compile/types.js +15 -0
- package/dist/core/compile/types.js.map +1 -0
- package/dist/core/export/bin.d.ts +61 -0
- package/dist/core/export/bin.js +221 -0
- package/dist/core/export/bin.js.map +1 -0
- package/dist/core/export/fzpz.d.ts +37 -0
- package/dist/core/export/fzpz.js +121 -0
- package/dist/core/export/fzpz.js.map +1 -0
- package/dist/core/export/index.d.ts +5 -0
- package/dist/core/export/index.js +6 -0
- package/dist/core/export/index.js.map +1 -0
- package/dist/core/export/install.d.ts +77 -0
- package/dist/core/export/install.js +183 -0
- package/dist/core/export/install.js.map +1 -0
- package/dist/core/export/prune.d.ts +72 -0
- package/dist/core/export/prune.js +165 -0
- package/dist/core/export/prune.js.map +1 -0
- package/dist/core/fritzing.d.ts +22 -0
- package/dist/core/fritzing.js +77 -0
- package/dist/core/fritzing.js.map +1 -0
- package/dist/core/identity.d.ts +29 -0
- package/dist/core/identity.js +70 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/image/bbox.d.ts +27 -0
- package/dist/core/image/bbox.js +24 -0
- package/dist/core/image/bbox.js.map +1 -0
- package/dist/core/image/index.d.ts +8 -0
- package/dist/core/image/index.js +9 -0
- package/dist/core/image/index.js.map +1 -0
- package/dist/core/image/key.d.ts +72 -0
- package/dist/core/image/key.js +317 -0
- package/dist/core/image/key.js.map +1 -0
- package/dist/core/image/prepare.d.ts +31 -0
- package/dist/core/image/prepare.js +98 -0
- package/dist/core/image/prepare.js.map +1 -0
- package/dist/core/image/remover.d.ts +17 -0
- package/dist/core/image/remover.js +51 -0
- package/dist/core/image/remover.js.map +1 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/index.js +17 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/kicad/footprint.d.ts +104 -0
- package/dist/core/kicad/footprint.js +317 -0
- package/dist/core/kicad/footprint.js.map +1 -0
- package/dist/core/kicad/index.d.ts +25 -0
- package/dist/core/kicad/index.js +197 -0
- package/dist/core/kicad/index.js.map +1 -0
- package/dist/core/kicad/sexpr.d.ts +35 -0
- package/dist/core/kicad/sexpr.js +163 -0
- package/dist/core/kicad/sexpr.js.map +1 -0
- package/dist/core/resolve.d.ts +113 -0
- package/dist/core/resolve.js +301 -0
- package/dist/core/resolve.js.map +1 -0
- package/dist/core/schema/part.d.ts +995 -0
- package/dist/core/schema/part.js +278 -0
- package/dist/core/schema/part.js.map +1 -0
- package/dist/core/schema/part.schema.json +1122 -0
- package/dist/core/svg.d.ts +20 -0
- package/dist/core/svg.js +56 -0
- package/dist/core/svg.js.map +1 -0
- package/dist/core/units.d.ts +28 -0
- package/dist/core/units.js +42 -0
- package/dist/core/units.js.map +1 -0
- package/dist/core/validate/checker.d.ts +46 -0
- package/dist/core/validate/checker.js +142 -0
- package/dist/core/validate/checker.js.map +1 -0
- package/dist/core/validate/doctor.d.ts +25 -0
- package/dist/core/validate/doctor.js +156 -0
- package/dist/core/validate/doctor.js.map +1 -0
- package/dist/core/validate/explain.d.ts +10 -0
- package/dist/core/validate/explain.js +135 -0
- package/dist/core/validate/explain.js.map +1 -0
- package/dist/core/validate/index.d.ts +21 -0
- package/dist/core/validate/index.js +96 -0
- package/dist/core/validate/index.js.map +1 -0
- package/dist/core/validate/structural.d.ts +74 -0
- package/dist/core/validate/structural.js +664 -0
- package/dist/core/validate/structural.js.map +1 -0
- package/dist/core/workspace.d.ts +69 -0
- package/dist/core/workspace.js +213 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/mcp/jsonpatch.d.ts +30 -0
- package/dist/mcp/jsonpatch.js +145 -0
- package/dist/mcp/jsonpatch.js.map +1 -0
- package/dist/mcp/main.d.ts +2 -0
- package/dist/mcp/main.js +5 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.d.ts +28 -0
- package/dist/mcp/server.js +310 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/server/api.d.ts +72 -0
- package/dist/server/api.js +507 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/events.d.ts +28 -0
- package/dist/server/events.js +134 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/http.d.ts +36 -0
- package/dist/server/http.js +127 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/index.d.ts +65 -0
- package/dist/server/index.js +193 -0
- package/dist/server/index.js.map +1 -0
- package/dist/ui/assets/index-DLU8opyI.js +63 -0
- package/dist/ui/assets/index-GhUA-T3b.css +1 -0
- package/dist/ui/index.html +14 -0
- package/package.json +89 -4
- package/skills/fritzkit/SKILL.md +690 -0
- package/skills/fritzkit/reference/examples.md +275 -0
- package/skills/fritzkit/reference/part-json.md +333 -0
- package/skills/fritzkit/scripts/measure.py +197 -0
- package/tools/fzp-checker/.python-version +1 -0
- package/tools/fzp-checker/README.md +45 -0
- package/tools/fzp-checker/check_fzp.py +48 -0
- package/tools/fzp-checker/pyproject.toml +26 -0
- package/tools/fzp-checker/uv.lock +266 -0
- package/tools/fzp-checker/vendor/LICENSE.txt +8 -0
- package/tools/fzp-checker/vendor/UPSTREAM.md +25 -0
- package/tools/fzp-checker/vendor/fzp_checker.py +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/__init__.py +26 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/check_missing_leg_ids.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/connector_numbering.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_checker_runner.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_checkers.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_svg_checkers.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/fzp_utils.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/svg_checkers.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/__pycache__/svg_utils.cpython-313.pyc +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/check_missing_leg_ids.py +44 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkascii.py +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkcase.py +156 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkcopies.py +104 -0
- package/tools/fzp-checker/vendor/scripts/checks/connector_numbering.py +79 -0
- package/tools/fzp-checker/vendor/scripts/checks/connectors_misnumbered.py +228 -0
- package/tools/fzp-checker/vendor/scripts/checks/explain_errors.md +95 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_checker_runner.py +717 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_checkers.py +1069 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_svg_checkers.py +62 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_utils.py +222 -0
- package/tools/fzp-checker/vendor/scripts/checks/inspector_fc51.png +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/invisibleconnectors.py +118 -0
- package/tools/fzp-checker/vendor/scripts/checks/nolayeridcheck.txt +758 -0
- package/tools/fzp-checker/vendor/scripts/checks/requirements.txt +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/svg_checkers.py +953 -0
- package/tools/fzp-checker/vendor/scripts/checks/svg_utils.py +96 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_checkers.py +839 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_id.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_node_members.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_present_valid.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_missing_attributes.fzp.test +16 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_present_valid.fzp.test +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_invalid.fzp.test +70 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_valid.fzp.test +70 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_refs_valid.fzp.test +53 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_mixed.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_silkscreen_nested.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_style_attr.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_white_stroke.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_wrong_color.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_inherited.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_legacy.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_nested_copper.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_none.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_standard.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_uppercase.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/css_connector.fzp.test +100 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/duplicate_ids.fzp.test +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_missing.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_present_valid.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/font_size.fzp.test +46 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_invalid_format.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_missing.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_present_valid.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_absent.fzp.test +15 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_present.fzp.test +15 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/hybrid_connectors.fzp.test +232 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/invalid_xml.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_match.fzp.test +29 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_mismatch.fzp.test +30 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_invalid.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_valid.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/matrix_transform.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_connector_refs.fzp.test +63 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_leg_ids.fzp.test +34 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_missing.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_non_alnum.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_absent.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_too_short.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_invalid.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_namedview.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_valid.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/pcb_only.fzp.test +48 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_name.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_value.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_present.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_present.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/stroke_test.fzp.test +60 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/template_svgs.fzp.test +35 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_ids.fzp.test +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_duplicates.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_unique.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/valid_xml.fzp.test +249 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_invalid_format.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_present_valid.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_present.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/connector_refs_valid_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/duplicate_ids_breadboard.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_absent_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_present_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/hybrid_connectors_breadboard.svg +102 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_invalid.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_valid.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/matrix_transform.svg +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_connector_refs_breadboard.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_leg_ids_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_match_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_mismatch_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/unique_ids_breadboard.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/hybrid_connectors_icon.svg +78 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_invalid.svg +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_namedview.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_valid.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/plain_pcb.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/connector_refs_valid_pcb.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_mixed.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_silkscreen_nested.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_style_attr.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_white_stroke.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_wrong_color.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_inherited.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_legacy.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_nested_copper.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_none.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_standard.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_uppercase.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/css_connector.svg +25 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/font_size.svg +54 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/hybrid_connectors_pcb.svg +35 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/missing_connector_refs_pcb.svg +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/pcb-arduino-shield.svg +25 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/stroke_test.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_match_pcb.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_mismatch_pcb.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/connector_refs_valid_schematic.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/hybrid_connectors_schematic.svg +59 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/missing_connector_refs_schematic.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_match_schematic.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_mismatch_schematic.svg +6 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared plumbing for the CLI verbs and the MCP tools: the injectable context, error
|
|
3
|
+
* classes with exit codes, error formatting, Fritzing path overrides and the
|
|
4
|
+
* <part> argument resolver (slug, part folder or .fzpz).
|
|
5
|
+
*
|
|
6
|
+
* Command code never writes to process.stdout directly: everything goes through the
|
|
7
|
+
* returned CommandResult (or ctx.out), so the MCP server's stdout stays pure JSON-RPC.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
10
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
11
|
+
import { FritzingRunningError } from "../core/export/install.js";
|
|
12
|
+
import { fritzingPaths, isFritzingRunning } from "../core/fritzing.js";
|
|
13
|
+
import { SLUG_RE } from "../core/schema/part.js";
|
|
14
|
+
import { listParts, PART_FILE, PartJsonError, resolveWorkspace } from "../core/workspace.js";
|
|
15
|
+
export const EXIT_OK = 0;
|
|
16
|
+
export const EXIT_ERROR = 1;
|
|
17
|
+
export const EXIT_NOT_IMPLEMENTED = 2;
|
|
18
|
+
export const EXIT_FRITZING_RUNNING = 3;
|
|
19
|
+
export const SCHEMA_HINT = "run `fritzkit schema` for the format";
|
|
20
|
+
export class CliError extends Error {
|
|
21
|
+
exitCode;
|
|
22
|
+
constructor(message, exitCode = EXIT_ERROR) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.exitCode = exitCode;
|
|
25
|
+
this.name = "CliError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class NotImplementedError extends CliError {
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message, EXIT_NOT_IMPLEMENTED);
|
|
31
|
+
this.name = "NotImplementedError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Duck-typed ZodError check (works across zod copies). */
|
|
35
|
+
export function isZodError(e) {
|
|
36
|
+
return (e instanceof Error &&
|
|
37
|
+
e.name === "ZodError" &&
|
|
38
|
+
Array.isArray(e.issues));
|
|
39
|
+
}
|
|
40
|
+
/** One line per zod issue (" path: message") plus the schema hint. */
|
|
41
|
+
export function formatZodIssues(issues) {
|
|
42
|
+
const lines = issues.map((i) => {
|
|
43
|
+
const path = i.path.map(String).join(".");
|
|
44
|
+
return ` ${path || "(root)"}: ${i.message}`;
|
|
45
|
+
});
|
|
46
|
+
return ["part.json does not match the fritzkit part schema:", ...lines, SCHEMA_HINT].join("\n");
|
|
47
|
+
}
|
|
48
|
+
/** Map any thrown value to an exit code and a human message. */
|
|
49
|
+
export function describeError(e) {
|
|
50
|
+
if (e instanceof CliError)
|
|
51
|
+
return { exitCode: e.exitCode, message: e.message };
|
|
52
|
+
if (e instanceof FritzingRunningError) {
|
|
53
|
+
return { exitCode: EXIT_FRITZING_RUNNING, message: fritzingRunningMessage() };
|
|
54
|
+
}
|
|
55
|
+
if (isZodError(e))
|
|
56
|
+
return { exitCode: EXIT_ERROR, message: formatZodIssues(e.issues) };
|
|
57
|
+
if (e instanceof PartJsonError)
|
|
58
|
+
return { exitCode: EXIT_ERROR, message: e.message };
|
|
59
|
+
if (e instanceof Error)
|
|
60
|
+
return { exitCode: EXIT_ERROR, message: e.message };
|
|
61
|
+
return { exitCode: EXIT_ERROR, message: String(e) };
|
|
62
|
+
}
|
|
63
|
+
export function fritzingRunningMessage(action = "install") {
|
|
64
|
+
return (`Fritzing is running, so fritzkit will not ${action}. Fritzing scans its user parts ` +
|
|
65
|
+
`folder only at startup and would not see the change until it restarts. Close ` +
|
|
66
|
+
`Fritzing (File > Quit) and run the command again.`);
|
|
67
|
+
}
|
|
68
|
+
export function cwdOf(ctx) {
|
|
69
|
+
return ctx.cwd ?? process.cwd();
|
|
70
|
+
}
|
|
71
|
+
export function workspaceOf(ctx) {
|
|
72
|
+
return resolveWorkspace(ctx.workspace === undefined ? undefined : resolve(cwdOf(ctx), ctx.workspace), ctx.env);
|
|
73
|
+
}
|
|
74
|
+
export function isRunningOf(ctx) {
|
|
75
|
+
return ctx.isRunning ?? isFritzingRunning;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* fritzingPaths(env) with test/CI overrides: FRITZKIT_FRITZING_USER_PARTS replaces the
|
|
79
|
+
* user parts folder, FRITZKIT_FRITZING_BINS the bins folder (my_parts.fzb inside it).
|
|
80
|
+
*/
|
|
81
|
+
export function fritzingPathsFor(env) {
|
|
82
|
+
const base = fritzingPaths(env);
|
|
83
|
+
const userPartsDir = env.FRITZKIT_FRITZING_USER_PARTS
|
|
84
|
+
? resolve(env.FRITZKIT_FRITZING_USER_PARTS)
|
|
85
|
+
: base.userPartsDir;
|
|
86
|
+
const binsDir = env.FRITZKIT_FRITZING_BINS ? resolve(env.FRITZKIT_FRITZING_BINS) : base.binsDir;
|
|
87
|
+
return { ...base, userPartsDir, binsDir, myPartsBin: join(binsDir, "my_parts.fzb") };
|
|
88
|
+
}
|
|
89
|
+
/** "Unknown part" error that lists what the workspace holds. */
|
|
90
|
+
export async function unknownPart(part, workspace) {
|
|
91
|
+
const parts = await listParts(workspace);
|
|
92
|
+
const have = parts.length > 0
|
|
93
|
+
? `Parts in ${workspace}: ${parts.map((p) => p.slug).join(", ")}`
|
|
94
|
+
: `The workspace ${workspace} has no parts yet; create one with: fritzkit new <slug>`;
|
|
95
|
+
return new CliError(`unknown part "${part}". ${have}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve a <part> argument: a slug in the workspace, a part folder (or its part.json),
|
|
99
|
+
* or a .fzpz file. Slugs win over same-named folders in the current directory.
|
|
100
|
+
*/
|
|
101
|
+
export async function resolveTarget(part, ctx) {
|
|
102
|
+
const workspace = workspaceOf(ctx);
|
|
103
|
+
if (SLUG_RE.test(part) && existsSync(join(workspace, part, PART_FILE))) {
|
|
104
|
+
return { kind: "dir", dir: join(workspace, part), slug: part };
|
|
105
|
+
}
|
|
106
|
+
const abs = resolve(cwdOf(ctx), part);
|
|
107
|
+
if (existsSync(abs)) {
|
|
108
|
+
const st = statSync(abs);
|
|
109
|
+
if (st.isFile() && /\.fzpz$/i.test(abs))
|
|
110
|
+
return { kind: "fzpz", path: abs, dir: dirname(abs) };
|
|
111
|
+
if (st.isFile() && basename(abs) === PART_FILE) {
|
|
112
|
+
return { kind: "dir", dir: dirname(abs), slug: basename(dirname(abs)) };
|
|
113
|
+
}
|
|
114
|
+
if (st.isDirectory() && existsSync(join(abs, PART_FILE))) {
|
|
115
|
+
return { kind: "dir", dir: abs, slug: basename(abs) };
|
|
116
|
+
}
|
|
117
|
+
if (st.isDirectory())
|
|
118
|
+
throw new CliError(`${abs} is a folder without a ${PART_FILE}`);
|
|
119
|
+
throw new CliError(`${abs} is neither a part folder, a ${PART_FILE} nor a .fzpz`);
|
|
120
|
+
}
|
|
121
|
+
if (/\.fzpz$/i.test(part))
|
|
122
|
+
throw new CliError(`no such file: ${abs}`);
|
|
123
|
+
throw await unknownPart(part, workspace);
|
|
124
|
+
}
|
|
125
|
+
/** Today's date (YYYY-MM-DD) unless the context fixes one. */
|
|
126
|
+
export function dateOf(ctx) {
|
|
127
|
+
return ctx.date ?? new Date().toISOString().slice(0, 10);
|
|
128
|
+
}
|
|
129
|
+
/** package.json version (same relative path from src/cli and dist/cli). */
|
|
130
|
+
export function cliVersion(url = new URL("../../package.json", import.meta.url)) {
|
|
131
|
+
try {
|
|
132
|
+
const pkg = JSON.parse(readFileSync(url, "utf8"));
|
|
133
|
+
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return "0.0.0";
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** fritzkit CLI entry point (package.json bin). All logic lives in program.ts. */
|
|
3
|
+
import { runCli } from "./program.js";
|
|
4
|
+
process.exitCode = await runCli(process.argv.slice(2), {
|
|
5
|
+
out: (s) => process.stdout.write(s),
|
|
6
|
+
err: (s) => process.stderr.write(s),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,kFAAkF;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACrD,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;CACpC,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The commander program behind `fritzkit`. buildProgram wires each verb to its handler in
|
|
3
|
+
* commands/*.ts; runCli parses argv, prints the result (text, or JSON with --json) and
|
|
4
|
+
* returns the exit code: 0 ok, 1 validation/usage error, 2 not implemented, 3 Fritzing
|
|
5
|
+
* running. Nothing here calls process.exit, so tests can drive it in-process.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import { type CommandContext } from "./context.js";
|
|
9
|
+
export interface CliIo {
|
|
10
|
+
/** stdout sink (receives whole chunks, newline included). */
|
|
11
|
+
out: (s: string) => void;
|
|
12
|
+
/** stderr sink. */
|
|
13
|
+
err: (s: string) => void;
|
|
14
|
+
}
|
|
15
|
+
/** Hook the `mcp` verb uses to start the stdio server (overridable in tests). */
|
|
16
|
+
export type McpStarter = (ctx: CommandContext) => Promise<void>;
|
|
17
|
+
export declare function buildProgram(io: CliIo, base: CommandContext, state: {
|
|
18
|
+
exitCode: number;
|
|
19
|
+
}, startMcp?: McpStarter): Command;
|
|
20
|
+
/** Parse user args (argv without node and the script) and run; resolves to the exit code. */
|
|
21
|
+
export declare function runCli(argv: string[], io: CliIo, base?: CommandContext, startMcp?: McpStarter): Promise<number>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The commander program behind `fritzkit`. buildProgram wires each verb to its handler in
|
|
3
|
+
* commands/*.ts; runCli parses argv, prints the result (text, or JSON with --json) and
|
|
4
|
+
* returns the exit code: 0 ok, 1 validation/usage error, 2 not implemented, 3 Fritzing
|
|
5
|
+
* running. Nothing here calls process.exit, so tests can drive it in-process.
|
|
6
|
+
*/
|
|
7
|
+
import { Command, CommanderError, Option } from "commander";
|
|
8
|
+
import { cliVersion, describeError, EXIT_ERROR, } from "./context.js";
|
|
9
|
+
import { doctorCommand } from "./commands/doctor.js";
|
|
10
|
+
import { exportCommand, installCommand } from "./commands/export.js";
|
|
11
|
+
import { importKicadCommand } from "./commands/kicad.js";
|
|
12
|
+
import { initCommand, listCommand, newCommand } from "./commands/parts.js";
|
|
13
|
+
import { pruneCommand } from "./commands/prune.js";
|
|
14
|
+
import { renderCommand } from "./commands/render.js";
|
|
15
|
+
import { schemaCommand } from "./commands/schema.js";
|
|
16
|
+
import { uiCommand } from "./commands/ui.js";
|
|
17
|
+
import { validateCommand } from "./commands/validate.js";
|
|
18
|
+
const defaultMcpStarter = async (ctx) => {
|
|
19
|
+
const { startStdioServer } = await import("../mcp/server.js");
|
|
20
|
+
await startStdioServer(ctx);
|
|
21
|
+
};
|
|
22
|
+
function wrap(data) {
|
|
23
|
+
return data !== null && typeof data === "object" && !Array.isArray(data)
|
|
24
|
+
? data
|
|
25
|
+
: { data };
|
|
26
|
+
}
|
|
27
|
+
export function buildProgram(io, base, state, startMcp = defaultMcpStarter) {
|
|
28
|
+
const program = new Command();
|
|
29
|
+
program
|
|
30
|
+
.name("fritzkit")
|
|
31
|
+
.description("Compile a JSON part spec (part.json) into a Fritzing part (.fzpz)")
|
|
32
|
+
.version(cliVersion(), "-V, --version")
|
|
33
|
+
.option("--workspace <dir>", "parts workspace (default: $FRITZKIT_WORKSPACE or ~/fritzkit/parts)")
|
|
34
|
+
.option("--json", "machine-readable JSON output")
|
|
35
|
+
.showHelpAfterError()
|
|
36
|
+
.exitOverride()
|
|
37
|
+
.configureOutput({ writeOut: io.out, writeErr: io.err });
|
|
38
|
+
// Every verb's action: build the context, run the handler, print, record the exit code.
|
|
39
|
+
const run = (fn) => async (...args) => {
|
|
40
|
+
const cmd = args[args.length - 1];
|
|
41
|
+
const g = cmd.optsWithGlobals();
|
|
42
|
+
const ctx = { ...base };
|
|
43
|
+
if (g.workspace !== undefined)
|
|
44
|
+
ctx.workspace = g.workspace;
|
|
45
|
+
try {
|
|
46
|
+
const r = await fn(ctx, ...args.slice(0, -1));
|
|
47
|
+
if (g.json) {
|
|
48
|
+
io.out(JSON.stringify({ exitCode: r.exitCode, ...wrap(r.data) }, null, 2) + "\n");
|
|
49
|
+
}
|
|
50
|
+
else if (r.text) {
|
|
51
|
+
io.out(r.text + "\n");
|
|
52
|
+
}
|
|
53
|
+
state.exitCode = r.exitCode;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
const { exitCode, message } = describeError(e);
|
|
57
|
+
if (g.json)
|
|
58
|
+
io.out(JSON.stringify({ exitCode, error: message }, null, 2) + "\n");
|
|
59
|
+
else
|
|
60
|
+
io.err(`${message.startsWith("fritzkit") ? "" : "fritzkit: "}${message}\n`);
|
|
61
|
+
state.exitCode = exitCode;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
program
|
|
65
|
+
.command("init")
|
|
66
|
+
.description("create the workspace folder and print its path")
|
|
67
|
+
.action(run((ctx) => initCommand(ctx)));
|
|
68
|
+
program
|
|
69
|
+
.command("new <slug>")
|
|
70
|
+
.description("create <workspace>/<slug>/part.json from the template")
|
|
71
|
+
.option("--title <title>", "part title (default: the slug)")
|
|
72
|
+
.action(run((ctx, slug, o) => newCommand(slug, o, ctx)));
|
|
73
|
+
program
|
|
74
|
+
.command("list")
|
|
75
|
+
.description("list the parts in the workspace")
|
|
76
|
+
.action(run((ctx) => listCommand(ctx)));
|
|
77
|
+
program
|
|
78
|
+
.command("validate <part>")
|
|
79
|
+
.description("check a part (slug, part folder or .fzpz): schema, compile, structure")
|
|
80
|
+
.option("--checker", "also run Fritzing's fzp checker (needs uv)")
|
|
81
|
+
.action(run((ctx, part, o) => validateCommand(part, o, ctx)));
|
|
82
|
+
program
|
|
83
|
+
.command("render <part>")
|
|
84
|
+
.description("write the view SVGs (default <partdir>/build/)")
|
|
85
|
+
.addOption(new Option("--view <view>", "view to render")
|
|
86
|
+
.choices(["breadboard", "schematic", "pcb", "icon", "all"])
|
|
87
|
+
.default("all"))
|
|
88
|
+
.option("--out <dir>", "output folder")
|
|
89
|
+
.option("--png", "also rasterise each SVG to PNG at 300 dpi")
|
|
90
|
+
.action(run((ctx, part, o) => renderCommand(part, o, ctx)));
|
|
91
|
+
program
|
|
92
|
+
.command("export <part>")
|
|
93
|
+
.description("compile and write <partdir>/<moduleId>.fzpz")
|
|
94
|
+
.option("--out <file>", "output .fzpz path")
|
|
95
|
+
.option("--install", "also install into Fritzing's user parts folder")
|
|
96
|
+
.option("--force", "export even when the validator reports errors")
|
|
97
|
+
.action(run((ctx, part, o) => exportCommand(part, o, ctx)));
|
|
98
|
+
program
|
|
99
|
+
.command("install <part>")
|
|
100
|
+
.description("export and install into Fritzing (same as export --install)")
|
|
101
|
+
.option("--out <file>", "output .fzpz path")
|
|
102
|
+
.option("--force", "install even when the validator reports errors")
|
|
103
|
+
.action(run((ctx, part, o) => installCommand(part, o, ctx)));
|
|
104
|
+
program
|
|
105
|
+
.command("prune <family-or-slug>")
|
|
106
|
+
.description("remove older installed versions of a part (dry run unless --yes)")
|
|
107
|
+
.option("--keep <moduleId>", "version to keep (default: the newest)")
|
|
108
|
+
.option("--yes", "actually delete")
|
|
109
|
+
.action(run((ctx, arg, o) => pruneCommand(arg, o, ctx)));
|
|
110
|
+
program
|
|
111
|
+
.command("doctor")
|
|
112
|
+
.description("check Node, Fritzing, uv, the fzp checker and sharp")
|
|
113
|
+
.action(run((ctx) => doctorCommand(ctx)));
|
|
114
|
+
program
|
|
115
|
+
.command("schema")
|
|
116
|
+
.description("print the part.json JSON Schema")
|
|
117
|
+
.option("--out <file>", "write it to a file instead")
|
|
118
|
+
.action(run((ctx, o) => schemaCommand(o, ctx)));
|
|
119
|
+
program
|
|
120
|
+
.command("import-kicad <file>")
|
|
121
|
+
.description("create a part folder from a KiCad .kicad_mod footprint")
|
|
122
|
+
.requiredOption("--slug <slug>", "slug of the new part")
|
|
123
|
+
.option("--title <title>", "part title (default: the footprint name)")
|
|
124
|
+
.action(run((ctx, file, o) => importKicadCommand(file, o, ctx)));
|
|
125
|
+
program
|
|
126
|
+
.command("mcp")
|
|
127
|
+
.description("start the fritzkit MCP server on stdio")
|
|
128
|
+
.action(async (_o, cmd) => {
|
|
129
|
+
const g = cmd.optsWithGlobals();
|
|
130
|
+
await startMcp(g.workspace !== undefined ? { ...base, workspace: g.workspace } : base);
|
|
131
|
+
});
|
|
132
|
+
program
|
|
133
|
+
.command("ui [part]")
|
|
134
|
+
.description("open the part editor in the browser (local server on 127.0.0.1)")
|
|
135
|
+
.option("--port <n>", "port to listen on (default 5173, or the next free one)")
|
|
136
|
+
.option("--no-open", "print the URL instead of opening the browser")
|
|
137
|
+
.action(run((ctx, part, o) => uiCommand(part, o, ctx)));
|
|
138
|
+
return program;
|
|
139
|
+
}
|
|
140
|
+
/** Parse user args (argv without node and the script) and run; resolves to the exit code. */
|
|
141
|
+
export async function runCli(argv, io, base = { env: process.env }, startMcp) {
|
|
142
|
+
const state = { exitCode: 0 };
|
|
143
|
+
const program = buildProgram(io, base, state, startMcp);
|
|
144
|
+
if (argv.length === 0) {
|
|
145
|
+
program.outputHelp();
|
|
146
|
+
return EXIT_ERROR;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
await program.parseAsync(argv, { from: "user" });
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
if (e instanceof CommanderError)
|
|
153
|
+
return e.exitCode === 0 ? 0 : EXIT_ERROR;
|
|
154
|
+
throw e;
|
|
155
|
+
}
|
|
156
|
+
return state.exitCode;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** SVG -> PNG with sharp (loaded lazily so verbs that never rasterise start fast). */
|
|
2
|
+
export declare const DEFAULT_DPI = 300;
|
|
3
|
+
/** Rasterise an SVG whose root width/height are in inches at `dpi` pixels per inch. */
|
|
4
|
+
export declare function svgToPng(svg: string, dpi?: number): Promise<Uint8Array>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** SVG -> PNG with sharp (loaded lazily so verbs that never rasterise start fast). */
|
|
2
|
+
export const DEFAULT_DPI = 300;
|
|
3
|
+
/** Rasterise an SVG whose root width/height are in inches at `dpi` pixels per inch. */
|
|
4
|
+
export async function svgToPng(svg, dpi = DEFAULT_DPI) {
|
|
5
|
+
const { default: sharp } = await import("sharp");
|
|
6
|
+
const buf = await sharp(Buffer.from(svg, "utf8"), { density: dpi }).png().toBuffer();
|
|
7
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=raster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster.js","sourceRoot":"","sources":["../../src/cli/raster.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAE/B,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,MAAc,WAAW;IACnE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACrF,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class PathParseError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Scale every length in an SVG path by `factor` (e.g. mm -> mil). Works for absolute
|
|
6
|
+
* and relative M/L/H/V/C/S/Q/T/A/Z commands, including implicit repetitions and the
|
|
7
|
+
* compact arc-flag form ("a1 1 0 01 5 5"). Arc rotation and flags are not scaled.
|
|
8
|
+
* Output is normalised: one command letter per segment, numbers formatted with fmt.
|
|
9
|
+
*/
|
|
10
|
+
export declare function scalePath(d: string, factor: number): string;
|
|
11
|
+
/** Darken a #RRGGBB colour by multiplying each channel by (1 - amount). */
|
|
12
|
+
export declare function darkenHex(hex: string, amount?: number): string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small pure helpers for the breadboard renderer: an SVG path number scaler (part
|
|
3
|
+
* outlines are written in mm, the SVG is in mil) and a hex colour darkener.
|
|
4
|
+
*/
|
|
5
|
+
import { fmt } from "../units.js";
|
|
6
|
+
/** Number of parameters each path command takes (per repetition). */
|
|
7
|
+
const PARAM_COUNT = {
|
|
8
|
+
m: 2,
|
|
9
|
+
l: 2,
|
|
10
|
+
h: 1,
|
|
11
|
+
v: 1,
|
|
12
|
+
c: 6,
|
|
13
|
+
s: 4,
|
|
14
|
+
q: 4,
|
|
15
|
+
t: 2,
|
|
16
|
+
a: 7,
|
|
17
|
+
z: 0,
|
|
18
|
+
};
|
|
19
|
+
const NUMBER_RE = /^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/;
|
|
20
|
+
export class PathParseError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "PathParseError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Scale every length in an SVG path by `factor` (e.g. mm -> mil). Works for absolute
|
|
28
|
+
* and relative M/L/H/V/C/S/Q/T/A/Z commands, including implicit repetitions and the
|
|
29
|
+
* compact arc-flag form ("a1 1 0 01 5 5"). Arc rotation and flags are not scaled.
|
|
30
|
+
* Output is normalised: one command letter per segment, numbers formatted with fmt.
|
|
31
|
+
*/
|
|
32
|
+
export function scalePath(d, factor) {
|
|
33
|
+
let i = 0;
|
|
34
|
+
const n = d.length;
|
|
35
|
+
const skipSep = () => {
|
|
36
|
+
while (i < n && /[\s,]/.test(d[i]))
|
|
37
|
+
i++;
|
|
38
|
+
};
|
|
39
|
+
const readNumber = () => {
|
|
40
|
+
skipSep();
|
|
41
|
+
const m = NUMBER_RE.exec(d.slice(i));
|
|
42
|
+
if (!m)
|
|
43
|
+
throw new PathParseError(`expected a number at offset ${i} in path "${d}"`);
|
|
44
|
+
i += m[0].length;
|
|
45
|
+
return Number(m[0]);
|
|
46
|
+
};
|
|
47
|
+
const readFlag = () => {
|
|
48
|
+
skipSep();
|
|
49
|
+
const ch = d[i];
|
|
50
|
+
if (ch !== "0" && ch !== "1") {
|
|
51
|
+
throw new PathParseError(`expected an arc flag (0 or 1) at offset ${i} in path "${d}"`);
|
|
52
|
+
}
|
|
53
|
+
i++;
|
|
54
|
+
return ch;
|
|
55
|
+
};
|
|
56
|
+
const startsNumber = () => {
|
|
57
|
+
skipSep();
|
|
58
|
+
return i < n && /[-+.\d]/.test(d[i]);
|
|
59
|
+
};
|
|
60
|
+
const out = [];
|
|
61
|
+
skipSep();
|
|
62
|
+
while (i < n) {
|
|
63
|
+
const cmd = d[i];
|
|
64
|
+
const lower = cmd.toLowerCase();
|
|
65
|
+
const count = PARAM_COUNT[lower];
|
|
66
|
+
if (count === undefined) {
|
|
67
|
+
throw new PathParseError(`unknown path command "${cmd}" at offset ${i} in path "${d}"`);
|
|
68
|
+
}
|
|
69
|
+
i++;
|
|
70
|
+
if (count === 0) {
|
|
71
|
+
out.push(cmd);
|
|
72
|
+
skipSep();
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
let first = true;
|
|
76
|
+
do {
|
|
77
|
+
const params = [];
|
|
78
|
+
for (let k = 0; k < count; k++) {
|
|
79
|
+
if (lower === "a" && (k === 3 || k === 4))
|
|
80
|
+
params.push(readFlag());
|
|
81
|
+
else if (lower === "a" && k === 2)
|
|
82
|
+
params.push(fmt(readNumber()));
|
|
83
|
+
else
|
|
84
|
+
params.push(fmt(readNumber() * factor));
|
|
85
|
+
}
|
|
86
|
+
// Implicit repetitions after M/m are line-tos; keep the explicit letter each time.
|
|
87
|
+
const letter = first ? cmd : lower === "m" ? (cmd === "M" ? "L" : "l") : cmd;
|
|
88
|
+
out.push(letter + params.join(" "));
|
|
89
|
+
first = false;
|
|
90
|
+
} while (startsNumber());
|
|
91
|
+
skipSep();
|
|
92
|
+
}
|
|
93
|
+
return out.join(" ");
|
|
94
|
+
}
|
|
95
|
+
/** Darken a #RRGGBB colour by multiplying each channel by (1 - amount). */
|
|
96
|
+
export function darkenHex(hex, amount = 0.3) {
|
|
97
|
+
const m = /^#([0-9A-Fa-f]{6})$/.exec(hex);
|
|
98
|
+
if (!m)
|
|
99
|
+
throw new Error(`darkenHex: not a #RRGGBB colour: ${hex}`);
|
|
100
|
+
const v = parseInt(m[1], 16);
|
|
101
|
+
const ch = (shift) => {
|
|
102
|
+
const c = Math.round(((v >> shift) & 0xff) * (1 - amount));
|
|
103
|
+
return Math.max(0, Math.min(255, c)).toString(16).padStart(2, "0").toUpperCase();
|
|
104
|
+
};
|
|
105
|
+
return `#${ch(16)}${ch(8)}${ch(0)}`;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=breadboard-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadboard-util.js","sourceRoot":"","sources":["../../../src/core/compile/breadboard-util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breadboard view renderer (Fritzing house style).
|
|
3
|
+
*
|
|
4
|
+
* Coordinates: part frame mm -> canvas mm (toCanvas) -> mil (1 viewBox unit = 1 mil).
|
|
5
|
+
* Draw order: board, photo, silkscreen + components, header bodies, leads, pads/pins,
|
|
6
|
+
* labels, terminals. Attributes only (no CSS), font Noto Sans only, no tspans.
|
|
7
|
+
*
|
|
8
|
+
* Conventions:
|
|
9
|
+
* - Silkscreen rect xMm/yMm is the TOP-LEFT corner; circle xMm/yMm is the centre; text
|
|
10
|
+
* xMm/yMm is the anchor point, yMm being the vertical CENTRE of the text.
|
|
11
|
+
* - Free-standing pins: the pad element is connectorNpin; a 1 mil connectorNterminal
|
|
12
|
+
* sits at its centre.
|
|
13
|
+
* - Headers: one cell per pin in the core header style; connectorNpin is the inner pin
|
|
14
|
+
* square (male), the hole (female) or the pad (castellated).
|
|
15
|
+
* - Leads follow the bendable-leg SVGs of the core library (LED-5mm-red-leg.svg and
|
|
16
|
+
* friends): the connectorNpin element sits where the lead leaves the board (it
|
|
17
|
+
* doubles as the solder blob) and the connectorNleg line runs from there to the free
|
|
18
|
+
* end. Leads have no terminal.
|
|
19
|
+
*/
|
|
20
|
+
import { type ResolvedConnector, type ResolvedPart } from "../resolve.js";
|
|
21
|
+
import { type Attrs } from "../svg.js";
|
|
22
|
+
import type { RenderContext } from "./types.js";
|
|
23
|
+
export declare const XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
24
|
+
/** Breadboard-only colours and sizes not (yet) in STYLE. */
|
|
25
|
+
export declare const BB: {
|
|
26
|
+
readonly boardStrokeMil: 8;
|
|
27
|
+
readonly boardDarken: 0.3;
|
|
28
|
+
readonly mountHoleFill: "#000000";
|
|
29
|
+
readonly mountRingMil: 10;
|
|
30
|
+
readonly padStroke: "#8C8663";
|
|
31
|
+
readonly padStrokeMil: 6;
|
|
32
|
+
readonly padHole: "#1F1F1F";
|
|
33
|
+
readonly labelGapMm: 0.4;
|
|
34
|
+
readonly headerLabelScale: 0.8;
|
|
35
|
+
readonly minLabelPitchMm: 2;
|
|
36
|
+
/** Average glyph advance of Noto Sans caps/digits, in em (for label fitting). */
|
|
37
|
+
readonly charWidthEm: 0.6;
|
|
38
|
+
readonly minHeaderLabelMil: 20;
|
|
39
|
+
};
|
|
40
|
+
export interface ContentOptions {
|
|
41
|
+
/** false strips every id attribute (icon view). */
|
|
42
|
+
ids: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Font size for one header's labels. Horizontal rows put labels side by side one pitch
|
|
46
|
+
* apart, so the size shrinks (for the whole header, never below BB.minHeaderLabelMil)
|
|
47
|
+
* until the longest label fits in 90% of the pitch; vertical columns keep the default.
|
|
48
|
+
*/
|
|
49
|
+
export declare function headerLabelSize(group: ResolvedConnector[], orientation: "horizontal" | "vertical", pitchMil: number): number;
|
|
50
|
+
/**
|
|
51
|
+
* The breadboard artwork as a list of elements, without the root svg or layer group.
|
|
52
|
+
* Shared by the breadboard view (ids on) and the icon view (ids off) so the icon is
|
|
53
|
+
* literally the same drawing, scaled.
|
|
54
|
+
*/
|
|
55
|
+
export declare function renderBreadboardContent(part: ResolvedPart, ctx: RenderContext, opts: ContentOptions): string[];
|
|
56
|
+
/** Root namespace attributes: xlink only when a photo is embedded. */
|
|
57
|
+
export declare function extraNamespaces(ctx: RenderContext): Attrs;
|
|
58
|
+
/** Join elements one per line inside a group, indented two spaces. */
|
|
59
|
+
export declare function group(id: string | undefined, children: string[], extra?: Attrs): string;
|
|
60
|
+
export declare function renderBreadboard(part: ResolvedPart, ctx: RenderContext): string;
|