agentbundle 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. agentbundle/__init__.py +14 -0
  2. agentbundle/__main__.py +5 -0
  3. agentbundle/_data/adapter.schema.json +270 -0
  4. agentbundle/_data/adapter.toml +584 -0
  5. agentbundle/_data/install-marker.py +1099 -0
  6. agentbundle/_data/pack.schema.json +152 -0
  7. agentbundle/_data/plugin-manifest.derived.schema.json +33 -0
  8. agentbundle/_data/plugin-manifest.schema.json +18 -0
  9. agentbundle/build/__init__.py +206 -0
  10. agentbundle/build/__main__.py +8 -0
  11. agentbundle/build/adapter_root_bins.py +336 -0
  12. agentbundle/build/adapters/__init__.py +46 -0
  13. agentbundle/build/adapters/claude_code.py +142 -0
  14. agentbundle/build/adapters/codex.py +227 -0
  15. agentbundle/build/adapters/copilot.py +149 -0
  16. agentbundle/build/adapters/kiro.py +608 -0
  17. agentbundle/build/adapters/kiro_cli.py +53 -0
  18. agentbundle/build/adapters/kiro_ide.py +275 -0
  19. agentbundle/build/contract.py +20 -0
  20. agentbundle/build/lint_packs.py +555 -0
  21. agentbundle/build/main.py +596 -0
  22. agentbundle/build/phase_order.py +40 -0
  23. agentbundle/build/projections/__init__.py +13 -0
  24. agentbundle/build/projections/codex_agent_toml.py +232 -0
  25. agentbundle/build/projections/copilot_agent_md.py +206 -0
  26. agentbundle/build/projections/copilot_hooks_json.py +142 -0
  27. agentbundle/build/projections/direct_directory.py +41 -0
  28. agentbundle/build/projections/hook_id.py +27 -0
  29. agentbundle/build/projections/kiro_ide_hook.py +256 -0
  30. agentbundle/build/projections/merge_into_agent_json.py +264 -0
  31. agentbundle/build/projections/merge_json.py +58 -0
  32. agentbundle/build/projections/user_merge_json.py +324 -0
  33. agentbundle/build/scope_rails.py +728 -0
  34. agentbundle/build/self_host.py +1486 -0
  35. agentbundle/build/shared_libs.py +309 -0
  36. agentbundle/build/target_resolver.py +85 -0
  37. agentbundle/build/tests/__init__.py +0 -0
  38. agentbundle/build/tests/test_adapter_claude_code.py +275 -0
  39. agentbundle/build/tests/test_adapter_codex.py +699 -0
  40. agentbundle/build/tests/test_adapter_copilot.py +91 -0
  41. agentbundle/build/tests/test_adapter_kiro.py +449 -0
  42. agentbundle/build/tests/test_adapter_kiro_alias.py +105 -0
  43. agentbundle/build/tests/test_adapter_kiro_cli.py +102 -0
  44. agentbundle/build/tests/test_adapter_kiro_ide.py +173 -0
  45. agentbundle/build/tests/test_adapter_root_bins_projection.py +429 -0
  46. agentbundle/build/tests/test_build_ships_seeds.py +78 -0
  47. agentbundle/build/tests/test_contract.py +582 -0
  48. agentbundle/build/tests/test_contract_scope.py +224 -0
  49. agentbundle/build/tests/test_contract_v07.py +191 -0
  50. agentbundle/build/tests/test_contract_v08.py +230 -0
  51. agentbundle/build/tests/test_direct_directory_cleanup.py +65 -0
  52. agentbundle/build/tests/test_end_to_end_build.py +227 -0
  53. agentbundle/build/tests/test_lint_agents_md_legacy_block.py +135 -0
  54. agentbundle/build/tests/test_lint_agents_md_risk_block.py +116 -0
  55. agentbundle/build/tests/test_lint_packs.py +703 -0
  56. agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +176 -0
  57. agentbundle/build/tests/test_pack_schema.py +265 -0
  58. agentbundle/build/tests/test_pack_schema_allowed_adapters.py +258 -0
  59. agentbundle/build/tests/test_pack_schema_install.py +305 -0
  60. agentbundle/build/tests/test_pipeline.py +272 -0
  61. agentbundle/build/tests/test_plugin_manifest_schema.py +327 -0
  62. agentbundle/build/tests/test_projections_merge_json.py +148 -0
  63. agentbundle/build/tests/test_scope_rails.py +398 -0
  64. agentbundle/build/tests/test_security.py +97 -0
  65. agentbundle/build/tests/test_self_host_check.py +2100 -0
  66. agentbundle/build/tests/test_shared_libs_projection.py +415 -0
  67. agentbundle/build/tests/test_shipped_packs_v07_declarations.py +100 -0
  68. agentbundle/build/tests/test_shipped_packs_v08_declarations.py +80 -0
  69. agentbundle/build/tests/test_validate.py +250 -0
  70. agentbundle/build/validate.py +141 -0
  71. agentbundle/catalogue.py +164 -0
  72. agentbundle/cli.py +486 -0
  73. agentbundle/commands/__init__.py +5 -0
  74. agentbundle/commands/_common.py +174 -0
  75. agentbundle/commands/_drop_warning.py +329 -0
  76. agentbundle/commands/adapt.py +343 -0
  77. agentbundle/commands/config.py +125 -0
  78. agentbundle/commands/diff.py +211 -0
  79. agentbundle/commands/init_state.py +279 -0
  80. agentbundle/commands/install.py +3026 -0
  81. agentbundle/commands/list_packs.py +170 -0
  82. agentbundle/commands/list_targets.py +23 -0
  83. agentbundle/commands/reconcile.py +161 -0
  84. agentbundle/commands/render.py +165 -0
  85. agentbundle/commands/scaffold.py +69 -0
  86. agentbundle/commands/uninstall.py +294 -0
  87. agentbundle/commands/upgrade.py +699 -0
  88. agentbundle/commands/validate.py +688 -0
  89. agentbundle/config.py +747 -0
  90. agentbundle/render.py +123 -0
  91. agentbundle/safety.py +633 -0
  92. agentbundle/scope.py +319 -0
  93. agentbundle/user_config.py +284 -0
  94. agentbundle/version.py +49 -0
  95. agentbundle-0.2.0.dist-info/METADATA +37 -0
  96. agentbundle-0.2.0.dist-info/RECORD +99 -0
  97. agentbundle-0.2.0.dist-info/WHEEL +5 -0
  98. agentbundle-0.2.0.dist-info/entry_points.txt +2 -0
  99. agentbundle-0.2.0.dist-info/top_level.txt +1 -0
