katalyst-taxonomy-cli 2.0.1a7__tar.gz → 2.0.1a9__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 (156) hide show
  1. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/PKG-INFO +1 -1
  2. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/pyproject.toml +35 -1
  3. katalyst_taxonomy_cli-2.0.1a9/src/Justfile +2 -0
  4. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/_wiring.py +8 -2
  5. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/app.py +26 -0
  6. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/bundle.py +7 -5
  7. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config_profile.py +40 -12
  8. katalyst_taxonomy_cli-2.0.1a9/src/katalyst_taxonomy_cli/commands/config_sources.py +405 -0
  9. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/create.py +27 -0
  10. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/deps.py +12 -2
  11. katalyst_taxonomy_cli-2.0.1a9/src/katalyst_taxonomy_cli/commands/drafts.py +103 -0
  12. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/lifecycle.py +59 -8
  13. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/lint.py +15 -0
  14. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/plugin.py +3 -4
  15. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/query.py +49 -4
  16. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/rescaffold.py +2 -1
  17. katalyst_taxonomy_cli-2.0.1a9/src/katalyst_taxonomy_cli/commands/show.py +60 -0
  18. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/update.py +32 -0
  19. katalyst_taxonomy_cli-2.0.1a9/src/katalyst_taxonomy_cli/commands/variant.py +271 -0
  20. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/context.py +13 -1
  21. katalyst_taxonomy_cli-2.0.1a9/src/katalyst_taxonomy_cli/options.py +122 -0
  22. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/releases.py +1 -1
  23. katalyst_taxonomy_cli-2.0.1a9/src/layer.yaml +23 -0
  24. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/conftest.py +1 -7
  25. katalyst_taxonomy_cli-2.0.1a9/tests/test_agents_home_mcp.py +126 -0
  26. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_cli_version.py +1 -1
  27. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_command.py +1 -1
  28. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_explain.py +1 -1
  29. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_plugins_command.py +1 -1
  30. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_profiles.py +1 -1
  31. katalyst_taxonomy_cli-2.0.1a9/tests/test_config_sources.py +308 -0
  32. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_core_schema.py +1 -1
  33. katalyst_taxonomy_cli-2.0.1a9/tests/test_create_variant_field.py +158 -0
  34. katalyst_taxonomy_cli-2.0.1a9/tests/test_help_names_no_product.py +51 -0
  35. katalyst_taxonomy_cli-2.0.1a9/tests/test_k1_runtime_additions.py +283 -0
  36. katalyst_taxonomy_cli-2.0.1a9/tests/test_kind_selector_shared_path.py +160 -0
  37. katalyst_taxonomy_cli-2.0.1a9/tests/test_lifecycle_moves.py +125 -0
  38. katalyst_taxonomy_cli-2.0.1a9/tests/test_mcp_config_tool_parity.py +684 -0
  39. katalyst_taxonomy_cli-2.0.1a9/tests/test_nested_collection_and_scope.py +142 -0
  40. katalyst_taxonomy_cli-2.0.1a9/tests/test_node_under_parent_directory.py +129 -0
  41. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_plugin_gating.py +1 -1
  42. katalyst_taxonomy_cli-2.0.1a9/tests/test_qualified_filenames.py +144 -0
  43. katalyst_taxonomy_cli-2.0.1a9/tests/test_relate_properties.py +148 -0
  44. katalyst_taxonomy_cli-2.0.1a9/tests/test_relocation.py +330 -0
  45. katalyst_taxonomy_cli-2.0.1a9/tests/test_rest_shipped_plugins.py +41 -0
  46. katalyst_taxonomy_cli-2.0.1a9/tests/test_scaffold_holdings.py +232 -0
  47. katalyst_taxonomy_cli-2.0.1a9/tests/test_schema_gate.py +141 -0
  48. katalyst_taxonomy_cli-2.0.1a9/tests/test_variant_command.py +167 -0
  49. katalyst_taxonomy_cli-2.0.1a9/xspec/.gitignore +7 -0
  50. katalyst_taxonomy_cli-2.0.1a9/xspec/Justfile +2 -0
  51. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/01_kata_init.feature +222 -0
  52. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/02_kata_clone.feature +103 -0
  53. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/04_kata_deps.feature +219 -0
  54. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/06_kata_status.feature +35 -0
  55. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/11_kata_create_expanded.feature +179 -0
  56. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/13_kata_portfolio_org.feature +174 -0
  57. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/14_kata_resolve.feature +94 -0
  58. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/17_kata_show.feature +37 -0
  59. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/19_kata_backend_ops.feature +19 -0
  60. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/20_kata_promotion.feature +27 -0
  61. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/21_kata_roundtrip.feature +86 -0
  62. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/22_kata_error_ux.feature +97 -0
  63. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/23_kata_show_deep.feature +103 -0
  64. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/24_kata_resolve_deep.feature +85 -0
  65. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/26_kata_fresh_repo.feature +19 -0
  66. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/31_kata_config_discovery.feature +212 -0
  67. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/32_kata_config_profiles.feature +189 -0
  68. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/43_kata_relate_update.feature +59 -0
  69. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/44_kata_create_typed_fields.feature +66 -0
  70. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/51_kata_labels_annotations.feature +76 -0
  71. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/57_kata_self_channels.feature +39 -0
  72. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/58_kata_import_change_set.feature +71 -0
  73. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/59_kata_update_in_place.feature +58 -0
  74. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/63_kata_library_layers.feature +115 -0
  75. katalyst_taxonomy_cli-2.0.1a9/xspec/features/cli/64_kata_xspec_layers.feature +150 -0
  76. katalyst_taxonomy_cli-2.0.1a9/xspec/layer.yaml +23 -0
  77. katalyst_taxonomy_cli-2.0.1a9/xspec/package.json +19 -0
  78. katalyst_taxonomy_cli-2.0.1a9/xspec/playwright.config.ts +5 -0
  79. katalyst_taxonomy_cli-2.0.1a9/xspec/tsconfig.json +4 -0
  80. katalyst_taxonomy_cli-2.0.1a7/src/katalyst_taxonomy_cli/commands/config_sources.py +0 -147
  81. katalyst_taxonomy_cli-2.0.1a7/src/katalyst_taxonomy_cli/commands/drafts.py +0 -63
  82. katalyst_taxonomy_cli-2.0.1a7/src/katalyst_taxonomy_cli/commands/show.py +0 -33
  83. katalyst_taxonomy_cli-2.0.1a7/src/katalyst_taxonomy_cli/options.py +0 -20
  84. katalyst_taxonomy_cli-2.0.1a7/tests/test_config_sources.py +0 -157
  85. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/.gitignore +0 -0
  86. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/__init__.py +0 -0
  87. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/__main__.py +0 -0
  88. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/__init__.py +0 -0
  89. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/api.py +0 -0
  90. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/backend.py +0 -0
  91. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/clone.py +0 -0
  92. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config.py +0 -0
  93. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config_filters.py +0 -0
  94. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config_home.py +0 -0
  95. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config_plugins.py +0 -0
  96. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/config_schemas.py +0 -0
  97. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/core.py +0 -0
  98. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/diff.py +0 -0
  99. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/export.py +0 -0
  100. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/init.py +0 -0
  101. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/kinds.py +0 -0
  102. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/migrate.py +0 -0
  103. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/promote.py +0 -0
  104. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/relate.py +0 -0
  105. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/relocate.py +0 -0
  106. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/remove.py +0 -0
  107. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/resolve.py +0 -0
  108. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/rollback.py +0 -0
  109. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/self_update.py +0 -0
  110. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/status.py +0 -0
  111. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/sync.py +0 -0
  112. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/commands/versions.py +0 -0
  113. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/discovery.py +0 -0
  114. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/fields.py +0 -0
  115. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/install.py +0 -0
  116. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/installer.py +0 -0
  117. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/output.py +0 -0
  118. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/src/katalyst_taxonomy_cli/py.typed +0 -0
  119. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_add.py +0 -0
  120. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_add_bundle.py +0 -0
  121. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_api_command.py +0 -0
  122. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_backend_option.py +0 -0
  123. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_clone.py +0 -0
  124. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_command_signatures.py +0 -0
  125. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_home.py +0 -0
  126. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_config_schemas_command.py +0 -0
  127. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_create.py +0 -0
  128. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_create_owners.py +0 -0
  129. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_create_typed_and_variants.py +0 -0
  130. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_deps.py +0 -0
  131. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_git_backend_cli.py +0 -0
  132. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_github_backend_cli.py +0 -0
  133. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_import_change_set.py +0 -0
  134. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_import_inside_repo.py +0 -0
  135. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_install.py +0 -0
  136. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_installer.py +0 -0
  137. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_kinds.py +0 -0
  138. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_kinds_plugin_settings.py +0 -0
  139. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_labels_annotations.py +0 -0
  140. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_lifecycle_kind_selector.py +0 -0
  141. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_lint_output.py +0 -0
  142. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_lint_profile_graph.py +0 -0
  143. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_lint_strict.py +0 -0
  144. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_migrate.py +0 -0
  145. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_optional_extras.py +0 -0
  146. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_output.py +0 -0
  147. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_plugin_command.py +0 -0
  148. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_relate_update.py +0 -0
  149. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_releases.py +0 -0
  150. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_relocate.py +0 -0
  151. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_remove.py +0 -0
  152. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_repository_targets.py +0 -0
  153. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_self_channels.py +0 -0
  154. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_self_update.py +0 -0
  155. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_template_merge.py +0 -0
  156. {katalyst_taxonomy_cli-2.0.1a7 → katalyst_taxonomy_cli-2.0.1a9}/tests/test_update_in_place.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: katalyst-taxonomy-cli
