karcytics-sdk 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. karcytics_sdk-2.0.0/PKG-INFO +156 -0
  2. karcytics_sdk-2.0.0/README.md +134 -0
  3. karcytics_sdk-2.0.0/pyproject.toml +112 -0
  4. karcytics_sdk-2.0.0/setup.cfg +4 -0
  5. karcytics_sdk-2.0.0/src/karcytics_sdk/__init__.py +10 -0
  6. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/__init__.py +0 -0
  7. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/commands/__init__.py +0 -0
  8. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/commands/diagnostics.py +81 -0
  9. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/commands/migrate.py +112 -0
  10. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/commands/scaffold.py +450 -0
  11. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/commands/security.py +109 -0
  12. karcytics_sdk-2.0.0/src/karcytics_sdk/cli/main.py +43 -0
  13. karcytics_sdk-2.0.0/src/karcytics_sdk/contrib/__init__.py +38 -0
  14. karcytics_sdk-2.0.0/src/karcytics_sdk/contrib/image_utils.py +682 -0
  15. karcytics_sdk-2.0.0/src/karcytics_sdk/host/__init__.py +40 -0
  16. karcytics_sdk-2.0.0/src/karcytics_sdk/host/ai.py +421 -0
  17. karcytics_sdk-2.0.0/src/karcytics_sdk/host/core_services.py +160 -0
  18. karcytics_sdk-2.0.0/src/karcytics_sdk/host/docs.py +45 -0
  19. karcytics_sdk-2.0.0/src/karcytics_sdk/host/marketplace_cache.py +157 -0
  20. karcytics_sdk-2.0.0/src/karcytics_sdk/host/sign_plugin.py +478 -0
  21. karcytics_sdk-2.0.0/src/karcytics_sdk/host/trust_manager.py +487 -0
  22. karcytics_sdk-2.0.0/src/karcytics_sdk/host/trust_overrides.py +113 -0
  23. karcytics_sdk-2.0.0/src/karcytics_sdk/host/trust_path.py +71 -0
  24. karcytics_sdk-2.0.0/src/karcytics_sdk/host/trust_storage.py +102 -0
  25. karcytics_sdk-2.0.0/src/karcytics_sdk/interfaces/__init__.py +5 -0
  26. karcytics_sdk-2.0.0/src/karcytics_sdk/interfaces/i_event_bus.py +15 -0
  27. karcytics_sdk-2.0.0/src/karcytics_sdk/interfaces/i_logger.py +26 -0
  28. karcytics_sdk-2.0.0/src/karcytics_sdk/interfaces/i_task_scheduler.py +17 -0
  29. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/__init__.py +137 -0
  30. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/analysis.py +207 -0
  31. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/base.py +347 -0
  32. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/components.py +671 -0
  33. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/context.py +29 -0
  34. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/daemon.py +693 -0
  35. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/dialogs.py +259 -0
  36. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/events.py +85 -0
  37. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/interfaces.py +46 -0
  38. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/io.py +189 -0
  39. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/logging.py +53 -0
  40. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/managed_task.py +48 -0
  41. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/manifest.py +32 -0
  42. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/manifest_parser.py +78 -0
  43. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/preferences.py +37 -0
  44. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/ribbon.py +81 -0
  45. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/security_parser.py +78 -0
  46. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/signals.py +45 -0
  47. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/state.py +57 -0
  48. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/theme_fallback.py +95 -0
  49. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/validation.py +114 -0
  50. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/wizard.py +443 -0
  51. karcytics_sdk-2.0.0/src/karcytics_sdk/plugin/workflow.py +74 -0
  52. karcytics_sdk-2.0.0/src/karcytics_sdk/py.typed +1 -0
  53. karcytics_sdk-2.0.0/src/karcytics_sdk/sdk_cli.py +119 -0
  54. karcytics_sdk-2.0.0/src/karcytics_sdk/testing/__init__.py +3 -0
  55. karcytics_sdk-2.0.0/src/karcytics_sdk/testing/contract.py +72 -0
  56. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/PKG-INFO +156 -0
  57. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/SOURCES.txt +73 -0
  58. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/dependency_links.txt +1 -0
  59. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/entry_points.txt +2 -0
  60. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/requires.txt +13 -0
  61. karcytics_sdk-2.0.0/src/karcytics_sdk.egg-info/top_level.txt +1 -0
  62. karcytics_sdk-2.0.0/tests/test_host_ai.py +195 -0
  63. karcytics_sdk-2.0.0/tests/test_host_security.py +463 -0
  64. karcytics_sdk-2.0.0/tests/test_image_utils.py +176 -0
  65. karcytics_sdk-2.0.0/tests/test_marketplace_cache.py +90 -0
  66. karcytics_sdk-2.0.0/tests/test_namespaces.py +30 -0
  67. karcytics_sdk-2.0.0/tests/test_plugin_architecture.py +56 -0
  68. karcytics_sdk-2.0.0/tests/test_plugin_ribbon.py +42 -0
  69. karcytics_sdk-2.0.0/tests/test_plugin_state.py +172 -0
  70. karcytics_sdk-2.0.0/tests/test_plugin_ui.py +562 -0
  71. karcytics_sdk-2.0.0/tests/test_sdk_cli.py +57 -0
  72. karcytics_sdk-2.0.0/tests/test_sign_plugin.py +161 -0
  73. karcytics_sdk-2.0.0/tests/test_testing_contract.py +74 -0
  74. karcytics_sdk-2.0.0/tests/test_theme_fallback.py +20 -0
  75. karcytics_sdk-2.0.0/tests/test_workflow_context.py +67 -0
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: karcytics-sdk
3
+ Version: 2.0.0
4
+ Summary: Software Development Kit and CLI for Karcytics.
5
+ Author: Kalaimaran Balasothy
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Operating System :: OS Independent
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: cryptography>=41.0.0
11
+ Requires-Dist: msgpack>=1.0.0
12
+ Requires-Dist: numpy
13
+ Requires-Dist: pandas
14
+ Requires-Dist: pillow>=12.3.0
15
+ Requires-Dist: PyQt6>=6.5.0
16
+ Requires-Dist: requests>=2.28.0
17
+ Requires-Dist: scikit-image>=0.26.0
18
+ Requires-Dist: scipy
19
+ Provides-Extra: docs
20
+ Requires-Dist: mkdocs-material; extra == "docs"
21
+ Requires-Dist: mkdocstrings[python]; extra == "docs"
22
+
23
+ # 🔌 Karcytics SDK
24
+
25
+ [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blueviolet?style=flat-square)](https://KalaimaranB.github.io/Karcytics-SDK/)
26
+ [![CI Build Status](https://img.shields.io/github/actions/workflow/status/KalaimaranB/Karcytics-SDK/test_and_lint.yml?branch=main&style=flat-square&label=CI%20build)](https://github.com/KalaimaranB/Karcytics-SDK/actions)
27
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/KalaimaranB/Karcytics-SDK/blob/main/LICENSE)
28
+
29
+ The Software Development Kit (SDK) and Command-Line Interface (CLI) for building, validating, and signing plugins for the **Karcytics** desktop scientific suite.
30
+
31
+ ---
32
+
33
+ ## 🚀 Key Features
34
+
35
+ - **Decoupled Architecture**: Build and test PyQt6-based scientific plugins independently of the main desktop app.
36
+ - **Fail-Safe Dynamic Theme Fallbacks**: Visual components automatically load custom HSL-tailored colors when running standalone inside CI/CD test gates or external visualizers.
37
+ - **Merkle-Tree Cryptographic Integrity**: Built-in Ed25519 signing and verification tools to secure user environments against remote execution and tampering.
38
+ - **PyPI-Ready Packaging**: Complete declarative `pyproject.toml` config, built to publish natively under the `karcytics-sdk` package.
39
+
40
+ ---
41
+
42
+ ## 🛠️ Installation
43
+
44
+ Install the SDK directly into your plugin's virtual environment:
45
+
46
+ ```bash
47
+ pip install karcytics-sdk
48
+ ```
49
+
50
+ *(Or during development, install in editable mode):*
51
+ ```bash
52
+ git clone https://github.com/KalaimaranB/Karcytics-SDK.git
53
+ cd Karcytics-SDK
54
+ pip install -e .
55
+ ```
56
+
57
+ ---
58
+
59
+ ## 📦 Creating a Custom Karcytics Plugin
60
+
61
+ To build a valid plugin, implement the `KarcyticsPlugin` interface and declare your entrypoints.
62
+
63
+ ### 1. `manifest.json`
64
+ Every plugin must include a manifest file in its root directory:
65
+ ```json
66
+ {
67
+ "id": "my_custom_plugin",
68
+ "name": "My Custom Plugin",
69
+ "version": "1.0.0",
70
+ "author": "Dr. Kalaimaran",
71
+ "description": "High-performance scientific analysis plugin.",
72
+ "category": "analysis",
73
+ "min_core_version": "1.0.0",
74
+ "entrypoint": "plugin:MyPluginClass"
75
+ }
76
+ ```
77
+
78
+ ### 2. `plugin.py`
79
+ ```python
80
+ from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
81
+ from karcytics_sdk.core.interfaces import KarcyticsPlugin
82
+ from karcytics_sdk.ui import PrimaryButton
83
+
84
+ class MyPluginClass(KarcyticsPlugin):
85
+ """A professional-grade Karcytics plugin."""
86
+
87
+ def initialize(self) -> None:
88
+ self.logger.info("Initializing custom plugin...")
89
+
90
+ def create_panel(self, parent=None) -> QWidget:
91
+ panel = QWidget(parent)
92
+ layout = QVBoxLayout(panel)
93
+
94
+ title = QLabel("Welcome to Custom Analysis Panel")
95
+ btn = PrimaryButton("Execute Step")
96
+
97
+ layout.addWidget(title)
98
+ layout.addWidget(btn)
99
+ return panel
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 🛡️ Cryptographic Trust Architecture
105
+
106
+ Karcytics implements a professional-grade **Chain of Trust** to protect laboratory environments:
107
+
108
+ ```
109
+ [ Root Authority ] (Hardcoded Core Key)
110
+
111
+ ▼ (signs)
112
+ [ Developer Key ] (Dev Certificate)
113
+
114
+ ▼ (signs)
115
+ [ Plugin Manifest ] (Ed25519 Signature + Merkle-Tree Hashes)
116
+ ```
117
+
118
+ ### 1. Generate Your Cryptographic Identity
119
+ ```bash
120
+ karcytics-sdk setup-identity
121
+ ```
122
+ - Local Private Key: `~/.karcytics/dev_private_key.pem`
123
+ - Developer Certificate: `~/.karcytics/dev_cert.bin`
124
+
125
+ ### 2. Sign Your Plugin payload
126
+ Calculates Merkle-hashes for all your files recursively, excludes development directories automatically, updates `manifest.json`, and writes `signature.bin`:
127
+ ```bash
128
+ karcytics-sdk sign <path/to/plugin>
129
+ ```
130
+
131
+ ### 3. Modularity Compliance Check
132
+ Verify your plugin matches QA and security standards:
133
+ ```bash
134
+ karcytics-sdk evaluate <path/to/plugin>
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 📘 Standalone Preview Support
140
+ Since the SDK decouples all theme components from the desktop core using robust try-except fallbacks, you can instantiate and preview components standalone in development:
141
+
142
+ ```python
143
+ import sys
144
+ from PyQt6.QtWidgets import QApplication
145
+ from karcytics_sdk.ui import PrimaryButton, WizardPanel
146
+
147
+ app = QApplication(sys.argv)
148
+ widget = WizardPanel() # Renders beautifully even without the main app!
149
+ widget.show()
150
+ sys.exit(app.exec())
151
+ ```
152
+
153
+ ---
154
+
155
+ ## 📄 License
156
+ This project is licensed under the MIT License.
@@ -0,0 +1,134 @@
1
+ # 🔌 Karcytics SDK
2
+
3
+ [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blueviolet?style=flat-square)](https://KalaimaranB.github.io/Karcytics-SDK/)
4
+ [![CI Build Status](https://img.shields.io/github/actions/workflow/status/KalaimaranB/Karcytics-SDK/test_and_lint.yml?branch=main&style=flat-square&label=CI%20build)](https://github.com/KalaimaranB/Karcytics-SDK/actions)
5
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/KalaimaranB/Karcytics-SDK/blob/main/LICENSE)
6
+
7
+ The Software Development Kit (SDK) and Command-Line Interface (CLI) for building, validating, and signing plugins for the **Karcytics** desktop scientific suite.
8
+
9
+ ---
10
+
11
+ ## 🚀 Key Features
12
+
13
+ - **Decoupled Architecture**: Build and test PyQt6-based scientific plugins independently of the main desktop app.
14
+ - **Fail-Safe Dynamic Theme Fallbacks**: Visual components automatically load custom HSL-tailored colors when running standalone inside CI/CD test gates or external visualizers.
15
+ - **Merkle-Tree Cryptographic Integrity**: Built-in Ed25519 signing and verification tools to secure user environments against remote execution and tampering.
16
+ - **PyPI-Ready Packaging**: Complete declarative `pyproject.toml` config, built to publish natively under the `karcytics-sdk` package.
17
+
18
+ ---
19
+
20
+ ## 🛠️ Installation
21
+
22
+ Install the SDK directly into your plugin's virtual environment:
23
+
24
+ ```bash
25
+ pip install karcytics-sdk
26
+ ```
27
+
28
+ *(Or during development, install in editable mode):*
29
+ ```bash
30
+ git clone https://github.com/KalaimaranB/Karcytics-SDK.git
31
+ cd Karcytics-SDK
32
+ pip install -e .
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 📦 Creating a Custom Karcytics Plugin
38
+
39
+ To build a valid plugin, implement the `KarcyticsPlugin` interface and declare your entrypoints.
40
+
41
+ ### 1. `manifest.json`
42
+ Every plugin must include a manifest file in its root directory:
43
+ ```json
44
+ {
45
+ "id": "my_custom_plugin",
46
+ "name": "My Custom Plugin",
47
+ "version": "1.0.0",
48
+ "author": "Dr. Kalaimaran",
49
+ "description": "High-performance scientific analysis plugin.",
50
+ "category": "analysis",
51
+ "min_core_version": "1.0.0",
52
+ "entrypoint": "plugin:MyPluginClass"
53
+ }
54
+ ```
55
+
56
+ ### 2. `plugin.py`
57
+ ```python
58
+ from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
59
+ from karcytics_sdk.core.interfaces import KarcyticsPlugin
60
+ from karcytics_sdk.ui import PrimaryButton
61
+
62
+ class MyPluginClass(KarcyticsPlugin):
63
+ """A professional-grade Karcytics plugin."""
64
+
65
+ def initialize(self) -> None:
66
+ self.logger.info("Initializing custom plugin...")
67
+
68
+ def create_panel(self, parent=None) -> QWidget:
69
+ panel = QWidget(parent)
70
+ layout = QVBoxLayout(panel)
71
+
72
+ title = QLabel("Welcome to Custom Analysis Panel")
73
+ btn = PrimaryButton("Execute Step")
74
+
75
+ layout.addWidget(title)
76
+ layout.addWidget(btn)
77
+ return panel
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 🛡️ Cryptographic Trust Architecture
83
+
84
+ Karcytics implements a professional-grade **Chain of Trust** to protect laboratory environments:
85
+
86
+ ```
87
+ [ Root Authority ] (Hardcoded Core Key)
88
+
89
+ ▼ (signs)
90
+ [ Developer Key ] (Dev Certificate)
91
+
92
+ ▼ (signs)
93
+ [ Plugin Manifest ] (Ed25519 Signature + Merkle-Tree Hashes)
94
+ ```
95
+
96
+ ### 1. Generate Your Cryptographic Identity
97
+ ```bash
98
+ karcytics-sdk setup-identity
99
+ ```
100
+ - Local Private Key: `~/.karcytics/dev_private_key.pem`
101
+ - Developer Certificate: `~/.karcytics/dev_cert.bin`
102
+
103
+ ### 2. Sign Your Plugin payload
104
+ Calculates Merkle-hashes for all your files recursively, excludes development directories automatically, updates `manifest.json`, and writes `signature.bin`:
105
+ ```bash
106
+ karcytics-sdk sign <path/to/plugin>
107
+ ```
108
+
109
+ ### 3. Modularity Compliance Check
110
+ Verify your plugin matches QA and security standards:
111
+ ```bash
112
+ karcytics-sdk evaluate <path/to/plugin>
113
+ ```
114
+
115
+ ---
116
+
117
+ ## 📘 Standalone Preview Support
118
+ Since the SDK decouples all theme components from the desktop core using robust try-except fallbacks, you can instantiate and preview components standalone in development:
119
+
120
+ ```python
121
+ import sys
122
+ from PyQt6.QtWidgets import QApplication
123
+ from karcytics_sdk.ui import PrimaryButton, WizardPanel
124
+
125
+ app = QApplication(sys.argv)
126
+ widget = WizardPanel() # Renders beautifully even without the main app!
127
+ widget.show()
128
+ sys.exit(app.exec())
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 📄 License
134
+ This project is licensed under the MIT License.
@@ -0,0 +1,112 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "karcytics-sdk"
7
+ version = "2.0.0"
8
+ description = "Software Development Kit and CLI for Karcytics."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [
12
+ { name = "Kalaimaran Balasothy" }
13
+ ]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ dependencies = [
19
+ "cryptography>=41.0.0",
20
+ "msgpack>=1.0.0",
21
+ "numpy",
22
+ "pandas",
23
+ "pillow>=12.3.0",
24
+ "PyQt6>=6.5.0",
25
+ "requests>=2.28.0",
26
+ "scikit-image>=0.26.0",
27
+ "scipy",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ docs = [
32
+ "mkdocs-material",
33
+ "mkdocstrings[python]",
34
+ ]
35
+
36
+ [project.scripts]
37
+ karcytics-sdk = "karcytics_sdk.cli.main:main"
38
+
39
+ [tool.setuptools.packages.find]
40
+ where = ["src"]
41
+
42
+ [tool.setuptools.package-data]
43
+ karcytics_sdk = ["py.typed"]
44
+
45
+ [tool.pytest.ini_options]
46
+ minversion = "7.0"
47
+ addopts = "-ra -q --tb=short --cov=src/karcytics_sdk --cov-report=term-missing --cov-report=html --cov-fail-under=45"
48
+ testpaths = ["tests"]
49
+ pythonpath = ["src"]
50
+ filterwarnings = [
51
+ "ignore:.*PyQt6.*:DeprecationWarning",
52
+ ]
53
+
54
+ [tool.coverage.run]
55
+ source = ["src/karcytics_sdk"]
56
+ omit = [
57
+ "*/__init__.py",
58
+ ]
59
+
60
+ [tool.coverage.report]
61
+ show_missing = true
62
+ exclude_lines = [
63
+ "pragma: no cover",
64
+ "if __name__ == .__main__.:",
65
+ "raise NotImplementedError",
66
+ ]
67
+
68
+ [tool.ruff]
69
+ line-length = 120
70
+ target-version = "py311"
71
+
72
+ [tool.ruff.lint]
73
+ select = [
74
+ "E", "F", "W", # Pyflakes & pycodestyle
75
+ "I", # isort (import sorting)
76
+ "UP", # pyupgrade
77
+ "B", # flake8-bugbear
78
+ "D", # pydocstyle
79
+ "C90", # mccabe complexity
80
+ "PLR", # pylint refactoring (complexity)
81
+ ]
82
+ ignore = [
83
+ "E501", # Line too long (handled by formatting standards)
84
+ "E722", # Bare excepts (utilised in AI connection retry fallbacks)
85
+ "D100", # Missing docstring in public module
86
+ "D101", # Missing docstring in public class (redundant for UI colors/fallback classes)
87
+ "D102", # Missing docstring in public method (redundant for standard UI properties/callbacks)
88
+ "D103", # Missing docstring in public function
89
+ "D104", # Missing docstring in public package
90
+ "D105", # Missing docstring in magic method (redundant by standard definition)
91
+ "D106", # Missing docstring in public nested class
92
+ "D107", # Missing docstring in __init__ (covered by class docstring)
93
+ "D205", # 1 blank line between summary and description
94
+ "B024", # ABC with no abstract methods (perfectly valid for base data/state models)
95
+ "B027", # Empty hooks in ABCs without abstract decorator (standard custom override hook pattern)
96
+ ]
97
+
98
+ [tool.ruff.lint.pydocstyle]
99
+ convention = "google"
100
+
101
+ [tool.ruff.lint.per-file-ignores]
102
+ "tests/*" = ["PLR2004", "PLR0913", "PLR0915", "PLR0917"]
103
+
104
+ [tool.mypy]
105
+ python_version = "3.12"
106
+ warn_return_any = false
107
+ warn_unused_configs = true
108
+ disallow_untyped_defs = false
109
+ check_untyped_defs = false
110
+ ignore_missing_imports = true
111
+ disable_error_code = ["assignment", "union-attr", "call-arg", "no-any-return", "method-assign", "misc", "no-redef"]
112
+ files = "src"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """Karcytics SDK — Software Development Kit for Karcytics desktop plugins.
2
+
3
+ Provides two main namespaces:
4
+ - plugin: Clean API for plugin development with zero unnecessary dependencies.
5
+ - host: Host-facing APIs for the Core application and SDK signing CLI.
6
+ """
7
+
8
+ from . import host, interfaces, plugin
9
+
10
+ __all__ = ["plugin", "host", "interfaces"]
File without changes
@@ -0,0 +1,81 @@
1
+ def setup_diagnostics_parser(subparsers):
2
+ # Command: sbom
3
+ sbom_parser = subparsers.add_parser("sbom", help="Generates and prints the SBOM in the specified format.")
4
+ sbom_parser.add_argument(
5
+ "--format", type=str, choices=["--json", "--markdown"], default="--markdown", help="Output format"
6
+ )
7
+ sbom_parser.set_defaults(func=generate_sbom)
8
+
9
+ # Command: evaluate
10
+ eval_parser = subparsers.add_parser("evaluate", help="Perform comprehensive CLI evaluation of a plugin.")
11
+ eval_parser.add_argument("plugin_dir", type=str, help="Path to the plugin directory.")
12
+ eval_parser.set_defaults(func=evaluate_plugin)
13
+
14
+ # Command: doctor
15
+ doctor_parser = subparsers.add_parser("doctor", help="Evaluate a plugin against new SDK architecture.")
16
+ doctor_parser.add_argument("plugin_dir", type=str, help="Path to the plugin directory.")
17
+ doctor_parser.set_defaults(func=doctor_plugin)
18
+
19
+
20
+ def generate_sbom(args) -> bool:
21
+ """Generates and prints the SBOM in the specified format."""
22
+ try:
23
+ import importlib
24
+
25
+ karcytics_core_sbom = importlib.import_module("karcytics.core.sbom")
26
+ generator = karcytics_core_sbom.SBOMGenerator()
27
+
28
+ if args.format == "--json":
29
+ print(generator.to_json())
30
+ else:
31
+ print(generator.to_markdown())
32
+ return True
33
+ except ImportError:
34
+ print("ERROR: SBOM generation is only supported when running inside the Karcytics main application.")
35
+ return False
36
+
37
+
38
+ def evaluate_plugin(args) -> bool:
39
+ """Perform comprehensive CLI evaluation of a plugin."""
40
+ import logging
41
+ import sys
42
+ from pathlib import Path
43
+
44
+ from PyQt6.QtWidgets import QApplication
45
+
46
+ from karcytics_sdk.plugin.manifest_parser import ManifestParser
47
+
48
+ print("Running Plugin Diagnostics Evaluator (evaluate)...")
49
+ _app = QApplication.instance() or QApplication(sys.argv)
50
+ logging.basicConfig(level=logging.INFO)
51
+
52
+ try:
53
+ parser = ManifestParser()
54
+ manifest = parser.parse_file(str(Path(args.plugin_dir) / "pyproject.toml"))
55
+ print(f"Manifest parsed successfully: {manifest.get('id')} v{manifest.get('version')}")
56
+
57
+ dependencies = manifest.get("python_dependencies") or manifest.get("dependencies", {})
58
+ if dependencies:
59
+ print("Auditing Plugin Dependencies...")
60
+ all_pinned = True
61
+ for dep, version in dependencies.items():
62
+ if any(c in version for c in (">", "<", "*", "^", "~")):
63
+ print(f"WARNING: Dependency '{dep}' is not pinned. Recommend exact pinning.")
64
+ all_pinned = False
65
+ else:
66
+ print(f"Dependency '{dep}' is pinned to version '{version}'")
67
+
68
+ if all_pinned:
69
+ print("All declared dependencies are securely pinned.")
70
+
71
+ return True
72
+ except Exception as e:
73
+ print(f"Evaluation failed: {e}")
74
+ return False
75
+
76
+
77
+ def doctor_plugin(args) -> bool:
78
+ """Evaluate a plugin against new SDK architecture (plugin.toml, strict imports)."""
79
+ print(f"Running Plugin Conformance Evaluator (doctor) on {args.plugin_dir}...")
80
+ print("Note: Scaffolded for Phase 1. Full static/runtime checks to be implemented.")
81
+ return True
@@ -0,0 +1,112 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+
5
+ def setup_migrate_parser(subparsers):
6
+ # Command: migrate
7
+ migrate_parser = subparsers.add_parser("migrate", help="Migrate a legacy plugin to the new architecture.")
8
+ migrate_parser.add_argument("plugin_dir", type=str, help="Path to the plugin directory.")
9
+ migrate_parser.set_defaults(func=migrate_plugin)
10
+
11
+
12
+ def migrate_plugin(args) -> bool: # noqa: C901
13
+ """Migrate a legacy plugin to the new architecture (pyproject.toml, src/ layout)."""
14
+ print(f"Migrating legacy plugin at {args.plugin_dir} to new SDK architecture...")
15
+
16
+ p_dir = Path(args.plugin_dir)
17
+ manifest_path = p_dir / "manifest.json"
18
+
19
+ if not manifest_path.exists():
20
+ print("ERROR: manifest.json not found. This doesn't look like a valid legacy plugin.")
21
+ return False
22
+
23
+ with open(manifest_path, encoding="utf-8") as f:
24
+ manifest_data = json.load(f)
25
+
26
+ plugin_id = manifest_data.get("id", p_dir.name.lower().replace("-", "_").replace(" ", "_"))
27
+
28
+ # 1. Generate pyproject.toml
29
+ print("1. Creating pyproject.toml and deprecating manifest.json...")
30
+
31
+ toml_path = p_dir / "pyproject.toml"
32
+
33
+ # Extract dependencies
34
+ dependencies_str = ""
35
+ if "python_dependencies" in manifest_data:
36
+ for dep, ver in manifest_data["python_dependencies"].items():
37
+ dependencies_str += f' "{dep}{ver}",\n'
38
+
39
+ # Build authors block for project
40
+ project_authors = ""
41
+ if "authors" in manifest_data:
42
+ for author in manifest_data["authors"]:
43
+ name = author.get("name", "Unknown")
44
+ project_authors += f' {{ name = "{name}" }},\n'
45
+
46
+ # Build authors block for plugin
47
+ plugin_authors = ""
48
+ if "authors" in manifest_data:
49
+ for author in manifest_data["authors"]:
50
+ name = author.get("name", "Unknown")
51
+ role = author.get("role", "Developer")
52
+ perms_str = json.dumps(author.get("permissions", []))
53
+ plugin_authors += f' {{ name = "{name}", role = "{role}", permissions = {perms_str} }},\n'
54
+
55
+ clean_project_authors = project_authors.rstrip(",\\n")
56
+ clean_deps = dependencies_str.rstrip(",\\n")
57
+ clean_plugin_authors = plugin_authors.rstrip(",\\n")
58
+ reqs_json = json.dumps(manifest_data.get("requires", ["task_scheduler", "logger", "event_bus"]))
59
+
60
+ toml_content = f'''[project]
61
+ name = "{manifest_data.get("name", p_dir.name.title())}"
62
+ version = "{manifest_data.get("version", "1.0.0")}"
63
+ description = "{manifest_data.get("description", "")}"
64
+ readme = "README.md"
65
+ requires-python = ">=3.11"
66
+ authors = [
67
+ {clean_project_authors}
68
+ ]
69
+ dependencies = [
70
+ {clean_deps}
71
+ ]
72
+
73
+ [tool.biopro.plugin]
74
+ id = "{plugin_id}"
75
+ min_core_version = "{manifest_data.get("min_core_version", "1.4.9")}"
76
+ entry_point = "biopro_plugins.{plugin_id}:initialize"
77
+ requires = {reqs_json}
78
+ authors = [
79
+ {clean_plugin_authors}
80
+ ]
81
+ '''
82
+ with open(toml_path, "w", encoding="utf-8") as f:
83
+ f.write(toml_content)
84
+
85
+ print(
86
+ " -> Renaming manifest.json to manifest.json.deprecated (DO NOT DELETE yet, the core still uses it internally!)"
87
+ )
88
+ manifest_path.rename(p_dir / "manifest.json.deprecated")
89
+
90
+ # 2. Setup src structure
91
+ print("2. Restructuring python files into src/...")
92
+ src_dir = p_dir / "src"
93
+ src_dir.mkdir(exist_ok=True)
94
+
95
+ plugin_pkg_dir = src_dir / "biopro_plugins" / plugin_id
96
+ plugin_pkg_dir.mkdir(parents=True, exist_ok=True)
97
+
98
+ # Move all .py files except setup.py to the new package directory
99
+ py_files_moved = 0
100
+ for file in p_dir.glob("*.py"):
101
+ if file.name not in {"setup.py", "conftest.py"}:
102
+ print(f" -> Moving {file.name} to {plugin_pkg_dir.relative_to(p_dir)}")
103
+ file.rename(plugin_pkg_dir / file.name)
104
+ py_files_moved += 1
105
+
106
+ if py_files_moved == 0:
107
+ # Create an empty __init__.py if no files were moved
108
+ (plugin_pkg_dir / "__init__.py").touch()
109
+
110
+ print("\n✅ Migration complete! Please verify your imports in the new src/biopro_plugins/ folder.")
111
+ print("Run 'karcytics-sdk sign .' to sign the new structure.")
112
+ return True