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.
- katalyst_plugin_scaffolding-1.0.1a1/.gitignore +123 -0
- katalyst_plugin_scaffolding-1.0.1a1/PKG-INFO +16 -0
- katalyst_plugin_scaffolding-1.0.1a1/layer/README.md +5 -0
- katalyst_plugin_scaffolding-1.0.1a1/pyproject.toml +48 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/__init__.py +5 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/__init__.py +15 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/released/0.1.0/SHA256SUMS +1 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/released/0.1.0/scaffolding.yaml +54 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/scaffolding.yaml +54 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/plugin.py +79 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/py.typed +0 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/rest_routes.py +117 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/schema.py +75 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/__init__.py +6 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/bundle_install.py +238 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/cli.py +177 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/composed_install.py +360 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/layout.py +332 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/plugin.py +142 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/plugin_dirs.py +44 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/py.typed +0 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/recipe_wiring.py +120 -0
- katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/templates/template_remove.py +153 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/README.md +5 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/features/plugin.feature +4 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/features/scaffolding.feature +17 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/features/steps/fixtures.ts +57 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/features/steps/steps.ts +74 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/package-lock.json +539 -0
- katalyst_plugin_scaffolding-1.0.1a1/xspec/package.json +11 -0
- 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,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,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."""
|
katalyst_plugin_scaffolding-1.0.1a1/src/katalyst_plugin_scaffolding/linkml/released/0.1.0/SHA256SUMS
ADDED
|
@@ -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)
|
|
File without changes
|
|
@@ -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
|
+
"""
|