agentbundle 0.21.0__tar.gz → 0.22.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.21.0 → agentbundle-0.22.0}/PKG-INFO +6 -1
- agentbundle-0.21.0/README.md → agentbundle-0.22.0/README-pypi.md +5 -0
- agentbundle-0.22.0/README.md +257 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/catalogue.schema.json +4 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_contract.py +4 -4
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_lint_agents_md_diataxis_block.py +3 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_lint_agents_md_legacy_block.py +2 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_lint_agents_md_risk_block.py +3 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_self_host_check.py +5 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_shared_prefix_contract.py +5 -2
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/build.py +3 -2
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/config.py +13 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/defaults.py +1 -2
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/install.py +2 -2
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/scope.py +1 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/source_defaults.py +15 -13
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/version.py +1 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/PKG-INFO +6 -1
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/SOURCES.txt +1 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/pyproject.toml +2 -2
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/__main__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/adapter.schema.json +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/adapter.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/install-defaults.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/install-marker.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/pack.schema.json +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/plugin-manifest.derived.schema.json +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/plugin-manifest.schema.json +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/profile.schema.json +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/__main__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapter_root_bins.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/claude_code.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/codex.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/copilot.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/cursor.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/gemini.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/kiro.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/kiro_cli.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/adapters/kiro_ide.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/contract.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/lint_packs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/main.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/phase_order.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/codex_agent_toml.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/copilot_agent_md.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/direct_directory.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/gemini_command_toml.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/hook_id.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/merge_json.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/projections/user_merge_json.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/composite-agents-md.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/composite-marketplace.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/marketplace.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/per-pack-apm-package.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/per-pack-claude-plugin.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/per-pack-overlay.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/recipes/self-host.toml +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/scope_rails.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/self_host.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/shared_libs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/target_resolver.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_claude_code.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_codex.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_copilot.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_cursor.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_gemini.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_kiro.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_kiro_alias.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_kiro_cli.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_kiro_ide.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_adapter_root_bins_projection.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_architect_design_reviewer_projection.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_architect_design_reviewer_rubric_parity.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_build_ships_seeds.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_contract_scope.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_contract_v07.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_contract_v08.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_direct_directory_cleanup.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_end_to_end_build.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_lint_packs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_pack_schema.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_pack_schema_allowed_adapters.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_pack_schema_install.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_pipeline.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_plugin_manifest_schema.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_projectable_subset.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_projections_merge_json.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_scope_rails.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_security.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_self_host_fixture_guard.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_self_host_recipe_config.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_shared_libs_projection.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_shipped_packs_v07_declarations.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_shipped_packs_v08_declarations.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_user_libs_projection.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_validate.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_writers_emit_lf.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/user_libs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/validate.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/archive.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/diagnostics.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/lint.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/package.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/results.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/self_host.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/skill_spec_lint.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/catalogue_tooling/verify.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/categories.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/cli.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/__init__.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/_common.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/_drop_warning.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/adapt.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_build.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_lint.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_package.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_self_host.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_sync_defaults.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_tooling_stub.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/catalogue_verify.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/config.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/diff.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/docs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/init_state.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/list_installed.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/list_packs.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/list_profiles.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/list_targets.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/oplog_cmd.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/pack_config_cmd.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/pack_evals.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/package_catalogue.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/profile.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/reconcile.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/render.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/scaffold.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/show.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/uninstall.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/upgrade.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/commands/validate.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/config.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/https_catalogue.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/oplog.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/pack_inventory.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/render.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/safety.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/statelock.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/user_config.py +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/dependency_links.txt +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/entry_points.txt +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/requires.txt +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle.egg-info/top_level.txt +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/setup.cfg +0 -0
- {agentbundle-0.21.0 → agentbundle-0.22.0}/tests/test_linear_primitive.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentbundle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.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
|
|
@@ -175,6 +175,11 @@ Developers installing from your fork get the internal channel without a manual
|
|
|
175
175
|
A malformed `enabled = true` config fails closed — no silent fallback to the public
|
|
176
176
|
source.
|
|
177
177
|
|
|
178
|
+
**Offline and air-gapped hosts:** set `AGENTBUNDLE_NO_REMOTE=1` to skip the org
|
|
179
|
+
Artifactory bootstrap and editable-install detection entirely. `agentbundle` falls
|
|
180
|
+
straight through to the packaged default, so hosts without network access to Artifactory
|
|
181
|
+
still resolve a source without errors.
|
|
182
|
+
|
|
178
183
|
See the full enterprise adoption guide at
|
|
179
184
|
`docs/guides/_shared/how-to/use-an-artifactory-catalogue.md` for all six flows
|
|
180
185
|
(org bootstrap, repo-scope CI upgrade, user-scope MDM, source-conflict remediation,
|
|
@@ -153,6 +153,11 @@ Developers installing from your fork get the internal channel without a manual
|
|
|
153
153
|
A malformed `enabled = true` config fails closed — no silent fallback to the public
|
|
154
154
|
source.
|
|
155
155
|
|
|
156
|
+
**Offline and air-gapped hosts:** set `AGENTBUNDLE_NO_REMOTE=1` to skip the org
|
|
157
|
+
Artifactory bootstrap and editable-install detection entirely. `agentbundle` falls
|
|
158
|
+
straight through to the packaged default, so hosts without network access to Artifactory
|
|
159
|
+
still resolve a source without errors.
|
|
160
|
+
|
|
156
161
|
See the full enterprise adoption guide at
|
|
157
162
|
`docs/guides/_shared/how-to/use-an-artifactory-catalogue.md` for all six flows
|
|
158
163
|
(org bootstrap, repo-scope CI upgrade, user-scope MDM, source-conflict remediation,
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# agentbundle
|
|
2
|
+
|
|
3
|
+
**The installer for [agent-ready-repo](https://github.com/eugenelim/agent-ready-repo).** Think npm, but for the skills, subagents, and hooks your coding agent runs on. One pack, one command, every major agent — Claude Code, Codex, Cursor, Copilot, Gemini, and Kiro (both the CLI and the IDE).
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e packages/agentbundle
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Python 3.11+. Runs on macOS, Linux, and Windows.
|
|
12
|
+
|
|
13
|
+
**Install into a repo** — so everyone who clones it gets the pack. `core` is the flagship pack, the loop itself:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
agentbundle install --pack core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
No catalogue argument needed: it defaults to the agent-ready-repo catalogue. It lands in the repo's agent config — subagents and skills included — and you commit it like any other project file. This is the default scope: the pack belongs to the project and the whole team.
|
|
20
|
+
|
|
21
|
+
**Install for yourself, everywhere** — so a pack follows you across every project, with no per-repo setup:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
agentbundle install --pack desk-research --scope user
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
User-scope packs land in your home directory, not the repo — they're yours, not the team's, and they're there in every project you open.
|
|
28
|
+
|
|
29
|
+
The install auto-detects your agent (`--adapter` overrides). Multi-IDE? Install the same pack for each agent at the same scope — they coexist, and the agents that read `.agents/skills/` (codex, cursor, gemini, copilot) share one skill copy instead of fighting over it. To install from a **different** catalogue, pass it as a trailing argument — a git URL or a local path (`agentbundle install --pack core <catalogue>`); a `config set source <catalogue>` makes that the default, and an editable clone (`pip install -e`) defaults to itself.
|
|
30
|
+
|
|
31
|
+
## More commands
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# See what the catalogue offers (bare uses the default; or name one explicitly)
|
|
35
|
+
agentbundle list-packs
|
|
36
|
+
agentbundle list-profiles
|
|
37
|
+
|
|
38
|
+
# See what a single pack contains — skills and agents, derived live from its tree
|
|
39
|
+
agentbundle show core
|
|
40
|
+
agentbundle show core --format json # stable object for scripts/agents
|
|
41
|
+
|
|
42
|
+
# See what YOU have installed — pack, adapter, scope, version, and whether
|
|
43
|
+
# an upgrade is available (both scopes by default)
|
|
44
|
+
agentbundle list-installed
|
|
45
|
+
agentbundle list-installed --no-check # skip the catalogue check (offline, fast)
|
|
46
|
+
agentbundle list-installed --check-drift # also count locally edited files
|
|
47
|
+
agentbundle list-installed --format json # machine-readable JSON (schema_version 1)
|
|
48
|
+
agentbundle list-installed --updates-only # show only rows needing attention
|
|
49
|
+
|
|
50
|
+
# Install a whole curated profile — a single-scope set of packs — in one command
|
|
51
|
+
agentbundle install --profile inception
|
|
52
|
+
|
|
53
|
+
# Preview any install without writing a file
|
|
54
|
+
agentbundle install --pack core --dry-run
|
|
55
|
+
|
|
56
|
+
# Upgrade to the version the catalogue ships — shows installed → target, asks first
|
|
57
|
+
agentbundle upgrade --pack core
|
|
58
|
+
agentbundle upgrade --pack core --yes # skip the prompt (CI)
|
|
59
|
+
|
|
60
|
+
# Uninstall — previews remove (Tier-1) vs keep (your edits), asks first
|
|
61
|
+
agentbundle uninstall --pack core --dry-run
|
|
62
|
+
agentbundle uninstall --pack core --yes
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**`list-installed`** reads your state files (not the catalogue) and reports every installed `(pack, adapter)` at each scope with its version and a four-value status — `up-to-date`, `upgrade-available`, `ahead` (installed version is newer than catalogue), or `unknown`; it degrades to `unknown` (never an error) when the catalogue can't be resolved, and `--no-check` skips the check entirely. `--format json` emits a stable JSON contract (`schema_version: 1`) to stdout — useful for CI automation of upgrade decisions. `--updates-only` hides `up-to-date` rows.
|
|
66
|
+
|
|
67
|
+
**`show <pack>`** answers "what skills and agents does this pack contain?" by walking the pack's source tree live on each call — so the answer can't drift, and nothing is persisted. `--format json` emits a stable object (`name`, `version`, `description`, `skills`, `agents`, `source`) for scripts and agents. When the catalogue can't be resolved, an *installed* pack still reports its inventory from your state files (marked `source: installed-state`); a not-installed pack errors.
|
|
68
|
+
|
|
69
|
+
A **profile** is a catalogue-curated, single-scope set of packs you install in one command — it declares its own scope, so `--scope` doesn't apply. **Upgrade takes no version** — the target is whatever the catalogue you point at declares; to pin a past version, point the catalogue at that git ref. Install a pack that's **already there** and `agentbundle` offers to `upgrade` it instead (`--yes` runs it straight away).
|
|
70
|
+
|
|
71
|
+
**Mutating commands ask first.** `uninstall`, the `--force` cleanup, and the upgrade offer all preview what they'll do and confirm before touching anything; `--dry-run` previews without writing, and `--yes` skips the prompt for non-interactive / CI use (where, without it, they refuse rather than hang).
|
|
72
|
+
|
|
73
|
+
## Enterprise distribution
|
|
74
|
+
|
|
75
|
+
For organizations running an internal Artifactory mirror or any static HTTPS server,
|
|
76
|
+
agentbundle's enterprise distribution capabilities handle the full adoption loop —
|
|
77
|
+
from org-wide channel configuration to CI-driven bulk upgrades.
|
|
78
|
+
|
|
79
|
+
**Install from an internal Artifactory channel:**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Point agentbundle at your org's channel descriptor (one-time per machine,
|
|
83
|
+
# or pre-configured in your org fork — see Org bootstrap below)
|
|
84
|
+
agentbundle config set source catalogue+https://artifactory.example.test/agentbundle/catalogues/core/channels/stable.json
|
|
85
|
+
|
|
86
|
+
agentbundle install --pack core
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The channel descriptor points to an immutable versioned archive; agentbundle
|
|
90
|
+
fetches, verifies its SHA-256 digest, and installs. Pass a bearer token via
|
|
91
|
+
`AGENTBUNDLE_HTTP_BEARER_TOKEN` — it is never stored in state, never printed, and
|
|
92
|
+
never forwarded to a different host.
|
|
93
|
+
|
|
94
|
+
**JSON output for CI pipelines:**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# See what's installed and what needs upgrading — machine-readable
|
|
98
|
+
agentbundle list-installed --format json
|
|
99
|
+
agentbundle list-installed --format json --updates-only
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Returns a stable JSON contract (`schema_version` 1) with per-row status
|
|
103
|
+
(`up-to-date` / `upgrade-available` / `ahead` / `unknown`) and machine-readable
|
|
104
|
+
reason codes for unknown rows. Pipe into `jq` or your CI annotation step.
|
|
105
|
+
|
|
106
|
+
**Bulk upgrade in one scoped command:**
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Upgrade all installed packs in a scope — preflights before any write
|
|
110
|
+
agentbundle upgrade --all --scope repo --yes
|
|
111
|
+
agentbundle upgrade --all --scope user --format json --yes
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Preflights all rows before writing anything; a blocked row stops the run before the
|
|
115
|
+
filesystem is touched. Partial failure is reported honestly — not described as a
|
|
116
|
+
rollback. Never silently downgrades an `ahead` row.
|
|
117
|
+
|
|
118
|
+
**Package your catalogue for Artifactory:**
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
agentbundle package-catalogue \
|
|
122
|
+
--root /path/to/catalogue \
|
|
123
|
+
--bundle my-packs \
|
|
124
|
+
--release 1.0.0 \
|
|
125
|
+
--channel stable \
|
|
126
|
+
--output dist/
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Produces a deterministic, reproducible gzip archive (versioned) and a mutable channel
|
|
130
|
+
descriptor JSON (`stable.json`), ready to upload to Artifactory. Identical inputs
|
|
131
|
+
produce byte-identical archives (honors `SOURCE_DATE_EPOCH`).
|
|
132
|
+
|
|
133
|
+
**Org bootstrap — ship the default channel in your fork:**
|
|
134
|
+
|
|
135
|
+
Add an `[organization.artifactory]` block to
|
|
136
|
+
`agentbundle/_data/install-defaults.toml` in your org's agentbundle fork:
|
|
137
|
+
|
|
138
|
+
```toml
|
|
139
|
+
[organization.artifactory]
|
|
140
|
+
enabled = true
|
|
141
|
+
base-url = "https://artifactory.example.test"
|
|
142
|
+
repository = "agentbundle"
|
|
143
|
+
bundle = "core"
|
|
144
|
+
channel = "stable"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Developers installing from your fork get the internal channel without a manual
|
|
148
|
+
`config set source` step. The block ships `enabled = false` in the public package.
|
|
149
|
+
A malformed `enabled = true` config fails closed — no silent fallback to the public
|
|
150
|
+
source.
|
|
151
|
+
|
|
152
|
+
See the full enterprise adoption guide at
|
|
153
|
+
`docs/guides/_shared/how-to/use-an-artifactory-catalogue.md` for all six flows
|
|
154
|
+
(org bootstrap, repo-scope CI upgrade, user-scope MDM, source-conflict remediation,
|
|
155
|
+
disconnected hosts, and security controls).
|
|
156
|
+
|
|
157
|
+
## Build your own catalogue
|
|
158
|
+
|
|
159
|
+
`agentbundle` isn't tied to the agent-ready-repo catalogue. Any repo that lays its packs out the same way can use it. A pack is a directory:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
my-pack/
|
|
163
|
+
pack.toml # name, version, adapter-contract, install scope,
|
|
164
|
+
# plus rich metadata (license, maintainers, links,
|
|
165
|
+
# categories, keywords) and a README pointer
|
|
166
|
+
.claude-plugin/
|
|
167
|
+
plugin.json # Claude Code plugin manifest (hand-authored)
|
|
168
|
+
README.md # the pack's portable doc — projected with the pack
|
|
169
|
+
.apm/ # primitives — projected by the build pipeline
|
|
170
|
+
skills/<name>/
|
|
171
|
+
SKILL.md # the skill body; one folder per skill
|
|
172
|
+
references/ # progressive-disclosure docs, loaded on demand
|
|
173
|
+
assets/ # templates the skill copies into the repo
|
|
174
|
+
agents/<name>.md # subagents
|
|
175
|
+
hooks/<name>.py # lifecycle hooks
|
|
176
|
+
seeds/ # files scaffolded into the adopter repo
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`pack.toml` is the **single source of truth** for a pack's metadata. Declare
|
|
180
|
+
`license`, `[[pack.maintainers]]`, `[pack.links]`, `categories`, and
|
|
181
|
+
`keywords` once; the build projects the cleanly-mappable subset — plus the
|
|
182
|
+
pack's `README.md` — into each distribution route's manifest (the `plugin.json`
|
|
183
|
+
/ `marketplace.json` entry), so the catalogue describes each pack richly rather
|
|
184
|
+
than with a single sentence. Extra fields stay in `pack.toml`; the projection
|
|
185
|
+
is deliberately lossy per tool.
|
|
186
|
+
|
|
187
|
+
Point a catalogue URI (a git URL or a local path) at the repo that holds your packs. Then `validate` a pack against the adapter contract, `render` it to preview the projection, and `install` it into a target repo. `scaffold` drops a pack's seeds into a fresh directory to start from. The build pipeline (`agentbundle.build`) is the same engine `make build` runs.
|
|
188
|
+
|
|
189
|
+
**Org adapter default:** If your org ships a private `agentbundle` wheel (or a fork pinned to your internal catalogue), you can set a default adapter for all developers without requiring them to run `agentbundle config set` or pass `--adapter` on every install. Add an `[organization]` table to `_data/install-defaults.toml` in your fork:
|
|
190
|
+
|
|
191
|
+
```toml
|
|
192
|
+
[organization]
|
|
193
|
+
preferred_adapter = "cursor"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
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.
|
|
197
|
+
|
|
198
|
+
**Lint your catalogue** — shallow structural checks run without extra dependencies:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
agentbundle catalogue lint --root .
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
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`:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install -e 'packages/agentbundle[lint]'
|
|
208
|
+
agentbundle catalogue lint --root . --deep
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Run Tier-A activation evals** to measure whether each covered skill fires on the prompts it should:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
agentbundle pack evals run --pack <pack-name> --catalogue-root .
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
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).
|
|
218
|
+
|
|
219
|
+
## Catalogue defaults and pack config API
|
|
220
|
+
|
|
221
|
+
**Catalogue defaults** let operators ship sensible starting values for every pack they distribute. Add a `[pack-defaults.<pack-name>]` table to `catalogue.toml` and the defaults are baked in at publish time. They slot into the three-layer cascade: pack-source defaults → operator defaults → user config. A custom install root is also supported via `[catalogue] user-dir = "~/custom/path"`.
|
|
222
|
+
|
|
223
|
+
**Pack scripts** can resolve their user-scope directory and read the merged config at runtime using the `agentbundle.config` API:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from agentbundle.config import pack_dir, load_pack_config
|
|
227
|
+
|
|
228
|
+
directory = pack_dir("my-pack") # ~/.agentbundle/my-pack/
|
|
229
|
+
config = load_pack_config("my-pack") # merged dict: pack defaults + operator + user
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Operation log** — scripts can append structured JSONL records to `<pack_dir>/ops.jsonl` for lightweight audit trails:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
from agentbundle.oplog import write_entry
|
|
236
|
+
|
|
237
|
+
write_entry("my-pack", "install", src="git+https://example.com/my-pack")
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**CLI commands** to read, write, and inspect pack config and operation logs:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
agentbundle pack-config show my-pack # all config values for a pack
|
|
244
|
+
agentbundle pack-config get my-pack api-key # single value
|
|
245
|
+
agentbundle pack-config set my-pack api-key v # write to user config.toml
|
|
246
|
+
|
|
247
|
+
agentbundle oplog show my-pack # JSONL operation history
|
|
248
|
+
agentbundle oplog clear my-pack # wipe history (asks first)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Credentials
|
|
252
|
+
|
|
253
|
+
`agentbundle` doesn't resolve secrets. Credentialed skills use [`credbroker`](../credbroker/README.md), a standalone resolver that keeps cleartext out of the model's reach.
|
|
254
|
+
|
|
255
|
+
## Learn more
|
|
256
|
+
|
|
257
|
+
The full story — the loop, the reviewers, the pack catalogue — is in the [agent-ready-repo README](https://github.com/eugenelim/agent-ready-repo#readme).
|
|
@@ -171,6 +171,10 @@
|
|
|
171
171
|
"bundle": {
|
|
172
172
|
"type": "string",
|
|
173
173
|
"description": "Catalogue bundle name (required when enabled)."
|
|
174
|
+
},
|
|
175
|
+
"channel": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "Artifactory channel name (required when enabled = true)."
|
|
174
178
|
}
|
|
175
179
|
}
|
|
176
180
|
}
|
|
@@ -602,10 +602,10 @@ class TestCodexSkillDirectDirectory(unittest.TestCase):
|
|
|
602
602
|
self.assertNotIn("managed-block-delimiter-end", entry)
|
|
603
603
|
|
|
604
604
|
def test_contract_files_byte_identical(self) -> None:
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
)
|
|
605
|
+
def _norm(p: Path) -> bytes:
|
|
606
|
+
return p.read_bytes().replace(b"\r\n", b"\n")
|
|
607
|
+
|
|
608
|
+
self.assertEqual(_norm(CONTRACT_PATH), _norm(DATA_CONTRACT_PATH))
|
|
609
609
|
|
|
610
610
|
def test_seed_agents_md_has_no_legacy_delimiters(self) -> None:
|
|
611
611
|
text = SEED_AGENTS_MD_PATH.read_text(encoding="utf-8")
|
|
@@ -47,12 +47,14 @@ def _make_quadrants(base: Path) -> None:
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def _run_linter(cwd: Path) -> subprocess.CompletedProcess[str]:
|
|
50
|
+
env = {**os.environ, "PYTHONIOENCODING": "utf-8", "PYTHONUTF8": "1"}
|
|
50
51
|
return subprocess.run(
|
|
51
52
|
[sys.executable, str(LINTER)],
|
|
52
53
|
cwd=cwd,
|
|
53
|
-
env=
|
|
54
|
+
env=env,
|
|
54
55
|
capture_output=True,
|
|
55
56
|
text=True,
|
|
57
|
+
encoding="utf-8",
|
|
56
58
|
check=False,
|
|
57
59
|
)
|
|
58
60
|
|
|
@@ -63,13 +63,14 @@ def _seed_tree(
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
def _run_linter(cwd: Path) -> subprocess.CompletedProcess[str]:
|
|
66
|
-
env =
|
|
66
|
+
env = {**os.environ, "PYTHONIOENCODING": "utf-8", "PYTHONUTF8": "1"}
|
|
67
67
|
return subprocess.run(
|
|
68
68
|
[sys.executable, str(LINTER)],
|
|
69
69
|
cwd=cwd,
|
|
70
70
|
env=env,
|
|
71
71
|
capture_output=True,
|
|
72
72
|
text=True,
|
|
73
|
+
encoding="utf-8",
|
|
73
74
|
check=False,
|
|
74
75
|
)
|
|
75
76
|
|
{agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_lint_agents_md_risk_block.py
RENAMED
|
@@ -52,12 +52,14 @@ def _seed(root: Path, canonical_block: str, agents_block: str) -> None:
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
def _run_linter(cwd: Path) -> subprocess.CompletedProcess[str]:
|
|
55
|
+
env = {**os.environ, "PYTHONIOENCODING": "utf-8", "PYTHONUTF8": "1"}
|
|
55
56
|
return subprocess.run(
|
|
56
57
|
[sys.executable, str(LINTER)],
|
|
57
58
|
cwd=cwd,
|
|
58
|
-
env=
|
|
59
|
+
env=env,
|
|
59
60
|
capture_output=True,
|
|
60
61
|
text=True,
|
|
62
|
+
encoding="utf-8",
|
|
61
63
|
check=False,
|
|
62
64
|
)
|
|
63
65
|
|
|
@@ -21,6 +21,7 @@ import json
|
|
|
21
21
|
import os
|
|
22
22
|
import shutil
|
|
23
23
|
import subprocess
|
|
24
|
+
import sys
|
|
24
25
|
import tempfile
|
|
25
26
|
import unittest
|
|
26
27
|
from pathlib import Path
|
|
@@ -1206,6 +1207,7 @@ class MarketplaceAggregationTests(unittest.TestCase):
|
|
|
1206
1207
|
)
|
|
1207
1208
|
|
|
1208
1209
|
|
|
1210
|
+
@unittest.skipIf(sys.platform == "win32", "symlinks require Developer Mode on Windows")
|
|
1209
1211
|
class ClaudeSymlinkTests(unittest.TestCase):
|
|
1210
1212
|
"""Unit tests for `_recreate_claude_symlink`."""
|
|
1211
1213
|
|
|
@@ -1349,6 +1351,7 @@ class ClaudeSymlinkFallbackTests(unittest.TestCase):
|
|
|
1349
1351
|
self.assertIn("CLAUDE.md", buf.getvalue())
|
|
1350
1352
|
self.assertIn("copy", buf.getvalue().lower())
|
|
1351
1353
|
|
|
1354
|
+
@unittest.skipIf(sys.platform == "win32", "symlinks require Developer Mode on Windows")
|
|
1352
1355
|
def test_default_path_unchanged_on_posix(self) -> None:
|
|
1353
1356
|
"""Sanity: with no force_copy and sys.platform unmonkeypatched,
|
|
1354
1357
|
the existing symlink behaviour is unchanged."""
|
|
@@ -1698,6 +1701,7 @@ class CrlfNormalisationTests(unittest.TestCase):
|
|
|
1698
1701
|
class FileModeBitsTests(unittest.TestCase):
|
|
1699
1702
|
"""Phase-2 comparison rule (b): mode bits drift for regular files."""
|
|
1700
1703
|
|
|
1704
|
+
@unittest.skipIf(sys.platform == "win32", "execute bits not supported on Windows")
|
|
1701
1705
|
def test_mode_bits_drift_for_regular_files(self) -> None:
|
|
1702
1706
|
with tempfile.TemporaryDirectory() as tmp:
|
|
1703
1707
|
shadow = Path(tmp) / "shadow"
|
|
@@ -1827,6 +1831,7 @@ class StrengthenedDiffRegressionIntegrationTests(unittest.TestCase):
|
|
|
1827
1831
|
def setUpClass(cls) -> None:
|
|
1828
1832
|
cls.contract = load_contract(CONTRACT_PATH)
|
|
1829
1833
|
|
|
1834
|
+
@unittest.skipIf(sys.platform == "win32", "symlinks/execute bits not supported on Windows")
|
|
1830
1835
|
def test_each_rule_catches_its_regression(self) -> None:
|
|
1831
1836
|
with tempfile.TemporaryDirectory() as tmp:
|
|
1832
1837
|
shadow = Path(tmp) / "shadow"
|
{agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/build/tests/test_shared_prefix_contract.py
RENAMED
|
@@ -100,9 +100,12 @@ class CohortSkillRoutingTests(unittest.TestCase):
|
|
|
100
100
|
|
|
101
101
|
class ContractMirrorTests(unittest.TestCase):
|
|
102
102
|
def test_data_and_docs_agree_byte_for_byte(self) -> None:
|
|
103
|
+
def _norm(p: Path) -> bytes:
|
|
104
|
+
return p.read_bytes().replace(b"\r\n", b"\n")
|
|
105
|
+
|
|
103
106
|
self.assertEqual(
|
|
104
|
-
_DATA_COPY
|
|
105
|
-
_DOCS_COPY
|
|
107
|
+
_norm(_DATA_COPY),
|
|
108
|
+
_norm(_DOCS_COPY),
|
|
106
109
|
"the _data/ and contracts/ adapter.toml copies must be identical",
|
|
107
110
|
)
|
|
108
111
|
|
|
@@ -35,8 +35,9 @@ def _validate_recipe_path(root: Path, recipe: str | None) -> None:
|
|
|
35
35
|
if not recipe:
|
|
36
36
|
raise ValueError("recipe path must not be empty")
|
|
37
37
|
rp = Path(recipe)
|
|
38
|
-
# Reject absolute paths (
|
|
39
|
-
|
|
38
|
+
# Reject absolute paths (Windows drive-absolute, POSIX absolute, or Unix-
|
|
39
|
+
# style root on Windows where Path.is_absolute() returns False for "/foo").
|
|
40
|
+
if rp.is_absolute() or (len(recipe) > 1 and recipe[1] == ":") or recipe.startswith("/"):
|
|
40
41
|
raise ValueError(f"recipe path must be relative, not absolute: {recipe!r}")
|
|
41
42
|
# Reject traversal
|
|
42
43
|
if ".." in rp.parts:
|
|
@@ -78,6 +78,7 @@ class ArtifactoryConfig:
|
|
|
78
78
|
base_url: str | None = None
|
|
79
79
|
repository: str | None = None
|
|
80
80
|
bundle: str | None = None
|
|
81
|
+
channel: str | None = None
|
|
81
82
|
|
|
82
83
|
|
|
83
84
|
@dataclass
|
|
@@ -446,9 +447,21 @@ def load_catalogue_config(root: Path) -> CatalogueConfig | None:
|
|
|
446
447
|
f"catalogue.toml: distribution.agentbundle.artifactory.{seg_name} "
|
|
447
448
|
f"must match [A-Za-z0-9._-]+, got {seg_val!r}"
|
|
448
449
|
)
|
|
450
|
+
channel = art_raw.get("channel")
|
|
451
|
+
if not channel or not isinstance(channel, str) or not channel.strip():
|
|
452
|
+
raise CatalogueConfigError(
|
|
453
|
+
"catalogue.toml: distribution.agentbundle.artifactory.channel "
|
|
454
|
+
"is required when enabled = true (e.g. channel = \"stable\")"
|
|
455
|
+
)
|
|
456
|
+
if not _SAFE_SEGMENT_RE.match(channel):
|
|
457
|
+
raise CatalogueConfigError(
|
|
458
|
+
f"catalogue.toml: distribution.agentbundle.artifactory.channel "
|
|
459
|
+
f"must match [A-Za-z0-9._-]+, got {channel!r}"
|
|
460
|
+
)
|
|
449
461
|
art.base_url = base_url
|
|
450
462
|
art.repository = repository
|
|
451
463
|
art.bundle = bundle
|
|
464
|
+
art.channel = channel
|
|
452
465
|
|
|
453
466
|
agentbundle_dist = AgentbundleDistribution(
|
|
454
467
|
install_defaults_output=install_defaults_output,
|
|
@@ -84,8 +84,7 @@ def compile_defaults(config: CatalogueConfig) -> str:
|
|
|
84
84
|
art_rows.append(("base-url", _emit_str(art.base_url or "")))
|
|
85
85
|
art_rows.append(("repository", _emit_str(art.repository or "")))
|
|
86
86
|
art_rows.append(("bundle", _emit_str(art.bundle or "")))
|
|
87
|
-
|
|
88
|
-
art_rows.append(("channel", _emit_str("")))
|
|
87
|
+
art_rows.append(("channel", _emit_str(art.channel or "")))
|
|
89
88
|
parts.append(_emit_section("organization.artifactory", art_rows))
|
|
90
89
|
|
|
91
90
|
# [defaults]
|
|
@@ -114,10 +114,10 @@ def _check_source_conflict(
|
|
|
114
114
|
)
|
|
115
115
|
lines = [
|
|
116
116
|
f"{pack_name}: source conflict at {scope} scope \u2014 "
|
|
117
|
-
f"incoming source {incoming_display
|
|
117
|
+
f"incoming source '{incoming_display}' differs from existing installation(s):",
|
|
118
118
|
]
|
|
119
119
|
for adapter, display in conflicts:
|
|
120
|
-
lines.append(f" {adapter}: {display
|
|
120
|
+
lines.append(f" {adapter}: '{display}'")
|
|
121
121
|
lines.append("--force does not override source conflicts.")
|
|
122
122
|
lines.append(
|
|
123
123
|
f"Recovery: run 'agentbundle upgrade --pack {pack_name}' from a concrete source "
|
|
@@ -213,7 +213,7 @@ def resolve_user_root(home: Path | None = None) -> Path:
|
|
|
213
213
|
raise UserScopeUnresolvable(
|
|
214
214
|
f"could not resolve $HOME path {expanded}: {exc}"
|
|
215
215
|
) from exc
|
|
216
|
-
if
|
|
216
|
+
if normalised == normalised.parent:
|
|
217
217
|
raise UserScopeUnresolvable("expanduser resolved to '/' ($HOME=/)")
|
|
218
218
|
return normalised
|
|
219
219
|
|
|
@@ -20,6 +20,7 @@ consults a repo-committed source. See
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
22
|
import json
|
|
23
|
+
import os
|
|
23
24
|
import re
|
|
24
25
|
import re as _re
|
|
25
26
|
import sys
|
|
@@ -572,19 +573,20 @@ def resolve_default_source(
|
|
|
572
573
|
file=stream,
|
|
573
574
|
)
|
|
574
575
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
read_org
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
dist
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
576
|
+
if not os.environ.get("AGENTBUNDLE_NO_REMOTE"):
|
|
577
|
+
# Layer 3 — org Artifactory bootstrap (RFC-0072 D2).
|
|
578
|
+
if read_org is None:
|
|
579
|
+
read_org = read_org_bootstrap
|
|
580
|
+
org = read_org() # None when disabled; raises CatalogueError on fail-closed
|
|
581
|
+
if org is not None:
|
|
582
|
+
return org
|
|
583
|
+
|
|
584
|
+
# Layer 4 — editable detection.
|
|
585
|
+
if dist is _UNSET:
|
|
586
|
+
dist = _load_distribution()
|
|
587
|
+
editable = _detect_editable_source(dist, stream=stream)
|
|
588
|
+
if editable is not None:
|
|
589
|
+
return editable
|
|
588
590
|
|
|
589
591
|
# Layer 5 — packaged default, validated.
|
|
590
592
|
if read_packaged is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentbundle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.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
|
|
@@ -175,6 +175,11 @@ Developers installing from your fork get the internal channel without a manual
|
|
|
175
175
|
A malformed `enabled = true` config fails closed — no silent fallback to the public
|
|
176
176
|
source.
|
|
177
177
|
|
|
178
|
+
**Offline and air-gapped hosts:** set `AGENTBUNDLE_NO_REMOTE=1` to skip the org
|
|
179
|
+
Artifactory bootstrap and editable-install detection entirely. `agentbundle` falls
|
|
180
|
+
straight through to the packaged default, so hosts without network access to Artifactory
|
|
181
|
+
still resolve a source without errors.
|
|
182
|
+
|
|
178
183
|
See the full enterprise adoption guide at
|
|
179
184
|
`docs/guides/_shared/how-to/use-an-artifactory-catalogue.md` for all six flows
|
|
180
185
|
(org bootstrap, repo-scope CI upgrade, user-scope MDM, source-conflict remediation,
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentbundle"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.22.0"
|
|
8
8
|
description = "npm for your coding agent. Install packs of skills, subagents, and hooks into any repo, for every major agent."
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
dependencies = []
|
|
11
11
|
authors = [{ name = "eugenelim", email = "eugenelim@users.noreply.github.com" }]
|
|
12
12
|
license = { text = "Apache-2.0 OR MIT" }
|
|
13
|
-
readme = "README.md"
|
|
13
|
+
readme = "README-pypi.md"
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Development Status :: 4 - Beta",
|
|
16
16
|
"License :: OSI Approved :: Apache Software License",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.21.0 → agentbundle-0.22.0}/agentbundle/_data/plugin-manifest.derived.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|