pycforge-sdk 0.6.3__py3-none-any.whl
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.
- pycforge_sdk/__init__.py +6 -0
- pycforge_sdk/__main__.py +3 -0
- pycforge_sdk/catalogue.py +287 -0
- pycforge_sdk/cli.py +114 -0
- pycforge_sdk/connection.py +136 -0
- pycforge_sdk/discovery.py +227 -0
- pycforge_sdk/editing.py +84 -0
- pycforge_sdk/engine_launch.py +45 -0
- pycforge_sdk/engine_worker.py +53 -0
- pycforge_sdk/gui/__init__.py +1 -0
- pycforge_sdk/gui/__main__.py +3 -0
- pycforge_sdk/gui/app.py +36 -0
- pycforge_sdk/gui/dialogs.py +310 -0
- pycforge_sdk/gui/editor.py +412 -0
- pycforge_sdk/gui/help/index.html +9 -0
- pycforge_sdk/gui/identity.py +139 -0
- pycforge_sdk/gui/jobs.py +146 -0
- pycforge_sdk/gui/reference.py +39 -0
- pycforge_sdk/gui/resources/sdk-mark.png +0 -0
- pycforge_sdk/gui/scanner.py +134 -0
- pycforge_sdk/gui/startup.py +118 -0
- pycforge_sdk/gui/visual/__init__.py +1 -0
- pycforge_sdk/gui/visual/action_contract.py +550 -0
- pycforge_sdk/gui/visual/icons.py +117 -0
- pycforge_sdk/gui/visual/qt_actions.py +501 -0
- pycforge_sdk/gui/visual/qt_branding.py +47 -0
- pycforge_sdk/gui/visual/qt_dialog_chrome.py +337 -0
- pycforge_sdk/gui/visual/qt_file_icons.py +130 -0
- pycforge_sdk/gui/visual/qt_icons.py +80 -0
- pycforge_sdk/gui/visual/qt_screen_geometry.py +166 -0
- pycforge_sdk/gui/visual/qt_title_controls.py +333 -0
- pycforge_sdk/gui/visual/qt_window_chrome.py +314 -0
- pycforge_sdk/gui/visual/qt_window_resize.py +93 -0
- pycforge_sdk/gui/visual/qt_workspace_widgets.py +448 -0
- pycforge_sdk/gui/visual/resources/icons/128/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/128/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/16/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/20/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/24/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/256/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/32/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/48/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/64/whitespace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/add-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/brand-mark.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/bundle-search.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/cancel.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/check.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/chevron-right.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/close.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/collapse-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/command-palette.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/convert.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/copy.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/cut.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/decision-trace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/details.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/diagnostics.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/duplicate-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/exit.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/expand-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/export.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/find.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/go-to-line.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/go-to-output.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/go-to-source.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/help.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/history.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/indent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/link-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/mappings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/move-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/move-line-down.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/move-line-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/move-up.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/next.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/open.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/outdent.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/outline.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/paste.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/previous.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/primary-module.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/redo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/remove-document.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/replace.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/save-as.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/save.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/select-all.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/settings.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/show-c.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/split-view.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/summary.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/telemetry.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/toggle-comment.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/toggle-fold.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/tools.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/undo.png +0 -0
- pycforge_sdk/gui/visual/resources/icons/96/whitespace.png +0 -0
- pycforge_sdk/gui/visual/theme.py +204 -0
- pycforge_sdk/gui/visual/theme_steel_stylesheet.py +901 -0
- pycforge_sdk/gui/visual/theme_stylesheet.py +597 -0
- pycforge_sdk/gui/visual/theme_workspace_stylesheet.py +169 -0
- pycforge_sdk/gui/visual/visual_tokens.py +146 -0
- pycforge_sdk/gui/widgets.py +68 -0
- pycforge_sdk/gui/window.py +559 -0
- pycforge_sdk/native.py +42 -0
- pycforge_sdk/package_metadata.py +21 -0
- pycforge_sdk/process.py +58 -0
- pycforge_sdk/project.py +143 -0
- pycforge_sdk/readiness.py +106 -0
- pycforge_sdk/results.py +45 -0
- pycforge_sdk/service.py +454 -0
- pycforge_sdk/workbench.py +88 -0
- pycforge_sdk-0.6.3.dist-info/METADATA +221 -0
- pycforge_sdk-0.6.3.dist-info/RECORD +559 -0
- pycforge_sdk-0.6.3.dist-info/WHEEL +5 -0
- pycforge_sdk-0.6.3.dist-info/entry_points.txt +5 -0
- pycforge_sdk-0.6.3.dist-info/licenses/LICENSE +674 -0
- pycforge_sdk-0.6.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""Bounded installation discovery, shared by human and automated SDK clients.
|
|
2
|
+
|
|
3
|
+
Searching enumerates known environment roots, never an entire drive. Candidates
|
|
4
|
+
are validated through PyCForge's public discovery protocol in separate processes.
|
|
5
|
+
Discovery neither changes the reference cache nor installs or registers anything.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from itertools import islice
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import re
|
|
12
|
+
import sys
|
|
13
|
+
import time
|
|
14
|
+
from . import catalogue
|
|
15
|
+
from .connection import Connection
|
|
16
|
+
from .results import Outcome, SDKError, operation
|
|
17
|
+
|
|
18
|
+
DISCOVERY_SCHEMA = "pycforge-sdk.discovery/0.1"
|
|
19
|
+
_PYTHON = re.compile(r"python(?:3(?:\.\d+)*)?(?:\.exe)?$", re.IGNORECASE)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _key(path):
|
|
23
|
+
# Resolving a venv's python symlink would lose the environment identity.
|
|
24
|
+
return os.path.normcase(os.path.abspath(os.path.expanduser(str(path))))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _children(path):
|
|
28
|
+
try:
|
|
29
|
+
return sorted(islice(Path(path).iterdir(), 256), key=lambda p: p.name.lower())
|
|
30
|
+
except OSError:
|
|
31
|
+
return []
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def support_folder(location):
|
|
35
|
+
"""Recognize the engine-owned support folder without importing engine code."""
|
|
36
|
+
path = Path(location).expanduser().absolute()
|
|
37
|
+
for item in (path, path / "crucible/landscape", path / "pycforge/crucible/landscape"):
|
|
38
|
+
if item.is_dir() and (item / "index.json").is_file() and (item / "api.xml").is_file():
|
|
39
|
+
return item
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def interpreters_at(location):
|
|
44
|
+
"""Resolve a Python, environment, or installed support folder without execution."""
|
|
45
|
+
path = Path(location).expanduser().absolute()
|
|
46
|
+
if path.is_file():
|
|
47
|
+
if path.name.lower() == "pythonw.exe":
|
|
48
|
+
path = path.with_name("python.exe")
|
|
49
|
+
return [path] if path.is_file() and _PYTHON.fullmatch(path.name) else []
|
|
50
|
+
if not path.is_dir():
|
|
51
|
+
return []
|
|
52
|
+
roots = [path]
|
|
53
|
+
support = support_folder(path)
|
|
54
|
+
if support:
|
|
55
|
+
roots.extend(list(support.parents)[:8])
|
|
56
|
+
found = []
|
|
57
|
+
for root in roots:
|
|
58
|
+
for relative in ("Scripts/python.exe", "bin/python", "bin/python3", "python.exe", "python", "python3"):
|
|
59
|
+
item = root / relative
|
|
60
|
+
if item.is_file() and _key(item) not in {_key(p) for p in found}:
|
|
61
|
+
found.append(item)
|
|
62
|
+
return found
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _windows_registry_locations():
|
|
66
|
+
"""PEP 514 Python registrations, including both registry views."""
|
|
67
|
+
if sys.platform != "win32":
|
|
68
|
+
return []
|
|
69
|
+
import winreg
|
|
70
|
+
values = []
|
|
71
|
+
for hive in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE):
|
|
72
|
+
for view in (winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY):
|
|
73
|
+
try:
|
|
74
|
+
with winreg.OpenKey(hive, r"Software\Python", 0, winreg.KEY_READ | view) as root:
|
|
75
|
+
for ci in range(min(winreg.QueryInfoKey(root)[0], 64)):
|
|
76
|
+
company = winreg.EnumKey(root, ci)
|
|
77
|
+
with winreg.OpenKey(root, company) as vendor:
|
|
78
|
+
for ti in range(min(winreg.QueryInfoKey(vendor)[0], 64)):
|
|
79
|
+
tag = winreg.EnumKey(vendor, ti)
|
|
80
|
+
try:
|
|
81
|
+
with winreg.OpenKey(vendor, tag + r"\InstallPath") as install:
|
|
82
|
+
for field in ("ExecutablePath", ""):
|
|
83
|
+
try:
|
|
84
|
+
value, kind = winreg.QueryValueEx(install, field)
|
|
85
|
+
if kind in (winreg.REG_SZ, winreg.REG_EXPAND_SZ):
|
|
86
|
+
values.append(os.path.expandvars(value))
|
|
87
|
+
except OSError:
|
|
88
|
+
pass
|
|
89
|
+
except OSError:
|
|
90
|
+
pass
|
|
91
|
+
except OSError:
|
|
92
|
+
pass
|
|
93
|
+
return values
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def common_locations():
|
|
97
|
+
"""Known Python/environment locations; no shell, registry writes or recursion."""
|
|
98
|
+
home = Path.home()
|
|
99
|
+
locations = [sys.executable]
|
|
100
|
+
for name in ("VIRTUAL_ENV", "CONDA_PREFIX"):
|
|
101
|
+
if os.environ.get(name):
|
|
102
|
+
locations.append(os.environ[name])
|
|
103
|
+
locations.extend(_windows_registry_locations())
|
|
104
|
+
# Ignore empty/relative PATH entries and Windows Store execution aliases.
|
|
105
|
+
for value in os.environ.get("PATH", "").split(os.pathsep)[:64]:
|
|
106
|
+
if value and Path(value).is_absolute() and "windowsapps" not in value.lower():
|
|
107
|
+
locations.append(value)
|
|
108
|
+
locations.append(getattr(sys, "_base_executable", sys.executable))
|
|
109
|
+
bases = [home / ".virtualenvs", home / ".venvs", home / "venvs",
|
|
110
|
+
home / ".pyenv/versions", home / ".local/share/pipx/venvs", home / ".local/pipx/venvs",
|
|
111
|
+
home / "miniconda3/envs", home / "anaconda3/envs", home / ".conda/envs"]
|
|
112
|
+
locations.extend([home / "miniconda3", home / "anaconda3"])
|
|
113
|
+
if sys.platform == "win32":
|
|
114
|
+
local = os.environ.get("LOCALAPPDATA")
|
|
115
|
+
if local:
|
|
116
|
+
bases.append(Path(local) / "Programs/Python")
|
|
117
|
+
for name in ("ProgramFiles", "ProgramFiles(x86)"):
|
|
118
|
+
if os.environ.get(name):
|
|
119
|
+
locations.extend(p for p in _children(os.environ[name]) if p.name.lower().startswith("python"))
|
|
120
|
+
elif sys.platform == "darwin":
|
|
121
|
+
bases.extend([Path("/Library/Frameworks/Python.framework/Versions"),
|
|
122
|
+
home / "Library/Python", Path("/opt/homebrew/opt")])
|
|
123
|
+
for base in bases:
|
|
124
|
+
locations.extend(_children(base))
|
|
125
|
+
# Conda records environments outside its default envs directory here.
|
|
126
|
+
try:
|
|
127
|
+
with (home / ".conda/environments.txt").open(encoding="utf-8") as file:
|
|
128
|
+
text = file.read(65537)
|
|
129
|
+
if len(text) <= 65536:
|
|
130
|
+
locations.extend(line.strip() for line in text.splitlines()[:128]
|
|
131
|
+
if line.strip() and Path(line.strip()).is_absolute())
|
|
132
|
+
except (OSError, UnicodeError):
|
|
133
|
+
pass
|
|
134
|
+
return locations
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _probe(python, timeout, cancel):
|
|
138
|
+
connection = Connection(python, ".", timeout=timeout, cancel=cancel)
|
|
139
|
+
discovery = connection.discover()
|
|
140
|
+
connection.snapshot = catalogue.read_snapshot(discovery)
|
|
141
|
+
if "authoring.json" in connection.snapshot.files:
|
|
142
|
+
connection.reference()
|
|
143
|
+
connection.workbench()
|
|
144
|
+
return {"engine_python": str(python), "engine": dict(connection.snapshot.identity),
|
|
145
|
+
"folder": str(discovery["folder"]), "execution_available": connection._authoring_ready}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@operation
|
|
149
|
+
def discover_engines(*, preferred=None, locations=None, timeout=3.0, search_timeout=20.0,
|
|
150
|
+
max_candidates=48, cancel=None, progress=None):
|
|
151
|
+
"""Find validated installations without changing a cache or authoring state.
|
|
152
|
+
|
|
153
|
+
A valid preferred installation wins immediately. Explicit locations restrict
|
|
154
|
+
the search; otherwise known installations and environment roots are checked.
|
|
155
|
+
Results identify partial searches and failures. Cancellation returns no choice.
|
|
156
|
+
Time/output budgets supervise child processes, not filesystem/network mounts.
|
|
157
|
+
"""
|
|
158
|
+
if (not 0 < timeout <= 300 or not 0 < search_timeout <= 300
|
|
159
|
+
or type(max_candidates) is not int or not 1 <= max_candidates <= 128):
|
|
160
|
+
raise SDKError("SDK_ARGUMENT", "Use positive timeouts up to 300 seconds and 1–128 candidates.")
|
|
161
|
+
if locations is not None and (not isinstance(locations, (list, tuple)) or len(locations) > 128):
|
|
162
|
+
raise SDKError("SDK_ARGUMENT", "Locations must be a list of at most 128 paths.")
|
|
163
|
+
started = time.monotonic()
|
|
164
|
+
def notify(**data):
|
|
165
|
+
if cancel is not None and cancel.is_set():
|
|
166
|
+
raise SDKError("SDK_CANCELED", "Installation search canceled.", status="canceled")
|
|
167
|
+
if progress:
|
|
168
|
+
progress({"schema": "pycforge-sdk.progress/0.1", "phase": "discovery", **data})
|
|
169
|
+
notify(name="Looking for installed PyCForge support files…", current=0, total=1)
|
|
170
|
+
sources = ([preferred] if preferred else []) + (list(locations) if locations is not None else common_locations())
|
|
171
|
+
candidates, seen = [], set()
|
|
172
|
+
support_requested = [support_folder(item) for item in (locations or [])]
|
|
173
|
+
support_requested = [item for item in support_requested if item is not None]
|
|
174
|
+
# An installed user-site catalogue may have its interpreter outside its parents.
|
|
175
|
+
if support_requested:
|
|
176
|
+
sources.extend(common_locations())
|
|
177
|
+
limited = False
|
|
178
|
+
for location in sources:
|
|
179
|
+
notify(name="Checking known installation locations…", current=0, total=1)
|
|
180
|
+
for python in interpreters_at(location):
|
|
181
|
+
key = _key(python)
|
|
182
|
+
if key in seen:
|
|
183
|
+
continue
|
|
184
|
+
seen.add(key)
|
|
185
|
+
if len(candidates) >= max_candidates:
|
|
186
|
+
limited = True
|
|
187
|
+
break
|
|
188
|
+
candidates.append(python)
|
|
189
|
+
if limited:
|
|
190
|
+
break
|
|
191
|
+
engines, attempts, identities = [], [], set()
|
|
192
|
+
preferred_keys = {_key(p) for p in interpreters_at(preferred)} if preferred else set()
|
|
193
|
+
reason = "searched"
|
|
194
|
+
for index, python in enumerate(candidates):
|
|
195
|
+
notify(name="Checking PyCForge installation…", path=str(python), current=index, total=len(candidates))
|
|
196
|
+
remaining = search_timeout - (time.monotonic() - started)
|
|
197
|
+
if remaining <= 0:
|
|
198
|
+
limited = True
|
|
199
|
+
break
|
|
200
|
+
try:
|
|
201
|
+
item = _probe(python, min(timeout, remaining), cancel)
|
|
202
|
+
if support_requested and not any(_key(item["folder"]) == _key(p) for p in support_requested):
|
|
203
|
+
attempts.append({"engine_python": str(python), "code": "SDK_LOCATION_MISMATCH",
|
|
204
|
+
"message": "This interpreter uses a different PyCForge support folder."})
|
|
205
|
+
continue
|
|
206
|
+
identity = (_key(item["folder"]), item["engine"]["manifest_sha256"])
|
|
207
|
+
if identity not in identities:
|
|
208
|
+
engines.append(item)
|
|
209
|
+
identities.add(identity)
|
|
210
|
+
if _key(python) in preferred_keys:
|
|
211
|
+
reason = "preferred"
|
|
212
|
+
limited = False
|
|
213
|
+
break
|
|
214
|
+
except (SDKError, catalogue.CatalogueError, OSError, ValueError, TypeError, KeyError) as exc:
|
|
215
|
+
if isinstance(exc, SDKError) and exc.status == "canceled":
|
|
216
|
+
raise
|
|
217
|
+
attempts.append({"engine_python": str(python), "code": getattr(exc, "code", "SDK_DISCOVERY"),
|
|
218
|
+
"message": str(exc)[:500]})
|
|
219
|
+
notify(name="Installation search finished", current=1, total=1)
|
|
220
|
+
data = {"schema": DISCOVERY_SCHEMA, "engines": engines, "attempts": attempts,
|
|
221
|
+
"limited": limited, "reason": reason, "candidate_count": len(candidates)}
|
|
222
|
+
if not engines:
|
|
223
|
+
message = ("The selected support folder needs its matching installed PyCForge environment. "
|
|
224
|
+
"A source folder alone does not provide a working engine." if support_requested else
|
|
225
|
+
"No compatible PyCForge installation was found in the checked locations.")
|
|
226
|
+
return Outcome("incomplete", data, ({"code": "SDK_ENGINE_NOT_FOUND", "message": message},))
|
|
227
|
+
return Outcome("succeeded", data)
|
pycforge_sdk/editing.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Bounded editor snapshots and optimistic, one-file atomic saves; no Qt."""
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import tempfile
|
|
4
|
+
from .project import Project, MAX_PROJECT, MAX_SOURCE, atomic_write, canonical
|
|
5
|
+
from .results import SDKError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def snapshot(project):
|
|
9
|
+
document = project.document
|
|
10
|
+
declaration = document.get("declaration")
|
|
11
|
+
if (type(declaration) is not dict or type(declaration.get("functions")) is not list
|
|
12
|
+
or any(type(f) is not dict or type(f.get("export")) is not str for f in declaration["functions"])
|
|
13
|
+
or any(key in declaration and type(declaration[key]) is not str for key in ("namespace", "package_id", "version", "schema"))):
|
|
14
|
+
raise SDKError("SDK_EDITOR_DATA", "The declaration needs an object with a list of named functions. Correct project.json and reopen it.")
|
|
15
|
+
documentation = document.get("documentation")
|
|
16
|
+
if isinstance(documentation, dict) and (type(documentation.get("functions", {})) is not dict or type(documentation.get("constants", {})) is not dict):
|
|
17
|
+
raise SDKError("SDK_EDITOR_DATA", "Help functions and constants must be objects. Correct project.json and reopen it.")
|
|
18
|
+
if isinstance(documentation, dict):
|
|
19
|
+
for function in documentation.get("functions", {}).values():
|
|
20
|
+
if (type(function) is not dict or type(function.get("parameters", [])) is not list
|
|
21
|
+
or any(type(p) is not str for p in function.get("parameters", []))):
|
|
22
|
+
raise SDKError("SDK_EDITOR_DATA", "Function Help needs an object with a list of parameter explanations. Correct project.json and reopen it.")
|
|
23
|
+
return {"directory": str(project.root), "project_sha256": project.sha256,
|
|
24
|
+
"document": document,
|
|
25
|
+
"sources": {name: value.decode("utf-8") for name, value in project.sources}}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def open_project(directory):
|
|
29
|
+
project = Project.load(directory)
|
|
30
|
+
project.ensure_current()
|
|
31
|
+
return snapshot(project)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def current(directory, expected_sha256):
|
|
35
|
+
project = Project.load(directory)
|
|
36
|
+
if project.sha256 != expected_sha256:
|
|
37
|
+
raise SDKError("SDK_EDIT_CONFLICT", "Project changed on disk. Reload it before saving; your saved files were preserved.")
|
|
38
|
+
return project
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def validate_draft(project, document, sources):
|
|
42
|
+
# Project.load owns data/path/budget validation for every client. A private
|
|
43
|
+
# staged snapshot never imports source and never creates verification.
|
|
44
|
+
data = canonical(document)
|
|
45
|
+
if len(data) + sum(len(v) for v in sources.values()) > MAX_PROJECT:
|
|
46
|
+
raise SDKError("SDK_PROJECT", "Project exceeds the 4 MiB budget; no files were changed.")
|
|
47
|
+
# Newly referenced existing files go through the same path/symlink/budget
|
|
48
|
+
# checks before any path is copied into the private validation directory.
|
|
49
|
+
candidate = Project.load(project.root, document_bytes=data)
|
|
50
|
+
snapshot(candidate)
|
|
51
|
+
sources = {**dict(candidate.sources), **sources}
|
|
52
|
+
with tempfile.TemporaryDirectory(prefix="sdk-edit-") as folder:
|
|
53
|
+
root = Path(folder)
|
|
54
|
+
(root / "project.json").write_bytes(data)
|
|
55
|
+
# Keys originate in an already validated Project, never draft paths.
|
|
56
|
+
for name, value in sources.items():
|
|
57
|
+
target = root / name
|
|
58
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
target.write_bytes(value)
|
|
60
|
+
snapshot(Project.load(root))
|
|
61
|
+
return data
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def save_project(directory, document, *, expected_sha256):
|
|
65
|
+
project = current(directory, expected_sha256)
|
|
66
|
+
data = validate_draft(project, document, dict(project.sources))
|
|
67
|
+
project.ensure_current()
|
|
68
|
+
atomic_write(project.root / "project.json", data)
|
|
69
|
+
return open_project(directory)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def save_source(directory, filename, source, *, expected_sha256):
|
|
73
|
+
project = current(directory, expected_sha256)
|
|
74
|
+
sources = dict(project.sources)
|
|
75
|
+
if filename not in sources or type(source) is not str:
|
|
76
|
+
raise SDKError("SDK_ARGUMENT", "Choose an existing UTF-8 project fixture.")
|
|
77
|
+
data = source.encode("utf-8")
|
|
78
|
+
if len(data) > MAX_SOURCE:
|
|
79
|
+
raise SDKError("SDK_PROJECT", "Fixture exceeds the 256 KiB budget; no files were changed.")
|
|
80
|
+
sources[filename] = data
|
|
81
|
+
validate_draft(project, project.document, sources)
|
|
82
|
+
project.ensure_current()
|
|
83
|
+
atomic_write(project.root / filename, data)
|
|
84
|
+
return open_project(directory)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Isolated engine entry point, including standard per-user installations.
|
|
2
|
+
|
|
3
|
+
Executed by the selected Python, not imported into the SDK process. Preserve
|
|
4
|
+
-I's exclusion of the working directory and PYTHONPATH. Add that interpreter's
|
|
5
|
+
standard user-site folder when its environment permits it; never process its
|
|
6
|
+
.pth files or accept an arbitrary source folder as an import path.
|
|
7
|
+
"""
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import runpy
|
|
10
|
+
import site
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def user_site_allowed():
|
|
15
|
+
if sys.prefix == sys.base_prefix:
|
|
16
|
+
return True
|
|
17
|
+
try:
|
|
18
|
+
lines = (Path(sys.prefix) / "pyvenv.cfg").read_text(encoding="utf-8").splitlines()
|
|
19
|
+
except (OSError, UnicodeError):
|
|
20
|
+
return False
|
|
21
|
+
return any(line.partition("=")[0].strip().lower() == "include-system-site-packages"
|
|
22
|
+
and line.partition("=")[2].strip().lower() == "true" for line in lines)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
if user_site_allowed():
|
|
27
|
+
folder = site.getusersitepackages()
|
|
28
|
+
if isinstance(folder, str) and Path(folder).is_dir() and folder not in sys.path:
|
|
29
|
+
# Match normal user-site precedence ahead of global site-packages,
|
|
30
|
+
# retaining the standard library first.
|
|
31
|
+
globals_ = site.getsitepackages()
|
|
32
|
+
position = next((i for i, p in enumerate(sys.path) if p in globals_), len(sys.path))
|
|
33
|
+
sys.path.insert(position, folder)
|
|
34
|
+
mode = sys.argv[1]
|
|
35
|
+
if mode == "discover":
|
|
36
|
+
sys.argv = ["pycforge", "--format", "json", "sdk-api"]
|
|
37
|
+
runpy.run_module("pycforge", run_name="__main__", alter_sys=True)
|
|
38
|
+
elif mode == "call":
|
|
39
|
+
runpy.run_path(str(Path(__file__).with_name("engine_worker.py")), run_name="__main__")
|
|
40
|
+
else:
|
|
41
|
+
raise ValueError("Unknown engine launch mode")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
main()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""SDK bridge executed by the selected engine interpreter using -I.
|
|
2
|
+
|
|
3
|
+
Only public PyCForge services are imported. The SDK need not be installed in
|
|
4
|
+
that interpreter. Incoming authoring data is JSON, never executable Python.
|
|
5
|
+
"""
|
|
6
|
+
import base64
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
request = json.loads(sys.stdin.buffer.read(8*1024*1024 + 1))
|
|
14
|
+
from pycforge.crucible.sdk_api import discover
|
|
15
|
+
identity = discover()
|
|
16
|
+
if request["identity"] != identity:
|
|
17
|
+
raise ValueError("Engine identity changed; reconnect and reverify.")
|
|
18
|
+
action, payload = request["action"], request["payload"]
|
|
19
|
+
from pycforge.crucible import ScalarAuthoring, ImportRegistrationStore
|
|
20
|
+
import pycforge.crucible as api
|
|
21
|
+
Authoring = getattr(api, "ExtensionAuthoring", ScalarAuthoring)
|
|
22
|
+
if action == "register":
|
|
23
|
+
store = ImportRegistrationStore(Path(payload["store"]) if payload.get("store") else None)
|
|
24
|
+
row = store.register_file(Path(payload["file"]))
|
|
25
|
+
from dataclasses import fields
|
|
26
|
+
result = {field.name: getattr(row, field.name) for field in fields(row) if field.name != "package"}
|
|
27
|
+
result["package_sha256"] = row.package.package_sha256 if row.package is not None else None
|
|
28
|
+
else:
|
|
29
|
+
candidate = Authoring(payload["declaration"])
|
|
30
|
+
if action == "inspect":
|
|
31
|
+
result = candidate.inspect()
|
|
32
|
+
elif action == "scan":
|
|
33
|
+
result = candidate.scan(payload.get("documentation"), examples=payload.get("examples"))
|
|
34
|
+
elif action == "convert":
|
|
35
|
+
result = candidate.convert(payload["source"], logical_name=payload["logical_name"]).semantic_dict()
|
|
36
|
+
elif action == "package":
|
|
37
|
+
result = {"package_base64": base64.b64encode(candidate.package(
|
|
38
|
+
**payload["metadata"], verification_producer=payload["verification_producer"],
|
|
39
|
+
documentation=payload["documentation"], examples=payload["examples"])).decode("ascii")}
|
|
40
|
+
else:
|
|
41
|
+
raise ValueError("Unknown bridge action")
|
|
42
|
+
if discover() != identity:
|
|
43
|
+
raise ValueError("Engine identity changed during the operation.")
|
|
44
|
+
return {"schema": "pycforge-sdk.bridge/0.1", "identity": identity, "ok": True, "result": result}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
try:
|
|
49
|
+
answer = main()
|
|
50
|
+
except Exception as exc:
|
|
51
|
+
answer = {"schema": "pycforge-sdk.bridge/0.1", "ok": False,
|
|
52
|
+
"diagnostic": {"code": getattr(exc, "code", "SDK_ENGINE_ERROR"), "message": str(exc)}}
|
|
53
|
+
print(json.dumps(answer, sort_keys=True, allow_nan=False))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Optional desktop client. Importing the SDK never imports this application."""
|
pycforge_sdk/gui/app.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Optional PySide6 entry point; dependency errors stay separate from the SDK."""
|
|
2
|
+
import argparse
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import sys
|
|
5
|
+
from .. import __version__
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main(argv=None):
|
|
9
|
+
parser = argparse.ArgumentParser(prog="pycforge-sdk-ui", description="PyCForge conversion extension workshop")
|
|
10
|
+
parser.add_argument("--version", action="version", version=__version__)
|
|
11
|
+
parser.add_argument("--engine-python")
|
|
12
|
+
parser.add_argument("--compiler")
|
|
13
|
+
parser.add_argument("--cache", type=Path)
|
|
14
|
+
parser.add_argument("--project", type=Path)
|
|
15
|
+
parser.add_argument("--timeout", type=float, default=30)
|
|
16
|
+
args = parser.parse_args(argv)
|
|
17
|
+
if not 0 < args.timeout <= 300: parser.error("timeout must be greater than zero and at most 300 seconds")
|
|
18
|
+
try:
|
|
19
|
+
from PySide6.QtCore import QTimer
|
|
20
|
+
from PySide6.QtWidgets import QApplication
|
|
21
|
+
except ImportError:
|
|
22
|
+
print("The desktop needs the optional GUI dependency. Install pycforge-sdk[gui] in this environment; the headless SDK remains usable.", file=sys.stderr)
|
|
23
|
+
return 3
|
|
24
|
+
from .visual.theme import apply_pycforge_theme
|
|
25
|
+
from .identity import sdk_icon
|
|
26
|
+
from .window import MainWindow
|
|
27
|
+
from .visual.qt_screen_geometry import fit_window_to_available_screen
|
|
28
|
+
app = QApplication.instance() or QApplication([sys.argv[0]])
|
|
29
|
+
app.setApplicationName("PyCForge SDK"); app.setApplicationVersion(__version__)
|
|
30
|
+
app.setWindowIcon(sdk_icon())
|
|
31
|
+
apply_pycforge_theme(app)
|
|
32
|
+
window = MainWindow(engine_python=args.engine_python, compiler=args.compiler, cache=args.cache, timeout=args.timeout)
|
|
33
|
+
fit_window_to_available_screen(window, preferred=(1320, 860), minimum=(920, 640))
|
|
34
|
+
if args.project: window.after_connect = str(args.project.absolute())
|
|
35
|
+
QTimer.singleShot(0, window.begin_startup)
|
|
36
|
+
return app.exec()
|