agentbundle 0.13.0__tar.gz → 0.17.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentbundle-0.13.0 → agentbundle-0.17.0}/PKG-INFO +22 -1
- {agentbundle-0.13.0 → agentbundle-0.17.0}/README.md +19 -0
- agentbundle-0.17.0/agentbundle/_data/catalogue.schema.json +170 -0
- agentbundle-0.17.0/agentbundle/_data/install-defaults.toml +9 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/__init__.py +43 -4
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/claude_code.py +16 -10
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/codex.py +20 -15
- agentbundle-0.17.0/agentbundle/build/recipes/composite-agents-md.toml +8 -0
- agentbundle-0.17.0/agentbundle/build/recipes/composite-marketplace.toml +9 -0
- agentbundle-0.17.0/agentbundle/build/recipes/marketplace.toml +8 -0
- agentbundle-0.17.0/agentbundle/build/recipes/per-pack-apm-package.toml +7 -0
- agentbundle-0.17.0/agentbundle/build/recipes/per-pack-claude-plugin.toml +7 -0
- agentbundle-0.17.0/agentbundle/build/recipes/per-pack-overlay.toml +7 -0
- agentbundle-0.17.0/agentbundle/build/recipes/self-host.toml +54 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_security.py +10 -7
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_shipped_packs_v08_declarations.py +1 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/__init__.py +12 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/archive.py +357 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/build.py +125 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/config.py +459 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/defaults.py +199 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/diagnostics.py +38 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/lint.py +648 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/package.py +623 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/results.py +69 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/self_host.py +73 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/skill_spec_lint.py +665 -0
- agentbundle-0.17.0/agentbundle/catalogue_tooling/verify.py +440 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/cli.py +156 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/adapt.py +1 -1
- agentbundle-0.17.0/agentbundle/commands/catalogue_build.py +46 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_lint.py +34 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_package.py +47 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_self_host.py +48 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_sync_defaults.py +43 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_tooling_stub.py +22 -0
- agentbundle-0.17.0/agentbundle/commands/catalogue_verify.py +47 -0
- agentbundle-0.17.0/agentbundle/commands/pack_evals.py +1242 -0
- agentbundle-0.17.0/agentbundle/commands/package_catalogue.py +66 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/upgrade.py +21 -2
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/scope.py +10 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/version.py +1 -1
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle.egg-info/PKG-INFO +22 -1
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle.egg-info/SOURCES.txt +29 -0
- agentbundle-0.17.0/agentbundle.egg-info/requires.txt +3 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/pyproject.toml +5 -2
- {agentbundle-0.13.0 → agentbundle-0.17.0}/tests/test_linear_primitive.py +2 -1
- agentbundle-0.13.0/agentbundle/_data/install-defaults.toml +0 -19
- agentbundle-0.13.0/agentbundle/commands/package_catalogue.py +0 -461
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/__init__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/__main__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/adapter.schema.json +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/adapter.toml +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/install-marker.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/pack.schema.json +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/plugin-manifest.derived.schema.json +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/plugin-manifest.schema.json +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/_data/profile.schema.json +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/__main__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapter_root_bins.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/__init__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/copilot.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/cursor.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/gemini.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/kiro.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/kiro_cli.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/adapters/kiro_ide.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/contract.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/lint_packs.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/main.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/phase_order.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/__init__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/codex_agent_toml.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/copilot_agent_md.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/direct_directory.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/gemini_command_toml.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/hook_id.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/merge_json.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/projections/user_merge_json.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/scope_rails.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/self_host.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/shared_libs.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/target_resolver.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/__init__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_claude_code.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_codex.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_copilot.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_cursor.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_gemini.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_kiro.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_kiro_alias.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_kiro_cli.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_kiro_ide.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_adapter_root_bins_projection.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_architect_design_reviewer_projection.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_architect_design_reviewer_rubric_parity.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_build_ships_seeds.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_contract.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_contract_scope.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_contract_v07.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_contract_v08.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_direct_directory_cleanup.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_end_to_end_build.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_lint_agents_md_diataxis_block.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_lint_agents_md_legacy_block.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_lint_agents_md_risk_block.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_lint_packs.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_pack_schema.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_pack_schema_allowed_adapters.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_pack_schema_install.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_pipeline.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_plugin_manifest_schema.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_projectable_subset.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_projections_merge_json.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_scope_rails.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_self_host_check.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_self_host_fixture_guard.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_self_host_recipe_config.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_shared_libs_projection.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_shared_prefix_contract.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_shipped_packs_v07_declarations.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_user_libs_projection.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_validate.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/tests/test_writers_emit_lf.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/user_libs.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/build/validate.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/catalogue.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/categories.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/__init__.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/_common.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/_drop_warning.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/config.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/diff.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/init_state.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/install.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/list_installed.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/list_packs.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/list_profiles.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/list_targets.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/profile.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/reconcile.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/render.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/scaffold.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/show.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/uninstall.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/commands/validate.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/config.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/https_catalogue.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/pack_inventory.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/render.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/safety.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/source_defaults.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/statelock.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle/user_config.py +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle.egg-info/dependency_links.txt +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle.egg-info/entry_points.txt +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/agentbundle.egg-info/top_level.txt +0 -0
- {agentbundle-0.13.0 → agentbundle-0.17.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentbundle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: npm for your coding agent. Install packs of skills, subagents, and hooks into any repo, for every major agent.
|
|
5
5
|
Author-email: eugenelim <eugenelim@users.noreply.github.com>
|
|
6
6
|
License: Apache-2.0 OR MIT
|
|
@@ -15,6 +15,8 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
|
+
Provides-Extra: lint
|
|
19
|
+
Requires-Dist: pyyaml>=6.0; extra == "lint"
|
|
18
20
|
|
|
19
21
|
# agentbundle
|
|
20
22
|
|
|
@@ -215,6 +217,25 @@ preferred_adapter = "cursor"
|
|
|
215
217
|
|
|
216
218
|
The org hint fires after the user-config but before the on-disk IDE probe — so `--adapter`, user-config, and upgrade state-hints all take priority. An invalid value exits 1 before writing anything. See the [`agentbundle` reference](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/guides/_shared/reference/agentbundle.md#org-adapter-default) for the full cascade.
|
|
217
219
|
|
|
220
|
+
**Lint your catalogue** — shallow structural checks run without extra dependencies:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
agentbundle catalogue lint --root .
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For full [agentskills.io spec](https://agentskills.io/specification) compliance (frontmatter key set, description policy, encoding, evals schema), install the `lint` extra and run with `--deep`:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
pip install 'agentbundle[lint]'
|
|
230
|
+
agentbundle catalogue lint --root . --deep
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Run Tier-A activation evals** to measure whether each covered skill fires on the prompts it should:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
agentbundle pack evals run --pack <pack-name> --catalogue-root .
|
|
237
|
+
```
|
|
238
|
+
|
|
218
239
|
See the [pack layout reference](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/architecture/pack-layout.md) and [authoring a skill](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/guides/_shared/how-to/author-a-skill.md).
|
|
219
240
|
|
|
220
241
|
## Credentials
|
|
@@ -197,6 +197,25 @@ preferred_adapter = "cursor"
|
|
|
197
197
|
|
|
198
198
|
The org hint fires after the user-config but before the on-disk IDE probe — so `--adapter`, user-config, and upgrade state-hints all take priority. An invalid value exits 1 before writing anything. See the [`agentbundle` reference](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/guides/_shared/reference/agentbundle.md#org-adapter-default) for the full cascade.
|
|
199
199
|
|
|
200
|
+
**Lint your catalogue** — shallow structural checks run without extra dependencies:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
agentbundle catalogue lint --root .
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
For full [agentskills.io spec](https://agentskills.io/specification) compliance (frontmatter key set, description policy, encoding, evals schema), install the `lint` extra and run with `--deep`:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
pip install 'agentbundle[lint]'
|
|
210
|
+
agentbundle catalogue lint --root . --deep
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Run Tier-A activation evals** to measure whether each covered skill fires on the prompts it should:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
agentbundle pack evals run --pack <pack-name> --catalogue-root .
|
|
217
|
+
```
|
|
218
|
+
|
|
200
219
|
See the [pack layout reference](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/architecture/pack-layout.md) and [authoring a skill](https://github.com/eugenelim/agent-ready-repo/blob/main/docs/guides/_shared/how-to/author-a-skill.md).
|
|
201
220
|
|
|
202
221
|
## Credentials
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "catalogue.schema.json",
|
|
4
|
+
"title": "CatalogueConfig",
|
|
5
|
+
"description": "JSON Schema for catalogue.toml — ini-005 Bucket 3 configuration layer.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["schema", "catalogue", "distribution"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"schema": {
|
|
11
|
+
"type": "integer",
|
|
12
|
+
"description": "Schema version — must be 1.",
|
|
13
|
+
"enum": [1]
|
|
14
|
+
},
|
|
15
|
+
"catalogue": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": [
|
|
19
|
+
"name",
|
|
20
|
+
"display-name",
|
|
21
|
+
"description",
|
|
22
|
+
"minimum-agentbundle-version",
|
|
23
|
+
"paths",
|
|
24
|
+
"build",
|
|
25
|
+
"package"
|
|
26
|
+
],
|
|
27
|
+
"properties": {
|
|
28
|
+
"name": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "Safe identifier — [A-Za-z0-9][A-Za-z0-9_-]*.",
|
|
31
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9_\\-]*$"
|
|
32
|
+
},
|
|
33
|
+
"display-name": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Human-readable catalogue name."
|
|
36
|
+
},
|
|
37
|
+
"description": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"description": "One-line description of the catalogue."
|
|
40
|
+
},
|
|
41
|
+
"minimum-agentbundle-version": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Minimum agentbundle version required to use this catalogue."
|
|
44
|
+
},
|
|
45
|
+
"paths": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"required": ["packs", "profiles", "contracts", "marketplace", "build-output"],
|
|
49
|
+
"properties": {
|
|
50
|
+
"packs": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Relative path to the packs directory."
|
|
53
|
+
},
|
|
54
|
+
"profiles": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Relative path to the profiles directory."
|
|
57
|
+
},
|
|
58
|
+
"contracts": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "Relative path to the contracts directory."
|
|
61
|
+
},
|
|
62
|
+
"marketplace": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Relative path to the marketplace.json file."
|
|
65
|
+
},
|
|
66
|
+
"build-output": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Relative path for build output."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"build": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"additionalProperties": false,
|
|
75
|
+
"required": ["recipes", "self-host", "claude-plugin-branch", "marketplace-description"],
|
|
76
|
+
"properties": {
|
|
77
|
+
"recipes": {
|
|
78
|
+
"type": "array",
|
|
79
|
+
"items": { "type": "string" },
|
|
80
|
+
"description": "Build recipe IDs or relative .toml paths."
|
|
81
|
+
},
|
|
82
|
+
"self-host": {
|
|
83
|
+
"type": "boolean",
|
|
84
|
+
"description": "Whether to generate self-host install-defaults.toml."
|
|
85
|
+
},
|
|
86
|
+
"claude-plugin-branch": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"description": "Branch name for claude-plugin publishing."
|
|
89
|
+
},
|
|
90
|
+
"marketplace-description": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"description": "Description for marketplace.json."
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"package": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"additionalProperties": false,
|
|
99
|
+
"required": ["include", "required"],
|
|
100
|
+
"properties": {
|
|
101
|
+
"include": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"items": { "type": "string" },
|
|
104
|
+
"description": "Pack paths to include in a packaged archive."
|
|
105
|
+
},
|
|
106
|
+
"required": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"items": { "type": "string" },
|
|
109
|
+
"description": "Pack paths that must be present (subset of include)."
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"distribution": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": false,
|
|
118
|
+
"required": ["agentbundle"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"agentbundle": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"additionalProperties": false,
|
|
123
|
+
"required": [
|
|
124
|
+
"install-defaults-output",
|
|
125
|
+
"preferred-adapter",
|
|
126
|
+
"default-source",
|
|
127
|
+
"artifactory"
|
|
128
|
+
],
|
|
129
|
+
"properties": {
|
|
130
|
+
"install-defaults-output": {
|
|
131
|
+
"type": "string",
|
|
132
|
+
"description": "Relative path for generated install-defaults.toml."
|
|
133
|
+
},
|
|
134
|
+
"preferred-adapter": {
|
|
135
|
+
"type": "string",
|
|
136
|
+
"description": "Default adapter hint written to install-defaults.toml."
|
|
137
|
+
},
|
|
138
|
+
"default-source": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"description": "Default catalogue source URI (git+https:// or local path)."
|
|
141
|
+
},
|
|
142
|
+
"artifactory": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"additionalProperties": false,
|
|
145
|
+
"required": ["enabled"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"enabled": {
|
|
148
|
+
"type": "boolean",
|
|
149
|
+
"description": "Whether the Artifactory bootstrap is active."
|
|
150
|
+
},
|
|
151
|
+
"base-url": {
|
|
152
|
+
"type": "string",
|
|
153
|
+
"description": "Artifactory base URL (https:// only, required when enabled)."
|
|
154
|
+
},
|
|
155
|
+
"repository": {
|
|
156
|
+
"type": "string",
|
|
157
|
+
"description": "Artifactory repository name (required when enabled)."
|
|
158
|
+
},
|
|
159
|
+
"bundle": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"description": "Catalogue bundle name (required when enabled)."
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Generated by agentbundle catalogue sync-defaults — source of truth: catalogue.toml
|
|
2
|
+
[organization]
|
|
3
|
+
preferred_adapter = "claude-code"
|
|
4
|
+
|
|
5
|
+
[organization.artifactory]
|
|
6
|
+
enabled = false
|
|
7
|
+
|
|
8
|
+
[defaults]
|
|
9
|
+
source = "git+https://github.com/eugenelim/agent-ready-repo"
|
|
@@ -111,7 +111,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
111
111
|
default="dist",
|
|
112
112
|
help="Where to write build artefacts (default: dist/).",
|
|
113
113
|
)
|
|
114
|
-
build_parser.set_defaults(func=
|
|
114
|
+
build_parser.set_defaults(func=_cmd_build_shim)
|
|
115
115
|
|
|
116
116
|
self_parser = subparsers.add_parser(
|
|
117
117
|
"self",
|
|
@@ -130,7 +130,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
130
130
|
"OS for filesystems or workflows that disallow symlinks."
|
|
131
131
|
),
|
|
132
132
|
)
|
|
133
|
-
self_parser.set_defaults(func=
|
|
133
|
+
self_parser.set_defaults(func=_cmd_self_shim)
|
|
134
134
|
|
|
135
135
|
check_parser = subparsers.add_parser(
|
|
136
136
|
"check",
|
|
@@ -146,7 +146,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
146
146
|
"regular-file CLAUDE.md copy rather than a symlink."
|
|
147
147
|
),
|
|
148
148
|
)
|
|
149
|
-
check_parser.set_defaults(func=
|
|
149
|
+
check_parser.set_defaults(func=_cmd_check_shim)
|
|
150
150
|
|
|
151
151
|
scaffold_parser = subparsers.add_parser(
|
|
152
152
|
"scaffold",
|
|
@@ -162,14 +162,53 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
162
162
|
help=(
|
|
163
163
|
"Windows-portability lint: reject packs that ship symlinks "
|
|
164
164
|
"or Windows-poisonous names under seeds/ or .apm/."
|
|
165
|
+
" [deprecated: use 'agentbundle catalogue lint']"
|
|
165
166
|
),
|
|
166
167
|
)
|
|
167
168
|
lint_packs_parser.add_argument("--packs-dir", default="packs")
|
|
168
|
-
lint_packs_parser.set_defaults(func=
|
|
169
|
+
lint_packs_parser.set_defaults(func=_cmd_lint_packs_shim)
|
|
169
170
|
|
|
170
171
|
return parser
|
|
171
172
|
|
|
172
173
|
|
|
174
|
+
def _cmd_build_shim(args) -> int:
|
|
175
|
+
print(
|
|
176
|
+
"agentbundle.build build is deprecated; use 'agentbundle catalogue build --root .' instead",
|
|
177
|
+
file=sys.stderr,
|
|
178
|
+
)
|
|
179
|
+
return int(cmd_build(args))
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _cmd_self_shim(args) -> int:
|
|
183
|
+
print(
|
|
184
|
+
"agentbundle.build self is deprecated; use 'agentbundle catalogue self-host --write --root .' instead",
|
|
185
|
+
file=sys.stderr,
|
|
186
|
+
)
|
|
187
|
+
return int(cmd_self(args))
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _cmd_check_shim(args) -> int:
|
|
191
|
+
print(
|
|
192
|
+
"agentbundle.build check is deprecated; use 'agentbundle catalogue self-host --check --root .' instead",
|
|
193
|
+
file=sys.stderr,
|
|
194
|
+
)
|
|
195
|
+
return int(cmd_check(args))
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _cmd_lint_packs_shim(args) -> int:
|
|
199
|
+
print(
|
|
200
|
+
"agentbundle.build lint-packs is deprecated; use 'agentbundle catalogue lint --root .' instead",
|
|
201
|
+
file=sys.stderr,
|
|
202
|
+
)
|
|
203
|
+
from agentbundle.catalogue_tooling.lint import lint_catalogue, render_table
|
|
204
|
+
|
|
205
|
+
packs_dir = Path(getattr(args, "packs_dir", "packs")).resolve()
|
|
206
|
+
root = packs_dir.parent
|
|
207
|
+
result = lint_catalogue(root)
|
|
208
|
+
print(render_table(result), file=sys.stderr)
|
|
209
|
+
return 0 if result.ok else 1
|
|
210
|
+
|
|
211
|
+
|
|
173
212
|
def _cmd_scaffold(args) -> int:
|
|
174
213
|
pack_seeds = Path(args.packs_dir) / args.pack / "seeds"
|
|
175
214
|
output = Path(args.output)
|
|
@@ -14,6 +14,7 @@ deep-merging the incoming TOML payload.
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
+
import os
|
|
17
18
|
import shutil
|
|
18
19
|
from pathlib import Path
|
|
19
20
|
from typing import Iterator
|
|
@@ -107,15 +108,17 @@ def _project_single(pack_path: Path, contract: dict, output_root: Path) -> None:
|
|
|
107
108
|
raise ValueError(f"claude-code: unhandled mode {mode!r} for {primitive_name}")
|
|
108
109
|
|
|
109
110
|
|
|
110
|
-
def
|
|
111
|
-
"""`shutil.copytree` ignore callback:
|
|
111
|
+
def _ignore_absolute_symlinks(directory: str, names: list[str]) -> set[str]:
|
|
112
|
+
"""`shutil.copytree` ignore callback: drop symlinks with absolute targets.
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
covers the skill root; this covers the subtree.
|
|
114
|
+
Relative symlinks (intra-skill cross-references) are preserved as
|
|
115
|
+
symlinks. Absolute symlinks always escape the tree and are a path-escape vector.
|
|
116
116
|
"""
|
|
117
117
|
base = Path(directory)
|
|
118
|
-
return {
|
|
118
|
+
return {
|
|
119
|
+
name for name in names
|
|
120
|
+
if (base / name).is_symlink() and os.path.isabs(os.readlink(base / name))
|
|
121
|
+
}
|
|
119
122
|
|
|
120
123
|
|
|
121
124
|
def _project_direct_directory(source_dir: Path, target_dir: Path) -> None:
|
|
@@ -136,10 +139,13 @@ def _project_direct_directory(source_dir: Path, target_dir: Path) -> None:
|
|
|
136
139
|
destination.unlink()
|
|
137
140
|
elif destination.exists():
|
|
138
141
|
shutil.rmtree(destination)
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
# symlinks=True preserves relative nested symlinks; absolute
|
|
143
|
+
# targets are filtered out by _ignore_absolute_symlinks.
|
|
144
|
+
shutil.copytree(
|
|
145
|
+
entry, destination,
|
|
146
|
+
symlinks=True,
|
|
147
|
+
ignore=_ignore_absolute_symlinks,
|
|
148
|
+
)
|
|
143
149
|
|
|
144
150
|
|
|
145
151
|
def _project_direct_file(source_dir: Path, output_root: Path, target_prefix: str) -> None:
|
|
@@ -29,16 +29,6 @@ from agentbundle.build.projections.codex_agent_toml import (
|
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
def _ignore_symlinks(directory: str, names: list[str]) -> set[str]:
|
|
33
|
-
"""`shutil.copytree` ignore callback: skip every symlink member.
|
|
34
|
-
|
|
35
|
-
Drops nested symlinks so they are never reproduced in the output
|
|
36
|
-
tree. The top-level `is_symlink()` skip in `project_packs` covers
|
|
37
|
-
the skill root; this covers the subtree.
|
|
38
|
-
"""
|
|
39
|
-
base = Path(directory)
|
|
40
|
-
return {name for name in names if (base / name).is_symlink()}
|
|
41
|
-
|
|
42
32
|
|
|
43
33
|
def _iter_primitives(contract: dict) -> Iterator[str]:
|
|
44
34
|
"""Yield Codex's projected primitive names in phase order."""
|
|
@@ -142,11 +132,13 @@ def project_packs(pack_paths: list[Path], contract: dict, output_root: Path) ->
|
|
|
142
132
|
destination.unlink()
|
|
143
133
|
elif destination.exists():
|
|
144
134
|
shutil.rmtree(destination)
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
135
|
+
# symlinks=True preserves relative nested symlinks;
|
|
136
|
+
# absolute targets are filtered by _ignore_absolute_symlinks.
|
|
137
|
+
shutil.copytree(
|
|
138
|
+
entry, destination,
|
|
139
|
+
symlinks=True,
|
|
140
|
+
ignore=_ignore_absolute_symlinks,
|
|
141
|
+
)
|
|
150
142
|
# Bound to `skill` only per spec § Never do. Other
|
|
151
143
|
# direct-directory primitives opt in explicitly.
|
|
152
144
|
if primitive_name == "skill":
|
|
@@ -166,6 +158,19 @@ def project_packs(pack_paths: list[Path], contract: dict, output_root: Path) ->
|
|
|
166
158
|
raise ValueError(f"codex: unhandled mode {mode!r} for {primitive_name}")
|
|
167
159
|
|
|
168
160
|
|
|
161
|
+
def _ignore_absolute_symlinks(directory: str, names: list[str]) -> set[str]:
|
|
162
|
+
"""`shutil.copytree` ignore callback: drop symlinks with absolute targets.
|
|
163
|
+
|
|
164
|
+
Relative symlinks (intra-skill cross-references) are preserved (AC5).
|
|
165
|
+
Absolute symlinks always escape the tree and are a path-escape vector.
|
|
166
|
+
"""
|
|
167
|
+
base = Path(directory)
|
|
168
|
+
return {
|
|
169
|
+
name for name in names
|
|
170
|
+
if (base / name).is_symlink() and os.path.isabs(os.readlink(base / name))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
169
174
|
def _project_direct_file(source_dir: Path, output_root: Path, target_prefix: str) -> None:
|
|
170
175
|
target_dir = output_root / target_prefix.rstrip("/")
|
|
171
176
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# RFC-0002 recipe: compose a self-host marketplace listing from each
|
|
2
|
+
# pack's .claude-plugin/plugin.json (distinct from the dist/-aggregating
|
|
3
|
+
# `marketplace` recipe).
|
|
4
|
+
|
|
5
|
+
[recipe]
|
|
6
|
+
name = "composite-marketplace"
|
|
7
|
+
type = "composite"
|
|
8
|
+
manifest-path = ".claude-plugin/plugin.json"
|
|
9
|
+
output-file = ".claude-plugin/marketplace.json"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# RFC-0001 recipe: aggregate every per-pack Claude plugin into one
|
|
2
|
+
# marketplace.json at dist/claude-plugins/marketplace.json.
|
|
3
|
+
|
|
4
|
+
[recipe]
|
|
5
|
+
name = "marketplace"
|
|
6
|
+
type = "aggregate"
|
|
7
|
+
input-subdir = "claude-plugins"
|
|
8
|
+
output-file = "claude-plugins/marketplace.json"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# RFC-0002 self-host recipe — composes the four-pack overlay used by
|
|
2
|
+
# `make build-self`.
|
|
3
|
+
#
|
|
4
|
+
# The self-host runner reads this recipe-shape contract and executes the
|
|
5
|
+
# concrete projection in `agentbundle.build.self_host`.
|
|
6
|
+
|
|
7
|
+
[recipe]
|
|
8
|
+
name = "self-host"
|
|
9
|
+
type = "composite"
|
|
10
|
+
description = "Overlay every pack's Claude Code projection onto this repo; compose AGENTS.md from packs/core/seeds and aggregate .claude-plugin/marketplace.json across packs."
|
|
11
|
+
|
|
12
|
+
[recipe.adapters]
|
|
13
|
+
# Authoritative source for `SELF_HOST_ADAPTERS` — `self_host.py` reads this list.
|
|
14
|
+
# Kiro and Copilot stay in the contract for distribution builds but are excluded
|
|
15
|
+
# here so self-host does not project `.kiro/` or `.github/instructions/`.
|
|
16
|
+
targets = ["claude-code", "codex"]
|
|
17
|
+
|
|
18
|
+
[recipe.packs]
|
|
19
|
+
# Authoritative source for `SELF_HOST_PACKS` — `self_host.py` reads this list.
|
|
20
|
+
# This repo is the catalogue's home, not an adopter, so `make build-self` only
|
|
21
|
+
# projects the in-house packs into the working tree. User-scope-default packs
|
|
22
|
+
# (architect, atlassian, contracts, converters, credential-brokers, figma) are
|
|
23
|
+
# advertised via `marketplace.json` but their primitives don't belong in this
|
|
24
|
+
# repo's `.claude/skills/` tree; `monorepo-extras` is repo-only by metadata but
|
|
25
|
+
# the bundle is not a canonical `new-package` consumer, so it's left out too.
|
|
26
|
+
include = ["core", "governance-extras", "user-guide-diataxis", "catalogue-curation"]
|
|
27
|
+
|
|
28
|
+
[recipe.iterate]
|
|
29
|
+
over = "packs/*/"
|
|
30
|
+
read-pack-metadata = "pack.toml"
|
|
31
|
+
|
|
32
|
+
[recipe.per-pack-overlay]
|
|
33
|
+
root = "."
|
|
34
|
+
copy-from-pack-apm = [
|
|
35
|
+
{ from = "{pack.path}/.apm/skills/", to = ".claude/skills/" },
|
|
36
|
+
{ from = "{pack.path}/.apm/agents/", to = ".claude/agents/" },
|
|
37
|
+
{ from = "{pack.path}/.apm/commands/", to = ".claude/commands/" },
|
|
38
|
+
{ from = "{pack.path}/.apm/hooks/", to = "tools/hooks/" },
|
|
39
|
+
]
|
|
40
|
+
copy-from-pack-seeds = [
|
|
41
|
+
{ from = "{pack.path}/seeds/", to = "." },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[recipe.composite-agents-md]
|
|
45
|
+
output-path = "AGENTS.md"
|
|
46
|
+
template-from = "packs/core/seeds/AGENTS.md"
|
|
47
|
+
managed-block-adapter = "codex"
|
|
48
|
+
managed-block-content-source = "all-installed-packs"
|
|
49
|
+
footer-from = "packs/core/seeds/_agents-footer.md"
|
|
50
|
+
|
|
51
|
+
[recipe.composite-marketplace]
|
|
52
|
+
output-path = ".claude-plugin/marketplace.json"
|
|
53
|
+
aggregate-from = "packs/*/.claude-plugin/plugin.json"
|
|
54
|
+
owner = { name = "eugenelim" }
|
|
@@ -45,10 +45,13 @@ class SymlinkProjectionTests(unittest.TestCase):
|
|
|
45
45
|
def setUpClass(cls) -> None:
|
|
46
46
|
cls.contract = load_contract(CONTRACT_PATH)
|
|
47
47
|
|
|
48
|
-
def
|
|
49
|
-
"""A pack with
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
def test_absolute_symlink_in_pack_skill_is_dropped(self) -> None:
|
|
49
|
+
"""A pack skill with an absolute symlink must not reproduce it
|
|
50
|
+
in the projection — not as a symlink, not as copied content.
|
|
51
|
+
|
|
52
|
+
Absolute symlinks escape the skill tree and are a path-escape
|
|
53
|
+
vector. _ignore_absolute_symlinks drops them before copytree
|
|
54
|
+
writes them to the output.
|
|
52
55
|
|
|
53
56
|
Test-only symlink creation: Windows-portability lint
|
|
54
57
|
(`lint_packs.py`) rejects symlinks in shipped pack content, so
|
|
@@ -66,9 +69,9 @@ class SymlinkProjectionTests(unittest.TestCase):
|
|
|
66
69
|
out = tmp_path / "out"
|
|
67
70
|
project_claude_code(pack, self.contract, out)
|
|
68
71
|
projected = out / ".claude" / "skills" / "foo" / "leak.txt"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
self.
|
|
72
|
+
# Absolute symlink is dropped entirely — not reproduced, not dereferenced.
|
|
73
|
+
self.assertFalse(projected.exists())
|
|
74
|
+
self.assertFalse(projected.is_symlink())
|
|
72
75
|
|
|
73
76
|
|
|
74
77
|
class PluginManifestValidationTests(unittest.TestCase):
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""agentbundle.catalogue_tooling — portable catalogue engine.
|
|
2
|
+
|
|
3
|
+
This package provides the configuration schema, result types, and command
|
|
4
|
+
stubs for the agentbundle catalogue * and agentbundle lint packs CLI surface.
|
|
5
|
+
|
|
6
|
+
Wave 2-4 specs fill the command logic; this package establishes the stable
|
|
7
|
+
contract layer between all modules.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from agentbundle.catalogue_tooling.config import CatalogueConfigError, load_catalogue_config
|
|
11
|
+
|
|
12
|
+
__all__ = ["CatalogueConfigError", "load_catalogue_config"]
|