3
- Version: 2.0.1a7
3
+ Version: 2.0.1a9
4
4
  Summary: CLI for katalyst-taxonomy — the kata command
5
5
  Author: eSimplicity
6
6
  License: Proprietary
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "katalyst-taxonomy-cli"
3
- version = "2.0.1a7"
3
+ version = "2.0.1a9"
4
4
  description = "CLI for katalyst-taxonomy — the kata command"
5
5
  license = { text = "Proprietary" }
6
6
  requires-python = ">=3.12"
@@ -41,3 +41,37 @@ packages = ["src/katalyst_taxonomy_cli"]
41
41
 
42
42
  [tool.hatch.build.targets.wheel.sources]
43
43
  "src" = ""
44
+
45
+ [dependency-groups]
46
+ dev = [
47
+ "katalyst-test-bundle",
48
+ "pytest>=8.2",
49
+ "pytest-cov>=5.0",
50
+ "ruff>=0.5",
51
+ "pyright>=1.1",
52
+ ]
53
+
54
+ [tool.pytest.ini_options]
55
+ addopts = ["-ra"]
56
+ testpaths = ["tests"]
57
+ pythonpath = ["src"]
58
+
59
+ [tool.ruff]
60
+ target-version = "py312"
61
+ line-length = 100
62
+ # As at the repository root, no first-party sources: every import sorts as a third-party one.
63
+ src = []
64
+
65
+ [tool.ruff.lint]
66
+ select = ["E4", "E7", "E9", "F", "B", "I"]
67
+
68
+ [tool.ruff.format]
69
+ quote-style = "double"
70
+
71
+ [tool.pyright]
72
+ include = ["src", "tests"]
73
+ exclude = ["**/node_modules", "**/__pycache__", "**/.*"]
74
+ venvPath = "."
75
+ venv = ".venv"
76
+ pythonVersion = "3.12"
77
+ typeCheckingMode = "strict"
@@ -0,0 +1,2 @@
1
+ # katalyst-taxonomy-cli: the Circuit's recipes, run from the package directory (cli/).
2
+ import '../../scripts/package.just'
@@ -107,16 +107,21 @@ def load_registry(ctx: CliContext) -> BackendRegistry:
107
107
  """Load the backend registry for *ctx*, honoring the active profile."""