agentbundle/render.py ADDED
@@ -0,0 +1,123 @@
1
+ """Thin wrapper around `agentbundle.build` — the library-first render API.
2
+
3
+ The CLI's `render`, `scaffold`, `install`, and `upgrade` subcommands all
4
+ route their projection work through this module so there is exactly one
5
+ implementation of "produce the projected output tree for a pack" in the
6
+ codebase.
7
+
8
+ Two surfaces:
9
+
10
+ - `render_pack_to_dir(pack_path, output_dir, contract=None)` — runs the
11
+ same three RFC-0001 recipes that `make build` runs (per-pack
12
+ claude-plugin, per-pack apm-package, marketplace) and writes them
13
+ into `output_dir`. Byte-identical to `make build`.
14
+
15
+ - `render_pack(pack_path, contract=None)` — same projection, but
16
+ materialised in a tempdir and returned as a `dict[str, bytes]`
17
+ keyed by path-relative-to-the-tempdir. Caller is responsible for
18
+ deciding where (or whether) to write the bytes. Used by `diff`,
19
+ `install`, `upgrade`, and the F-build parity test.
20
+
21
+ Adapter target enumeration lives at `list_adapters()`; it queries the
22
+ runtime registry at `agentbundle.build.adapters` so adding an adapter
23
+ to the registry adds it to `agentbundle list-targets` automatically.
24
+ """
25
+
26
+ from __future__ import annotations
27
+
28
+ import tempfile
29
+ from pathlib import Path
30
+ from typing import Sequence
31
+
32
+ from agentbundle.build import adapters as _adapters
33
+ import tomllib
34
+
35
+ from agentbundle.build.main import (
36
+ DEFAULT_RECIPES,
37
+ Pack,
38
+ _read_bundled,
39
+ discover_packs,
40
+ load_recipe,
41
+ run_recipe,
42
+ validate_pack_metadata,
43
+ )
44
+
45
+
46
+ def list_adapters() -> Sequence[str]:
47
+ """Return the adapter names the CLI ships against, in stable sort order."""
48
+ return sorted(_adapters.registry.keys())
49
+
50
+
51
+ def _resolve_contract(contract: dict | None) -> dict:
52
+ return contract if contract is not None else tomllib.loads(_read_bundled("adapter.toml"))
53
+
54
+
55
+ def _pack_from_path(pack_path: Path) -> Pack:
56
+ pack_path = pack_path.resolve()
57
+ if not (pack_path / "pack.toml").exists():
58
+ raise FileNotFoundError(f"no pack.toml at {pack_path}")
59
+ validate_pack_metadata(pack_path / "pack.toml")
60
+ return Pack(name=pack_path.name, path=pack_path)
61
+
62
+
63
+ def render_pack_to_dir(
64
+ pack_path: Path,
65
+ output_dir: Path,
66
+ *,
67
+ contract: dict | None = None,
68
+ recipes: Sequence[str] = DEFAULT_RECIPES,
69
+ ) -> None:
70
+ """Render a single pack to `output_dir` using the named recipes.
71
+
72
+ `output_dir` is created if absent. The three default recipes match
73
+ what `make build` runs; the F-build parity test pins this.
74
+ """
75
+ pack = _pack_from_path(pack_path)
76
+ contract_data = _resolve_contract(contract)
77
+ output_dir.mkdir(parents=True, exist_ok=True)
78
+ for recipe_name in recipes:
79
+ recipe = load_recipe(recipe_name)
80
+ run_recipe(recipe, [pack], output_dir, contract_data)
81
+
82
+
83
+ def render_pack(
84
+ pack_path: Path,
85
+ *,
86
+ contract: dict | None = None,
87
+ recipes: Sequence[str] = DEFAULT_RECIPES,
88
+ ) -> dict[str, bytes]:
89
+ """Render a pack to a tempdir and return its bytes keyed by relpath.
90
+
91
+ Bytes — not str — because hook bodies may be non-UTF-8 binaries in
92
+ principle (and because `bytes` is the right shape for hash + write).
93
+ """
94
+ with tempfile.TemporaryDirectory() as raw:
95
+ out = Path(raw)
96
+ render_pack_to_dir(pack_path, out, contract=contract, recipes=recipes)
97
+ return _collect_tree(out)
98
+
99
+
100
+ def render_packs_to_dir(
101
+ packs_dir: Path,
102
+ output_dir: Path,
103
+ *,
104
+ contract: dict | None = None,
105
+ recipes: Sequence[str] = DEFAULT_RECIPES,
106
+ ) -> None:
107
+ """Render every pack under `packs_dir` — the full `make build` shape."""
108
+ contract_data = _resolve_contract(contract)
109
+ packs = discover_packs(packs_dir)
110
+ output_dir.mkdir(parents=True, exist_ok=True)
111
+ for recipe_name in recipes:
112
+ recipe = load_recipe(recipe_name)
113
+ run_recipe(recipe, packs, output_dir, contract_data)
114
+
115
+
116
+ def _collect_tree(root: Path) -> dict[str, bytes]:
117
+ """Walk `root` and return every file's bytes keyed by relpath (POSIX-style)."""
118
+ out: dict[str, bytes] = {}
119
+ for path in sorted(root.rglob("*")):
120
+ if path.is_file():
121
+ relpath = path.relative_to(root).as_posix()
122
+ out[relpath] = path.read_bytes()
123
+ return out