agentbundle 0.29.5__tar.gz → 0.29.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. {agentbundle-0.29.5 → agentbundle-0.29.7}/PKG-INFO +8 -4
  2. {agentbundle-0.29.5 → agentbundle-0.29.7}/README-pypi.md +7 -3
  3. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/adapter.toml +3 -0
  4. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/manifest.json +1 -1
  5. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/packs/AGENTS.md +38 -38
  6. agentbundle-0.29.7/agentbundle/_data/marketplace-entry.schema.json +110 -0
  7. agentbundle-0.29.7/agentbundle/_data/plugin-manifest.derived.schema.json +147 -0
  8. agentbundle-0.29.7/agentbundle/_data/plugin-manifest.schema.json +110 -0
  9. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/claude_code.py +27 -2
  10. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/main.py +88 -16
  11. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_end_to_end_build.py +11 -3
  12. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_pipeline.py +2 -2
  13. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_plugin_manifest_schema.py +4 -4
  14. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_projectable_subset.py +4 -4
  15. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_self_host_check.py +0 -1
  16. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/self_host_windows.py +15 -2
  17. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/verify.py +84 -25
  18. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/upgrade.py +1 -1
  19. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/version.py +1 -1
  20. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/PKG-INFO +8 -4
  21. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/SOURCES.txt +1 -0
  22. {agentbundle-0.29.5 → agentbundle-0.29.7}/pyproject.toml +1 -1
  23. agentbundle-0.29.5/agentbundle/_data/plugin-manifest.derived.schema.json +0 -73
  24. agentbundle-0.29.5/agentbundle/_data/plugin-manifest.schema.json +0 -45
  25. {agentbundle-0.29.5 → agentbundle-0.29.7}/README.md +0 -0
  26. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/__init__.py +0 -0
  27. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/__main__.py +0 -0
  28. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/adapter.schema.json +0 -0
  29. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-authoring-standards.md +0 -0
  30. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-ci-contract.md +0 -0
  31. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/packs/README.md +0 -0
  32. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/packs/_example/README.md +0 -0
  33. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/packs/_example/pack.toml +0 -0
  34. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/profiles/AGENTS.md +0 -0
  35. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/profiles/README.md +0 -0
  36. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/profiles/_example/README.md +0 -0
  37. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue-scaffold/profiles/_example/profile.toml +0 -0
  38. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/catalogue.schema.json +0 -0
  39. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/guide.schema.json +0 -0
  40. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/install-defaults.toml +0 -0
  41. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/install-marker.py +0 -0
  42. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/pack.schema.json +0 -0
  43. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/profile.schema.json +0 -0
  44. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/skill-manifest.schema.json +0 -0
  45. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/skill.schema.json +0 -0
  46. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/_data/target-vocab.toml +0 -0
  47. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/__init__.py +0 -0
  48. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/__main__.py +0 -0
  49. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapter_root_bins.py +0 -0
  50. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/__init__.py +0 -0
  51. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/codex.py +0 -0
  52. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/copilot.py +0 -0
  53. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/cursor.py +0 -0
  54. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/gemini.py +0 -0
  55. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/kiro.py +0 -0
  56. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/kiro_cli.py +0 -0
  57. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/adapters/kiro_ide.py +0 -0
  58. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/contract.py +0 -0
  59. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/lint_packs.py +0 -0
  60. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/phase_order.py +0 -0
  61. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/__init__.py +0 -0
  62. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/codex_agent_toml.py +0 -0
  63. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/copilot_agent_md.py +0 -0
  64. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
  65. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/direct_directory.py +0 -0
  66. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/gemini_command_toml.py +0 -0
  67. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/hook_id.py +0 -0
  68. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
  69. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
  70. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/merge_json.py +0 -0
  71. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/projections/user_merge_json.py +0 -0
  72. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/composite-agents-md.toml +0 -0
  73. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/composite-marketplace.toml +0 -0
  74. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/marketplace.toml +0 -0
  75. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/per-pack-apm-package.toml +0 -0
  76. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/per-pack-claude-plugin.toml +0 -0
  77. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/per-pack-overlay.toml +0 -0
  78. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/recipes/self-host.toml +0 -0
  79. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/scope_rails.py +0 -0
  80. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/self_host.py +0 -0
  81. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/shared_libs.py +0 -0
  82. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/target_resolver.py +0 -0
  83. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/__init__.py +0 -0
  84. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_claude_code.py +0 -0
  85. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_codex.py +0 -0
  86. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_copilot.py +0 -0
  87. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_cursor.py +0 -0
  88. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_gemini.py +0 -0
  89. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_kiro.py +0 -0
  90. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_kiro_alias.py +0 -0
  91. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_kiro_cli.py +0 -0
  92. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_kiro_ide.py +0 -0
  93. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_adapter_root_bins_projection.py +0 -0
  94. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_architect_design_reviewer_projection.py +0 -0
  95. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_architect_design_reviewer_rubric_parity.py +0 -0
  96. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_build_ships_seeds.py +0 -0
  97. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_contract.py +0 -0
  98. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_contract_scope.py +0 -0
  99. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_contract_v07.py +0 -0
  100. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_contract_v08.py +0 -0
  101. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_direct_directory_cleanup.py +0 -0
  102. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_lint_agents_md_diataxis_block.py +0 -0
  103. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_lint_agents_md_legacy_block.py +0 -0
  104. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_lint_agents_md_risk_block.py +0 -0
  105. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_lint_packs.py +0 -0
  106. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +0 -0
  107. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_pack_schema.py +0 -0
  108. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_pack_schema_allowed_adapters.py +0 -0
  109. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_pack_schema_install.py +0 -0
  110. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_projections_merge_json.py +0 -0
  111. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_scope_rails.py +0 -0
  112. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_security.py +0 -0
  113. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_self_host_fixture_guard.py +0 -0
  114. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_self_host_recipe_config.py +0 -0
  115. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_shared_libs_projection.py +0 -0
  116. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_shared_prefix_contract.py +0 -0
  117. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_shipped_packs_v07_declarations.py +0 -0
  118. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_shipped_packs_v08_declarations.py +0 -0
  119. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_user_libs_projection.py +0 -0
  120. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_validate.py +0 -0
  121. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_workspace_status_projection.py +0 -0
  122. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/tests/test_writers_emit_lf.py +0 -0
  123. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/user_libs.py +0 -0
  124. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/build/validate.py +0 -0
  125. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue.py +0 -0
  126. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/__init__.py +0 -0
  127. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/archive.py +0 -0
  128. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/build.py +0 -0
  129. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/config.py +0 -0
  130. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/defaults.py +0 -0
  131. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/diagnostics.py +0 -0
  132. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/identity.py +0 -0
  133. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/initialise.py +0 -0
  134. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/initialise_self_hosted.py +0 -0
  135. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/lint.py +0 -0
  136. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/package.py +0 -0
  137. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/results.py +0 -0
  138. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/self_host.py +0 -0
  139. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/skill_spec_lint.py +0 -0
  140. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/catalogue_tooling/toml_emit.py +0 -0
  141. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/categories.py +0 -0
  142. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/cli.py +0 -0
  143. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/__init__.py +0 -0
  144. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/_common.py +0 -0
  145. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/_drop_warning.py +0 -0
  146. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/adapt.py +0 -0
  147. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_build.py +0 -0
  148. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_init.py +0 -0
  149. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_lint.py +0 -0
  150. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_package.py +0 -0
  151. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_self_host.py +0 -0
  152. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_sync_defaults.py +0 -0
  153. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_tooling_stub.py +0 -0
  154. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/catalogue_verify.py +0 -0
  155. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/config.py +0 -0
  156. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/diff.py +0 -0
  157. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/docs.py +0 -0
  158. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/init_state.py +0 -0
  159. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/install.py +0 -0
  160. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/list_installed.py +0 -0
  161. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/list_packs.py +0 -0
  162. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/list_profiles.py +0 -0
  163. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/list_targets.py +0 -0
  164. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/oplog_cmd.py +0 -0
  165. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/pack_config_cmd.py +0 -0
  166. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/pack_evals.py +0 -0
  167. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/package_catalogue.py +0 -0
  168. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/profile.py +0 -0
  169. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/reconcile.py +0 -0
  170. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/render.py +0 -0
  171. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/scaffold.py +0 -0
  172. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/show.py +0 -0
  173. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/uninstall.py +0 -0
  174. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/commands/validate.py +0 -0
  175. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/config.py +0 -0
  176. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/https_catalogue.py +0 -0
  177. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/local_exclude.py +0 -0
  178. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/oplog.py +0 -0
  179. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/pack_inventory.py +0 -0
  180. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/render.py +0 -0
  181. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/safety.py +0 -0
  182. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/scaffold.py +0 -0
  183. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/scope.py +0 -0
  184. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/source_defaults.py +0 -0
  185. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/statelock.py +0 -0
  186. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/user_config.py +0 -0
  187. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle/workspace_mcp.py +0 -0
  188. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/dependency_links.txt +0 -0
  189. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/entry_points.txt +0 -0
  190. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/requires.txt +0 -0
  191. {agentbundle-0.29.5 → agentbundle-0.29.7}/agentbundle.egg-info/top_level.txt +0 -0
  192. {agentbundle-0.29.5 → agentbundle-0.29.7}/setup.cfg +0 -0
  193. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_adapter_permissions_projection.py +0 -0
  194. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_linear_primitive.py +0 -0
  195. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_elicit.py +0 -0
  196. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_event_bridge.py +0 -0
  197. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_git.py +0 -0
  198. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_lifecycle.py +0 -0
  199. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_stdin.py +0 -0
  200. {agentbundle-0.29.5 → agentbundle-0.29.7}/tests/test_workspace_mcp_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentbundle
3
- Version: 0.29.5
3
+ Version: 0.29.7
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
@@ -269,7 +269,10 @@ ignore them there; the separation is structural, not incidental.
269
269
  `keywords` once; the build projects the cleanly-mappable subset — plus the
270
270
  pack's `README.md` — into each distribution route's manifest (the `plugin.json`
271
271
  / `marketplace.json` entry), so the catalogue describes each pack richly rather
272
- than with a single sentence. Extra fields stay in `pack.toml`; the projection
272
+ than with a single sentence. A marketplace entry's `source` is a `git-subdir`
273
+ object (`url`, `path`, and one of `ref`/`sha`) pointing at the pack's directory
274
+ on the published distribution branch, and every entry is schema-validated at
275
+ build time against `marketplace-entry.schema.json`. Extra fields stay in `pack.toml`; the projection
273
276
  is deliberately lossy per tool.
274
277
 
275
278
  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.
@@ -285,8 +288,9 @@ The org hint fires after the user-config but before the on-disk IDE probe — so
285
288
 
286
289
  **Bundled contracts** — the wheel ships the machine contracts used for offline validation:
287
290
  `pack.schema.json`, `skill.schema.json`, `guide.schema.json`, `skill-manifest.schema.json`,
288
- `profile.schema.json`, `catalogue.schema.json`, `target-vocab.toml`, and the adapter
289
- contract files. All are available without network access via `importlib.resources`.
291
+ `profile.schema.json`, `catalogue.schema.json`, `plugin-manifest.schema.json`,
292
+ `plugin-manifest.derived.schema.json`, `marketplace-entry.schema.json`,
293
+ `target-vocab.toml`, and the adapter contract files. All are available without network access via `importlib.resources`.
290
294
 