108
108
  from katalyst_taxonomy.config.backends import load_backends
109
109
 
110
- return load_backends(ctx.cwd, profile=ctx.profile)
110
+ registry = load_backends(ctx.cwd, profile=ctx.profile)
111
+ return registry.with_variants(ctx.variants) if ctx.variants else registry
111
112
 
112
113
 
113
- def _registry(ctx: CliContext) -> BackendRegistry:
114
+ def registry_for(ctx: CliContext) -> BackendRegistry:
115
+ """:func:`load_registry`, with a configuration error as a user error, not a traceback."""
114
116
  try:
115
117
  return load_registry(ctx)
116
118
  except Exception as exc: # noqa: BLE001 - config errors are user errors, not tracebacks
117
119
  raise click.ClickException(str(exc)) from exc
118
120
 
119
121
 
122
+ _registry = registry_for
123
+
124
+
120
125
  def _named(registry: BackendRegistry, target: str | None, address: str) -> tuple[str | None, str]:
121
126
  """The backend named by *address* or *target*, and the bare FQTN.
122
127
 
@@ -169,6 +174,7 @@ def resolve_backend(
169
174
  raise click.ClickException(
170
175
  f"Name the backend to use with --backend. This profile reads: {reads}."
171
176
  )
177
+ registry.check_variant_write(name)
172
178
  backend = registry.get(name)
173
179
  except BackendAddressError as exc:
174
180
  raise click.ClickException(str(exc)) from exc
@@ -56,6 +56,7 @@ class KataGroup(click.Group):
56
56
  from katalyst_taxonomy.config.profiles import UnknownProfileError
57
57
  from katalyst_taxonomy.domain.homes import HomeError
58
58
  from katalyst_taxonomy.domain.permissions import PermissionDeniedError
59
+ from katalyst_taxonomy.domain.variants import VariantError
59
60
  from katalyst_taxonomy.plugins.errors import PluginError
60
61
  from katalyst_taxonomy.ports.backend import UnsupportedCapabilityError
61
62
 
@@ -67,6 +68,10 @@ class KataGroup(click.Group):
67
68
  # "Backend 'x' does not support UPDATE": a fact about the backend the user
68
69
  # named, with the capabilities it does have — not a traceback.
69
70
  raise click.ClickException(str(exc)) from exc
71
+ except VariantError as exc:
72
+ # A variant that is not there, is stale, or a write that names several: the
73
+ # message says which and what to do.
74
+ raise click.ClickException(str(exc)) from exc
70
75
  except PluginError as exc:
71
76
  # A plugin that will not activate is a user-fixable configuration or
72
77
  # environment problem, not a bug in this process — it gets the same
@@ -413,6 +418,7 @@ def tax(
413
418
  profile=profile,
414
419
  )
415
420
  _register_source_providers(profile)
421
+ _report_pending_sources()
416
422
  if ctx.invoked_subcommand == "plugin":
417
423
  # `kata tax plugin remove` is how a broken source plugin is taken out; a plugin
418
424
  # that will not activate must not stop the command that removes it.
@@ -469,6 +475,24 @@ def _register_source_providers(profile: str | None) -> None:
469
475
  ensure_source_providers(True, profile=profile)
470
476
 
471
477
 
478
+ def _report_pending_sources() -> None:
479
+ """Say which plugins and schema bundles a sourced profile declares that are not loaded.
480
+
481
+ Loading one runs its code, so it waits for the user to accept it
482
+ (:mod:`katalyst_taxonomy.services.source_consent`). This only reports, on stderr and
483
+ never failing the command; ``kata config sync`` is where it is accepted.
484
+ """
485
+ from katalyst_taxonomy.adapters.orchestration import pending_source_declarations
486
+
487
+ for declaration in pending_source_declarations():
488
+ click.echo(
489
+ f"{declaration.describe()}; it is not loaded, because it runs code. Run "
490
+ f"'{('kata config sync ' + declaration.profile).strip()}' to review and accept it, or "
491
+ f"'{declaration.install_command} {declaration.shown_source}' to install it yourself.",
492
+ err=True,
493
+ )
494
+
495
+
472
496
  # ---------------------------------------------------------------------------
473
497
  # Plugin activation (#219)
474
498
  # ---------------------------------------------------------------------------
@@ -547,6 +571,7 @@ def _register_core_commands() -> None:
547
571
  status,
548
572
  sync,
549
573
  update,
574
+ variant,
550
575
  versions,
551
576
  )
552
577
  from .commands import (
@@ -596,6 +621,7 @@ def _register_core_commands() -> None:
596
621
  tax.add_command(plugin.plugin)
597
622
  tax.add_command(export.export)
598
623
  tax.add_command(backend.backend)
624
+ tax.add_command(variant.variant)
599
625
  tax.add_command(remove.remove)
600
626
  tax.add_command(rescaffold.rescaffold)
601
627
 
@@ -45,13 +45,11 @@ def add_bundle(ctx: CliContext, source_uri: str, yes: bool) -> None:
45
45
  that depend solely on katalyst-engine are accepted.
46
46
  """
