agentbundle 0.10.2__tar.gz → 0.11.1__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.10.2 → agentbundle-0.11.1}/PKG-INFO +7 -1
- {agentbundle-0.10.2 → agentbundle-0.11.1}/README.md +6 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/lint_packs.py +7 -8
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shipped_packs_v08_declarations.py +3 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/cli.py +25 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/install.py +19 -2
- agentbundle-0.11.1/agentbundle/commands/show.py +272 -0
- agentbundle-0.11.1/agentbundle/pack_inventory.py +61 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/version.py +1 -1
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle.egg-info/PKG-INFO +7 -1
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle.egg-info/SOURCES.txt +2 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/pyproject.toml +1 -1
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/__main__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/adapter.schema.json +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/adapter.toml +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/install-defaults.toml +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/install-marker.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/pack.schema.json +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/plugin-manifest.derived.schema.json +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/plugin-manifest.schema.json +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/_data/profile.schema.json +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/__main__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapter_root_bins.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/claude_code.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/codex.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/copilot.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/cursor.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/gemini.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/kiro.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/kiro_cli.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/adapters/kiro_ide.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/contract.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/main.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/phase_order.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/codex_agent_toml.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/copilot_agent_md.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/direct_directory.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/gemini_command_toml.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/hook_id.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/merge_json.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/user_merge_json.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/scope_rails.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/self_host.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/shared_libs.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/target_resolver.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_claude_code.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_codex.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_copilot.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_cursor.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_gemini.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_kiro.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_kiro_alias.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_kiro_cli.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_kiro_ide.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_root_bins_projection.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_architect_design_reviewer_projection.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_architect_design_reviewer_rubric_parity.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_build_ships_seeds.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_contract.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_contract_scope.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_contract_v07.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_contract_v08.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_direct_directory_cleanup.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_end_to_end_build.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_lint_agents_md_diataxis_block.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_lint_agents_md_legacy_block.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_lint_agents_md_risk_block.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_lint_packs.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_pack_schema.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_pack_schema_allowed_adapters.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_pack_schema_install.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_pipeline.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_plugin_manifest_schema.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_projectable_subset.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_projections_merge_json.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_scope_rails.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_security.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_self_host_check.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_self_host_fixture_guard.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_self_host_recipe_config.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shared_libs_projection.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shared_prefix_contract.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shipped_packs_v07_declarations.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_user_libs_projection.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_validate.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_writers_emit_lf.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/user_libs.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/validate.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/catalogue.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/categories.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/__init__.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/_common.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/_drop_warning.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/adapt.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/config.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/diff.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/init_state.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/list_installed.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/list_packs.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/list_profiles.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/list_targets.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/profile.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/reconcile.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/render.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/scaffold.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/uninstall.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/upgrade.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/commands/validate.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/config.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/render.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/safety.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/scope.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/source_defaults.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/statelock.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/user_config.py +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle.egg-info/dependency_links.txt +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle.egg-info/entry_points.txt +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle.egg-info/top_level.txt +0 -0
- {agentbundle-0.10.2 → agentbundle-0.11.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentbundle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
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
|
|
@@ -55,6 +55,10 @@ The install auto-detects your agent (`--adapter` overrides). Multi-IDE? Install
|
|
|
55
55
|
agentbundle list-packs
|
|
56
56
|
agentbundle list-profiles
|
|
57
57
|
|
|
58
|
+
# See what a single pack contains — skills and agents, derived live from its tree
|
|
59
|
+
agentbundle show core
|
|
60
|
+
agentbundle show core --format json # stable object for scripts/agents
|
|
61
|
+
|
|
58
62
|
# See what YOU have installed — pack, adapter, scope, version, and whether
|
|
59
63
|
# an upgrade is available (both scopes by default)
|
|
60
64
|
agentbundle list-installed
|
|
@@ -78,6 +82,8 @@ agentbundle uninstall --pack core --yes
|
|
|
78
82
|
|
|
79
83
|
**`list-installed`** reads your state files (not the catalogue) and reports every installed `(pack, adapter)` at each scope with its version and an `up-to-date` / `upgrade-available` / `unknown` status; it degrades to `unknown` (never an error) when the catalogue can't be resolved, and `--no-check` skips the check entirely.
|
|
80
84
|
|
|
85
|
+
**`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.
|
|
86
|
+
|
|
81
87
|
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).
|
|
82
88
|
|
|
83
89
|
**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).
|
|
@@ -37,6 +37,10 @@ The install auto-detects your agent (`--adapter` overrides). Multi-IDE? Install
|
|
|
37
37
|
agentbundle list-packs
|
|
38
38
|
agentbundle list-profiles
|
|
39
39
|
|
|
40
|
+
# See what a single pack contains — skills and agents, derived live from its tree
|
|
41
|
+
agentbundle show core
|
|
42
|
+
agentbundle show core --format json # stable object for scripts/agents
|
|
43
|
+
|
|
40
44
|
# See what YOU have installed — pack, adapter, scope, version, and whether
|
|
41
45
|
# an upgrade is available (both scopes by default)
|
|
42
46
|
agentbundle list-installed
|
|
@@ -60,6 +64,8 @@ agentbundle uninstall --pack core --yes
|
|
|
60
64
|
|
|
61
65
|
**`list-installed`** reads your state files (not the catalogue) and reports every installed `(pack, adapter)` at each scope with its version and an `up-to-date` / `upgrade-available` / `unknown` status; it degrades to `unknown` (never an error) when the catalogue can't be resolved, and `--no-check` skips the check entirely.
|
|
62
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
|
+
|
|
63
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).
|
|
64
70
|
|
|
65
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).
|
|
@@ -35,6 +35,7 @@ import tomllib
|
|
|
35
35
|
from typing import NamedTuple, Pattern
|
|
36
36
|
from pathlib import Path
|
|
37
37
|
|
|
38
|
+
from agentbundle.pack_inventory import apm_entries
|
|
38
39
|
from agentbundle.safety import PathJailError, assert_portable_name
|
|
39
40
|
|
|
40
41
|
# Subtrees in a pack that ship to adopters. `seeds/` is the
|
|
@@ -278,10 +279,10 @@ def _extract_frontmatter_fields(
|
|
|
278
279
|
|
|
279
280
|
def _check_skill_metadata(pack_dir: Path, constraints: Constraints) -> list[str]:
|
|
280
281
|
findings: list[str] = []
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
for entry in
|
|
282
|
+
# Enumeration lives in one place (RFC-0060 AC9): the shared raw walk.
|
|
283
|
+
# Lint keeps its own per-entry filtering (it lints SKILL.md-less dirs too,
|
|
284
|
+
# which `show` excludes) — the walk is shared, the filter is not.
|
|
285
|
+
for entry in apm_entries(pack_dir, "skills"):
|
|
285
286
|
if not entry.is_dir():
|
|
286
287
|
continue
|
|
287
288
|
dir_name = entry.name
|
|
@@ -331,10 +332,8 @@ def _check_skill_metadata(pack_dir: Path, constraints: Constraints) -> list[str]
|
|
|
331
332
|
|
|
332
333
|
def _check_agent_metadata(pack_dir: Path, constraints: Constraints) -> list[str]:
|
|
333
334
|
findings: list[str] = []
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
return findings
|
|
337
|
-
for entry in sorted(agents_dir.iterdir()):
|
|
335
|
+
# Shared raw walk (RFC-0060 AC9); lint keeps its own .md-file filter.
|
|
336
|
+
for entry in apm_entries(pack_dir, "agents"):
|
|
338
337
|
if not entry.is_file() or entry.suffix != ".md":
|
|
339
338
|
continue
|
|
340
339
|
stem = entry.stem
|
|
@@ -12,6 +12,8 @@ The `research` pack (shipped later by the `research-pack` spec) also
|
|
|
12
12
|
declared v0.8 at birth. A future pack landing at v0.8 should add itself to
|
|
13
13
|
``V08_PACKS`` so this test surfaces the new declaration.
|
|
14
14
|
|
|
15
|
+
- ``catalogue-curation`` (RFC-0059) landed at v0.8 and is registered here.
|
|
16
|
+
|
|
15
17
|
Packs in-tree NOT at v0.8:
|
|
16
18
|
|
|
17
19
|
- ``credential-brokers``: still at v0.7 (RFC-0013 shipped on v0.7 and
|
|
@@ -37,6 +39,7 @@ PACKS_DIR = REPO_ROOT / "packs"
|
|
|
37
39
|
|
|
38
40
|
V08_PACKS = (
|
|
39
41
|
"atlassian",
|
|
42
|
+
"catalogue-curation",
|
|
40
43
|
"contracts",
|
|
41
44
|
"converters",
|
|
42
45
|
"figma",
|
|
@@ -274,6 +274,31 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
274
274
|
)
|
|
275
275
|
sp.set_defaults(func=_lazy("list_installed"))
|
|
276
276
|
|
|
277
|
+
# --- show --- (catalogue query; walks a pack's .apm/ tree live)
|
|
278
|
+
sp = subparsers.add_parser(
|
|
279
|
+
"show",
|
|
280
|
+
help=(
|
|
281
|
+
"Show a pack's skills and agents, derived live from its .apm/ tree. "
|
|
282
|
+
"Falls back to the install state when the catalogue is unresolvable."
|
|
283
|
+
),
|
|
284
|
+
)
|
|
285
|
+
sp.add_argument("pack", help="Pack name to inspect (e.g. core).")
|
|
286
|
+
sp.add_argument(
|
|
287
|
+
"--format",
|
|
288
|
+
choices=("table", "json"),
|
|
289
|
+
default="table",
|
|
290
|
+
help="Output format (default: table).",
|
|
291
|
+
)
|
|
292
|
+
sp.add_argument(
|
|
293
|
+
"--root",
|
|
294
|
+
default=".",
|
|
295
|
+
help=(
|
|
296
|
+
"Repo root used to locate the repo-scope install-state file for the "
|
|
297
|
+
"catalogue-unresolvable fallback. Default: current directory."
|
|
298
|
+
),
|
|
299
|
+
)
|
|
300
|
+
sp.set_defaults(func=_lazy("show"))
|
|
301
|
+
|
|
277
302
|
# --- scaffold --- (no --scope; always repo-targeted)
|
|
278
303
|
sp = subparsers.add_parser(
|
|
279
304
|
"scaffold",
|
|
@@ -534,6 +534,9 @@ def run(args: "argparse.Namespace") -> int:
|
|
|
534
534
|
pack_name=pack_name,
|
|
535
535
|
scope=requested_scope,
|
|
536
536
|
catalogue_uri=catalogue_uri,
|
|
537
|
+
resolved_adapter=(
|
|
538
|
+
user_target_adapter if requested_scope == "user" else repo_target_adapter
|
|
539
|
+
),
|
|
537
540
|
)
|
|
538
541
|
|
|
539
542
|
# 4b. Already at the *other* scope, no --force → refuse cross-scope.
|
|
@@ -1880,7 +1883,12 @@ def _scan_dist_tree_artifacts(root: Path, pack_name: str) -> list[Path]:
|
|
|
1880
1883
|
|
|
1881
1884
|
|
|
1882
1885
|
def _offer_upgrade(
|
|
1883
|
-
args: "argparse.Namespace",
|
|
1886
|
+
args: "argparse.Namespace",
|
|
1887
|
+
*,
|
|
1888
|
+
pack_name: str,
|
|
1889
|
+
scope: str,
|
|
1890
|
+
catalogue_uri: str,
|
|
1891
|
+
resolved_adapter: "str | None" = None,
|
|
1884
1892
|
) -> int:
|
|
1885
1893
|
"""Hand off an already-installed `install` to `upgrade` (CLI-hygiene AC11/12).
|
|
1886
1894
|
|
|
@@ -1891,6 +1899,11 @@ def _offer_upgrade(
|
|
|
1891
1899
|
no-op), forwarding ``--adapter`` and threading ``_user_config`` so adapter
|
|
1892
1900
|
resolution matches a direct ``upgrade`` invocation, and leaving all five
|
|
1893
1901
|
primitive flags unset (whole-pack). Returns ``upgrade.run``'s exit code.
|
|
1902
|
+
|
|
1903
|
+
``resolved_adapter`` is the adapter install auto-detected for this run (may
|
|
1904
|
+
differ from ``args.adapter`` when ``--adapter`` was omitted). Used as a
|
|
1905
|
+
fallback so the upgrade targets the same row the install would have written,
|
|
1906
|
+
even when the pack is installed for multiple adapters at this scope.
|
|
1894
1907
|
"""
|
|
1895
1908
|
import argparse as _argparse
|
|
1896
1909
|
|
|
@@ -1908,7 +1921,11 @@ def _offer_upgrade(
|
|
|
1908
1921
|
# adapter the user picked. Without this, a pack installed for multiple
|
|
1909
1922
|
# adapters at one scope trips upgrade's multi-adapter disambiguator even
|
|
1910
1923
|
# though the operator already passed `--adapter` to `install`.
|
|
1911
|
-
|
|
1924
|
+
# Fall back to `resolved_adapter` when --adapter was omitted: install
|
|
1925
|
+
# auto-detects a target adapter and the upgrade offer must target that same
|
|
1926
|
+
# row rather than leaving upgrade to re-disambiguate (and fail) when multiple
|
|
1927
|
+
# adapter rows exist at this scope.
|
|
1928
|
+
ns.adapter = getattr(args, "adapter", None) or resolved_adapter
|
|
1912
1929
|
ns.yes = True
|
|
1913
1930
|
ns.dry_run = False
|
|
1914
1931
|
ns.skill = ns.agent = ns.hook = ns.seed = ns.command = None
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""``agentbundle show <pack>`` subcommand.
|
|
2
|
+
|
|
3
|
+
Answers "what skills and agents does pack X contain?" by walking the pack's
|
|
4
|
+
``.apm/`` source tree **live** on each call (ADR-0049 / RFC-0060): nothing is
|
|
5
|
+
persisted and no manifest is touched, so the answer cannot drift from what the
|
|
6
|
+
pack actually ships.
|
|
7
|
+
|
|
8
|
+
Two honest, state-differentiated sources:
|
|
9
|
+
|
|
10
|
+
- **Primary — catalogue.** Resolve the pack in the active catalogue, walk
|
|
11
|
+
``.apm/skills/`` and ``.apm/agents/``, and print the pack's ``pack.toml``
|
|
12
|
+
metadata alongside its full, sorted skill + agent inventory
|
|
13
|
+
(``source: catalogue``).
|
|
14
|
+
- **Degrade — install state.** When the catalogue is unresolvable, an
|
|
15
|
+
*installed* pack still yields its inventory from the install-state file —
|
|
16
|
+
the union of skill/agent names across every adapter row in both the user
|
|
17
|
+
and repo scope (``source: installed-state``) — while a *not-installed* pack
|
|
18
|
+
fails with a one-line error, because there is no source to read.
|
|
19
|
+
|
|
20
|
+
``--format json`` emits the same as a single stable object for programmatic
|
|
21
|
+
consumers. The inventory is never filtered (``show`` reports what *exists*, not
|
|
22
|
+
what a user can invoke), and it is the full, untagged set — every skill under
|
|
23
|
+
``.apm/skills/``, not the ``[pack.evals].skills`` subset.
|
|
24
|
+
|
|
25
|
+
Exit codes:
|
|
26
|
+
0 — success (catalogue path or installed-state fallback).
|
|
27
|
+
1 — unknown pack, or unresolvable-catalogue-and-not-installed (one-line
|
|
28
|
+
stderr, empty stdout — including under ``--format json``).
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import sys
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
from typing import TYPE_CHECKING
|
|
36
|
+
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
import argparse
|
|
39
|
+
|
|
40
|
+
from agentbundle.config import State
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def run(args: "argparse.Namespace") -> int:
|
|
44
|
+
"""Entry point for ``agentbundle show``."""
|
|
45
|
+
from agentbundle.catalogue import CatalogueError, resolve_catalogue
|
|
46
|
+
from agentbundle.commands._common import resolve_catalogue_uri
|
|
47
|
+
from agentbundle.pack_inventory import agent_names, skill_names
|
|
48
|
+
|
|
49
|
+
pack_name: str = args.pack
|
|
50
|
+
fmt: str = getattr(args, "format", "table")
|
|
51
|
+
|
|
52
|
+
# ── Resolve the catalogue (authoritative primary source) ──────────────────
|
|
53
|
+
try:
|
|
54
|
+
catalogue_dir = resolve_catalogue(resolve_catalogue_uri(args))
|
|
55
|
+
except CatalogueError:
|
|
56
|
+
# Honest, state-differentiated degrade (ADR-0049).
|
|
57
|
+
return _degrade(args, pack_name, fmt)
|
|
58
|
+
|
|
59
|
+
# ── Name-match the pack in the catalogue ──────────────────────────────────
|
|
60
|
+
match = _find_pack_dir(catalogue_dir, pack_name)
|
|
61
|
+
if match is None:
|
|
62
|
+
print(f"show: pack {pack_name!r} not found in catalogue", file=sys.stderr)
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
pack_dir, toml = match
|
|
66
|
+
pack = toml.get("pack", {})
|
|
67
|
+
_emit(
|
|
68
|
+
fmt,
|
|
69
|
+
name=pack.get("name") or pack_dir.name,
|
|
70
|
+
# Pass metadata through as-is: an *absent* key is null; a present
|
|
71
|
+
# (even empty) value is not coerced, so "declared empty" and "absent"
|
|
72
|
+
# stay distinguishable on the authoritative catalogue path.
|
|
73
|
+
version=pack.get("version"),
|
|
74
|
+
description=pack.get("description"),
|
|
75
|
+
skills=skill_names(pack_dir),
|
|
76
|
+
agents=agent_names(pack_dir),
|
|
77
|
+
source="catalogue",
|
|
78
|
+
)
|
|
79
|
+
return 0
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# ---------------------------------------------------------------------------
|
|
83
|
+
# Primary path — catalogue lookup
|
|
84
|
+
# ---------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _find_pack_dir(catalogue_dir: Path, pack_name: str) -> tuple[Path, dict] | None:
|
|
88
|
+
"""Return ``(pack_dir, parsed pack.toml)`` for *pack_name*, or None.
|
|
89
|
+
|
|
90
|
+
Reuses ``list-packs``' ``_discover_pack_dirs`` so the accepted catalogue
|
|
91
|
+
layouts stay identical, then matches on the pack's declared ``[pack].name``
|
|
92
|
+
(falling back to the directory name) — the step the AC5 "unknown pack" path
|
|
93
|
+
depends on.
|
|
94
|
+
"""
|
|
95
|
+
from agentbundle.commands.list_packs import _discover_pack_dirs
|
|
96
|
+
from agentbundle.config import ConfigError, load_pack_toml
|
|
97
|
+
|
|
98
|
+
for pack_dir in _discover_pack_dirs(catalogue_dir):
|
|
99
|
+
try:
|
|
100
|
+
toml = load_pack_toml(pack_dir / "pack.toml")
|
|
101
|
+
except ConfigError:
|
|
102
|
+
continue
|
|
103
|
+
# A declared ``[pack].name`` is authoritative (list-packs keys display
|
|
104
|
+
# on it); fall back to the directory name only when it is absent, so a
|
|
105
|
+
# coincidental dir-name match never shadows a pack declaring a different
|
|
106
|
+
# name.
|
|
107
|
+
name = toml.get("pack", {}).get("name") or pack_dir.name
|
|
108
|
+
if name == pack_name:
|
|
109
|
+
return pack_dir, toml
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# ---------------------------------------------------------------------------
|
|
114
|
+
# Degrade path — install-state fallback
|
|
115
|
+
# ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _degrade(args: "argparse.Namespace", pack_name: str, fmt: str) -> int:
|
|
119
|
+
"""Recover the inventory from the install state when the catalogue is gone.
|
|
120
|
+
|
|
121
|
+
Reads both the user and repo scope (mirroring ``list-installed``). An
|
|
122
|
+
*installed* pack yields the union of skill/agent names across every adapter
|
|
123
|
+
row in both scopes, deduped + sorted (``source: installed-state``, metadata
|
|
124
|
+
null); a *not-installed* pack errors and exits non-zero.
|
|
125
|
+
"""
|
|
126
|
+
states = _load_states(args)
|
|
127
|
+
if not any(state.has_pack(pack_name) for state in states):
|
|
128
|
+
print(
|
|
129
|
+
f"show: catalogue unavailable and pack {pack_name!r} is not installed",
|
|
130
|
+
file=sys.stderr,
|
|
131
|
+
)
|
|
132
|
+
return 1
|
|
133
|
+
|
|
134
|
+
skills: set[str] = set()
|
|
135
|
+
agents: set[str] = set()
|
|
136
|
+
for state in states:
|
|
137
|
+
for pack_state in state.rows_for_pack(pack_name).values():
|
|
138
|
+
for relpath in pack_state.files:
|
|
139
|
+
skill = _skill_from_relpath(relpath)
|
|
140
|
+
if skill:
|
|
141
|
+
skills.add(skill)
|
|
142
|
+
agent = _agent_from_relpath(relpath)
|
|
143
|
+
if agent:
|
|
144
|
+
agents.add(agent)
|
|
145
|
+
|
|
146
|
+
_emit(
|
|
147
|
+
fmt,
|
|
148
|
+
name=pack_name, # the argument passed to `show`; state has no pack name
|
|
149
|
+
version=None, # inventory-only fallback — never fabricated from state
|
|
150
|
+
description=None,
|
|
151
|
+
skills=sorted(skills),
|
|
152
|
+
agents=sorted(agents),
|
|
153
|
+
source="installed-state",
|
|
154
|
+
)
|
|
155
|
+
return 0
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _load_states(args: "argparse.Namespace") -> list["State"]:
|
|
159
|
+
"""Load the user- and repo-scope install-state files, read-only.
|
|
160
|
+
|
|
161
|
+
Mirrors ``list-installed``'s two-scope gather: user
|
|
162
|
+
(``~/.agentbundle/state.toml`` via ``scope.resolve_user_root``) and repo
|
|
163
|
+
(``<--root>/.agentbundle-state.toml``). An unresolvable user home is skipped;
|
|
164
|
+
an absent state file loads as an empty ``State``; a legacy/incompatible file
|
|
165
|
+
(``StateFileLegacy`` — a ``ConfigError``) is skipped, not fatal.
|
|
166
|
+
"""
|
|
167
|
+
from agentbundle import scope as scope_mod
|
|
168
|
+
from agentbundle.config import ConfigError, load_state
|
|
169
|
+
|
|
170
|
+
candidates: list[tuple[str, Path]] = []
|
|
171
|
+
try:
|
|
172
|
+
user_root = scope_mod.resolve_user_root()
|
|
173
|
+
except scope_mod.UserScopeUnresolvable:
|
|
174
|
+
pass
|
|
175
|
+
else:
|
|
176
|
+
candidates.append(("user", user_root / ".agentbundle" / "state.toml"))
|
|
177
|
+
repo_root = Path(getattr(args, "root", ".") or ".").resolve()
|
|
178
|
+
candidates.append(("repo", repo_root / ".agentbundle-state.toml"))
|
|
179
|
+
|
|
180
|
+
states: list["State"] = []
|
|
181
|
+
for scope_name, path in candidates:
|
|
182
|
+
try:
|
|
183
|
+
states.append(load_state(path))
|
|
184
|
+
except ConfigError as exc:
|
|
185
|
+
# Mirror `list-installed`: a legacy/incompatible state file is
|
|
186
|
+
# warned-and-skipped, not silently dropped — otherwise an installed
|
|
187
|
+
# pack whose only row lives there would masquerade as not-installed
|
|
188
|
+
# on this degrade path with no hint why.
|
|
189
|
+
print(f"show: skipping {scope_name} scope: {exc}", file=sys.stderr)
|
|
190
|
+
return states
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _skill_from_relpath(relpath: str) -> str | None:
|
|
194
|
+
"""Skill name = the path segment immediately after a ``skills/`` component.
|
|
195
|
+
|
|
196
|
+
Layout-agnostic across ``.claude/skills/``, the shared ``.agents/skills/``
|
|
197
|
+
(codex/copilot/cursor/gemini), and ``.kiro/skills/``. Any projected file
|
|
198
|
+
under ``skills/<name>/`` maps to ``<name>``; the caller dedupes.
|
|
199
|
+
"""
|
|
200
|
+
parts = Path(relpath).parts
|
|
201
|
+
for i, part in enumerate(parts):
|
|
202
|
+
if part == "skills" and i + 1 < len(parts):
|
|
203
|
+
return parts[i + 1]
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _agent_from_relpath(relpath: str) -> str | None:
|
|
208
|
+
"""Agent name = the filename directly under an ``agents/`` component, with
|
|
209
|
+
its extension stripped by an **extension-agnostic** rule.
|
|
210
|
+
|
|
211
|
+
Strip a trailing ``.agent.md`` (copilot's double-suffix) if present, else
|
|
212
|
+
``Path.stem`` (the single final extension). Recovers ``<n>`` uniformly from
|
|
213
|
+
``.claude/agents/<n>.md``, ``.codex/agents/<n>.toml``,
|
|
214
|
+
``.kiro/agents/<n>.json``, and ``.github/agents/<n>.agent.md`` — so
|
|
215
|
+
co-installed adapter rows dedupe to one entry.
|
|
216
|
+
"""
|
|
217
|
+
path = Path(relpath)
|
|
218
|
+
parts = path.parts
|
|
219
|
+
# A top-level ``agents/`` component only — never an ``agents/`` dir nested
|
|
220
|
+
# inside a skill's payload (``.../skills/<n>/agents/helper.md``), which would
|
|
221
|
+
# surface a phantom agent.
|
|
222
|
+
if len(parts) >= 2 and parts[-2] == "agents" and "skills" not in parts:
|
|
223
|
+
name = path.name
|
|
224
|
+
if name.endswith(".agent.md"):
|
|
225
|
+
return name[: -len(".agent.md")]
|
|
226
|
+
return path.stem
|
|
227
|
+
return None
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
# ---------------------------------------------------------------------------
|
|
231
|
+
# Rendering
|
|
232
|
+
# ---------------------------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _emit(
|
|
236
|
+
fmt: str,
|
|
237
|
+
*,
|
|
238
|
+
name: str,
|
|
239
|
+
version: str | None,
|
|
240
|
+
description: str | None,
|
|
241
|
+
skills: list[str],
|
|
242
|
+
agents: list[str],
|
|
243
|
+
source: str,
|
|
244
|
+
) -> None:
|
|
245
|
+
"""Render the inventory as a table block or a single JSON object."""
|
|
246
|
+
if fmt == "json":
|
|
247
|
+
import json
|
|
248
|
+
|
|
249
|
+
obj = {
|
|
250
|
+
"name": name,
|
|
251
|
+
"version": version,
|
|
252
|
+
"description": description,
|
|
253
|
+
"skills": skills,
|
|
254
|
+
"agents": agents,
|
|
255
|
+
"source": source,
|
|
256
|
+
}
|
|
257
|
+
print(json.dumps(obj))
|
|
258
|
+
return
|
|
259
|
+
|
|
260
|
+
from agentbundle.commands._common import render_table
|
|
261
|
+
|
|
262
|
+
rows: list[list[str]] = [["name", name]]
|
|
263
|
+
# Fallback (installed-state) omits version/description — the state has neither.
|
|
264
|
+
if version is not None:
|
|
265
|
+
rows.append(["version", version])
|
|
266
|
+
if description is not None:
|
|
267
|
+
rows.append(["description", description])
|
|
268
|
+
rows.append(["skills", ", ".join(skills) if skills else "-"])
|
|
269
|
+
rows.append(["agents", ", ".join(agents) if agents else "-"])
|
|
270
|
+
render_table(["FIELD", "VALUE"], rows, wrap_col=1)
|
|
271
|
+
if source != "catalogue":
|
|
272
|
+
print(f"source: {source} (catalogue unavailable)")
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Live pack-inventory walk over a pack's ``.apm/`` source tree.
|
|
2
|
+
|
|
3
|
+
A pack's authoritative contents live under ``<pack>/.apm/``:
|
|
4
|
+
|
|
5
|
+
- skills at ``.apm/skills/<name>/SKILL.md`` → ``<name>``
|
|
6
|
+
- agents at ``.apm/agents/<name>.md`` → ``<name>``
|
|
7
|
+
|
|
8
|
+
This module is the single enumeration path for that tree (ADR-0049 /
|
|
9
|
+
RFC-0060 AC9): both ``agentbundle show`` and ``build/lint_packs`` walk it
|
|
10
|
+
through :func:`apm_entries`, so the directory traversal lives in one place.
|
|
11
|
+
The primitive returns **raw sorted entries** — each caller applies its own
|
|
12
|
+
filter (``show`` counts only ``SKILL.md``-bearing skill dirs and ``.md``
|
|
13
|
+
agent files; ``lint_packs`` lints every entry, ``SKILL.md`` or not).
|
|
14
|
+
|
|
15
|
+
Pure stdlib ``pathlib`` — no I/O beyond reading the directory tree, and
|
|
16
|
+
nothing is persisted (ADR-0049: derive live, persist nothing).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def apm_entries(pack_dir: Path, subdir: str) -> list[Path]:
|
|
25
|
+
"""Return the sorted direct children of ``<pack_dir>/.apm/<subdir>``.
|
|
26
|
+
|
|
27
|
+
Returns ``[]`` when the directory is absent (AC4) — a pack that ships no
|
|
28
|
+
skills, or no agents, is not an error. Sorted ascending by path so every
|
|
29
|
+
consumer sees a deterministic order. This is the shared raw walk (AC9);
|
|
30
|
+
callers filter the entries themselves.
|
|
31
|
+
"""
|
|
32
|
+
d = pack_dir / ".apm" / subdir
|
|
33
|
+
if not d.is_dir():
|
|
34
|
+
return []
|
|
35
|
+
return sorted(d.iterdir())
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def skill_names(pack_dir: Path) -> list[str]:
|
|
39
|
+
"""Sorted names of ``.apm/skills/<name>/`` dirs that contain a ``SKILL.md``.
|
|
40
|
+
|
|
41
|
+
A skills subdirectory without a ``SKILL.md`` is not a skill (AC2); a
|
|
42
|
+
missing ``.apm/skills/`` yields ``[]`` (AC4).
|
|
43
|
+
"""
|
|
44
|
+
return [
|
|
45
|
+
entry.name
|
|
46
|
+
for entry in apm_entries(pack_dir, "skills")
|
|
47
|
+
if entry.is_dir() and (entry / "SKILL.md").is_file()
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def agent_names(pack_dir: Path) -> list[str]:
|
|
52
|
+
"""Sorted stems of ``.apm/agents/*.md`` files.
|
|
53
|
+
|
|
54
|
+
Non-``.md`` entries and subdirectories are ignored (AC2); a missing
|
|
55
|
+
``.apm/agents/`` yields ``[]`` (AC4).
|
|
56
|
+
"""
|
|
57
|
+
return [
|
|
58
|
+
entry.stem
|
|
59
|
+
for entry in apm_entries(pack_dir, "agents")
|
|
60
|
+
if entry.is_file() and entry.suffix == ".md"
|
|
61
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentbundle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
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
|
|
@@ -55,6 +55,10 @@ The install auto-detects your agent (`--adapter` overrides). Multi-IDE? Install
|
|
|
55
55
|
agentbundle list-packs
|
|
56
56
|
agentbundle list-profiles
|
|
57
57
|
|
|
58
|
+
# See what a single pack contains — skills and agents, derived live from its tree
|
|
59
|
+
agentbundle show core
|
|
60
|
+
agentbundle show core --format json # stable object for scripts/agents
|
|
61
|
+
|
|
58
62
|
# See what YOU have installed — pack, adapter, scope, version, and whether
|
|
59
63
|
# an upgrade is available (both scopes by default)
|
|
60
64
|
agentbundle list-installed
|
|
@@ -78,6 +82,8 @@ agentbundle uninstall --pack core --yes
|
|
|
78
82
|
|
|
79
83
|
**`list-installed`** reads your state files (not the catalogue) and reports every installed `(pack, adapter)` at each scope with its version and an `up-to-date` / `upgrade-available` / `unknown` status; it degrades to `unknown` (never an error) when the catalogue can't be resolved, and `--no-check` skips the check entirely.
|
|
80
84
|
|
|
85
|
+
**`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.
|
|
86
|
+
|
|
81
87
|
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).
|
|
82
88
|
|
|
83
89
|
**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).
|
|
@@ -6,6 +6,7 @@ agentbundle/catalogue.py
|
|
|
6
6
|
agentbundle/categories.py
|
|
7
7
|
agentbundle/cli.py
|
|
8
8
|
agentbundle/config.py
|
|
9
|
+
agentbundle/pack_inventory.py
|
|
9
10
|
agentbundle/render.py
|
|
10
11
|
agentbundle/safety.py
|
|
11
12
|
agentbundle/scope.py
|
|
@@ -119,6 +120,7 @@ agentbundle/commands/profile.py
|
|
|
119
120
|
agentbundle/commands/reconcile.py
|
|
120
121
|
agentbundle/commands/render.py
|
|
121
122
|
agentbundle/commands/scaffold.py
|
|
123
|
+
agentbundle/commands/show.py
|
|
122
124
|
agentbundle/commands/uninstall.py
|
|
123
125
|
agentbundle/commands/upgrade.py
|
|
124
126
|
agentbundle/commands/validate.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentbundle"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.11.1"
|
|
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 = []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/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
|
|
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
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/copilot_hooks_json.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/gemini_command_toml.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/projections/merge_into_agent_json.py
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
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_claude_code.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_adapter_kiro_alias.py
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
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_direct_directory_cleanup.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_lint_agents_md_risk_block.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_pack_schema_install.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_plugin_manifest_schema.py
RENAMED
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_projectable_subset.py
RENAMED
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_projections_merge_json.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_self_host_fixture_guard.py
RENAMED
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_self_host_recipe_config.py
RENAMED
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shared_libs_projection.py
RENAMED
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_shared_prefix_contract.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentbundle-0.10.2 → agentbundle-0.11.1}/agentbundle/build/tests/test_user_libs_projection.py
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|