agentbundle 0.29.3__tar.gz → 0.29.4__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.3 → agentbundle-0.29.4}/PKG-INFO +15 -2
  2. {agentbundle-0.29.3 → agentbundle-0.29.4}/README-pypi.md +14 -1
  3. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-authoring-standards.md +131 -0
  4. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/manifest.json +4 -4
  5. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/packs/AGENTS.md +6 -5
  6. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/packs/README.md +2 -2
  7. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/self_host_windows.py +2 -2
  8. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/version.py +1 -1
  9. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/PKG-INFO +15 -2
  10. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/SOURCES.txt +1 -4
  11. {agentbundle-0.29.3 → agentbundle-0.29.4}/pyproject.toml +1 -1
  12. agentbundle-0.29.3/agentbundle/_data/catalogue-scaffold/packs/_example/evals/eval_queries.json +0 -42
  13. agentbundle-0.29.3/tests/test_loop_engine_events_jsonl.py +0 -168
  14. agentbundle-0.29.3/tests/test_workspace_status_engine_autonomous.py +0 -124
  15. {agentbundle-0.29.3 → agentbundle-0.29.4}/README.md +0 -0
  16. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/__init__.py +0 -0
  17. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/__main__.py +0 -0
  18. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/adapter.schema.json +0 -0
  19. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/adapter.toml +0 -0
  20. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-ci-contract.md +0 -0
  21. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/packs/_example/README.md +0 -0
  22. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/packs/_example/pack.toml +0 -0
  23. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/profiles/AGENTS.md +0 -0
  24. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/profiles/README.md +0 -0
  25. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/profiles/_example/README.md +0 -0
  26. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue-scaffold/profiles/_example/profile.toml +0 -0
  27. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/catalogue.schema.json +0 -0
  28. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/guide.schema.json +0 -0
  29. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/install-defaults.toml +0 -0
  30. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/install-marker.py +0 -0
  31. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/pack.schema.json +0 -0
  32. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/plugin-manifest.derived.schema.json +0 -0
  33. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/plugin-manifest.schema.json +0 -0
  34. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/profile.schema.json +0 -0
  35. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/skill-manifest.schema.json +0 -0
  36. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/skill.schema.json +0 -0
  37. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/_data/target-vocab.toml +0 -0
  38. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/__init__.py +0 -0
  39. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/__main__.py +0 -0
  40. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapter_root_bins.py +0 -0
  41. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/__init__.py +0 -0
  42. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/claude_code.py +0 -0
  43. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/codex.py +0 -0
  44. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/copilot.py +0 -0
  45. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/cursor.py +0 -0
  46. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/gemini.py +0 -0
  47. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/kiro.py +0 -0
  48. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/kiro_cli.py +0 -0
  49. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/adapters/kiro_ide.py +0 -0
  50. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/contract.py +0 -0
  51. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/lint_packs.py +0 -0
  52. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/main.py +0 -0
  53. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/phase_order.py +0 -0
  54. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/__init__.py +0 -0
  55. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/codex_agent_toml.py +0 -0
  56. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/copilot_agent_md.py +0 -0
  57. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
  58. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/direct_directory.py +0 -0
  59. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/gemini_command_toml.py +0 -0
  60. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/hook_id.py +0 -0
  61. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
  62. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
  63. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/merge_json.py +0 -0
  64. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/projections/user_merge_json.py +0 -0
  65. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/composite-agents-md.toml +0 -0
  66. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/composite-marketplace.toml +0 -0
  67. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/marketplace.toml +0 -0
  68. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/per-pack-apm-package.toml +0 -0
  69. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/per-pack-claude-plugin.toml +0 -0
  70. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/per-pack-overlay.toml +0 -0
  71. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/recipes/self-host.toml +0 -0
  72. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/scope_rails.py +0 -0
  73. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/self_host.py +0 -0
  74. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/shared_libs.py +0 -0
  75. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/target_resolver.py +0 -0
  76. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/__init__.py +0 -0
  77. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_claude_code.py +0 -0
  78. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_codex.py +0 -0
  79. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_copilot.py +0 -0
  80. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_cursor.py +0 -0
  81. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_gemini.py +0 -0
  82. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_kiro.py +0 -0
  83. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_kiro_alias.py +0 -0
  84. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_kiro_cli.py +0 -0
  85. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_kiro_ide.py +0 -0
  86. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_adapter_root_bins_projection.py +0 -0
  87. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_architect_design_reviewer_projection.py +0 -0
  88. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_architect_design_reviewer_rubric_parity.py +0 -0
  89. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_build_ships_seeds.py +0 -0
  90. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_contract.py +0 -0
  91. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_contract_scope.py +0 -0
  92. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_contract_v07.py +0 -0
  93. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_contract_v08.py +0 -0
  94. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_direct_directory_cleanup.py +0 -0
  95. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_end_to_end_build.py +0 -0
  96. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_lint_agents_md_diataxis_block.py +0 -0
  97. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_lint_agents_md_legacy_block.py +0 -0
  98. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_lint_agents_md_risk_block.py +0 -0
  99. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_lint_packs.py +0 -0
  100. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_load_pack_hook_wiring_safely.py +0 -0
  101. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_pack_schema.py +0 -0
  102. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_pack_schema_allowed_adapters.py +0 -0
  103. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_pack_schema_install.py +0 -0
  104. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_pipeline.py +0 -0
  105. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_plugin_manifest_schema.py +0 -0
  106. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_projectable_subset.py +0 -0
  107. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_projections_merge_json.py +0 -0
  108. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_scope_rails.py +0 -0
  109. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_security.py +0 -0
  110. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_self_host_check.py +0 -0
  111. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_self_host_fixture_guard.py +0 -0
  112. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_self_host_recipe_config.py +0 -0
  113. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_shared_libs_projection.py +0 -0
  114. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_shared_prefix_contract.py +0 -0
  115. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_shipped_packs_v07_declarations.py +0 -0
  116. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_shipped_packs_v08_declarations.py +0 -0
  117. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_user_libs_projection.py +0 -0
  118. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_validate.py +0 -0
  119. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_workspace_status_projection.py +0 -0
  120. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/tests/test_writers_emit_lf.py +0 -0
  121. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/user_libs.py +0 -0
  122. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/build/validate.py +0 -0
  123. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue.py +0 -0
  124. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/__init__.py +0 -0
  125. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/archive.py +0 -0
  126. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/build.py +0 -0
  127. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/config.py +0 -0
  128. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/defaults.py +0 -0
  129. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/diagnostics.py +0 -0
  130. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/identity.py +0 -0
  131. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/initialise.py +0 -0
  132. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/initialise_self_hosted.py +0 -0
  133. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/lint.py +0 -0
  134. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/package.py +0 -0
  135. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/results.py +0 -0
  136. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/self_host.py +0 -0
  137. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/skill_spec_lint.py +0 -0
  138. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/toml_emit.py +0 -0
  139. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/catalogue_tooling/verify.py +0 -0
  140. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/categories.py +0 -0
  141. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/cli.py +0 -0
  142. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/__init__.py +0 -0
  143. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/_common.py +0 -0
  144. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/_drop_warning.py +0 -0
  145. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/adapt.py +0 -0
  146. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_build.py +0 -0
  147. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_init.py +0 -0
  148. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_lint.py +0 -0
  149. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_package.py +0 -0
  150. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_self_host.py +0 -0
  151. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_sync_defaults.py +0 -0
  152. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_tooling_stub.py +0 -0
  153. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/catalogue_verify.py +0 -0
  154. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/config.py +0 -0
  155. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/diff.py +0 -0
  156. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/docs.py +0 -0
  157. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/init_state.py +0 -0
  158. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/install.py +0 -0
  159. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/list_installed.py +0 -0
  160. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/list_packs.py +0 -0
  161. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/list_profiles.py +0 -0
  162. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/list_targets.py +0 -0
  163. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/oplog_cmd.py +0 -0
  164. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/pack_config_cmd.py +0 -0
  165. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/pack_evals.py +0 -0
  166. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/package_catalogue.py +0 -0
  167. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/profile.py +0 -0
  168. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/reconcile.py +0 -0
  169. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/render.py +0 -0
  170. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/scaffold.py +0 -0
  171. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/show.py +0 -0
  172. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/uninstall.py +0 -0
  173. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/upgrade.py +0 -0
  174. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/commands/validate.py +0 -0
  175. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/config.py +0 -0
  176. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/https_catalogue.py +0 -0
  177. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/local_exclude.py +0 -0
  178. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/oplog.py +0 -0
  179. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/pack_inventory.py +0 -0
  180. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/render.py +0 -0
  181. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/safety.py +0 -0
  182. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/scaffold.py +0 -0
  183. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/scope.py +0 -0
  184. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/source_defaults.py +0 -0
  185. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/statelock.py +0 -0
  186. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/user_config.py +0 -0
  187. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle/workspace_mcp.py +0 -0
  188. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/dependency_links.txt +0 -0
  189. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/entry_points.txt +0 -0
  190. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/requires.txt +0 -0
  191. {agentbundle-0.29.3 → agentbundle-0.29.4}/agentbundle.egg-info/top_level.txt +0 -0
  192. {agentbundle-0.29.3 → agentbundle-0.29.4}/setup.cfg +0 -0
  193. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_adapter_permissions_projection.py +0 -0
  194. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_linear_primitive.py +0 -0
  195. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_workspace_mcp_elicit.py +0 -0
  196. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_workspace_mcp_event_bridge.py +0 -0
  197. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_workspace_mcp_git.py +0 -0
  198. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_workspace_mcp_lifecycle.py +0 -0
  199. {agentbundle-0.29.3 → agentbundle-0.29.4}/tests/test_workspace_mcp_stdin.py +0 -0
  200. {agentbundle-0.29.3 → agentbundle-0.29.4}/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.3