47
47
  from katalyst_taxonomy.services.bundle_service import install_bundle
48
+ from katalyst_taxonomy.services.source_consent import CONFIRM_PROMPT, consent_notice
48
49
 
49
50
  if not yes:
50
- click.echo(
51
- "Installing a remote bundle path-imports and executes its Python code.\n"
52
- f"Source: {source_uri}"
53
- )
54
- if not click.confirm("Proceed?", default=False):
51
+ click.echo(consent_notice("schemas", source_uri))
52
+ if not click.confirm(CONFIRM_PROMPT, default=False):
55
53
  ctx.output.echo("Aborted.")
56
54
  raise SystemExit(1)
57
55
 
@@ -90,6 +88,10 @@ def list_bundles(ctx: CliContext) -> None:
90
88
  f" {b.name or b.fqn or '(unnamed)'}{version} [{shown_source(b.source)}] "
91
89
  f"{pin}, {b.state} kinds: {kinds}"
92
90
  )
91
+ if b.error:
92
+ ctx.output.echo(f" error: {b.error}")
93
+ if any(b.state == "failed" for b in bundles):
94
+ ctx.output.echo("A failed bundle is skipped. `kata tax bundle remove <name>` drops it.")
93
95
 
94
96
 
95
97
  @bundle.command("remove")