291
295
  **Lint your catalogue** — shallow structural checks run without extra dependencies:
292
296
 
@@ -247,7 +247,10 @@ ignore them there; the separation is structural, not incidental.
247
247
  `keywords` once; the build projects the cleanly-mappable subset — plus the
248
248
  pack's `README.md` — into each distribution route's manifest (the `plugin.json`
249
249
  / `marketplace.json` entry), so the catalogue describes each pack richly rather
250
- than with a single sentence. Extra fields stay in `pack.toml`; the projection
250
+ than with a single sentence. A marketplace entry's `source` is a `git-subdir`
251
+ object (`url`, `path`, and one of `ref`/`sha`) pointing at the pack's directory
252
+ on the published distribution branch, and every entry is schema-validated at
253
+ build time against `marketplace-entry.schema.json`. Extra fields stay in `pack.toml`; the projection
251
254
  is deliberately lossy per tool.
252
255
 
253
256
  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.
@@ -263,8 +266,9 @@ The org hint fires after the user-config but before the on-disk IDE probe — so
263
266
 
264
267
  **Bundled contracts** — the wheel ships the machine contracts used for offline validation:
265
268
  `pack.schema.json`, `skill.schema.json`, `guide.schema.json`, `skill-manifest.schema.json`,
266
- `profile.schema.json`, `catalogue.schema.json`, `target-vocab.toml`, and the adapter
267
- contract files. All are available without network access via `importlib.resources`.
269
+ `profile.schema.json`, `catalogue.schema.json`, `plugin-manifest.schema.json`,
270
+ `plugin-manifest.derived.schema.json`, `marketplace-entry.schema.json`,
271
+ `target-vocab.toml`, and the adapter contract files. All are available without network access via `importlib.resources`.
268
272
 
269
273
  **Lint your catalogue** — shallow structural checks run without extra dependencies:
270
274
 