3
+ Version: 0.29.4
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
@@ -234,16 +234,29 @@ my-pack/
234
234
  .claude-plugin/
235
235
  plugin.json # Claude Code plugin manifest (hand-authored)
236
236
  README.md # the pack's portable doc — projected with the pack
237
- .apm/ # primitives — projected by the build pipeline
237
+ .apm/ # runtime — projected by the build pipeline
238
238
  skills/<name>/
239
239
  SKILL.md # the skill body; one folder per skill
240
+ scripts/ # helper code the skill invokes
240
241
  references/ # progressive-disclosure docs, loaded on demand
241
242
  assets/ # templates the skill copies into the repo
243
+ evals/ # activation + output-quality evals, skill-local
242
244
  agents/<name>.md # subagents
243
245
  hooks/<name>.py # lifecycle hooks
246
+ tests/ # implementation tests — NEVER projected
247
+ skills/<name>/
248
+ hooks/
249
+ pack/
244
250
  seeds/ # files scaffolded into the adopter repo
245
251
  ```
246
252
 
253
+ Three boundaries: the **pack** owns and executes its tests, **`.apm/`** is the
254
+ runtime export boundary, and a **skill** owns its eval fixtures. Only `.apm/`
255
+ and `seeds/` are projected into an installed environment — `tests/` is visible
256
+ in a catalogue archive, so an extracted pack can verify itself, but `install`
257
+ never places it. Keep tests out of `.apm/` even though the installer would
258
+ ignore them there; the separation is structural, not incidental.
259
+
247
260
  `pack.toml` is the **single source of truth** for a pack's metadata. Declare
248
261
  `license`, `[[pack.maintainers]]`, `[pack.links]`, `categories`, and
249
262
  `keywords` once; the build projects the cleanly-mappable subset — plus the
@@ -212,16 +212,29 @@ my-pack/
212
212
  .claude-plugin/
213
213
  plugin.json # Claude Code plugin manifest (hand-authored)
214
214
  README.md # the pack's portable doc — projected with the pack
215
- .apm/ # primitives — projected by the build pipeline
215
+ .apm/ # runtime — projected by the build pipeline
216
216
  skills/<name>/
217
217
  SKILL.md # the skill body; one folder per skill
218
+ scripts/ # helper code the skill invokes
218
219
  references/ # progressive-disclosure docs, loaded on demand
219
220
  assets/ # templates the skill copies into the repo
221
+ evals/ # activation + output-quality evals, skill-local
220
222
  agents/<name>.md # subagents
221
223
  hooks/<name>.py # lifecycle hooks
224
+ tests/ # implementation tests — NEVER projected
225
+ skills/<name>/
226
+ hooks/
227
+ pack/
222
228
  seeds/ # files scaffolded into the adopter repo
223
229
  ```