@@ -8,21 +8,22 @@ MCP ``config_profile_*`` tools and REST ``/config/profiles`` call::
8
8
 
9
9
  kata config profile list | show NAME
10
10
  kata config profile create NAME [--copy-from P | --source URI [--source-profile P]
11
- [--token-env VAR]] [--use]
11
+ [--token-env VAR] [--sync-every D]] [--use]
12
12
  kata config profile delete NAME [--force]
13
13
  kata config profile rename NAME NEW_NAME
14
14
  kata config profile use NAME
15
15
  kata config profile set-list PROFILE {schemas|plugins|templates} [NAMES...] [--all]
16
16
  kata config profile set-source-options NAME [--source-profile P] [--token-env VAR]
17
- [--unset profile|token_env]
17
+ [--sync-every D] [--unset profile|token_env|sync]
18
18
  kata config profile backend list PROFILE | show PROFILE NAME
19
19
  kata config profile backend add PROFILE NAME --type TYPE [settings]
20
20
  kata config profile backend set PROFILE NAME [settings] [--unset KEY]
21
21
  kata config profile backend remove PROFILE NAME [--force]
22
22
 
23
23
  Every change is saved as a whole-document save is: validated, the previous file kept
24
- as ``config.yaml.bak``, and the profile's repositories made to match (declared
25
- templates installed into a new filesystem backend; nothing deleted on removing one).
24
+ as ``config.yaml.bak``, and its plugin and schema sources fetched and every source
25
+ pinned. A change writes to no repository: a repository that lacks a template its profile
26
+ uses is named, with the ``kata tax add`` command that installs it.
26
27
 
27
28
  A profile created with ``--source`` is read from elsewhere (see ``kata config sync``):
28
29
  its backends and lists are refused here, naming the source to change instead. Which
@@ -185,6 +186,9 @@ def _report(out: OutputPort, change: ProfileChange, message: str, fmt: str) -> N
185
186
  if payload["backupPath"]:
186
187
  out.info(f"Previous file kept as {payload['backupPath']}")
187
188
  for step in payload["synced"]:
189
+ if step["action"] == "missing":
190
+ out.info(f"{step['backend']}: {step['detail']}")
191
+ continue
188
192
  where = f" in {step['backend']}" if step["backend"] else ""
189
193
  line = f"{step['action']} {step['kind']} {step['name']}{where}"
190
194
  detail = f": {step['detail']}" if step["detail"] else ""
@@ -260,6 +264,10 @@ def profile_list(selected: str | None, fmt: str) -> None:
260
264
  ("config file", payload["configFile"]),
261
265
  ]
262
266
  )
