katalyst-plugin-harness 0.1.1a1__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.
- katalyst_plugin_harness-0.1.1a1/.gitignore +123 -0
- katalyst_plugin_harness-0.1.1a1/PKG-INFO +15 -0
- katalyst_plugin_harness-0.1.1a1/pyproject.toml +48 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/__init__.py +7 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/adapters/__init__.py +1 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/adapters/jinja_settings.py +61 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/adapters/opkg.py +214 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/adapters/packages.py +62 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/adapters/taxonomy_catalog.py +206 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/cli.py +138 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/composition.py +80 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/creation/agent.yaml.j2 +20 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/creation/agent_skill.yaml.j2 +13 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/creation/harness.yaml.j2 +18 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/__init__.py +41 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/errors.py +17 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/model.py +153 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/package.py +238 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/reports.py +128 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/domain/wiring.py +140 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/__init__.py +15 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/harness.yaml +225 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/harness_relationships.yaml +57 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/released/0.1.0/SHA256SUMS +2 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/released/0.1.0/harness.yaml +225 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/linkml/released/0.1.0/harness_relationships.yaml +57 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/lint.py +48 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/mcp_tools.py +71 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/plugin.py +48 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/ports/__init__.py +8 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/ports/catalog.py +15 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/ports/openpackage.py +39 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/ports/packages.py +22 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/ports/templates.py +19 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/py.typed +0 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/schema.py +123 -0
- katalyst_plugin_harness-0.1.1a1/src/katalyst_plugin_harness/service.py +217 -0
- katalyst_plugin_harness-0.1.1a1/tests/conftest.py +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/README.md +11 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/_manifests/agents.yaml +95 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-code-reviewer.md +386 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-code-reviewer.yaml +34 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-architect.md +142 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-architect.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-backend.md +161 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-backend.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-commit.md +182 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-commit.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-deploy.md +117 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-deploy.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-design.md +168 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-design.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-devops.md +140 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-devops.yaml +26 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-feedback.md +148 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-feedback.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-frontend.md +215 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-frontend.yaml +29 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-implement.md +137 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-implement.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-operate.md +178 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-operate.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-orchestrate.md +125 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-orchestrate.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-pm.md +214 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-pm.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-product.md +148 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-product.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-qa-lead.md +147 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-qa-lead.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-qa.md +156 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-qa.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-release.md +146 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-release.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-review.md +206 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-review.yaml +26 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-security.md +148 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-security.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-tester.md +299 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-tester.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-verify.md +181 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge-verify.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge.md +273 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-forge.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-intake.md +258 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-intake.yaml +21 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-scribe.md +282 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-scribe.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-validator.md +259 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension-validator.yaml +21 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension.md +134 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-extension.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-analyzer.md +231 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-analyzer.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-intake.md +223 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-intake.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-scribe.md +462 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-scribe.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-validator.md +311 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type-validator.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type.md +126 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-layer-type.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-intake.md +594 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-intake.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-scribe.md +548 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-scribe.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-validator.md +270 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy-validator.yaml +21 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy.md +269 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-build-taxonomy.yaml +29 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-dependency-analyzer.md +321 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-dependency-analyzer.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-practice-auditor.md +138 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-practice-auditor.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-validator-fixer.md +342 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-validator-fixer.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-writer.md +316 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-tax-writer.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-adr.md +340 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-adr.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-capability.md +385 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-capability.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-ddd.md +519 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-ddd.yaml +26 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-expert.md +208 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-expert.yaml +29 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-nfr.md +352 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-nfr.yaml +24 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-adr.md +122 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-adr.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-api.md +95 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-api.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-auth.md +94 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-auth.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-bdd.md +141 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-bdd.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-config.md +97 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-config.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-ddd.md +155 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-ddd.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-docs.md +94 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-docs.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-domain.md +95 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-domain.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-nfr.md +145 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-nfr.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-system.md +135 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-system.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-ui.md +95 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-scan-ui.yaml +25 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-spec.md +466 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-spec.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-system.md +563 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-system.yaml +27 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-user-need.md +367 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-user-need.yaml +26 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-user-type.md +284 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent/kata-xray-user-type.yaml +23 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-feature/SKILL.md +278 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-feature/scripts/forge_run_report.py +132 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-feature.yaml +16 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-model-router/SKILL.md +322 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-model-router/scripts/dispatch.py +1044 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-model-router/scripts/doctor.py +465 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/forge-model-router.yaml +22 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-app-docker/SKILL.md +185 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-app-docker.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-astro/SKILL.md +331 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-astro.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-cicd/SKILL.md +111 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-cicd.yaml +15 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-circuit/SKILL.md +136 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-circuit.yaml +16 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-environments/SKILL.md +165 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-environments.yaml +13 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-extension-builder/SKILL.md +199 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-extension-builder.yaml +13 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/SKILL.md +247 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/scripts/forge-reconcile.mjs +226 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/scripts/forge-size-gate.sh +61 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/scripts/kata-gate.sh +232 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/scripts/marker-contract.mjs +380 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge/scripts/worktree-gate.sh +121 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-forge.yaml +21 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-iac-terragrunt/SKILL.md +167 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-iac-terragrunt.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-k8s-argocd/SKILL.md +159 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-k8s-argocd.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-k8s-kustomize/SKILL.md +152 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-k8s-kustomize.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-layer-type-builder/SKILL.md +176 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-layer-type-builder.yaml +13 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-navigator/SKILL.md +155 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-navigator.yaml +13 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-loader/SKILL.md +136 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-loader.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-reporter/SKILL.md +129 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-reporter.yaml +13 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-resolver/SKILL.md +296 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-resolver/context-sources.yaml +68 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-practice-resolver.yaml +15 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-taxonomy/SKILL.md +385 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-taxonomy.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-ux-audit/SKILL.md +173 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-ux-audit.yaml +14 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-writer/SKILL.md +291 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/agent_skill/katalyst-writer.yaml +15 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/harness/claude/agent.yaml.j2 +3 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/harness/claude.yaml +105 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/harness/opencode/agent.yaml.j2 +19 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/agentic/harness/opencode.yaml +90 -0
- katalyst_plugin_harness-0.1.1a1/tests/fixtures/collection/templates/manifest.json +26 -0
- katalyst_plugin_harness-0.1.1a1/tests/golden/installed-claude.yaml +752 -0
- katalyst_plugin_harness-0.1.1a1/tests/golden/installed-opencode.yaml +1340 -0
- katalyst_plugin_harness-0.1.1a1/tests/golden/package-claude.yaml +1213 -0
- katalyst_plugin_harness-0.1.1a1/tests/golden/package-opencode.yaml +1850 -0
- katalyst_plugin_harness-0.1.1a1/tests/harness_support.py +198 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_additions.py +92 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_cli.py +177 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_lint.py +66 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_package.py +282 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_real_opkg.py +128 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_harness_sync.py +139 -0
- katalyst_plugin_harness-0.1.1a1/tests/test_opkg_resolution.py +102 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
# Not a Python build directory: Bard's SPA keeps shared helpers (utils.ts, download.ts) in
|
|
19
|
+
# src/lib, and ignoring it left a fresh clone unable to build or test the SPA.
|
|
20
|
+
!plugins/bard/web/src/lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
coverage.xml
|
|
47
|
+
*.cover
|
|
48
|
+
*.py,cover
|
|
49
|
+
.hypothesis/
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Environments
|
|
57
|
+
.env
|
|
58
|
+
.venv
|
|
59
|
+
env/
|
|
60
|
+
venv/
|
|
61
|
+
ENV/
|
|
62
|
+
env.bak/
|
|
63
|
+
venv.bak/
|
|
64
|
+
|
|
65
|
+
# Spyder project settings
|
|
66
|
+
.spyderproject
|
|
67
|
+
.spyproject
|
|
68
|
+
|
|
69
|
+
# Rope project settings
|
|
70
|
+
.ropeproject
|
|
71
|
+
|
|
72
|
+
# mkdocs documentation
|
|
73
|
+
/site
|
|
74
|
+
|
|
75
|
+
# mypy / pyright
|
|
76
|
+
.mypy_cache/
|
|
77
|
+
.dmypy.json
|
|
78
|
+
dmypy.json
|
|
79
|
+
.pyright/
|
|
80
|
+
|
|
81
|
+
# Ruff
|
|
82
|
+
.ruff_cache/
|
|
83
|
+
|
|
84
|
+
# IDE
|
|
85
|
+
.idea/
|
|
86
|
+
.vscode/
|
|
87
|
+
*.swp
|
|
88
|
+
*.swo
|
|
89
|
+
*~
|
|
90
|
+
|
|
91
|
+
# OS
|
|
92
|
+
.DS_Store
|
|
93
|
+
Thumbs.db
|
|
94
|
+
|
|
95
|
+
# Local configuration
|
|
96
|
+
*.local
|
|
97
|
+
|
|
98
|
+
# Browser/Playwright state files
|
|
99
|
+
browser-state-*.json
|
|
100
|
+
|
|
101
|
+
# Agent harness scratch (run exhaust, never the design bundle)
|
|
102
|
+
.opencode/sessions/
|
|
103
|
+
.opencode/analysis/
|
|
104
|
+
.opencode/package-lock.json
|
|
105
|
+
|
|
106
|
+
# Build artifacts
|
|
107
|
+
site/
|
|
108
|
+
stack-tests/cucumber-report/
|
|
109
|
+
stack-tests/test-results/
|
|
110
|
+
|
|
111
|
+
# Generated artifacts (rebuild with `just generate-schemas`)
|
|
112
|
+
taxonomy/src/katalyst_taxonomy/engine/generated/
|
|
113
|
+
.worktrees/
|
|
114
|
+
.plan-74-75-76-77.md
|
|
115
|
+
.HANDOFF-scaffolding-wiring.md
|
|
116
|
+
.HANDOFF-2-cicd-migration.md
|
|
117
|
+
.HANDOFF-action-execution-fixes.md
|
|
118
|
+
.HANDOFF-bdd-coverage.md
|
|
119
|
+
.HANDOFF-*.md
|
|
120
|
+
docs/superpowers/
|
|
121
|
+
|
|
122
|
+
# Node dependencies — installed, never committed
|
|
123
|
+
node_modules/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: katalyst-plugin-harness
|
|
3
|
+
Version: 0.1.1a1
|
|
4
|
+
Summary: Katalyst harness plugin — install the taxonomy's agents and skills into coding-agent harnesses with OpenPackage
|
|
5
|
+
Author: eSimplicity
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Requires-Dist: click>=8.0
|
|
9
|
+
Requires-Dist: jinja2>=3.1
|
|
10
|
+
Requires-Dist: katalyst-core<1,>=0.1
|
|
11
|
+
Requires-Dist: katalyst-engine<6,>=5
|
|
12
|
+
Requires-Dist: katalyst-taxonomy-cli<3,>=2
|
|
13
|
+
Requires-Dist: katalyst-taxonomy-mcp<5,>=4
|
|
14
|
+
Requires-Dist: katalyst-taxonomy<6,>=5
|
|
15
|
+
Requires-Dist: pyyaml
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "katalyst-plugin-harness"
|
|
3
|
+
version = "0.1.1a1"
|
|
4
|
+
description = "Katalyst harness plugin — install the taxonomy's agents and skills into coding-agent harnesses with OpenPackage"
|
|
5
|
+
license = { text = "Proprietary" }
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "eSimplicity" }
|
|
9
|
+
]
|
|
10
|
+
dependencies = [
|
|
11
|
+
# Bounded to the config-rooted runtime this plugin is written against.
|
|
12
|
+
"katalyst-taxonomy>=5,<6",
|
|
13
|
+
"katalyst-engine>=5,<6",
|
|
14
|
+
# Its MCP tools use the server's response helpers; its commands, the CLI context and options.
|
|
15
|
+
"katalyst-taxonomy-mcp>=4,<5",
|
|
16
|
+
"katalyst-taxonomy-cli>=2,<3",
|
|
17
|
+
"katalyst-core>=0.1,<1",
|
|
18
|
+
"pyyaml",
|
|
19
|
+
# A harness's settings for an agent are rendered from the Jinja template its node names.
|
|
20
|
+
"jinja2>=3.1",
|
|
21
|
+
"click>=8.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.entry-points."katalyst_taxonomy.plugins"]
|
|
25
|
+
harness = "katalyst_plugin_harness:HarnessPlugin"
|
|
26
|
+
|
|
27
|
+
# agent, agent_skill and harness are ordinary registered kinds, declared like any bundle's,
|
|
28
|
+
# so any schema bundle's repository can carry agents.
|
|
29
|
+
[project.entry-points."katalyst_core.modules"]
|
|
30
|
+
# The schema, as LinkML modules on katalyst-core (the bundle builds its definitions
|
|
31
|
+
# from them).
|
|
32
|
+
harness = "katalyst_plugin_harness.linkml:MODULES"
|
|
33
|
+
|
|
34
|
+
[project.entry-points."katalyst_engine.bundles"]
|
|
35
|
+
harness-schema = "katalyst_plugin_harness.schema:HarnessSchemaBundle"
|
|
36
|
+
|
|
37
|
+
[project.entry-points."katalyst_taxonomy.cli"]
|
|
38
|
+
harness = "katalyst_plugin_harness.cli:create_group"
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["hatchling"]
|
|
42
|
+
build-backend = "hatchling.build"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/katalyst_plugin_harness"]
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel.sources]
|
|
48
|
+
"src" = ""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""The harness plugin's adapters: OpenPackage, the package cache, Jinja, the taxonomy."""
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Jinja: a harness's settings for one agent or skill, rendered and read as YAML."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, cast
|
|
8
|
+
|
|
9
|
+
import yaml
|
|
10
|
+
from jinja2 import Environment, FileSystemLoader, StrictUndefined, TemplateError
|
|
11
|
+
|
|
12
|
+
from katalyst_plugin_harness.domain.errors import HarnessError
|
|
13
|
+
|
|
14
|
+
__all__ = ["JinjaSettingsRenderer"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class JinjaSettingsRenderer:
|
|
18
|
+
"""Implements :class:`~katalyst_plugin_harness.ports.SettingsRenderer`.
|
|
19
|
+
|
|
20
|
+
Undefined names are errors (``StrictUndefined``): a template naming a field the node
|
|
21
|
+
does not have fails instead of rendering an empty value. An empty rendering is no
|
|
22
|
+
settings.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self) -> None:
|
|
26
|
+
self._environments: dict[Path, Environment] = {}
|
|
27
|
+
|
|
28
|
+
def _environment(self, directory: Path) -> Environment:
|
|
29
|
+
environment = self._environments.get(directory)
|
|
30
|
+
if environment is None:
|
|
31
|
+
environment = Environment(
|
|
32
|
+
loader=FileSystemLoader(str(directory)),
|
|
33
|
+
undefined=StrictUndefined,
|
|
34
|
+
keep_trailing_newline=True,
|
|
35
|
+
autoescape=False,
|
|
36
|
+
)
|
|
37
|
+
self._environments[directory] = environment
|
|
38
|
+
return environment
|
|
39
|
+
|
|
40
|
+
def render(self, template: Path, context: Mapping[str, object]) -> Mapping[str, object]:
|
|
41
|
+
if not template.is_file():
|
|
42
|
+
raise HarnessError(f"harness template not found: {template}")
|
|
43
|
+
try:
|
|
44
|
+
text = (
|
|
45
|
+
self._environment(template.parent)
|
|
46
|
+
.get_template(template.name)
|
|
47
|
+
.render(**dict(context))
|
|
48
|
+
)
|
|
49
|
+
except TemplateError as exc:
|
|
50
|
+
raise HarnessError(f"{template}: {exc}") from exc
|
|
51
|
+
try:
|
|
52
|
+
loaded: object = yaml.safe_load(text)
|
|
53
|
+
except yaml.YAMLError as exc:
|
|
54
|
+
raise HarnessError(f"{template} did not render YAML: {exc}") from exc
|
|
55
|
+
if loaded is None:
|
|
56
|
+
return {}
|
|
57
|
+
if not isinstance(loaded, dict):
|
|
58
|
+
raise HarnessError(
|
|
59
|
+
f"{template} must render a mapping of settings, got {type(loaded).__name__}"
|
|
60
|
+
)
|
|
61
|
+
return cast("dict[str, Any]", loaded)
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""OpenPackage (``opkg``) run as a subprocess: the pinned CLI, fetched with npm on first use.
|
|
2
|
+
|
|
3
|
+
Where ``opkg`` comes from, in order: ``KATALYST_OPKG`` (a path to an executable — for
|
|
4
|
+
machines whose endpoint security only allows an approved binary, and for offline use),
|
|
5
|
+
then the pinned version installed in the Katalyst cache
|
|
6
|
+
(``<cache home>/harness/opkg/<version>``), fetched there with npm the first time. An
|
|
7
|
+
``opkg`` on ``PATH`` is deliberately not used: the pinned one is what is tested.
|
|
8
|
+
|
|
9
|
+
What OpenPackage installed is read from its index (``.openpackage/openpackage.index.yml``
|
|
10
|
+
in the workspace, or in the home directory for a global install), which it documents as
|
|
11
|
+
the record of every file a package put where.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import shutil
|
|
18
|
+
import subprocess
|
|
19
|
+
from collections.abc import Callable, Mapping
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any, cast
|
|
22
|
+
|
|
23
|
+
import yaml
|
|
24
|
+
|
|
25
|
+
from katalyst_plugin_harness.domain.errors import (
|
|
26
|
+
OpenPackageError,
|
|
27
|
+
OpenPackageUnavailableError,
|
|
28
|
+
)
|
|
29
|
+
from katalyst_plugin_harness.domain.model import Scope
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"OPKG_ENV",
|
|
33
|
+
"OPKG_VERSION",
|
|
34
|
+
"SubprocessOpenPackage",
|
|
35
|
+
"opkg_cache_dir",
|
|
36
|
+
"resolve_opkg",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
#: The OpenPackage CLI the harness plugin is built and tested against.
|
|
40
|
+
OPKG_VERSION = "0.9.5"
|
|
41
|
+
|
|
42
|
+
#: Overrides where ``opkg`` comes from: a path to the executable.
|
|
43
|
+
OPKG_ENV = "KATALYST_OPKG"
|
|
44
|
+
|
|
45
|
+
_INDEX = Path(".openpackage") / "openpackage.index.yml"
|
|
46
|
+
|
|
47
|
+
#: How much of a failed run's output an error carries.
|
|
48
|
+
_TAIL_LINES = 30
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def opkg_cache_dir(version: str = OPKG_VERSION) -> Path:
|
|
52
|
+
"""Where the pinned ``opkg`` is installed: ``<cache home>/harness/opkg/<version>``."""
|
|
53
|
+
from katalyst_taxonomy.domain.homes import resolve_home
|
|
54
|
+
|
|
55
|
+
return resolve_home().cache_dir / "harness" / "opkg" / version
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _opkg_in(prefix: Path) -> Path | None:
|
|
59
|
+
binary = prefix / "node_modules" / ".bin" / "opkg"
|
|
60
|
+
return binary if binary.is_file() else None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _fetch_opkg(
|
|
64
|
+
prefix: Path, version: str, echo: Callable[[str], None], which: Callable[[str], str | None]
|
|
65
|
+
) -> Path:
|
|
66
|
+
npm = which("npm")
|
|
67
|
+
if npm is None:
|
|
68
|
+
raise OpenPackageUnavailableError(
|
|
69
|
+
f"OpenPackage (opkg {version}) is needed to install into a harness, and npm, "
|
|
70
|
+
f"which fetches it, is not on PATH (it comes with Node.js 20+). Install Node.js, "
|
|
71
|
+
f"or set {OPKG_ENV} to an opkg executable."
|
|
72
|
+
)
|
|
73
|
+
echo(f"Fetching OpenPackage {version} into {prefix} (first run only)…")
|
|
74
|
+
prefix.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
result = subprocess.run(
|
|
76
|
+
[
|
|
77
|
+
npm,
|
|
78
|
+
"install",
|
|
79
|
+
"--prefix",
|
|
80
|
+
str(prefix),
|
|
81
|
+
"--no-save",
|
|
82
|
+
"--no-audit",
|
|
83
|
+
"--no-fund",
|
|
84
|
+
f"opkg@{version}",
|
|
85
|
+
],
|
|
86
|
+
check=False,
|
|
87
|
+
capture_output=True,
|
|
88
|
+
text=True,
|
|
89
|
+
stdin=subprocess.DEVNULL,
|
|
90
|
+
)
|
|
91
|
+
binary = _opkg_in(prefix)
|
|
92
|
+
if result.returncode != 0 or binary is None:
|
|
93
|
+
raise OpenPackageUnavailableError(
|
|
94
|
+
f"Fetching OpenPackage {version} failed (npm exit {result.returncode}): "
|
|
95
|
+
f"{_tail(result.stdout + result.stderr)}\n"
|
|
96
|
+
f"Set {OPKG_ENV} to an opkg executable to use one you already have."
|
|
97
|
+
)
|
|
98
|
+
return binary
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def resolve_opkg(
|
|
102
|
+
*,
|
|
103
|
+
env: Mapping[str, str] | None = None,
|
|
104
|
+
echo: Callable[[str], None] = print,
|
|
105
|
+
which: Callable[[str], str | None] = shutil.which,
|
|
106
|
+
cache_dir: Path | None = None,
|
|
107
|
+
) -> Path:
|
|
108
|
+
"""The ``opkg`` executable to run: ``KATALYST_OPKG``, else the pinned one (fetched).
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
OpenPackageUnavailableError: ``KATALYST_OPKG`` names no file, or there is no
|
|
112
|
+
cached copy and no npm to fetch one with.
|
|
113
|
+
"""
|
|
114
|
+
environ = os.environ if env is None else env
|
|
115
|
+
explicit = environ.get(OPKG_ENV, "").strip()
|
|
116
|
+
if explicit:
|
|
117
|
+
chosen = Path(explicit).expanduser()
|
|
118
|
+
if not chosen.is_file():
|
|
119
|
+
raise OpenPackageUnavailableError(f"{OPKG_ENV} names no file: {chosen}")
|
|
120
|
+
return chosen
|
|
121
|
+
prefix = cache_dir if cache_dir is not None else opkg_cache_dir()
|
|
122
|
+
cached = _opkg_in(prefix)
|
|
123
|
+
if cached is not None:
|
|
124
|
+
return cached
|
|
125
|
+
return _fetch_opkg(prefix, OPKG_VERSION, echo, which)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _tail(output: str) -> str:
|
|
129
|
+
lines = [line for line in output.strip().splitlines() if line.strip()]
|
|
130
|
+
return "\n".join(lines[-_TAIL_LINES:])
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class SubprocessOpenPackage:
|
|
134
|
+
"""Implements :class:`~katalyst_plugin_harness.ports.OpenPackage` with the ``opkg`` CLI.
|
|
135
|
+
|
|
136
|
+
*resolve* finds the executable; it is called on the first install or uninstall, so
|
|
137
|
+
reading what is installed (``status``, a dry run) never fetches anything. *home* is
|
|
138
|
+
where a global install goes (default: the user's home).
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
def __init__(
|
|
142
|
+
self,
|
|
143
|
+
resolve: Callable[[], Path] = resolve_opkg,
|
|
144
|
+
*,
|
|
145
|
+
home: Path | None = None,
|
|
146
|
+
env: Mapping[str, str] | None = None,
|
|
147
|
+
) -> None:
|
|
148
|
+
self._resolve = resolve
|
|
149
|
+
self._executable: Path | None = None
|
|
150
|
+
self._home = home
|
|
151
|
+
self._env = env
|
|
152
|
+
|
|
153
|
+
def _home_dir(self) -> Path:
|
|
154
|
+
return self._home if self._home is not None else Path.home()
|
|
155
|
+
|
|
156
|
+
def _run(self, args: list[str], *, scope: Scope, workspace: Path) -> None:
|
|
157
|
+
if self._executable is None:
|
|
158
|
+
self._executable = self._resolve()
|
|
159
|
+
command = [str(self._executable), *args, *(["--global"] if scope == "global" else [])]
|
|
160
|
+
environ = {**(os.environ if self._env is None else self._env), "NO_COLOR": "1"}
|
|
161
|
+
if self._home is not None:
|
|
162
|
+
environ["HOME"] = str(self._home)
|
|
163
|
+
try:
|
|
164
|
+
result = subprocess.run(
|
|
165
|
+
command,
|
|
166
|
+
cwd=workspace,
|
|
167
|
+
env=environ,
|
|
168
|
+
check=False,
|
|
169
|
+
capture_output=True,
|
|
170
|
+
text=True,
|
|
171
|
+
stdin=subprocess.DEVNULL,
|
|
172
|
+
)
|
|
173
|
+
except OSError as exc:
|
|
174
|
+
raise OpenPackageError(f"could not run {command[0]}: {exc}") from exc
|
|
175
|
+
if result.returncode != 0:
|
|
176
|
+
raise OpenPackageError(
|
|
177
|
+
f"opkg {args[0]} failed (exit {result.returncode}):\n"
|
|
178
|
+
f"{_tail(result.stdout + result.stderr)}"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def install(self, package_dir: Path, *, platform: str, scope: Scope, workspace: Path) -> None:
|
|
182
|
+
self._run(
|
|
183
|
+
["install", str(package_dir), "--platforms", platform, "--force"],
|
|
184
|
+
scope=scope,
|
|
185
|
+
workspace=workspace,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def uninstall(self, package: str, *, scope: Scope, workspace: Path) -> None:
|
|
189
|
+
self._run(["uninstall", package], scope=scope, workspace=workspace)
|
|
190
|
+
|
|
191
|
+
def installed(
|
|
192
|
+
self, package: str, *, scope: Scope, workspace: Path
|
|
193
|
+
) -> Mapping[str, tuple[str, ...]] | None:
|
|
194
|
+
index = (self._home_dir() if scope == "global" else workspace) / _INDEX
|
|
195
|
+
try:
|
|
196
|
+
loaded: object = yaml.safe_load(index.read_text(encoding="utf-8"))
|
|
197
|
+
except FileNotFoundError:
|
|
198
|
+
return None
|
|
199
|
+
except (OSError, yaml.YAMLError) as exc:
|
|
200
|
+
raise OpenPackageError(f"cannot read OpenPackage's index {index}: {exc}") from exc
|
|
201
|
+
packages = _mapping(_mapping(loaded).get("packages"))
|
|
202
|
+
if package not in packages:
|
|
203
|
+
return None
|
|
204
|
+
files = _mapping(_mapping(packages[package]).get("files"))
|
|
205
|
+
return {
|
|
206
|
+
str(source): tuple(str(t) for t in cast("list[Any]", targets))
|
|
207
|
+
if isinstance(targets, list)
|
|
208
|
+
else ()
|
|
209
|
+
for source, targets in files.items()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _mapping(value: object) -> dict[str, Any]:
|
|
214
|
+
return cast("dict[str, Any]", value) if isinstance(value, dict) else {}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Packages written to the Katalyst cache, one directory per harness of one repository.
|
|
2
|
+
|
|
3
|
+
``<cache home>/harness/packages/<repository key>/<harness>/``: the key is derived from
|
|
4
|
+
the repository's path, so two repositories with a harness of the same name do not share a
|
|
5
|
+
package. A markdown file is its generated frontmatter followed by the body file's text;
|
|
6
|
+
every other file is copied as it is.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import hashlib
|
|
12
|
+
import shutil
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
import yaml
|
|
16
|
+
|
|
17
|
+
from katalyst_plugin_harness.domain.package import MANIFEST, Package
|
|
18
|
+
|
|
19
|
+
__all__ = ["CachePackageStore", "markdown", "package_root"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def package_root(workspace: Path) -> Path:
|
|
23
|
+
"""Where the packages of the repository at *workspace* are built."""
|
|
24
|
+
from katalyst_taxonomy.domain.homes import resolve_home
|
|
25
|
+
|
|
26
|
+
key = hashlib.sha256(str(workspace.resolve()).encode()).hexdigest()[:16]
|
|
27
|
+
return resolve_home().cache_dir / "harness" / "packages" / key
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _yaml(data: object) -> str:
|
|
31
|
+
return yaml.safe_dump(data, sort_keys=False, width=100, allow_unicode=True)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def markdown(frontmatter: object, body: str) -> str:
|
|
35
|
+
"""A markdown file: ``---`` frontmatter ``---``, a blank line, then *body*."""
|
|
36
|
+
return f"---\n{_yaml(frontmatter)}---\n\n{body.lstrip(chr(10))}"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class CachePackageStore:
|
|
40
|
+
"""Implements :class:`~katalyst_plugin_harness.ports.PackageStore` under *root*."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, root: Path) -> None:
|
|
43
|
+
self._root = root
|
|
44
|
+
|
|
45
|
+
def location(self, package: Package) -> Path:
|
|
46
|
+
return self._root / package.harness.name
|
|
47
|
+
|
|
48
|
+
def write(self, package: Package) -> Path:
|
|
49
|
+
directory = self.location(package)
|
|
50
|
+
if directory.exists():
|
|
51
|
+
shutil.rmtree(directory)
|
|
52
|
+
directory.mkdir(parents=True)
|
|
53
|
+
(directory / MANIFEST).write_text(_yaml(dict(package.manifest)), encoding="utf-8")
|
|
54
|
+
for item in package.files:
|
|
55
|
+
target = directory / item.path
|
|
56
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
57
|
+
if item.frontmatter is None:
|
|
58
|
+
shutil.copy2(item.source, target)
|
|
59
|
+
else:
|
|
60
|
+
body = item.source.read_text(encoding="utf-8")
|
|
61
|
+
target.write_text(markdown(dict(item.frontmatter), body), encoding="utf-8")
|
|
62
|
+
return directory
|