224
230
 
231
+ Three boundaries: the **pack** owns and executes its tests, **`.apm/`** is the
232
+ runtime export boundary, and a **skill** owns its eval fixtures. Only `.apm/`
233
+ and `seeds/` are projected into an installed environment — `tests/` is visible
234
+ in a catalogue archive, so an extracted pack can verify itself, but `install`
235
+ never places it. Keep tests out of `.apm/` even though the installer would
236
+ ignore them there; the separation is structural, not incidental.
237
+
225
238
  `pack.toml` is the **single source of truth** for a pack's metadata. Declare
226
239
  `license`, `[[pack.maintainers]]`, `[pack.links]`, `categories`, and
227
240
  `keywords` once; the build projects the cleanly-mappable subset — plus the
@@ -49,6 +49,32 @@ user journey it serves — not a skill inventory. See the `_example` pack for a
49
49
 
50
50
  ## 4. Pack layout
51
51
 
52
+ Three boundaries, each owned by a different thing:
53
+
54
+ - The **pack** is the ownership and test-execution boundary.
55
+ - `.apm/` is the **runtime export** boundary.
56
+ - A **skill** is the evaluation-fixture boundary.
57
+
58
+ ```
59
+ packs/<pack>/
60
+ ├── pack.toml
61
+ ├── README.md
62
+ ├── .apm/ # runtime — projected into installed environments
63
+ │ └── skills/<skill>/
64
+ │ ├── SKILL.md
65
+ │ ├── scripts/
66
+ │ ├── references/
67
+ │ ├── assets/
68
+ │ └── evals/ # skill-local, projected with the skill
69
+ ├── tests/ # implementation verification — never projected
70
+ │ └── skills/<skill>/
71
+ └── seeds/ # governance files projected to the repo root
72
+ ```
73
+
74
+ Deterministic implementation tests live under `packs/<pack>/tests/`. Runtime
75
+ skill evals live under `.apm/skills/<skill>/evals/`. `[pack.evals].skills`
76
+ selects which skill-local activation evals the pack evaluator runs.
77
+
52
78
  Primitive sources live under `.apm/` and are projected per adapter by `catalogue self-host`.
53
79
 
54
80
  | Source directory | Primitive type |