267
+ if payload.get("sharedConfiguration"):
268
+ out.info(f"Using the shared configuration {payload['sharedConfiguration']}.")
269
+ if payload.get("activeProblem"):
270
+ out.warning(payload["activeProblem"])
263
271
 
264
272
 
265
273
  @profile.command("show")
@@ -334,6 +342,12 @@ def profile_show(name: str, fmt: str) -> None:
334
342
  metavar="VAR",
335
343
  help="A kata API source: the environment variable holding its bearer token.",
336
344
  )
345
+ @click.option(
346
+ "--sync-every",
347
+ default=None,
348
+ metavar="DURATION",
349
+ help="Update a sourced profile by itself: 30m, 1h, 1d (not for a commit).",
350
+ )
337
351
  @click.option("--use", "activate", is_flag=True, help="Make it the active profile.")
338
352
  @click.option("--format", "fmt", type=_FORMAT_CHOICE, default="text")
339
353
  def profile_create(
@@ -342,6 +356,7 @@ def profile_create(
342
356
  source: str | None,
343
357
  source_profile: str | None,
344
358
  token_env: str | None,
359
+ sync_every: str | None,
345
360
  activate: bool,
346
361
  fmt: str,
347
362
  ) -> None:
@@ -359,6 +374,7 @@ def profile_create(
359
374
  source=source,
360
375
  source_profile=source_profile,
361
376
  token_env=token_env,
377
+ sync_every=sync_every,
362
378
  )
363
379
  )
364
380
  out = _output()
@@ -435,30 +451,41 @@ def profile_set_list(
435
451
  metavar="VAR",
436
452
  help="A kata API source: the environment variable holding its bearer token.",
437
453
  )
454
+ @click.option(
455
+ "--sync-every",
456
+ default=None,
457
+ metavar="DURATION",
458
+ help="Update the profile by itself: 30m, 1h, 1d (not for a commit).",
459
+ )
438
460
  @click.option(
439
461
  "--unset",
440
462
  "unset",
441
463
  multiple=True,
442
- type=click.Choice(["profile", "token_env"]),
443
- help="Remove an option: profile (then the source's profile named NAME) or token_env.",
464
+ type=click.Choice(["profile", "token_env", "sync"]),
465
+ help="Remove an option: profile (then the source's profile named NAME), token_env or sync.",
444
466
  )
445
467
  @click.option("--format", "fmt", type=_FORMAT_CHOICE, default="text")
446
468
  def profile_set_source_options(
447
469
  name: str,
448
470
  source_profile: str | None,
449
471
  token_env: str | None,
472
+ sync_every: str | None,
450
473
  unset: tuple[str, ...],
451
474
  fmt: str,
452
475
  ) -> None:
453
- """Change which profile of its source sourced profile NAME is, or its token variable.
476
+ """Change which profile of its source sourced profile NAME is, its token variable, or how often it updates itself.
454
477
 
455
478
  Only this file's reference changes; 'kata config sync NAME' fetches what it names.
456
479
  """
457
- if source_profile is None and token_env is None and not unset:
458
- raise click.UsageError("Give --source-profile, --token-env or --unset.")
480
+ if source_profile is None and token_env is None and sync_every is None and not unset:
481
+ raise click.UsageError("Give --source-profile, --token-env, --sync-every or --unset.")
459
482
  change: ProfileChange = _run(
460
483
  lambda: _service().set_source_options(
461
- name, source_profile=source_profile, token_env=token_env, unset=unset
484
+ name,
485
+ source_profile=source_profile,
486
+ token_env=token_env,
487
+ sync_every=sync_every,
488
+ unset=unset,
462
489
  )
463
490
  )
464
491
  out = _output()
@@ -540,8 +567,9 @@ def backend_add(
540
567
  ) -> None:
541
568
  """Add backend NAME of --type to PROFILE, with its settings as flags.
542
569
 
543
- Only the settings the type reads are accepted. A filesystem backend added to a
544
- profile gets the declared templates that profile uses installed into it.
570
+ Only the settings the type reads are accepted. Adding a backend writes to no
571
+ repository: one that lacks a declared template its profile uses is named, with the
572
+ ``kata tax add --bundle`` command that installs it.
545
573
  """
546
574
  from katalyst_taxonomy.services.profiles import backend_entry
547
575