@@ -188,12 +188,14 @@ install-routes = ["cli", "claude-plugins", "apm"]
188
188
  primitive = "skill"
189
189
  mode = "direct-directory"
190
190
  target-path = ".claude/skills/"
191
+ plugin-target-path = "skills/"
191
192
  on-conflict = "prompt-then-preserve"
192
193
 
193
194
  [[adapter."claude-code".projection]]
194
195
  primitive = "agent"
195
196
  mode = "direct-file"
196
197
  target-path = ".claude/agents/"
198
+ plugin-target-path = "agents/"
197
199
  on-conflict = "prompt-then-preserve"
198
200
 
199
201
  [[adapter."claude-code".projection]]
@@ -213,6 +215,7 @@ on-conflict = "merge-managed-key-only"
213
215
  primitive = "command"
214
216
  mode = "direct-file"
215
217
  target-path = ".claude/commands/"
218
+ plugin-target-path = "commands/"
216
219
  on-conflict = "prompt-then-preserve"
217
220
 
218
221
  # hook-body — scope-conditional target.
@@ -2,7 +2,7 @@
2
2
  "files": {
3
3
  "guides/_shared/reference/catalogue-authoring-standards.md": "cec0f7afd7a0bf61d7bedd9facd096b083cb7413679a6fbcd0af28d40bece58c",
4
4
  "guides/_shared/reference/catalogue-ci-contract.md": "fae793ab47989b6dd3c731afcb0b4cda21c7d08bbe7fa40fca6d3abb3d158141",
5
- "packs/AGENTS.md": "861a029007741cd7645cdfcc018e5ac85cf218d332f6688115156c9c676381b8",
5
+ "packs/AGENTS.md": "9bfeda4069826e518a4f4fdae45bd40f4393c1c5aaf146149d3eb4aece30be83",
6
6
  "packs/README.md": "d2de5f9556f4c8e521103474bde74636e02cc805f9bf5312a3a61a1f3eb45d8f",
7
7
  "packs/_example/.apm/skills/example-skill/SKILL.md": "33be8cbf4b2c014a5a63e788b7d0b350ad8061c6c4b2579369a3e984135bf9f1",
8
8
  "packs/_example/.apm/skills/example-skill/evals/eval_queries.json": "f41ecda0834a22f3b4823c81ab02e58b0e4beba610e3b40c185579abff9cfeee",
@@ -6,9 +6,11 @@ Read `packs/AGENTS.local.md` when present — it carries host-specific overrides
6
6
  ## Pack layout
7
7
 
8
8
  The pack is the ownership and test-execution boundary; `.apm/` is the runtime export boundary; a skill is the
9
- evaluation-fixture boundary. Tests go in `packs/<pack>/tests/`, never under `.apm/`; evals stay skill-local at
10
- `.apm/skills/<skill>/evals/` and project with the skill. `tools/lint-pack-test-boundary.py` enforces both across
11
- every pack, plus one pytest process per skill test dir. Shape: `docs/architecture/pack-layout.md`.
9
+ evaluation-fixture boundary. Skill tests go in `packs/<pack>/tests/skills/<skill>/` and hook tests in
10
+ `packs/<pack>/tests/hooks/` — never under `.apm/`, which adapters project verbatim into an installed tree.
11
+ Evals stay skill-local at `.apm/skills/<skill>/evals/` and project with the skill. Run **one pytest process
12
+ per skill test directory**: two skills may ship the same test basename, and a shared `sys.path` binds one
13
+ skill's module for both suites and passes green.
12
14
 
13
15
  | Path | Purpose |
14
16
  |------|---------|
@@ -28,14 +30,13 @@ every pack, plus one pytest process per skill test dir. Shape: `docs/architectur
28
30
 
29
31
  ## Reserved authoring assets
30
32
 
31
- Any immediate child of the packs root whose name begins with `_` is a reserved authoring asset.
32
- Reserved directories are not catalogue payload — they do not appear in `list-packs`, are not
33
- installed, and are not included in packaged archives. See `packs/README.md`.
33
+ Any immediate child of the packs root whose name begins with `_` is a reserved authoring asset: not
34
+ catalogue payload, absent from `list-packs`, never installed or packaged. See `packs/README.md`.
34
35
 
35
36
  ## pack.toml schema map
36
37
 
37
- > The machine source of truth for pack.toml format is `contracts/pack.schema.json`.
38
- > The table below is a navigational summary; the JSON Schema is normative.
38
+ > The normative source for pack.toml format is the `pack` JSON Schema that ships inside `agentbundle`;
39
+ > `agentbundle catalogue lint --root .` validates against it. The table below is a navigational summary.
39
40
 
40
41
  | Table | Required fields | Notable optional fields |
41
42
  |-------|----------------|------------------------|
@@ -64,14 +65,14 @@ For CI pipeline orchestration — publication ordering, exit codes, JSON output
64
65
 
65
66
  ## Version bump rule
66
67
 
67
- Every **non-cosmetic** change to pack content requires a version bump in both:
68
- 1. `pack.toml` → `[pack] version`
69
- 2. `.claude-plugin/plugin.json` → `"version"`
68
+ Every **non-cosmetic** change to pack content requires a version bump in **both** `pack.toml` →
69
+ `[pack] version` and `.claude-plugin/plugin.json` → `"version"`.
70
70
 
71
71
  Which increment: **patch** for changed bodies/directives/conventions; **minor** for new primitives;
72
72
  **major** for removals. Never ride an unreleased version from another in-flight PR.
73
73
 
74
- Host-specific post-bump steps (changelog, marketplace regeneration) are in `packs/AGENTS.local.md`.
74
+ Further post-bump steps (changelog, marketplace regeneration) are host-specific — see `AGENTS.local.md` if
75
+ your catalogue has one.
75
76
 
76
77
  ## Self-hosting projection
77
78
 
@@ -80,52 +81,50 @@ projects them to every shipped adapter's layout. Never edit a projected output d
80
81
 
81
82
  On a dirty working tree: `agentbundle catalogue self-host --root . --write --force`.
82
83
 
83
- **Critical ordering:** when a session edits both seeds and non-seed pack sources (`.apm/**`,
84
- `pack.toml`), run self-host AFTER all edits — not between them.
84
+ **Critical ordering:** when a session edits both seeds and non-seed pack sources (`.apm/**`, `pack.toml`),
85
+ run self-host AFTER all edits — not between them.
85
86
 
86
87
  ## Claude plugin JSON format
87
88
 
88
- Each pack's `.claude-plugin/plugin.json` is validated against `contracts/plugin-manifest.schema.json`.
89
- Non-compliant manifests block publishing.
89
+ Each pack's `.claude-plugin/plugin.json` is validated against the plugin-manifest JSON Schema that ships
90
+ inside `agentbundle`; `agentbundle catalogue lint --root .` reports violations. Non-compliant manifests
91
+ block publishing.
90
92
 
91
93
  **Required:** `name` (string), `version` (string matching `pack.toml`), `description` (string).
92
94
 
93
- **Allowed optional fields** — `skills`, `agents` (arrays of strings); `author` (`{name, email?}`);
94
- `license`, `homepage`, `repository`, `category`, `displayName` (strings); `keywords` (array);
95
- `source` (`{source, repo, branch, directory}`).
95
+ **Allowed optional fields** — `skills`, `agents` (arrays of strings); `author` (`{name, email?}`); `license`,
96
+ `homepage`, `repository`, `category`, `displayName` (strings); `keywords` (array); `source`
97
+ (`{source, repo, branch, directory}`).
96
98
 
97
99
  `additionalProperties: false` — any unknown key fails validation.
98
100
 
99
101
  ## Authoring or editing a skill
100
102
 
101
- `README.md` states pack intent and the user journey it serves — not a contributor capability list.
102
- Edit `.apm/skills/<name>/SKILL.md`. Run self-host to project. Run
103
- `agentbundle catalogue lint --root . --deep` to confirm spec compliance.
103
+ `README.md` states pack intent and the user journey it serves — not a contributor capability list. Edit
104
+ `.apm/skills/<name>/SKILL.md`, run self-host to project, then `agentbundle catalogue lint --root . --deep`.
104
105
 
105
- Full authoring standards — frontmatter key whitelist, body structure, naming, three-tier dependency
106
- policy, and evals — live in [`guides/_shared/how-to/author-a-skill.md`](../guides/_shared/how-to/author-a-skill.md).
106
+ Full authoring standards — frontmatter key whitelist, body structure, naming, three-tier dependency policy,
107
+ evals — live in [`catalogue-authoring-standards.md`](../guides/_shared/reference/catalogue-authoring-standards.md).
107
108
 
108
109
  ## Eval coverage
109
110
 
110
111
  A non-cosmetic pack update must also update the pack's eval harness:
111
- - **Tier-A activation** — `evals/eval_queries.json` (~8–10 should-trigger + ~8–10 near-miss) and
112
- a `[pack.evals]` block in `pack.toml` listing every user-triggered skill.
112
+ - **Tier-A activation** — `evals/eval_queries.json` (~8–10 should-trigger + ~8–10 near-miss) and a
113
+ `[pack.evals]` block in `pack.toml` listing every user-triggered skill.
113
114
  - **Tier-4 LLM-judge rubric** — `evals/evals.json` for judgment/authoring skills.
114
115
  - **Tier-B-lite behavior check** — add an `expect` block to an `evals/evals.json` entry (non-destructive,
115
- non-credentialed skills only). Four things that must be explicit to avoid format churn:
116
- - Field name is **`files`** (not `fixture`): paths are relative to the **skill root**
117
- (e.g. `"evals/files/sample.md"`), not relative to `evals/`. The runner seeds a temp workspace
118
- with these files before invoking the skill.
116
+ non-credentialed skills only). Four things must be explicit, or the format churns:
117
+ - The field is **`files`**, not `fixture`, and its paths are relative to the **skill root**
118
+ (`"evals/files/sample.md"`) — not to `evals/`. The runner seeds a temp workspace with them first.
119
119
  - `expect.produces`: filenames the run must create in the workspace.
120
120
  - `expect.output_contains` / `expect.output_excludes`: substrings in captured output.
121
- - **Your skill script must accept the workspace path** — via a `--fixture`/`--root` flag or by
122
- treating CWD as the workspace — so the runner can confine writes and verify `produces`.
123
- Full procedure: [`guides/_shared/how-to/author-a-skill.md`](../guides/_shared/how-to/author-a-skill.md).
121
+ - **Your skill script must accept the workspace path** — a `--fixture`/`--root` flag, or treat CWD as
122
+ the workspace — so the runner can confine writes and verify `produces`.
123
+ Full procedure: [`guides/_shared/reference/catalogue-authoring-standards.md`](../guides/_shared/reference/catalogue-authoring-standards.md).
124
124
 
125
125
  ## Windows-safe Python scripts
126
126
 
127
- Any script under `.apm/` that prints to stdout or stderr must include the UTF-8 reconfigure guard
128
- immediately after `import sys`, before any `print()` call:
127
+ Any script under `.apm/` that prints to stdout or stderr must include the UTF-8 reconfigure guard immediately after `import sys`, before any `print()` call:
129
128
 
130
129
  ```python
131
130
  sys.stdout.reconfigure(encoding="utf-8", errors="strict")
@@ -145,6 +144,7 @@ Stubs in `plan.md` tasks must be `raise NotImplementedError # STUB: ACn` — no
145
144
 
146
145
  ## Shipped pack content carries no internal-governance citations
147
146
 
148
- Anywhere under `packs/` — `.apm/**`, `pack.toml`, `README`/`JOURNEY`/`DESIGN`, `seeds/**` —
149
- never cite this catalogue's own governance: `RFC-0NNN`, `ADR-0NNN`, spec/plan or AC citations,
150
- internal doc paths. Keep the rule, drop the citation. Detail: `packs/AGENTS.local.md`.
147
+ Anywhere under `packs/` — `.apm/**`, `pack.toml`, `README`/`JOURNEY`/`DESIGN`, `seeds/**` — never cite your
148
+ catalogue's own governance: decision-record or proposal numbers, spec/plan or acceptance-criterion citations,
149
+ or repository-only paths. Shipped content lands in someone else's tree, where each is a dead end. **Keep the
150
+ rule, drop the citation** — state what the reader must do, in full.
@@ -0,0 +1,110 @@
1
+ {
2
+ "x-spec": "docs/specs/claude-plugins-manifest-correctness",
3
+ "type": "object",
4
+ "required": [
5
+ "name",
6
+ "version",
7
+ "description"
8
+ ],
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "name": {
12
+ "type": "string"
13
+ },
14
+ "version": {
15
+ "type": "string"
16
+ },
17
+ "description": {
18
+ "type": "string"
19
+ },
20
+ "skills": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "string"
24
+ }
25
+ },
26
+ "agents": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "author": {
33
+ "type": "object",
34
+ "required": [
35
+ "name"
36
+ ],
37
+ "properties": {
38
+ "name": {
39
+ "type": "string"
40
+ },
41
+ "email": {
42
+ "type": "string"
43
+ }
44
+ }
45
+ },
46
+ "license": {
47
+ "type": "string"
48
+ },
49
+ "homepage": {
50
+ "type": "string"
51
+ },
52
+ "repository": {
53
+ "type": "string"
54
+ },
55
+ "keywords": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "string"
59
+ }
60
+ },
61
+ "displayName": {
62
+ "type": "string"
63
+ },
64
+ "category": {
65
+ "type": "string"
66
+ },
67
+ "source": {
68
+ "type": "object",
69
+ "required": [
70
+ "source",
71
+ "url",
72
+ "path"
73
+ ],
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "source": {
77
+ "type": "string",
78
+ "enum": [
79
+ "git-subdir"
80
+ ]
81
+ },
82
+ "url": {
83
+ "type": "string",
84
+ "pattern": "^https://github\\.com/[^/]+/[^/]+\\.git$"
85
+ },
86
+ "path": {
87
+ "type": "string",
88
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
89
+ },
90
+ "ref": {
91
+ "type": "string"
92
+ },
93
+ "sha": {
94
+ "type": "string"
95
+ }
96
+ },
97
+ "if": {
98
+ "required": [
99
+ "ref"
100
+ ]
101
+ },
102
+ "then": {},
103
+ "else": {
104
+ "required": [
105
+ "sha"
106
+ ]
107
+ }
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,147 @@
1
+ {
2
+ "x-spec": "docs/specs/claude-plugins-manifest-correctness",
3
+ "type": "object",
4
+ "required": [
5
+ "name",
6
+ "version",
7
+ "description"
8
+ ],
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "name": {
12
+ "type": "string"
13
+ },
14
+ "version": {
15
+ "type": "string"
16
+ },
17
+ "description": {
18
+ "type": "string"
19
+ },
20
+ "skills": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "string"
24
+ }
25
+ },
26
+ "agents": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "author": {
33
+ "type": "object",
34
+ "required": [
35
+ "name"
36
+ ],
37
+ "properties": {
38
+ "name": {
39
+ "type": "string"
40
+ },
41
+ "email": {
42
+ "type": "string"
43
+ }
44
+ }
45
+ },
46
+ "license": {
47
+ "type": "string"
48
+ },
49
+ "homepage": {
50
+ "type": "string"
51
+ },
52
+ "repository": {
53
+ "type": "string"
54
+ },
55
+ "keywords": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "string"
59
+ }
60
+ },
61
+ "displayName": {
62
+ "type": "string"
63
+ },
64
+ "source": {
65
+ "type": "object",
66
+ "required": [
67
+ "source",
68
+ "url",
69
+ "path"
70
+ ],
71
+ "additionalProperties": false,
72
+ "properties": {
73
+ "source": {
74
+ "type": "string",
75
+ "enum": [
76
+ "git-subdir"
77
+ ]
78
+ },
79
+ "url": {
80
+ "type": "string",
81
+ "pattern": "^https://github\\.com/[^/]+/[^/]+\\.git$"
82
+ },
83
+ "path": {
84
+ "type": "string",
85
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
86
+ },
87
+ "ref": {
88
+ "type": "string"
89
+ },
90
+ "sha": {
91
+ "type": "string"
92
+ }
93
+ },
94
+ "if": {
95
+ "required": [
96
+ "ref"
97
+ ]
98
+ },
99
+ "then": {},
100
+ "else": {
101
+ "required": [
102
+ "sha"
103
+ ]
104
+ }
105
+ },
106
+ "hooks": {
107
+ "type": "object",
108
+ "additionalProperties": false,
109
+ "properties": {
110
+ "SessionStart": {
111
+ "type": "array",
112
+ "items": {
113
+ "type": "object",
114
+ "additionalProperties": false,
115
+ "properties": {
116
+ "hooks": {
117
+ "type": "array",
118
+ "items": {
119
+ "type": "object",
120
+ "required": [
121
+ "type",
122
+ "command"
123
+ ],
124
+ "additionalProperties": false,
125
+ "properties": {
126
+ "type": {
127
+ "type": "string",
128
+ "enum": [
129
+ "command"
130
+ ]
131
+ },
132
+ "command": {
133
+ "type": "string"
134
+ },
135
+ "timeout": {
136
+ "type": "integer"
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
@@ -0,0 +1,110 @@
1
+ {
2
+ "x-spec": "docs/specs/claude-plugins-manifest-correctness",
3
+ "type": "object",
4
+ "required": [
5
+ "name",
6
+ "version",
7
+ "description"
8
+ ],
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "name": {
12
+ "type": "string"
13
+ },
14
+ "version": {
15
+ "type": "string"
16
+ },
17
+ "description": {
18
+ "type": "string"
19
+ },
20
+ "skills": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "string"
24
+ }
25
+ },
26
+ "agents": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "string"
30
+ }
31
+ },
32
+ "author": {
33
+ "type": "object",
34
+ "required": [
35
+ "name"
36
+ ],
37
+ "properties": {
38
+ "name": {
39
+ "type": "string"
40
+ },
41
+ "email": {
42
+ "type": "string"
43
+ }
44
+ }
45
+ },
46
+ "license": {
47
+ "type": "string"
48
+ },
49
+ "homepage": {
50
+ "type": "string"
51
+ },
52
+ "repository": {
53
+ "type": "string"
54
+ },
55
+ "keywords": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "string"
59
+ }
60
+ },
61
+ "category": {
62
+ "type": "string"
63
+ },
64
+ "displayName": {
65
+ "type": "string"
66
+ },
67
+ "source": {
68
+ "type": "object",
69
+ "required": [
70
+ "source",
71
+ "url",
72
+ "path"
73
+ ],
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "source": {
77
+ "type": "string",
78
+ "enum": [
79
+ "git-subdir"
80
+ ]
81
+ },
82
+ "url": {
83
+ "type": "string",
84
+ "pattern": "^https://github\\.com/[^/]+/[^/]+\\.git$"
85
+ },
86
+ "path": {
87
+ "type": "string",
88
+ "pattern": "^[a-z0-9][a-z0-9-]*$"
89
+ },
90
+ "ref": {
91
+ "type": "string"
92
+ },
93
+ "sha": {
94
+ "type": "string"
95
+ }
96
+ },
97
+ "if": {
98
+ "required": [
99
+ "ref"
100
+ ]
101
+ },
102
+ "then": {},
103
+ "else": {
104
+ "required": [
105
+ "sha"
106
+ ]
107
+ }
108
+ }
109
+ }
110
+ }
@@ -62,11 +62,33 @@ def project_packs(pack_paths: list[Path], contract: dict, output_root: Path) ->
62
62
  # Mirror of kiro.py:_skill_direct_directory_target — keep in sync.
63
63
  # A shared helper is barred by the spec's `Never do` boundary (no
64
64
  # expansion of projections/direct_directory.py beyond `sweep_orphans`).
65
+ def _resolve_target(output_root: Path, target_path: str) -> Path:
66
+ """Join a contract ``target-path`` onto ``output_root``, confined.
67
+
68
+ ``target-path`` (and its route-scoped sibling ``plugin-target-path``) are
69
+ contract *data*. An absolute value discards the base entirely on join
70
+ (``Path("/a/b") / "/etc/x"`` is ``/etc/x``) and a ``..``-bearing one walks
71
+ out of it — and because the orphan sweep resolves the same value, an
72
+ escaped target becomes the root of a ``shutil.rmtree``. Confine after
73
+ resolution rather than trusting the string (CWE-73, not just CWE-22).
74
+ """
75
+ candidate = output_root / target_path.rstrip("/")
76
+ root_resolved = output_root.resolve()
77
+ try:
78
+ candidate.resolve().relative_to(root_resolved)
79
+ except ValueError:
80
+ raise ValueError(
81
+ f"claude-code: target-path {target_path!r} escapes the output root "
82
+ f"{output_root}"
83
+ ) from None
84
+ return candidate
85
+
86
+
65
87
  def _skill_direct_directory_target(contract: dict, output_root: Path) -> Path | None:
66
88
  adapter_block = contract["adapter"]["claude-code"]
67
89
  for entry in adapter_block.get("projection", []):
68
90
  if entry.get("primitive") == "skill" and entry.get("mode") == "direct-directory":
69
- return output_root / entry["target-path"].rstrip("/")
91
+ return _resolve_target(output_root, entry["target-path"])
70
92
  return None
71
93
 
72
94
 
@@ -128,8 +150,11 @@ def _project_single(pack_path: Path, contract: dict, output_root: Path) -> None:
128
150
  continue
129
151
 
130
152
  if mode == "direct-directory":
131
- _project_direct_directory(source_dir, output_root / rule["target-path"].rstrip("/"))
153
+ _project_direct_directory(
154
+ source_dir, _resolve_target(output_root, rule["target-path"])
155
+ )
132
156
  elif mode == "direct-file":
157
+ _resolve_target(output_root, rule["target-path"]) # confinement check
133
158
  _project_direct_file(source_dir, output_root, rule["target-path"])
134
159
  elif mode == "merge-json":
135
160
  project_merge_json(source_dir, output_root, rule)