@@ -58,6 +84,111 @@ Primitive sources live under `.apm/` and are projected per adapter by `catalogue
58
84
  | `.apm/hooks/` | Hook bodies |
59
85
  | `.apm/hook-wiring/` | Hook wiring |
60
86
  | `.apm/commands/` | Commands |
87
+ | `.apm/shared-libs/` | Shared libraries |
88
+ | `.apm/skills/<skill>/evals/` | Activation and output-quality evals (projected with the skill) |
89
+
90
+ ### Tests live with the pack, outside the payload they validate
91
+
92
+ Keep tests beside the pack they validate, but out of the runtime payload.
93
+ `.apm/` holds only files meant to participate in installation, projection, or
94
+ execution — so a test never belongs there, **even where the installer happens
95
+ to ignore its path**. Runtime separation is expressed by directory structure,
96
+ not by relying on an implicit exclusion that a future adapter may not honour.
97
+
98
+ ```
99
+ packs/<pack>/tests/
100
+ ├── skills/
101
+ │ └── <skill>/ # unit/, integration/, fixtures/ as the skill warrants
102
+ ├── hooks/
103
+ ├── pack/ # manifest, metadata, projection
104
+ └── fixtures/
105
+ ```
106
+
107
+ Tests should execute or import the real implementation under `.apm/`. Never
108
+ duplicate production code into the test tree.
109
+
110
+ ### Tests versus evaluations
111
+
112
+ Two different questions, two homes.
113
+
114
+ | | `tests/` | `evals/` |
115
+ |---|---|---|
116
+ | Verifies | Deterministic software behaviour | Agent-level behaviour |
117
+ | Covers | Function output, parsing, exit status, CLI behaviour, error handling, projected install contents | Whether a skill activates, whether a near-miss avoids activation, whether output satisfies a rubric |
118
+ | Run by | pytest, Vitest, Go test, shell tooling | The eval runner |
119
+ | Lives at | `packs/<pack>/tests/` | `.apm/skills/<skill>/evals/` |
120
+
121
+ Evaluations do not replace unit or integration tests for scripts.
122
+
123
+ Evals are skill-local by design, not by accident. A fixture only means anything
124
+ next to the skill it exercises, so it belongs to the skill and is projected with
125
+ it — the adapters copy `.apm/skills/<skill>/` wholesale. That is why the `tests/`
126
+ rule is scoped to the `.apm/` boundary rather than "anything that isn't runtime":
127
+ `evals/` is runtime-adjacent content, a test suite is not. The linter enforces
128
+ this — it looks for `eval_queries.json` and `evals.json` under
129
+ `<skill>/evals/`, and requires one for every skill named in `[pack.evals].skills`.
130
+
131
+ A **diagnostic** may live under `.apm/` when it is an intentional runtime
132
+ feature users or agents invoke — `scripts/doctor.py`,
133
+ `scripts/check_environment.py`. Those are runtime commands, not test suites.
134
+
135
+ ### Catalogue archives may carry tests; installers must not install them
136
+
137
+ A catalogue or source archive walks `packs/**`, so it carries a pack's
138
+ `pack.toml`, `README.md`, `.apm/**`, `seeds/**`, `tests/**`, `docs/**`,
139
+ `.claude-plugin/`, and pack-root markdown. Shipping tests in a source-oriented
140
+ archive supports downstream verification, auditing, security review, and
141
+ testing an extracted release.
142
+
143
+ Catalogue inclusion does not imply runtime installation. Installers and
144
+ projection adapters treat `.apm/` and `seeds/` as the projected surfaces, so
145
+ nothing outside those two — `tests/` included — reaches an installed
146
+ environment.
147
+
148
+ ### Test dependencies are not runtime dependencies
149
+
150
+ A skill's runtime dependency declaration lists only what the installed skill
151
+ needs at run time. `pytest`, `hypothesis`, `vitest`, `eslint`,
152
+ `mypy`, `ruff` and friends belong in development configuration.
153
+
154
+ Fixtures under a pack's test tree ship in the archive, so they must carry no
155
+ credentials or private data, prefer synthetic data, stay modest in size, and
156
+ name their licence when sourced externally. Fuzzing corpora, generated output,
157
+ coverage reports, and caches are neither committed nor packaged.
158
+
159
+ ### Repository-root tests
160
+
161
+ A test concerning one pack stays inside that pack. Behaviour no single pack
162
+ owns — the catalogue system, packaging, shared projection machinery, profiles,
163
+ cross-pack interaction — belongs to the repository, not to a pack.
164
+
165
+ Where that lives is the repository's call. This catalogue keeps it in the
166
+ engine's own suite (`packages/agentbundle/tests/`) rather than a root `tests/`
167
+ tree; a catalogue that wants the separate tree can add one. Don't create a
168
+ top-level directory for a single test — the ownership rule is what matters,
169
+ not the path.
170
+
171
+ ### Normative summary
172
+
173
+ - A pack **MUST** be the ownership boundary for its tests.
174
+ - Pack-specific tests **MUST** live under `packs/<pack>/tests/`.
175
+ - Ordinary tests **MUST NOT** live under `.apm/`.
176
+ - `.apm/` **MUST** contain only runtime or projectable content.
177
+ - Agent evaluations **MUST** live under `.apm/skills/<skill>/evals/` and stay
178
+ distinct from implementation tests.
179
+ - Test dependencies **MUST NOT** be declared as runtime dependencies.
180
+ - Tests **MAY** be included in catalogue or source archives.
181
+ - Tests **MUST NOT** be projected into installed agent environments. Evals
182
+ **are** projected, as a skill subdirectory — they are runtime-adjacent.
183
+ - Tests that no single pack owns **SHOULD** be kept out of pack test trees,
184
+ wherever the repository chooses to put them.
185
+ - CI **SHOULD** exercise both the source implementation and the projected
186
+ runtime artifact.
187
+
188
+ Release validation should therefore project the pack into a temporary agent
189
+ environment, smoke-test it there, and confirm the projection contains no
190
+ `tests/`, `__pycache__/`, `.pytest_cache/`, coverage output, or
191
+ `test-results/`.
61
192
 
62
193
  ---
63
194
 
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "files": {
3
- "guides/_shared/reference/catalogue-authoring-standards.md": "4fe9ce077af089ab52840d1b3de600c09ca23eace114c1e28c4685a3b7289520",
3
+ "guides/_shared/reference/catalogue-authoring-standards.md": "0d278062872d62d059e322bae9e5af9f573d79bc93ff24ca18fb750705da5cc6",
4
4
  "guides/_shared/reference/catalogue-ci-contract.md": "fae793ab47989b6dd3c731afcb0b4cda21c7d08bbe7fa40fca6d3abb3d158141",
5
- "packs/AGENTS.md": "4d9e94478d3c941d4a08c8827ed9d30edaa07207854eac020b9fc3014f5b3237",
6
- "packs/README.md": "68a141500fed78988dbfe7400ea9b8fa0b7d97186d420a93dfe40763272b69ee",
5
+ "packs/AGENTS.md": "7b534acfdaab757079ca678d9290c2257267d7f4e0b4b3c3401d9da22cb4be0b",
6
+ "packs/README.md": "d2de5f9556f4c8e521103474bde74636e02cc805f9bf5312a3a61a1f3eb45d8f",
7
7
  "packs/_example/.apm/skills/example-skill/SKILL.md": "33be8cbf4b2c014a5a63e788b7d0b350ad8061c6c4b2579369a3e984135bf9f1",
8
+ "packs/_example/.apm/skills/example-skill/evals/eval_queries.json": "f41ecda0834a22f3b4823c81ab02e58b0e4beba610e3b40c185579abff9cfeee",
8
9
  "packs/_example/.claude-plugin/plugin.json": "d38c8456640d5e2f9296361f7e3e675e368ddd3eb22a6245267560f460155f41",
9
10
  "packs/_example/README.md": "ef130c9c1f97a75a07cc59fc55fc5b3bf71846dd2f06c3cddf5a1154023b6ef6",
10
- "packs/_example/evals/eval_queries.json": "f41ecda0834a22f3b4823c81ab02e58b0e4beba610e3b40c185579abff9cfeee",
11
11
  "packs/_example/pack.toml": "94e2c7fd25d4d115858728c7ecb8f739adfd0f594b29596c106daba0791a4b94",
12
12
  "profiles/AGENTS.md": "8950438d9e0f57c13613104c88c90b598b53196c91bfdced6d63e4e01b5e9254",
13
13
  "profiles/README.md": "a0b0268edc57fc575f7fea08f3363ba7da9f6e67dc4a0a6f8bd38c9668c97922",
@@ -5,12 +5,16 @@ Read `packs/AGENTS.local.md` when present — it carries host-specific overrides
5
5
 
6
6
  ## Pack layout
7
7
 
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.
11
+
8
12
  | Path | Purpose |
9
13
  |------|---------|
10
14
  | `pack.toml` | Pack metadata — version, description, adapter-contract, categories |
11
15
  | `.claude-plugin/plugin.json` | Claude plugin manifest source (must match `pack.toml` version, stay schema-valid) |
12
16
  | `seeds/` | Adopter scaffold templates (brownfield install) |
13
- | `docs/` | Concept anchor and pack guides — never projected or installed |
17
+ | `tests/` · `docs/` | Never projected — implementation tests (`skills/<skill>/`, `hooks/`, `pack/`) · concept anchor and pack guides |
14
18
  | `.apm/skills/` | Skill sources → projected per adapter |
15
19
  | `.apm/agents/` | Agent sources → projected per adapter |
16
20
  | `.apm/hooks/` | Hook-body sources → projected per adapter |
@@ -40,10 +44,7 @@ installed, and are not included in packaged archives. See `packs/README.md`.
40
44
  | `[pack.evals]` | — | `skills` (array of covered skill names) |
41
45
  | `[pack.recipes.*]` | `description` | `steps`, `adapter` |
42
46
  | `[pack.dependencies]` | — | `required`, `recommended`, `conflicts` (arrays) |
43
- | `[pack.seeds]` | — | Seed path configuration |
44
- | `[pack.layout]` | — | Per-scope layout overrides |
45
- | `[pack.first-value]` | — | First-value install metadata |
46
- | `[pack.adaptation]` | — | Adaptation inference rules |
47
+ | `[pack.seeds]` · `[pack.layout]` · `[pack.first-value]` · `[pack.adaptation]` | — | Seed paths · per-scope layout overrides · first-value install metadata · adaptation inference rules |
47
48
 
48
49
  `[pack.install]` is required when `adapter-contract.version` ≥ 0.2.
49
50
 
@@ -20,7 +20,7 @@ Copy `packs/_example` to `packs/<your-pack>`, then:
20
20
  1. Update `pack.toml` — set `[pack].name`, `version`, `description`, and `[pack.install]` fields.
21
21
  2. Update `.claude-plugin/plugin.json` — set `name`, `version`, and `description` to match.
22
22
  3. Rename `.apm/skills/example-skill` to your skill name and rewrite `SKILL.md`.
23
- 4. Update `evals/eval_queries.json` with activation fixtures for your skill.
23
+ 4. Update `.apm/skills/<skill>/evals/eval_queries.json` with activation fixtures for your skill.
24
24
  5. Rewrite `README.md` with your pack's outcome, audience, and install instructions.
25
25
  6. Run `agentbundle catalogue verify --root .` from the catalogue root.
26
26
 
@@ -50,7 +50,7 @@ full primitive directory list and adapter-contract map.
50
50
 
51
51
  `seeds/` holds adopter scaffold templates delivered on brownfield install.
52
52
 
53
- `evals/eval_queries.json` holds Tier-A activation eval fixtures — should-trigger and near-miss
53
+ `.apm/skills/<skill>/evals/eval_queries.json` holds Tier-A activation eval fixtures — should-trigger and near-miss
54
54
  queries for each user-triggered skill. List every covered skill in `[pack.evals].skills`.
55
55
 
56
56
  ## Versioning expectations
@@ -81,8 +81,8 @@ def run_windows_compat(root: Path) -> int:
81
81
  ),
82
82
  (
83
83
  "hook parity-net suite (windows-hooks-phase3)",
84
- [py, "-m", "pytest", "tests/hooks/"],
85
- pkg,
84
+ [py, "-m", "pytest", str(root / "packs" / "core" / "tests" / "hooks")],
85
+ root,
86
86
  ),
87
87
  # Atlassian SSO suites (asyncio + SSL-context wiring is platform-sensitive)
88
88
  (
@@ -14,7 +14,7 @@ import tomllib
14
14
  from importlib.resources import files
15
15
  from pathlib import Path
16
16
 
17
- CLI_VERSION = "0.29.3"
17
+ CLI_VERSION = "0.29.4"
18
18
 
19
19
  _HERE = Path(__file__).resolve().parent
20
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentbundle
3
- Version: 0.29.3
3
+ Version: 0.29.4
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
@@ -234,16 +234,29 @@ my-pack/
234
234
  .claude-plugin/
235
235
  plugin.json # Claude Code plugin manifest (hand-authored)
236
236
  README.md # the pack's portable doc — projected with the pack
237
- .apm/ # primitives — projected by the build pipeline
237
+ .apm/ # runtime — projected by the build pipeline
238
238
  skills/<name>/
239
239
  SKILL.md # the skill body; one folder per skill
240
+ scripts/ # helper code the skill invokes
240
241
  references/ # progressive-disclosure docs, loaded on demand
241
242
  assets/ # templates the skill copies into the repo
243
+ evals/ # activation + output-quality evals, skill-local
242
244
  agents/<name>.md # subagents
243
245
  hooks/<name>.py # lifecycle hooks
246
+ tests/ # implementation tests — NEVER projected
247
+ skills/<name>/
248
+ hooks/
249
+ pack/
244
250
  seeds/ # files scaffolded into the adopter repo
245
251
  ```
246
252
 
253
+ Three boundaries: the **pack** owns and executes its tests, **`.apm/`** is the
254
+ runtime export boundary, and a **skill** owns its eval fixtures. Only `.apm/`
255
+ and `seeds/` are projected into an installed environment — `tests/` is visible
256
+ in a catalogue archive, so an extracted pack can verify itself, but `install`
257
+ never places it. Keep tests out of `.apm/` even though the installer would
258
+ ignore them there; the separation is structural, not incidental.
259
+
247
260
  `pack.toml` is the **single source of truth** for a pack's metadata. Declare
248
261
  `license`, `[[pack.maintainers]]`, `[pack.links]`, `categories`, and
249
262
  `keywords` once; the build projects the cleanly-mappable subset — plus the
@@ -46,7 +46,6 @@ agentbundle/_data/catalogue-scaffold/packs/AGENTS.md
46
46
  agentbundle/_data/catalogue-scaffold/packs/README.md
47
47
  agentbundle/_data/catalogue-scaffold/packs/_example/README.md
48
48
  agentbundle/_data/catalogue-scaffold/packs/_example/pack.toml
49
- agentbundle/_data/catalogue-scaffold/packs/_example/evals/eval_queries.json
50
49
  agentbundle/_data/catalogue-scaffold/profiles/AGENTS.md
51
50
  agentbundle/_data/catalogue-scaffold/profiles/README.md
52
51
  agentbundle/_data/catalogue-scaffold/profiles/_example/README.md
@@ -188,11 +187,9 @@ agentbundle/commands/upgrade.py
188
187
  agentbundle/commands/validate.py
189
188
  tests/test_adapter_permissions_projection.py
190
189
  tests/test_linear_primitive.py
191
- tests/test_loop_engine_events_jsonl.py
192
190
  tests/test_workspace_mcp_elicit.py
193
191
  tests/test_workspace_mcp_event_bridge.py
194
192
  tests/test_workspace_mcp_git.py
195
193
  tests/test_workspace_mcp_lifecycle.py
196
194
  tests/test_workspace_mcp_stdin.py
197
- tests/test_workspace_mcp_tools.py
198
- tests/test_workspace_status_engine_autonomous.py
195
+ tests/test_workspace_mcp_tools.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agentbundle"
7
- version = "0.29.3"
7
+ version = "0.29.4"
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 = []
@@ -1,42 +0,0 @@
1
- [
2
- {
3
- "query": "run example",
4
- "skill": "example-skill",
5
- "should_trigger": true
6
- },
7
- {
8
- "query": "show example skill output",
9
- "skill": "example-skill",
10
- "should_trigger": true
11
- },
12
- {
13
- "query": "what does example-skill do",
14
- "skill": "example-skill",
15
- "should_trigger": true
16
- },
17
- {
18
- "query": "demonstrate the example",
19
- "skill": "example-skill",
20
- "should_trigger": true
21
- },
22
- {
23
- "query": "run the example skill now",
24
- "skill": "example-skill",
25
- "should_trigger": true
26
- },
27
- {
28
- "query": "give me a demo",
29
- "skill": "example-skill",
30
- "should_trigger": false
31
- },
32
- {
33
- "query": "show me a test run of architect-design",
34
- "skill": "example-skill",
35
- "should_trigger": false
36
- },
37
- {
38
- "query": "how do I install a pack",
39
- "skill": "example-skill",
40
- "should_trigger": false
41
- }
42
- ]
@@ -1,168 +0,0 @@
1
- """Tests for loop-engine events.jsonl outbox protocol."""
2
- from __future__ import annotations
3
-
4
- import json
5
- import subprocess
6
- import sys
7
- from pathlib import Path
8
-
9
- import pytest
10
-
11
- _SCRIPTS = (
12
- Path(__file__).resolve().parents[3]
13
- / "packs" / "core" / ".apm" / "skills" / "work-loop" / "scripts"
14
- )
15
- _LOOP_ENGINE = _SCRIPTS / "loop-engine.py"
16
- _LOOP_COHORT = _SCRIPTS / "loop-cohort.py"
17
-
18
-
19
- def _run(script: Path, *args: str, cwd: Path) -> subprocess.CompletedProcess:
20
- return subprocess.run(
21
- [sys.executable, str(script), *args],
22
- capture_output=True, text=True, encoding="utf-8",
23
- cwd=str(cwd),
24
- )
25
-
26
-
27
- def _init_git_repo(tmp_path: Path) -> Path:
28
- """Initialize a minimal git repo at tmp_path; return repo root."""
29
- subprocess.run(["git", "init", str(tmp_path)], check=True, capture_output=True)
30
- for cmd in (
31
- ["git", "config", "user.email", "test@example.com"],
32
- ["git", "config", "user.name", "Test"],
33
- ):
34
- subprocess.run(cmd, check=True, capture_output=True, cwd=str(tmp_path))
35
- return tmp_path
36
-
37
-
38
- def _make_spec_dir(repo: Path, name: str = "test-spec") -> Path:
39
- spec_dir = repo / "docs" / "specs" / name
40
- spec_dir.mkdir(parents=True, exist_ok=True)
41
- (spec_dir / "spec.md").write_text("- **Status:** Approved\n")
42
- (spec_dir / "plan.md").write_text("- **Status:** Approved\n")
43
- return spec_dir
44
-
45
-
46
- def _engine_init(repo: Path, spec_dir: Path) -> str:
47
- """Run loop-engine init + loop-cohort init; return run_id."""
48
- r = _run(_LOOP_ENGINE, "init", str(spec_dir), "--mode", "code", "--json", cwd=repo)
49
- assert r.returncode == 0, r.stderr
50
- run_id = json.loads(r.stdout.strip())["run_id"]
51
- r = _run(_LOOP_COHORT, "init", str(spec_dir), "--run-id", run_id, cwd=repo)
52
- assert r.returncode == 0, r.stderr
53
- return run_id
54
-
55
-
56
- class TestOutboxInit:
57
- """cmd_init creates .loop-run/ + empty events.jsonl + gitignore entry."""
58
-
59
- def test_events_jsonl_created_empty(self, tmp_path: pytest.TempDir) -> None:
60
- repo = _init_git_repo(tmp_path)
61
- spec_dir = _make_spec_dir(repo)
62
- _engine_init(repo, spec_dir)
63
- jsonl = repo / ".loop-run" / "events.jsonl"
64
- assert jsonl.exists(), "events.jsonl must be created by cmd_init"
65
- assert jsonl.read_text() == "", "events.jsonl must start empty (no header line)"
66
-
67
- def test_gitignore_entry_added(self, tmp_path: pytest.TempDir) -> None:
68
- repo = _init_git_repo(tmp_path)
69
- spec_dir = _make_spec_dir(repo)
70
- _engine_init(repo, spec_dir)
71
- lines = (repo / ".gitignore").read_text().splitlines()
72
- assert ".loop-run/" in lines
73
-
74
- def test_gitignore_not_duplicated_on_second_init(self, tmp_path: pytest.TempDir) -> None:
75
- repo = _init_git_repo(tmp_path)
76
- (repo / ".gitignore").write_text(".loop-run/\n")
77
- spec_dir = _make_spec_dir(repo)
78
- _engine_init(repo, spec_dir)
79
- lines = (repo / ".gitignore").read_text().splitlines()
80
- assert lines.count(".loop-run/") == 1
81
-
82
-
83
- class TestOutboxTransition:
84
- """Outbox write protocol: pending → state → jsonl → delete pending."""
85
-
86
- def test_transition_appends_event_line(self, tmp_path: pytest.TempDir) -> None:
87
- repo = _init_git_repo(tmp_path)
88
- spec_dir = _make_spec_dir(repo)
89
- _engine_init(repo, spec_dir)
90
- r = _run(_LOOP_ENGINE, "transition", str(spec_dir), "spec-ready", cwd=repo)
91
- assert r.returncode == 0, r.stderr
92
- jsonl = repo / ".loop-run" / "events.jsonl"
93
- lines = [ln for ln in jsonl.read_text().splitlines() if ln.strip()]
94
- assert len(lines) == 1
95
- event = json.loads(lines[0])
96
- assert event["from"] == "SPEC-PLAN-DRAFTING"
97
- assert event["event"] == "spec-ready"
98
- assert event["to"] == "SPEC-PLAN-REVIEW"
99
- assert event["seq"] == 1
100
- for key in ("run_id", "spec", "at"):
101
- assert key in event, f"missing required key: {key!r}"
102
-
103
- def test_event_schema_field_names(self, tmp_path: pytest.TempDir) -> None:
104
- """Event fields must be seq/run_id/spec/from/event/to/at (design.md:317)."""
105
- repo = _init_git_repo(tmp_path)
106
- spec_dir = _make_spec_dir(repo)
107
- _engine_init(repo, spec_dir)
108
- _run(_LOOP_ENGINE, "transition", str(spec_dir), "spec-ready", cwd=repo)
109
- jsonl = repo / ".loop-run" / "events.jsonl"
110
- event = json.loads(jsonl.read_text().strip())
111
- required_keys = {"seq", "run_id", "spec", "from", "event", "to", "at"}
112
- forbidden_aliases = {"to_state", "from_state", "timestamp"}
113
- assert set(event.keys()) >= required_keys
114
- assert not (set(event.keys()) & forbidden_aliases), (
115
- f"event uses forbidden alias(es): {set(event.keys()) & forbidden_aliases}"
116
- )
117
-
118
- def test_no_pending_file_after_successful_transition(self, tmp_path: pytest.TempDir) -> None:
119
- repo = _init_git_repo(tmp_path)
120
- spec_dir = _make_spec_dir(repo)
121
- _engine_init(repo, spec_dir)
122
- _run(_LOOP_ENGINE, "transition", str(spec_dir), "spec-ready", cwd=repo)
123
- assert not (repo / ".loop-run" / "events.pending").exists()
124
-
125
- def test_multiple_transitions_append_in_order(self, tmp_path: pytest.TempDir) -> None:
126
- repo = _init_git_repo(tmp_path)
127
- spec_dir = _make_spec_dir(repo)
128
- _engine_init(repo, spec_dir)
129
- _run(_LOOP_ENGINE, "transition", str(spec_dir), "spec-ready", cwd=repo)
130
- _run(_LOOP_ENGINE, "transition", str(spec_dir), "reviewers-clean", cwd=repo)
131
- jsonl = repo / ".loop-run" / "events.jsonl"
132
- lines = [json.loads(ln) for ln in jsonl.read_text().splitlines() if ln.strip()]
133
- assert len(lines) == 2
134
- assert lines[0]["seq"] == 1
135
- assert lines[1]["seq"] == 2
136
- assert lines[1]["from"] == "SPEC-PLAN-REVIEW"
137
-
138
-
139
- class TestOutboxReset:
140
- """cmd_reset removes .loop-run/."""
141
-
142
- def test_loop_run_removed_on_reset(self, tmp_path: pytest.TempDir) -> None:
143
- repo = _init_git_repo(tmp_path)
144
- spec_dir = _make_spec_dir(repo)
145
- _engine_init(repo, spec_dir)
146
- assert (repo / ".loop-run").exists()
147
- r = _run(_LOOP_ENGINE, "reset", str(spec_dir), cwd=repo)
148
- assert r.returncode == 0, r.stderr
149
- assert not (repo / ".loop-run").exists()
150
-
151
-
152
- class TestOutboxRecovery:
153
- """Outbox recovery: replay/discard stale events.pending."""
154
-
155
- def test_outbox_recovery_replay_when_to_matches_state(self) -> None:
156
- pytest.skip("STUB: replay the pending event when its `to` matches state")
157
-
158
- def test_outbox_recovery_discard_when_to_mismatches_state(self) -> None:
159
- pytest.skip("STUB: discard the pending event when its `to` mismatches state")
160
-
161
- def test_cmd_transition_recovers_stale_pending_before_new_transition(self) -> None:
162
- pytest.skip("STUB: crash-then-next-transition — pending from prior crash must be replayed/discarded at top of next cmd_transition, not lost")
163
-
164
- def test_cmd_transition_recovers_foreign_spec_pending_before_writing_own(self) -> None:
165
- pytest.skip("STUB: cross-spec — crash on spec-A then transition on spec-B must recover spec-A's pending against spec-A's engine-state.json before writing spec-B's new pending event — skipping leaves spec-A's event silently lost to the step-2 overwrite")
166
-
167
- def test_io_failure_does_not_abort_transition(self) -> None:
168
- pytest.skip("STUB (graceful-degradation): monkeypatch events.jsonl append to raise PermissionError; assert engine-state.json write still succeeds and a warning is emitted")