katalyst-plugin-scaffolding 1.0.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.
Files changed (31) hide show
  1. katalyst_plugin_scaffolding-1.0.1a1/.gitignore +123 -0
  2. katalyst_plugin_scaffolding-1.0.1a1/PKG-INFO +16 -0
  3. katalyst_plugin_scaffolding-1.0.1a1/layer/README.md +5 -0
  4. katalyst_plugin_scaffolding-1.0.1a1/pyproject.toml +48 -0
  5. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/__init__.py +5 -0
  6. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/__init__.py +15 -0
  7. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/released/0.1.0/SHA256SUMS +1 -0
  8. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/released/0.1.0/scaffolding.yaml +54 -0
  9. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/scaffolding.yaml +54 -0
  10. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/plugin.py +79 -0
  11. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/py.typed +0 -0
  12. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/rest_routes.py +117 -0
  13. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/schema.py +75 -0
  14. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/__init__.py +6 -0
  15. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/bundle_install.py +238 -0
  16. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/cli.py +177 -0
  17. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/composed_install.py +360 -0
  18. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/layout.py +332 -0
  19. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/plugin.py +142 -0
  20. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/plugin_dirs.py +44 -0
  21. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/py.typed +0 -0
  22. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/recipe_wiring.py +120 -0
  23. katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/template_remove.py +153 -0
  24. katalyst_plugin_scaffolding-1.0.1a1/xspec/README.md +5 -0
  25. katalyst_plugin_scaffolding-1.0.1a1/xspec/features/plugin.feature +4 -0
  26. katalyst_plugin_scaffolding-1.0.1a1/xspec/features/scaffolding.feature +17 -0
  27. katalyst_plugin_scaffolding-1.0.1a1/xspec/features/steps/fixtures.ts +57 -0
  28. katalyst_plugin_scaffolding-1.0.1a1/xspec/features/steps/steps.ts +74 -0
  29. katalyst_plugin_scaffolding-1.0.1a1/xspec/package-lock.json +539 -0
  30. katalyst_plugin_scaffolding-1.0.1a1/xspec/package.json +11 -0
  31. katalyst_plugin_scaffolding-1.0.1a1/xspec/playwright.config.ts +12 -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,16 @@
1
+ Metadata-Version: 2.5
2
+ Name: katalyst-plugin-scaffolding
3
+ Version: 1.0.1a1
4
+ Summary: Katalyst scaffolding plugin
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: pydantic>=2.0
16
+ Requires-Dist: pyyaml
@@ -0,0 +1,5 @@
1
+ # scaffolding library layer
2
+
3
+ This directory is the plugin's taxonomy-library layer: package-owned fixtures,
4
+ contracts, and future layer-local resources. It is intentionally separate from
5
+ runtime source and from the plugin's xspec project.
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "katalyst-plugin-scaffolding"
3
+ version = "1.0.1a1"
4
+ description = "Katalyst scaffolding plugin"
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 REST routes 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
+ # The recipe wiring is rendered from the Jinja templates a collection names.
20
+ "jinja2>=3.1",
21
+ "pydantic>=2.0",
22
+ "click>=8.0",
23
+ ]
24
+
25
+ [project.entry-points."katalyst_taxonomy.plugins"]
26
+ scaffolding = "katalyst_plugin_scaffolding:ScaffoldingPlugin"
27
+
28
+ # node_wiring documents are ordinary registered kinds, declared like any bundle's.
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
+ scaffolding = "katalyst_plugin_scaffolding.linkml:MODULES"
33
+
34
+ [project.entry-points."katalyst_engine.bundles"]
35
+ scaffolding-schema = "katalyst_plugin_scaffolding.schema:ScaffoldingSchemaBundle"
36
+
37
+ [project.entry-points."katalyst_taxonomy.cli"]
38
+ add = "katalyst_plugin_scaffolding.templates.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_scaffolding"]
46
+
47
+ [tool.hatch.build.targets.wheel.sources]
48
+ "src" = ""
@@ -0,0 +1,5 @@
1
+ """Scaffolding plugin — universal scaffold for node creation."""
2
+
3
+ from .plugin import ScaffoldingPlugin
4
+
5
+ __all__ = ["ScaffoldingPlugin"]
@@ -0,0 +1,15 @@
1
+ """LinkML modules this package ships, on katalyst-core.
2
+
3
+ Registered under the ``katalyst_core.modules`` entry point, so core loads them by name.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from pathlib import Path
9
+
10
+ __all__ = ["MODULES"]
11
+
12
+ MODULES: dict[str, Path] = {
13
+ path.stem: path for path in sorted(Path(__file__).parent.glob("*.yaml"))
14
+ }
15
+ """Module name (as an ``imports:`` line writes it) to its YAML file."""
@@ -0,0 +1 @@
1
+ cb3f7942331947e4995dc5a067f51435bd59e2ea7292eabdf1be26eb2141340b scaffolding.yaml
@@ -0,0 +1,54 @@
1
+ # Generated once from the Python definitions (LinkML rebuild, phase 4); edit here.
2
+ id: https://w3id.org/katalyst/scaffolding/scaffolding
3
+ name: scaffolding
4
+ title: scaffolding scaffolding wing
5
+ version: 0.1.0
6
+ license: Proprietary
7
+ prefixes:
8
+ scaffolding: https://w3id.org/katalyst/scaffolding/
9
+ kc: https://w3id.org/katalyst/core/
10
+ linkml: https://w3id.org/linkml/
11
+ dcterms: http://purl.org/dc/terms/
12
+ default_prefix: scaffolding
13
+ default_range: string
14
+ imports:
15
+ - linkml:types
16
+ - katalyst_core
17
+ description: The scaffolding wing.
18
+ annotations:
19
+ wing: scaffolding
20
+ display_name: Scaffolding
21
+ describes_kind: wing
22
+ classes:
23
+ NodeWiring:
24
+ is_a: Node
25
+ class_uri: scaffolding:NodeWiring
26
+ description: 'A node wiring: a node_wiring node of the scaffolding wing.'
27
+ attributes:
28
+ description:
29
+ description: What this wiring adds to scaffolded nodes
30
+ slot_uri: dcterms:description
31
+ extends:
32
+ description: 'The templates it extends: targetKind and targetNames (''*'' for all)'
33
+ slot_uri: scaffolding:extends
34
+ range: AnyValue
35
+ provides_template:
36
+ description: Template directory whose files are added, relative to this document
37
+ slot_uri: scaffolding:providesTemplate
38
+ annotations:
39
+ kind: node_wiring
40
+ wing: scaffolding
41
+ label: Node Wiring
42
+ label_plural: Node Wirings
43
+ display_order: 900
44
+ directory_name: node_wiring
45
+ root: true
46
+ leaf: true
47
+ storage:
48
+ tag: storage
49
+ value:
50
+ root: .global/taxonomy
51
+ container: file
52
+ filename: identity
53
+ nest_under_parent: false
54
+ scaffold: null
@@ -0,0 +1,54 @@
1
+ # Generated once from the Python definitions (LinkML rebuild, phase 4); edit here.
2
+ id: https://w3id.org/katalyst/scaffolding/scaffolding
3
+ name: scaffolding
4
+ title: scaffolding scaffolding wing
5
+ version: 0.1.0
6
+ license: Proprietary
7
+ prefixes:
8
+ scaffolding: https://w3id.org/katalyst/scaffolding/
9
+ kc: https://w3id.org/katalyst/core/
10
+ linkml: https://w3id.org/linkml/
11
+ dcterms: http://purl.org/dc/terms/
12
+ default_prefix: scaffolding
13
+ default_range: string
14
+ imports:
15
+ - linkml:types
16
+ - katalyst_core
17
+ description: The scaffolding wing.
18
+ annotations:
19
+ wing: scaffolding
20
+ display_name: Scaffolding
21
+ describes_kind: wing
22
+ classes:
23
+ NodeWiring:
24
+ is_a: Node
25
+ class_uri: scaffolding:NodeWiring
26
+ description: 'A node wiring: a node_wiring node of the scaffolding wing.'
27
+ attributes:
28
+ description:
29
+ description: What this wiring adds to scaffolded nodes
30
+ slot_uri: dcterms:description
31
+ extends:
32
+ description: 'The templates it extends: targetKind and targetNames (''*'' for all)'
33
+ slot_uri: scaffolding:extends
34
+ range: AnyValue
35
+ provides_template:
36
+ description: Template directory whose files are added, relative to this document
37
+ slot_uri: scaffolding:providesTemplate
38
+ annotations:
39
+ kind: node_wiring
40
+ wing: scaffolding
41
+ label: Node Wiring
42
+ label_plural: Node Wirings
43
+ display_order: 900
44
+ directory_name: node_wiring
45
+ root: true
46
+ leaf: true
47
+ storage:
48
+ tag: storage
49
+ value:
50
+ root: .global/taxonomy
51
+ container: file
52
+ filename: identity
53
+ nest_under_parent: false
54
+ scaffold: null
@@ -0,0 +1,79 @@
1
+ """Scaffolding plugin — the template-bundle machinery scaffolding copies from.
2
+
3
+ Registers how template bundles are installed into, removed from, listed in and described
4
+ for a repository; how a fetched collection's bundle manifests are found; the probe
5
+ ``node_wiring`` documents check; the create hook that writes a scaffolded node's
6
+ wiring file; and ``/ext/scaffolding/variants``, the installed variants a form offers
7
+ (:mod:`katalyst_plugin_scaffolding.rest_routes`). ``kata tax add`` arrives over the ``katalyst_taxonomy.cli`` entry point.
8
+
9
+ The scaffold copy itself is not here. The runtime's scaffolding hook
10
+ (:mod:`katalyst_taxonomy.services.scaffolding_hook`) populates a new node's directory
11
+ when a scaffold variant resolves and the kind's template root holds a directory for it
12
+ (otherwise it is a no-op); the variants it copies are the templates this plugin
13
+ installed. There is no engine-level ``scaffoldable`` flag: where a node records its
14
+ variant is its kind's declaration (``ScaffoldPolicy.variant_annotation``, the field with
15
+ the scaffold-variant role).
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import importlib.metadata
21
+
22
+ from katalyst_taxonomy.plugins.protocol import PluginContext, PluginManifest
23
+
24
+
25
+ def _version() -> str:
26
+ """The installed distribution version, for :attr:`PluginManifest.version`.
27
+
28
+ No built-in plugin populated ``version`` before #219 — it was declared and
29
+ always empty, so ``kata config plugins`` could not tell you what you were
30
+ running. Read from installed metadata rather than a hardcoded literal so it
31
+ cannot drift from the package it describes.
32
+ """
33
+ try:
34
+ return importlib.metadata.version("katalyst-plugin-scaffolding")
35
+ except importlib.metadata.PackageNotFoundError: # pragma: no cover - source checkout
36
+ return ""
37
+
38
+
39
+ class ScaffoldingPlugin:
40
+ """The scaffolding plugin: template-bundle machinery and the node wiring create hook.
41
+
42
+ ``scaffold``: it installs the templates scaffolding copies; ``post_create``: its create
43
+ hook runs after a node is created.
44
+ """
45
+
46
+ @property
47
+ def name(self) -> str:
48
+ return "scaffolding"
49
+
50
+ @property
51
+ def manifest(self) -> PluginManifest:
52
+ return PluginManifest(
53
+ name="scaffolding",
54
+ capabilities=("scaffold", "post_create"),
55
+ description="Template bundles for scaffolding, and the node wiring create hook",
56
+ version=_version(),
57
+ )
58
+
59
+ def register(self, context: PluginContext) -> None:
60
+ """Register the template-bundle machinery and the create hook with *context*."""
61
+ from katalyst_plugin_scaffolding.rest_routes import ScaffoldingRestRoutes
62
+ from katalyst_plugin_scaffolding.templates.bundle_install import (
63
+ describe_bundle,
64
+ install_template_for_plugin,
65
+ installed_bundles,
66
+ )
67
+ from katalyst_plugin_scaffolding.templates.plugin import register_template_contributions
68
+ from katalyst_plugin_scaffolding.templates.template_remove import (
69
+ remove_template_for_plugin,
70
+ )
71
+
72
+ # No init hook: `kata tax init` installs what the user config declares
73
+ # (spec.templates), which a bundle's own init hook may add to.
74
+ register_template_contributions(context)
75
+ context.rest_routes.append(ScaffoldingRestRoutes())
76
+ context.template_installers.append(install_template_for_plugin)
77
+ context.template_removers.append(remove_template_for_plugin)
78
+ context.template_listers.append(installed_bundles)
79
+ context.template_describers.append(describe_bundle)
@@ -0,0 +1,117 @@
1
+ # pyright: reportUnusedFunction=false
2
+ #
3
+ # The routes are nested functions registered by their decorators and never referenced by
4
+ # name; the REST app mounts the router this returns.
5
+ """``/ext/scaffolding`` — the installed scaffold variants, for a form that creates nodes.
6
+
7
+ ================================== ======================================================
8
+ Route Answers
9
+ ================================== ======================================================
10
+ ``GET /ext/scaffolding/variants`` every scaffold variant installed in the repository
11
+ (``?kind=`` one kind's; ``?holds=ROLE`` those whose
12
+ nodes hold ROLE): its bundle and version, its
13
+ declaration, what its nodes hold, its files, its
14
+ expansions and every token it renders with where the
15
+ value comes from
16
+ ================================== ======================================================
17
+
18
+ A read: nothing is written. ``backend`` names the repository, as every REST route that
19
+ reads one repository's files does. The answer is
20
+ :mod:`katalyst_taxonomy.services.scaffold_catalog`'s.
21
+ """
22
+
23
+ # No `from __future__ import annotations`: FastAPI reads the handlers' annotations.
24
+ from pathlib import Path
25
+ from typing import Any
26
+
27
+
28
+ class ScaffoldingRestRoutes:
29
+ """Implements :class:`~katalyst_taxonomy.plugins.extensions.RestRoutes`."""
30
+
31
+ @property
32
+ def name(self) -> str:
33
+ return "scaffolding"
34
+
35
+ def router(self) -> Any:
36
+ from fastapi import APIRouter
37
+ from fastapi.responses import JSONResponse
38
+ from katalyst_taxonomy.config.installs import declared_config
39
+ from katalyst_taxonomy.services.scaffold_catalog import (
40
+ BundleFiles,
41
+ declared_tokens,
42
+ scaffold_variants,
43
+ )
44
+ from katalyst_taxonomy_mcp.response import ok
45
+ from katalyst_taxonomy_mcp.rest.repository import repository_or_refusal
46
+
47
+ from katalyst_plugin_scaffolding.templates.bundle_install import (
48
+ describe_bundle,
49
+ installed_bundles,
50
+ )
51
+
52
+ router = APIRouter()
53
+
54
+ def bundles(root: Path) -> list[BundleFiles]:
55
+ """The declared template bundles *root* has installed, with the files of each."""
56
+ config = declared_config()[0]
57
+ declared = config.spec.templates if config is not None else ()
58
+ have = set(installed_bundles(root, {t.name: t.source for t in declared}))
59
+ out: list[BundleFiles] = []
60
+ for template in declared:
61
+ if template.name not in have:
62
+ continue
63
+ described = describe_bundle(root, template.name, template.source) or {}
64
+ files = [str(f) for f in described.get("files") or ()]
65
+ out.append(BundleFiles(template.name, str(template.version or ""), files))
66
+ return out
67
+
68
+ @router.get("/variants", response_model=None)
69
+ def variants(
70
+ kind: str | None = None, holds: str | None = None, backend: str | None = None
71
+ ) -> Any:
72
+ """The variants installed in *backend*'s repository: of *kind*, holding *holds*."""
73
+ repository = repository_or_refusal(backend)
74
+ if isinstance(repository, JSONResponse):
75
+ return repository
76
+ root = repository.root
77
+ found = scaffold_variants(
78
+ root,
79
+ filesystem=_Files(),
80
+ bundles=bundles(root),
81
+ kind=kind or None,
82
+ holds=holds or None,
83
+ )
84
+ return ok(
85
+ {
86
+ "backend": repository.name,
87
+ "kind": kind,
88
+ "holds": holds,
89
+ "variants": [variant.to_dict() for variant in found],
90
+ # The kind's own scaffold tokens: fields only a template renders.
91
+ "tokens": declared_tokens(kind) if kind else [],
92
+ }
93
+ )
94
+
95
+ return router
96
+
97
+
98
+ class _Files:
99
+ """The repository's files, read — the ``FileReader`` the catalog reads through."""
100
+
101
+ def exists(self, path: Path) -> bool:
102
+ return path.exists()
103
+
104
+ def is_directory(self, path: Path) -> bool:
105
+ return path.is_dir()
106
+
107
+ def is_file(self, path: Path) -> bool:
108
+ return path.is_file()
109
+
110
+ def read_file(self, path: Path) -> str:
111
+ return path.read_text(encoding="utf-8")
112
+
113
+ def list_directory(self, path: Path) -> list[Path]:
114
+ return list(path.iterdir()) if path.is_dir() else []
115
+
116
+ def glob(self, path: Path, pattern: str) -> list[Path]:
117
+ return list(path.glob(pattern))
@@ -0,0 +1,75 @@
1
+ """Schema bundle for the scaffolding plugin: the ``node_wiring`` kind.
2
+
3
+ A ``node_wiring`` document is ordinary taxonomy content. It lives in a repository,
4
+ under ``.global/taxonomy/node_wiring/``, and adds files to scaffolded nodes: it names
5
+ the templates it extends and the template directory it provides, and it activates only
6
+ when the plugins it requires are installed.
7
+
8
+ Declaring it (in the LinkML module ``linkml/scaffolding.yaml``) makes it a registered kind like any other, validated and listed. The
9
+ runtime keeps no list of kinds to skip.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from functools import cache
15
+
16
+ from katalyst_engine.bundle.protocol import BundleManifest
17
+ from katalyst_engine.core.identity import Identity
18
+ from katalyst_engine.core.version import Version
19
+ from katalyst_engine.schema.definition import (
20
+ NodeDefinition,
21
+ SchemaDefinition,
22
+ WingDefinition,
23
+ )
24
+ from katalyst_engine.schema.manager import SchemaManager
25
+ from katalyst_engine.toolkit.linkml import LinkMLDefinitions, installed_definitions
26
+
27
+ #: The bundle's entry-point name, as a profile's ``schemas`` list names it.
28
+ BUNDLE_NAME = "scaffolding-schema"
29
+ WING = "scaffolding"
30
+ KIND = "node_wiring"
31
+
32
+ #: The LinkML module this bundle builds its definitions from (``linkml/scaffolding.yaml``).
33
+ MODULES = ("scaffolding",)
34
+
35
+
36
+ @cache
37
+ def _definitions() -> LinkMLDefinitions:
38
+ return installed_definitions(MODULES)
39
+
40
+
41
+ NODE_WIRING: NodeDefinition = next(n for n in _definitions().nodes if n.describes_kind == KIND)
42
+ SCAFFOLDING_WING: WingDefinition = next(w for w in _definitions().wings if w.identity.name == WING)
43
+
44
+
45
+ class ScaffoldingSchemaBundle:
46
+ """Contributes ``node_wiring``, and the wing it lives in."""
47
+
48
+ @property
49
+ def manifest(self) -> BundleManifest:
50
+ return BundleManifest(
51
+ identity=Identity(kind="bundle", name=BUNDLE_NAME),
52
+ version=Version(major=0, minor=1),
53
+ modules=MODULES,
54
+ provided_kinds=frozenset({KIND}),
55
+ wing_names=frozenset({WING}),
56
+ description="Schema for the documents the scaffolding plugin reads",
57
+ )
58
+
59
+ def node_definitions(self) -> list[NodeDefinition]:
60
+ return [NODE_WIRING]
61
+
62
+ def wing_definitions(self) -> list[WingDefinition]:
63
+ return [SCAFFOLDING_WING]
64
+
65
+ def schema_definition(self) -> SchemaDefinition:
66
+ return SchemaDefinition(
67
+ identity=Identity(kind="schema", name=BUNDLE_NAME),
68
+ describes_kind="taxonomy",
69
+ api_version="v2alpha",
70
+ schema_version=Version(major=0, minor=1),
71
+ node_definitions=(NODE_WIRING.identity,),
72
+ )
73
+
74
+ def register(self, manager: SchemaManager) -> None:
75
+ manager.register_schema(self.schema_definition(), node_definitions=self.node_definitions())
@@ -0,0 +1,6 @@
1
+ """Template bundles, as a taxonomy plugin.
2
+
3
+ Installs, lists, describes and removes the template bundles a user config declares
4
+ (``spec.templates``) — every bundle the same way, from its manifest in its declared
5
+ source — and contributes the ``kata tax add`` command.
6
+ """