ansible-aom 0.102.13__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 (471) hide show
  1. ansible_aom-0.102.13/.agent/hooks/graphify-refresh.sh +84 -0
  2. ansible_aom-0.102.13/.agent/hooks/pre-commit-wrapper.sh +5 -0
  3. ansible_aom-0.102.13/.ansible-lint +24 -0
  4. ansible_aom-0.102.13/.claude/settings.json +37 -0
  5. ansible_aom-0.102.13/.claude/skills/verify/SKILL.md +63 -0
  6. ansible_aom-0.102.13/.envrc +1 -0
  7. ansible_aom-0.102.13/.githooks/post-commit +21 -0
  8. ansible_aom-0.102.13/.githooks/post-commit-graphify +93 -0
  9. ansible_aom-0.102.13/.githooks/pre-commit +7 -0
  10. ansible_aom-0.102.13/.githooks/pre-push +87 -0
  11. ansible_aom-0.102.13/.github/dependabot.yml +16 -0
  12. ansible_aom-0.102.13/.github/workflows/ci.yml +80 -0
  13. ansible_aom-0.102.13/.github/workflows/release.yml +135 -0
  14. ansible_aom-0.102.13/.gitignore +64 -0
  15. ansible_aom-0.102.13/.gitmodules +3 -0
  16. ansible_aom-0.102.13/.pre-commit-config.yaml +76 -0
  17. ansible_aom-0.102.13/.python-version +1 -0
  18. ansible_aom-0.102.13/AGENTS.md +133 -0
  19. ansible_aom-0.102.13/ARCHITECTURE.md +567 -0
  20. ansible_aom-0.102.13/CHANGELOG.md +17 -0
  21. ansible_aom-0.102.13/CODE_OF_CONDUCT.md +9 -0
  22. ansible_aom-0.102.13/CONTRIBUTING.md +22 -0
  23. ansible_aom-0.102.13/LICENSE +674 -0
  24. ansible_aom-0.102.13/PKG-INFO +38 -0
  25. ansible_aom-0.102.13/README.md +325 -0
  26. ansible_aom-0.102.13/SECURITY.md +16 -0
  27. ansible_aom-0.102.13/SPECIFICATION.md +3208 -0
  28. ansible_aom-0.102.13/SUPPORT.md +12 -0
  29. ansible_aom-0.102.13/TEST_PLAYBOOKS.md +1264 -0
  30. ansible_aom-0.102.13/TEST_SPECIFICATION.md +5077 -0
  31. ansible_aom-0.102.13/docs/brainstorms/2026-06-29-verbosity-handling.md +1180 -0
  32. ansible_aom-0.102.13/docs/brainstorms/2026-06-30-qc-review-triage.md +404 -0
  33. ansible_aom-0.102.13/docs/brainstorms/2026-06-30-verbosity-pre-impl-interview.md +356 -0
  34. ansible_aom-0.102.13/docs/superpowers/specs/2026-05-19-free-strategy-tree-view-design.md +362 -0
  35. ansible_aom-0.102.13/docs/superpowers/specs/2026-05-19-liveness-indicator-design.md +260 -0
  36. ansible_aom-0.102.13/docs/superpowers/specs/2026-05-20-inspect-rebuild-design.md +370 -0
  37. ansible_aom-0.102.13/docs/superpowers/specs/2026-05-21-diagnostics-layer-design.md +223 -0
  38. ansible_aom-0.102.13/docs/superpowers/specs/2026-05-21-render-state-perf-design.md +249 -0
  39. ansible_aom-0.102.13/docs/superpowers/specs/2026-06-02-live-loop-item-streaming-design.md +251 -0
  40. ansible_aom-0.102.13/docs/superpowers/specs/2026-06-16-run-duration-estimate-design.md +240 -0
  41. ansible_aom-0.102.13/docs/superpowers/specs/2026-07-21-worktree-safe-version-hook-design.md +50 -0
  42. ansible_aom-0.102.13/flake.lock +61 -0
  43. ansible_aom-0.102.13/flake.nix +103 -0
  44. ansible_aom-0.102.13/packaging/aom.spec +47 -0
  45. ansible_aom-0.102.13/pyproject.toml +222 -0
  46. ansible_aom-0.102.13/schemas/README.md +11 -0
  47. ansible_aom-0.102.13/schemas/run_summary.v1.json +109 -0
  48. ansible_aom-0.102.13/scripts/bump_version.py +256 -0
  49. ansible_aom-0.102.13/scripts/check_version_bump.py +289 -0
  50. ansible_aom-0.102.13/scripts/check_version_consistency.py +63 -0
  51. ansible_aom-0.102.13/scripts/install-hooks.sh +43 -0
  52. ansible_aom-0.102.13/scripts/verify_anchors.py +227 -0
  53. ansible_aom-0.102.13/src/ansible_aom/__init__.py +74 -0
  54. ansible_aom-0.102.13/src/ansible_aom/__main__.py +8 -0
  55. ansible_aom-0.102.13/src/ansible_aom/ansible/__init__.py +6 -0
  56. ansible_aom-0.102.13/src/ansible_aom/ansible/callback/aom_jsonl.py +227 -0
  57. ansible_aom-0.102.13/src/ansible_aom/ansible/preflight.py +222 -0
  58. ansible_aom-0.102.13/src/ansible_aom/ansible/runner.py +1223 -0
  59. ansible_aom-0.102.13/src/ansible_aom/callbacks/__init__.py +6 -0
  60. ansible_aom-0.102.13/src/ansible_aom/callbacks/aom_connection.py +122 -0
  61. ansible_aom-0.102.13/src/ansible_aom/cli.py +674 -0
  62. ansible_aom-0.102.13/src/ansible_aom/compact/__init__.py +1 -0
  63. ansible_aom-0.102.13/src/ansible_aom/compact/display.py +493 -0
  64. ansible_aom-0.102.13/src/ansible_aom/compact/exit_code.py +12 -0
  65. ansible_aom-0.102.13/src/ansible_aom/compact/format.py +947 -0
  66. ansible_aom-0.102.13/src/ansible_aom/compact/password.py +52 -0
  67. ansible_aom-0.102.13/src/ansible_aom/compact/renderer.py +2174 -0
  68. ansible_aom-0.102.13/src/ansible_aom/completion.py +109 -0
  69. ansible_aom-0.102.13/src/ansible_aom/core/__init__.py +7 -0
  70. ansible_aom-0.102.13/src/ansible_aom/core/_async_poll.py +20 -0
  71. ansible_aom-0.102.13/src/ansible_aom/core/config.py +131 -0
  72. ansible_aom-0.102.13/src/ansible_aom/core/config_layer.py +167 -0
  73. ansible_aom-0.102.13/src/ansible_aom/core/default_config.yaml +33 -0
  74. ansible_aom-0.102.13/src/ansible_aom/core/diagnostics.py +564 -0
  75. ansible_aom-0.102.13/src/ansible_aom/core/duration.py +95 -0
  76. ansible_aom-0.102.13/src/ansible_aom/core/estimate.py +186 -0
  77. ansible_aom-0.102.13/src/ansible_aom/core/event_types.py +146 -0
  78. ansible_aom-0.102.13/src/ansible_aom/core/exit_code.py +48 -0
  79. ansible_aom-0.102.13/src/ansible_aom/core/heartbeat.py +115 -0
  80. ansible_aom-0.102.13/src/ansible_aom/core/icons.py +200 -0
  81. ansible_aom-0.102.13/src/ansible_aom/core/includes.py +1295 -0
  82. ansible_aom-0.102.13/src/ansible_aom/core/inspect_model.py +1554 -0
  83. ansible_aom-0.102.13/src/ansible_aom/core/log_filter.py +122 -0
  84. ansible_aom-0.102.13/src/ansible_aom/core/models.py +404 -0
  85. ansible_aom-0.102.13/src/ansible_aom/core/overhead.py +180 -0
  86. ansible_aom-0.102.13/src/ansible_aom/core/parity.py +112 -0
  87. ansible_aom-0.102.13/src/ansible_aom/core/parser.py +827 -0
  88. ansible_aom-0.102.13/src/ansible_aom/core/prompts.py +201 -0
  89. ansible_aom-0.102.13/src/ansible_aom/core/redaction.py +310 -0
  90. ansible_aom-0.102.13/src/ansible_aom/core/replay.py +43 -0
  91. ansible_aom-0.102.13/src/ansible_aom/core/run_config.py +201 -0
  92. ansible_aom-0.102.13/src/ansible_aom/core/run_state.py +1813 -0
  93. ansible_aom-0.102.13/src/ansible_aom/core/state_machine.py +27 -0
  94. ansible_aom-0.102.13/src/ansible_aom/core/stderr_classifier.py +305 -0
  95. ansible_aom-0.102.13/src/ansible_aom/core/text.py +15 -0
  96. ansible_aom-0.102.13/src/ansible_aom/core/timestamp.py +40 -0
  97. ansible_aom-0.102.13/src/ansible_aom/core/tree.py +153 -0
  98. ansible_aom-0.102.13/src/ansible_aom/core/tree_projection.py +3108 -0
  99. ansible_aom-0.102.13/src/ansible_aom/drivers/__init__.py +10 -0
  100. ansible_aom-0.102.13/src/ansible_aom/drivers/live.py +56 -0
  101. ansible_aom-0.102.13/src/ansible_aom/drivers/protocol.py +44 -0
  102. ansible_aom-0.102.13/src/ansible_aom/drivers/replay.py +252 -0
  103. ansible_aom-0.102.13/src/ansible_aom/formats/__init__.py +6 -0
  104. ansible_aom-0.102.13/src/ansible_aom/formats/json.py +258 -0
  105. ansible_aom-0.102.13/src/ansible_aom/inspect/__init__.py +1 -0
  106. ansible_aom-0.102.13/src/ansible_aom/inspect/cli.py +354 -0
  107. ansible_aom-0.102.13/src/ansible_aom/inspect/formatters.py +337 -0
  108. ansible_aom-0.102.13/src/ansible_aom/inspect/text.py +380 -0
  109. ansible_aom-0.102.13/src/ansible_aom/renderer/__init__.py +1 -0
  110. ansible_aom-0.102.13/src/ansible_aom/renderer/factory.py +63 -0
  111. ansible_aom-0.102.13/src/ansible_aom/renderer/protocol.py +251 -0
  112. ansible_aom-0.102.13/src/ansible_aom/rerun/__init__.py +1 -0
  113. ansible_aom-0.102.13/src/ansible_aom/rerun/cli.py +466 -0
  114. ansible_aom-0.102.13/src/ansible_aom/session/__init__.py +10 -0
  115. ansible_aom-0.102.13/src/ansible_aom/session/history.py +361 -0
  116. ansible_aom-0.102.13/src/ansible_aom/session/index.py +711 -0
  117. ansible_aom-0.102.13/src/ansible_aom/session/store.py +915 -0
  118. ansible_aom-0.102.13/src/ansible_aom/session/summary.py +124 -0
  119. ansible_aom-0.102.13/src/ansible_aom/tui/__init__.py +1 -0
  120. ansible_aom-0.102.13/src/ansible_aom/tui/screens/__init__.py +1 -0
  121. ansible_aom-0.102.13/src/ansible_aom/tui/screens/inspect.py +1646 -0
  122. ansible_aom-0.102.13/tests/__init__.py +0 -0
  123. ansible_aom-0.102.13/tests/_utils.py +94 -0
  124. ansible_aom-0.102.13/tests/compact/__init__.py +0 -0
  125. ansible_aom-0.102.13/tests/compact/golden/all_skipped__80x24.txt +11 -0
  126. ansible_aom-0.102.13/tests/compact/golden/all_unreachable__80x24.txt +13 -0
  127. ansible_aom-0.102.13/tests/compact/golden/cancelled__80x24.txt +8 -0
  128. ansible_aom-0.102.13/tests/compact/golden/dry_run_check__80x24.txt +7 -0
  129. ansible_aom-0.102.13/tests/compact/golden/empty_run__80x24.txt +1 -0
  130. ansible_aom-0.102.13/tests/compact/golden/multi_host_mixed__80x24.txt +27 -0
  131. ansible_aom-0.102.13/tests/compact/golden/multiple_plays__80x24.txt +16 -0
  132. ansible_aom-0.102.13/tests/compact/golden/playbook_failed__80x24.txt +12 -0
  133. ansible_aom-0.102.13/tests/compact/golden/single_task_ok__80x24.txt +7 -0
  134. ansible_aom-0.102.13/tests/compact/golden/unknown_event_type__80x24.txt +8 -0
  135. ansible_aom-0.102.13/tests/compact/test_ascii_fallback.py +111 -0
  136. ansible_aom-0.102.13/tests/compact/test_check_mode_chip.py +109 -0
  137. ansible_aom-0.102.13/tests/compact/test_completion_label.py +53 -0
  138. ansible_aom-0.102.13/tests/compact/test_completion_recap.py +139 -0
  139. ansible_aom-0.102.13/tests/compact/test_completion_summary.py +86 -0
  140. ansible_aom-0.102.13/tests/compact/test_display_ansi.py +119 -0
  141. ansible_aom-0.102.13/tests/compact/test_emit_event_log_batching.py +209 -0
  142. ansible_aom-0.102.13/tests/compact/test_error_message_extraction.py +373 -0
  143. ansible_aom-0.102.13/tests/compact/test_fanout_summary.py +121 -0
  144. ansible_aom-0.102.13/tests/compact/test_free_strategy_task_header.py +91 -0
  145. ansible_aom-0.102.13/tests/compact/test_full_completion_summary.py +227 -0
  146. ansible_aom-0.102.13/tests/compact/test_golden_frames.py +564 -0
  147. ansible_aom-0.102.13/tests/compact/test_hide_state.py +530 -0
  148. ansible_aom-0.102.13/tests/compact/test_host_table.py +207 -0
  149. ansible_aom-0.102.13/tests/compact/test_incremental_counters.py +98 -0
  150. ansible_aom-0.102.13/tests/compact/test_inspect_text_golden.py +207 -0
  151. ansible_aom-0.102.13/tests/compact/test_log_flush_batching.py +177 -0
  152. ansible_aom-0.102.13/tests/compact/test_long_output_cap.py +122 -0
  153. ansible_aom-0.102.13/tests/compact/test_loop_item_lines.py +213 -0
  154. ansible_aom-0.102.13/tests/compact/test_loop_item_streaming.py +389 -0
  155. ansible_aom-0.102.13/tests/compact/test_mitogen_robustness.py +226 -0
  156. ansible_aom-0.102.13/tests/compact/test_password.py +505 -0
  157. ansible_aom-0.102.13/tests/compact/test_per_task_timing.py +236 -0
  158. ansible_aom-0.102.13/tests/compact/test_preflight_summary.py +230 -0
  159. ansible_aom-0.102.13/tests/compact/test_preserve_tree_on_cancel.py +98 -0
  160. ansible_aom-0.102.13/tests/compact/test_prior_denominator.py +130 -0
  161. ansible_aom-0.102.13/tests/compact/test_prior_run_line.py +110 -0
  162. ansible_aom-0.102.13/tests/compact/test_render_dirty_flag.py +178 -0
  163. ansible_aom-0.102.13/tests/compact/test_render_preflight_scaling.py +155 -0
  164. ansible_aom-0.102.13/tests/compact/test_renderer_set_definitions.py +116 -0
  165. ansible_aom-0.102.13/tests/compact/test_renderer_stats.py +98 -0
  166. ansible_aom-0.102.13/tests/compact/test_row_count.py +132 -0
  167. ansible_aom-0.102.13/tests/compact/test_skipped_collapsing.py +186 -0
  168. ansible_aom-0.102.13/tests/compact/test_small_terminal.py +285 -0
  169. ansible_aom-0.102.13/tests/compact/test_spinner_animation.py +80 -0
  170. ansible_aom-0.102.13/tests/compact/test_stale_task_suffix.py +99 -0
  171. ansible_aom-0.102.13/tests/compact/test_status_bar_colors.py +252 -0
  172. ansible_aom-0.102.13/tests/compact/test_status_bar_estimated_total.py +38 -0
  173. ansible_aom-0.102.13/tests/compact/test_status_bar_eta.py +41 -0
  174. ansible_aom-0.102.13/tests/compact/test_status_bar_liveness.py +270 -0
  175. ansible_aom-0.102.13/tests/compact/test_status_tally_bar.py +139 -0
  176. ansible_aom-0.102.13/tests/compact/test_summary_flush_scaling.py +168 -0
  177. ansible_aom-0.102.13/tests/compact/test_task_progress.py +353 -0
  178. ansible_aom-0.102.13/tests/compact/test_task_summary.py +301 -0
  179. ansible_aom-0.102.13/tests/compact/test_task_summary_calculation.py +164 -0
  180. ansible_aom-0.102.13/tests/compact/test_tree_event_replay.py +230 -0
  181. ansible_aom-0.102.13/tests/compact/test_tree_large_playbook.py +216 -0
  182. ansible_aom-0.102.13/tests/compact/test_tree_pipe_continuation.py +568 -0
  183. ansible_aom-0.102.13/tests/compact/test_tree_projection_lifecycle.py +210 -0
  184. ansible_aom-0.102.13/tests/compact/test_tree_render.py +949 -0
  185. ansible_aom-0.102.13/tests/compact/test_tree_upcoming_plays.py +209 -0
  186. ansible_aom-0.102.13/tests/compact/test_tree_upcoming_tasks.py +150 -0
  187. ansible_aom-0.102.13/tests/compact/test_unknown_event_hint.py +125 -0
  188. ansible_aom-0.102.13/tests/compact/test_unmatched_event_hint.py +47 -0
  189. ansible_aom-0.102.13/tests/compact/test_warning_color.py +59 -0
  190. ansible_aom-0.102.13/tests/compact/test_warning_visibility.py +91 -0
  191. ansible_aom-0.102.13/tests/conftest.py +300 -0
  192. ansible_aom-0.102.13/tests/fixtures/ansible/dynamic_target.yml +10 -0
  193. ansible_aom-0.102.13/tests/fixtures/ansible/ignore_errors.yml +13 -0
  194. ansible_aom-0.102.13/tests/fixtures/ansible/imported_tasks.yml +7 -0
  195. ansible_aom-0.102.13/tests/fixtures/ansible/included_tasks.yml +7 -0
  196. ansible_aom-0.102.13/tests/fixtures/ansible/missing_role.yml +5 -0
  197. ansible_aom-0.102.13/tests/fixtures/ansible/multi_hosts.yml +8 -0
  198. ansible_aom-0.102.13/tests/fixtures/ansible/multi_play.yml +21 -0
  199. ansible_aom-0.102.13/tests/fixtures/ansible/nested_level1.yml +6 -0
  200. ansible_aom-0.102.13/tests/fixtures/ansible/nested_level2.yml +7 -0
  201. ansible_aom-0.102.13/tests/fixtures/ansible/no_name.yml +11 -0
  202. ansible_aom-0.102.13/tests/fixtures/ansible/roles/angie_ssl_terminator/tasks/main.yml +31 -0
  203. ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman/tasks/main.yml +24 -0
  204. ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman_role_rel/tasks/_includes/setup.yml +8 -0
  205. ansible_aom-0.102.13/tests/fixtures/ansible/roles/podman_role_rel/tasks/main.yml +15 -0
  206. ansible_aom-0.102.13/tests/fixtures/ansible/roles/test_role/tasks/main.yml +11 -0
  207. ansible_aom-0.102.13/tests/fixtures/ansible/simple.yml +16 -0
  208. ansible_aom-0.102.13/tests/fixtures/ansible/syntax_error.yml +10 -0
  209. ansible_aom-0.102.13/tests/fixtures/ansible/unreachable.yml +15 -0
  210. ansible_aom-0.102.13/tests/fixtures/ansible/with_block.yml +20 -0
  211. ansible_aom-0.102.13/tests/fixtures/ansible/with_dynamic_include.yml +7 -0
  212. ansible_aom-0.102.13/tests/fixtures/ansible/with_import.yml +13 -0
  213. ansible_aom-0.102.13/tests/fixtures/ansible/with_include.yml +10 -0
  214. ansible_aom-0.102.13/tests/fixtures/ansible/with_include_role.yml +14 -0
  215. ansible_aom-0.102.13/tests/fixtures/ansible/with_loop.yml +12 -0
  216. ansible_aom-0.102.13/tests/fixtures/ansible/with_nested_include.yml +10 -0
  217. ansible_aom-0.102.13/tests/fixtures/ansible/with_nested_role.yml +8 -0
  218. ansible_aom-0.102.13/tests/fixtures/ansible/with_pre_post.yml +21 -0
  219. ansible_aom-0.102.13/tests/fixtures/ansible/with_role.yml +10 -0
  220. ansible_aom-0.102.13/tests/fixtures/ansible/with_role_rel_include.yml +6 -0
  221. ansible_aom-0.102.13/tests/fixtures/ansible/with_throttle.yml +9 -0
  222. ansible_aom-0.102.13/tests/fixtures/multi_host_mixed.jsonl +13 -0
  223. ansible_aom-0.102.13/tests/fixtures/playbook_failed.jsonl +7 -0
  224. ansible_aom-0.102.13/tests/fixtures/redaction_bypass.jsonl +34 -0
  225. ansible_aom-0.102.13/tests/fixtures/sessions/019e4000-0000-7000-8000-000000000001/events.jsonl +7 -0
  226. ansible_aom-0.102.13/tests/fixtures/sessions/019e4000-0000-7000-8000-000000000001/meta.json +10 -0
  227. ansible_aom-0.102.13/tests/fixtures/sessions/019e4100-0000-7000-8000-000000000003/events.jsonl +7 -0
  228. ansible_aom-0.102.13/tests/fixtures/sessions/019e4100-0000-7000-8000-000000000003/meta.json +10 -0
  229. ansible_aom-0.102.13/tests/fixtures/sessions/019e4200-0000-7000-8000-000000000004/events.jsonl +5 -0
  230. ansible_aom-0.102.13/tests/fixtures/sessions/019e4200-0000-7000-8000-000000000004/meta.json +10 -0
  231. ansible_aom-0.102.13/tests/fixtures/sessions/019e4300-0000-7000-8000-000000000005/events.jsonl +3 -0
  232. ansible_aom-0.102.13/tests/fixtures/sessions/019e4300-0000-7000-8000-000000000005/meta.json +7 -0
  233. ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/events.jsonl +7 -0
  234. ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/meta.json +10 -0
  235. ansible_aom-0.102.13/tests/fixtures/sessions/019e4520-fa64-7000-a627-000000000002/stderr.log +14 -0
  236. ansible_aom-0.102.13/tests/fixtures/sessions/019e4600-0000-7000-8000-000000000006/events.jsonl +8 -0
  237. ansible_aom-0.102.13/tests/fixtures/sessions/019e4600-0000-7000-8000-000000000006/meta.json +10 -0
  238. ansible_aom-0.102.13/tests/fixtures/sessions/__init__.py +0 -0
  239. ansible_aom-0.102.13/tests/fixtures/sessions/conftest.py +75 -0
  240. ansible_aom-0.102.13/tests/fixtures/single_task_ok.jsonl +5 -0
  241. ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_multi_host.jsonl +4 -0
  242. ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_sequential_host.jsonl +4 -0
  243. ansible_aom-0.102.13/tests/fixtures/stderr_sources/connection_simple_cycle.jsonl +2 -0
  244. ansible_aom-0.102.13/tests/fixtures/stderr_sources/mixed_playbook_with_stderr.jsonl +10 -0
  245. ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_different_hosts_unique.jsonl +5 -0
  246. ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_no_active_connection.jsonl +3 -0
  247. ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_same_host_ambiguous.jsonl +5 -0
  248. ansible_aom-0.102.13/tests/fixtures/stderr_sources/overlap_three_same_host.jsonl +7 -0
  249. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_connection.jsonl +1 -0
  250. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_connection_lifecycle.jsonl +1 -0
  251. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_deprecation.jsonl +1 -0
  252. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_error.jsonl +1 -0
  253. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_inventory.jsonl +1 -0
  254. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_plugin_loading.jsonl +1 -0
  255. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_prompt.jsonl +1 -0
  256. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_run_level.jsonl +1 -0
  257. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_ssh_debug.jsonl +1 -0
  258. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_ssh_info.jsonl +1 -0
  259. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_unknown.jsonl +1 -0
  260. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_vault.jsonl +1 -0
  261. ansible_aom-0.102.13/tests/fixtures/stderr_sources/source_warning.jsonl +1 -0
  262. ansible_aom-0.102.13/tests/integration/__init__.py +4 -0
  263. ansible_aom-0.102.13/tests/integration/test_compact_renderer.py +1203 -0
  264. ansible_aom-0.102.13/tests/integration/test_concurrent_inspect.py +526 -0
  265. ansible_aom-0.102.13/tests/integration/test_ctrl_c_race.py +182 -0
  266. ansible_aom-0.102.13/tests/integration/test_error_handling.py +574 -0
  267. ansible_aom-0.102.13/tests/integration/test_fixture_layout.py +16 -0
  268. ansible_aom-0.102.13/tests/integration/test_history_roundtrip.py +186 -0
  269. ansible_aom-0.102.13/tests/integration/test_ignore_errors_callback.py +106 -0
  270. ansible_aom-0.102.13/tests/integration/test_include_import_role.py +270 -0
  271. ansible_aom-0.102.13/tests/integration/test_inspect_cli.py +260 -0
  272. ansible_aom-0.102.13/tests/integration/test_invariants_session_roundtrip.py +310 -0
  273. ansible_aom-0.102.13/tests/integration/test_loop_item_events.py +187 -0
  274. ansible_aom-0.102.13/tests/integration/test_meta_task_callback.py +249 -0
  275. ansible_aom-0.102.13/tests/integration/test_no_eof_hang.py +134 -0
  276. ansible_aom-0.102.13/tests/integration/test_no_record.py +70 -0
  277. ansible_aom-0.102.13/tests/integration/test_playbook_parser.py +1050 -0
  278. ansible_aom-0.102.13/tests/integration/test_preflight_runner.py +280 -0
  279. ansible_aom-0.102.13/tests/integration/test_r6_encoding_roundtrip.py +259 -0
  280. ansible_aom-0.102.13/tests/integration/test_real_ansible.py +232 -0
  281. ansible_aom-0.102.13/tests/integration/test_redaction.py +978 -0
  282. ansible_aom-0.102.13/tests/integration/test_renderer_eta.py +271 -0
  283. ansible_aom-0.102.13/tests/integration/test_renderer_parity.py +119 -0
  284. ansible_aom-0.102.13/tests/integration/test_replay.py +110 -0
  285. ansible_aom-0.102.13/tests/integration/test_replay_determinism.py +471 -0
  286. ansible_aom-0.102.13/tests/integration/test_rerun.py +140 -0
  287. ansible_aom-0.102.13/tests/integration/test_rerun_roundtrip.py +462 -0
  288. ansible_aom-0.102.13/tests/integration/test_runner.py +265 -0
  289. ansible_aom-0.102.13/tests/integration/test_runner_interactive_prompts.py +513 -0
  290. ansible_aom-0.102.13/tests/integration/test_runner_on_start_host.py +103 -0
  291. ansible_aom-0.102.13/tests/integration/test_runner_session_recording.py +295 -0
  292. ansible_aom-0.102.13/tests/integration/test_session.py +919 -0
  293. ansible_aom-0.102.13/tests/integration/test_throttle.py +318 -0
  294. ansible_aom-0.102.13/tests/playbooks/01-single-task-success/site.yml +8 -0
  295. ansible_aom-0.102.13/tests/playbooks/02-single-task-changed/cleanup.sh +2 -0
  296. ansible_aom-0.102.13/tests/playbooks/02-single-task-changed/site.yml +10 -0
  297. ansible_aom-0.102.13/tests/playbooks/03-task-failure/site.yml +12 -0
  298. ansible_aom-0.102.13/tests/playbooks/04-ignore-errors/site.yml +13 -0
  299. ansible_aom-0.102.13/tests/playbooks/05-skipped-tasks/site.yml +15 -0
  300. ansible_aom-0.102.13/tests/playbooks/06-unreachable/site.yml +7 -0
  301. ansible_aom-0.102.13/tests/playbooks/07-multi-host-mixed/site.yml +20 -0
  302. ansible_aom-0.102.13/tests/playbooks/08-multiple-plays/site.yml +35 -0
  303. ansible_aom-0.102.13/tests/playbooks/09-handler-tasks/cleanup.sh +2 -0
  304. ansible_aom-0.102.13/tests/playbooks/09-handler-tasks/site.yml +16 -0
  305. ansible_aom-0.102.13/tests/playbooks/10-free-strategy/site.yml +13 -0
  306. ansible_aom-0.102.13/tests/playbooks/11-role-grouping/roles/nginx/tasks/main.yml +22 -0
  307. ansible_aom-0.102.13/tests/playbooks/11-role-grouping/site.yml +6 -0
  308. ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/README.md +39 -0
  309. ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/site.yml +10 -0
  310. ansible_aom-0.102.13/tests/playbooks/12-vault-encrypted/vars/secrets.yml +2 -0
  311. ansible_aom-0.102.13/tests/playbooks/13-ssh-password/README.md +25 -0
  312. ansible_aom-0.102.13/tests/playbooks/13-ssh-password/site.yml +8 -0
  313. ansible_aom-0.102.13/tests/playbooks/14-become-password/README.md +29 -0
  314. ansible_aom-0.102.13/tests/playbooks/14-become-password/site.yml +9 -0
  315. ansible_aom-0.102.13/tests/playbooks/15-vault-password-change/README.md +38 -0
  316. ansible_aom-0.102.13/tests/playbooks/16-warnings/site.yml +8 -0
  317. ansible_aom-0.102.13/tests/playbooks/17-deprecation-warnings/site.yml +11 -0
  318. ansible_aom-0.102.13/tests/playbooks/17-deprecation-warnings/tasks/subtask.yml +4 -0
  319. ansible_aom-0.102.13/tests/playbooks/18-no-log-redaction/site.yml +23 -0
  320. ansible_aom-0.102.13/tests/playbooks/19-password-field-redaction/site.yml +24 -0
  321. ansible_aom-0.102.13/tests/playbooks/20-url-cli-credential-redaction/site.yml +20 -0
  322. ansible_aom-0.102.13/tests/playbooks/21-module-args-redaction/site.yml +21 -0
  323. ansible_aom-0.102.13/tests/playbooks/22-play-recap/site.yml +12 -0
  324. ansible_aom-0.102.13/tests/playbooks/23-command-not-found/README.md +17 -0
  325. ansible_aom-0.102.13/tests/playbooks/24-user-cancellation/site.yml +7 -0
  326. ansible_aom-0.102.13/tests/playbooks/25-syntax-error/site.yml +9 -0
  327. ansible_aom-0.102.13/tests/playbooks/26-empty-playbook/site.yml +5 -0
  328. ansible_aom-0.102.13/tests/playbooks/27-single-host-localhost/site.yml +9 -0
  329. ansible_aom-0.102.13/tests/playbooks/28-host-pattern-filtering/site.yml +8 -0
  330. ansible_aom-0.102.13/tests/playbooks/29-tags/site.yml +24 -0
  331. ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/site.yml +10 -0
  332. ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/tasks/dynamic.yml +7 -0
  333. ansible_aom-0.102.13/tests/playbooks/30-include-vs-import/tasks/static.yml +7 -0
  334. ansible_aom-0.102.13/tests/playbooks/31-block-tasks/site.yml +31 -0
  335. ansible_aom-0.102.13/tests/playbooks/32-large-playbook/generate.py +16 -0
  336. ansible_aom-0.102.13/tests/playbooks/33-mixed-warnings-execution/site.yml +23 -0
  337. ansible_aom-0.102.13/tests/playbooks/ansible.cfg +5 -0
  338. ansible_aom-0.102.13/tests/playbooks/inventory.ini +19 -0
  339. ansible_aom-0.102.13/tests/tui/__init__.py +0 -0
  340. ansible_aom-0.102.13/tests/tui/test_inspect_screen.py +1430 -0
  341. ansible_aom-0.102.13/tests/tui/test_panels.py +1475 -0
  342. ansible_aom-0.102.13/tests/unit/test_aom_connection.py +168 -0
  343. ansible_aom-0.102.13/tests/unit/test_aom_trace_events.py +80 -0
  344. ansible_aom-0.102.13/tests/unit/test_aom_verbose_line_fuzz.py +205 -0
  345. ansible_aom-0.102.13/tests/unit/test_async_preflight.py +64 -0
  346. ansible_aom-0.102.13/tests/unit/test_build_configuration.py +93 -0
  347. ansible_aom-0.102.13/tests/unit/test_bump_version.py +277 -0
  348. ansible_aom-0.102.13/tests/unit/test_callback_env.py +167 -0
  349. ansible_aom-0.102.13/tests/unit/test_check_version_bump.py +320 -0
  350. ansible_aom-0.102.13/tests/unit/test_cli.py +1862 -0
  351. ansible_aom-0.102.13/tests/unit/test_cli_duplicate_playbook.py +35 -0
  352. ansible_aom-0.102.13/tests/unit/test_cli_inventory_autodetect.py +92 -0
  353. ansible_aom-0.102.13/tests/unit/test_cli_limit_merge.py +97 -0
  354. ansible_aom-0.102.13/tests/unit/test_cli_matrix.py +75 -0
  355. ansible_aom-0.102.13/tests/unit/test_cli_replay.py +143 -0
  356. ansible_aom-0.102.13/tests/unit/test_cli_tui_launch.py +26 -0
  357. ansible_aom-0.102.13/tests/unit/test_compact_pause_visibility.py +115 -0
  358. ansible_aom-0.102.13/tests/unit/test_completion.py +184 -0
  359. ansible_aom-0.102.13/tests/unit/test_config.py +737 -0
  360. ansible_aom-0.102.13/tests/unit/test_config_layer.py +420 -0
  361. ansible_aom-0.102.13/tests/unit/test_core_text.py +24 -0
  362. ansible_aom-0.102.13/tests/unit/test_diagnostics.py +143 -0
  363. ansible_aom-0.102.13/tests/unit/test_diagnostics_summary_print.py +82 -0
  364. ansible_aom-0.102.13/tests/unit/test_diagnostics_wiring.py +81 -0
  365. ansible_aom-0.102.13/tests/unit/test_distribution.py +139 -0
  366. ansible_aom-0.102.13/tests/unit/test_duration.py +55 -0
  367. ansible_aom-0.102.13/tests/unit/test_dynamic_counters.py +570 -0
  368. ansible_aom-0.102.13/tests/unit/test_dynamic_expansion.py +1015 -0
  369. ansible_aom-0.102.13/tests/unit/test_encoding_robustness.py +134 -0
  370. ansible_aom-0.102.13/tests/unit/test_estimate.py +206 -0
  371. ansible_aom-0.102.13/tests/unit/test_event_processing.py +2148 -0
  372. ansible_aom-0.102.13/tests/unit/test_event_source.py +284 -0
  373. ansible_aom-0.102.13/tests/unit/test_event_store_crash_recovery.py +499 -0
  374. ansible_aom-0.102.13/tests/unit/test_heartbeat.py +241 -0
  375. ansible_aom-0.102.13/tests/unit/test_history.py +401 -0
  376. ansible_aom-0.102.13/tests/unit/test_history_loop_totals.py +117 -0
  377. ansible_aom-0.102.13/tests/unit/test_history_observed_count.py +156 -0
  378. ansible_aom-0.102.13/tests/unit/test_history_task_wall.py +209 -0
  379. ansible_aom-0.102.13/tests/unit/test_host_resolution.py +457 -0
  380. ansible_aom-0.102.13/tests/unit/test_icons.py +508 -0
  381. ansible_aom-0.102.13/tests/unit/test_include_cache.py +1686 -0
  382. ansible_aom-0.102.13/tests/unit/test_inspect_accumulator.py +280 -0
  383. ansible_aom-0.102.13/tests/unit/test_inspect_changes.py +221 -0
  384. ansible_aom-0.102.13/tests/unit/test_inspect_debug.py +241 -0
  385. ansible_aom-0.102.13/tests/unit/test_inspect_index_wiring.py +160 -0
  386. ansible_aom-0.102.13/tests/unit/test_inspect_model.py +650 -0
  387. ansible_aom-0.102.13/tests/unit/test_inspect_model_verbose.py +150 -0
  388. ansible_aom-0.102.13/tests/unit/test_inspect_prune.py +49 -0
  389. ansible_aom-0.102.13/tests/unit/test_inspect_warnings.py +118 -0
  390. ansible_aom-0.102.13/tests/unit/test_interactive_prompt.py +137 -0
  391. ansible_aom-0.102.13/tests/unit/test_invariants_runstate_renderer.py +363 -0
  392. ansible_aom-0.102.13/tests/unit/test_json_renderer.py +450 -0
  393. ansible_aom-0.102.13/tests/unit/test_layering.py +178 -0
  394. ansible_aom-0.102.13/tests/unit/test_linear_dead_host_synthesis.py +301 -0
  395. ansible_aom-0.102.13/tests/unit/test_log_filter.py +326 -0
  396. ansible_aom-0.102.13/tests/unit/test_loop_item_count.py +124 -0
  397. ansible_aom-0.102.13/tests/unit/test_meta_schema_version.py +144 -0
  398. ansible_aom-0.102.13/tests/unit/test_models.py +1631 -0
  399. ansible_aom-0.102.13/tests/unit/test_no_record.py +108 -0
  400. ansible_aom-0.102.13/tests/unit/test_overhead.py +234 -0
  401. ansible_aom-0.102.13/tests/unit/test_overhead_display.py +115 -0
  402. ansible_aom-0.102.13/tests/unit/test_parser.py +2033 -0
  403. ansible_aom-0.102.13/tests/unit/test_parser_orjson_swap.py +88 -0
  404. ansible_aom-0.102.13/tests/unit/test_parser_recap_cap.py +60 -0
  405. ansible_aom-0.102.13/tests/unit/test_pause_lingering_cleanup.py +123 -0
  406. ansible_aom-0.102.13/tests/unit/test_pause_prompt_reconstruction.py +168 -0
  407. ansible_aom-0.102.13/tests/unit/test_play_boundary_state.py +343 -0
  408. ansible_aom-0.102.13/tests/unit/test_poll_and_retry_hint.py +124 -0
  409. ansible_aom-0.102.13/tests/unit/test_posix_callback.py +303 -0
  410. ansible_aom-0.102.13/tests/unit/test_pre_push.py +46 -0
  411. ansible_aom-0.102.13/tests/unit/test_preflight.py +150 -0
  412. ansible_aom-0.102.13/tests/unit/test_prior_run_loop_totals_injection.py +41 -0
  413. ansible_aom-0.102.13/tests/unit/test_profile_tracemalloc.py +104 -0
  414. ansible_aom-0.102.13/tests/unit/test_properties_parser.py +198 -0
  415. ansible_aom-0.102.13/tests/unit/test_properties_redaction.py +237 -0
  416. ansible_aom-0.102.13/tests/unit/test_properties_state.py +246 -0
  417. ansible_aom-0.102.13/tests/unit/test_psutil_safe_probe.py +111 -0
  418. ansible_aom-0.102.13/tests/unit/test_pty_stream.py +894 -0
  419. ansible_aom-0.102.13/tests/unit/test_publication_docs.py +83 -0
  420. ansible_aom-0.102.13/tests/unit/test_redaction.py +1064 -0
  421. ansible_aom-0.102.13/tests/unit/test_redaction_layer4.py +425 -0
  422. ansible_aom-0.102.13/tests/unit/test_redaction_redteam_fixture.py +162 -0
  423. ansible_aom-0.102.13/tests/unit/test_render_storm.py +75 -0
  424. ansible_aom-0.102.13/tests/unit/test_renderer_stats_parity.py +51 -0
  425. ansible_aom-0.102.13/tests/unit/test_renderer_unbounded_caps.py +91 -0
  426. ansible_aom-0.102.13/tests/unit/test_replay.py +320 -0
  427. ansible_aom-0.102.13/tests/unit/test_replay_schema_boundary.py +410 -0
  428. ansible_aom-0.102.13/tests/unit/test_rerun_cli.py +703 -0
  429. ansible_aom-0.102.13/tests/unit/test_run_config.py +143 -0
  430. ansible_aom-0.102.13/tests/unit/test_run_diagnostics.py +214 -0
  431. ansible_aom-0.102.13/tests/unit/test_run_state_index.py +239 -0
  432. ansible_aom-0.102.13/tests/unit/test_run_state_memory_bounds.py +210 -0
  433. ansible_aom-0.102.13/tests/unit/test_run_state_set_caps.py +85 -0
  434. ansible_aom-0.102.13/tests/unit/test_run_summary_schema.py +273 -0
  435. ansible_aom-0.102.13/tests/unit/test_runner_ctrl_c_race.py +210 -0
  436. ansible_aom-0.102.13/tests/unit/test_runner_eof_watchdog.py +306 -0
  437. ansible_aom-0.102.13/tests/unit/test_runner_event_fallback.py +644 -0
  438. ansible_aom-0.102.13/tests/unit/test_runner_events_recorded.py +296 -0
  439. ansible_aom-0.102.13/tests/unit/test_runner_heartbeat.py +127 -0
  440. ansible_aom-0.102.13/tests/unit/test_runner_isalive_in_loop.py +205 -0
  441. ansible_aom-0.102.13/tests/unit/test_runner_prompt_echo.py +53 -0
  442. ansible_aom-0.102.13/tests/unit/test_runner_searchwindowsize.py +156 -0
  443. ansible_aom-0.102.13/tests/unit/test_runner_session_footer.py +29 -0
  444. ansible_aom-0.102.13/tests/unit/test_runner_session_meta.py +46 -0
  445. ansible_aom-0.102.13/tests/unit/test_runner_stall_flush.py +424 -0
  446. ansible_aom-0.102.13/tests/unit/test_runner_watchdog_endtime.py +192 -0
  447. ansible_aom-0.102.13/tests/unit/test_runtime_role_task_count.py +326 -0
  448. ansible_aom-0.102.13/tests/unit/test_session_collectors.py +192 -0
  449. ansible_aom-0.102.13/tests/unit/test_session_diagnostics.py +136 -0
  450. ansible_aom-0.102.13/tests/unit/test_session_helpers.py +97 -0
  451. ansible_aom-0.102.13/tests/unit/test_session_index.py +801 -0
  452. ansible_aom-0.102.13/tests/unit/test_session_meta_persistence.py +33 -0
  453. ansible_aom-0.102.13/tests/unit/test_session_store_async_write.py +229 -0
  454. ansible_aom-0.102.13/tests/unit/test_sink_disable_and_preflight_ms.py +76 -0
  455. ansible_aom-0.102.13/tests/unit/test_stale_running_cleanup.py +281 -0
  456. ansible_aom-0.102.13/tests/unit/test_state_dir_isolation.py +23 -0
  457. ansible_aom-0.102.13/tests/unit/test_status_tally.py +85 -0
  458. ansible_aom-0.102.13/tests/unit/test_stderr_classifier.py +852 -0
  459. ansible_aom-0.102.13/tests/unit/test_task_completion.py +218 -0
  460. ansible_aom-0.102.13/tests/unit/test_template_variable_names.py +732 -0
  461. ansible_aom-0.102.13/tests/unit/test_tree_classify_and_role_labels.py +2309 -0
  462. ansible_aom-0.102.13/tests/unit/test_tree_meta_hostless.py +198 -0
  463. ansible_aom-0.102.13/tests/unit/test_tree_nested_role_order_stability.py +578 -0
  464. ansible_aom-0.102.13/tests/unit/test_tree_nested_roles.py +1272 -0
  465. ansible_aom-0.102.13/tests/unit/test_tree_projection.py +6576 -0
  466. ansible_aom-0.102.13/tests/unit/test_tree_ungrouped_roles.py +613 -0
  467. ansible_aom-0.102.13/tests/unit/test_verify_anchors.py +416 -0
  468. ansible_aom-0.102.13/tests/unit/test_version_consistency.py +47 -0
  469. ansible_aom-0.102.13/tests/unit/test_versioning.py +11 -0
  470. ansible_aom-0.102.13/tests/unit/test_warnings.py +315 -0
  471. ansible_aom-0.102.13/uv.lock +1874 -0
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+ # graphify-refresh: AST-only refresh of the knowledge graph artifacts.
3
+ #
4
+ # The graph is generated from the MAIN aom repo's source, so
5
+ # `graphify update .` / cluster-only / tree / export wiki run at the repo
6
+ # root. graphify writes its artifacts into graphify-out/, which is a git
7
+ # submodule owning its own repository — so the regenerated files live in
8
+ # that submodule repo and never pollute aom's PR diff.
9
+ #
10
+ # Flow:
11
+ # 1. Ensure the graphify-out submodule is checked out.
12
+ # 2. Regenerate artifacts from the main repo root (they land inside the
13
+ # submodule worktree).
14
+ # 3. Commit + push inside the submodule (best-effort).
15
+ # 4. Stage the updated submodule pointer (gitlink) in the superproject,
16
+ # so aom's diff stays a single line per regeneration.
17
+ # Skips gracefully if graphify-out/ is not initialized or the CLI is missing.
18
+ set -e
19
+
20
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo ".")"
21
+ cd "$REPO_ROOT"
22
+
23
+ if [ ! -d graphify-out ] || [ ! -f graphify-out/graph.json ]; then
24
+ echo "graphify-out/ not initialized, skipping graph refresh"
25
+ exit 0
26
+ fi
27
+
28
+ if ! command -v graphify >/dev/null 2>&1; then
29
+ echo "graphify CLI not found, skipping graph refresh"
30
+ exit 0
31
+ fi
32
+
33
+ # Ensure the submodule is populated so graphify-out is a real git repo.
34
+ git submodule update --init graphify-out 2>/dev/null || true
35
+
36
+ # Raise HTML viz node limit. Default (5000) is too small for this repo's
37
+ # ~12k-node graph. Override locally with `GRAPHIFY_VIZ_NODE_LIMIT=... git commit`.
38
+ export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-20000}"
39
+
40
+ # NixOS: graphify needs numpy which needs libstdc++.so.6.
41
+ # If it's not on the default LD_LIBRARY_PATH, try to add it.
42
+ if ! python3 -c "import numpy" 2>/dev/null; then
43
+ _LIBSTDCXX="$(gcc -print-file-name=libstdc++.so.6 2>/dev/null || true)"
44
+ if [ -n "$_LIBSTDCXX" ] && [ -f "$_LIBSTDCXX" ]; then
45
+ _LIBDIR="$(dirname "$_LIBSTDCXX")"
46
+ export LD_LIBRARY_PATH="${_LIBDIR}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
47
+ fi
48
+ fi
49
+
50
+ # Generate against the main repo source. Artifacts land in graphify-out/
51
+ # (the submodule worktree).
52
+ graphify install 2>/dev/null || true
53
+ graphify update . || exit 1
54
+ graphify cluster-only . 2>/dev/null || true
55
+ graphify tree 2>/dev/null || true
56
+
57
+ if [ -f graphify-out/graph.json ]; then
58
+ graphify export wiki 2>/dev/null || true
59
+ fi
60
+
61
+ # Commit + push the refreshed artifacts inside the submodule.
62
+ if git -C graphify-out rev-parse --git-dir >/dev/null 2>&1 \
63
+ && git -C graphify-out remote >/dev/null 2>&1; then
64
+ if ! git -C graphify-out diff --quiet; then
65
+ git -C graphify-out add -u \
66
+ graph.json \
67
+ .graphify_labels.json \
68
+ .graphify_analysis.json \
69
+ .graphify_semantic_marker \
70
+ GRAPH_TREE.html \
71
+ GRAPH_REPORT.md \
72
+ graph.html \
73
+ wiki/ 2>/dev/null || true
74
+ git -C graphify-out commit -m "chore: regenerate graph artifacts" >/dev/null 2>&1 || true
75
+ # Push is best-effort; a missing/denied remote must not fail the commit.
76
+ git -C graphify-out push 2>/dev/null \
77
+ || echo "graphify: submodule push skipped (no reachable remote)"
78
+ fi
79
+ else
80
+ echo "graphify: submodule repo/remote not present, artifacts left uncommitted"
81
+ fi
82
+
83
+ # Stage the updated submodule pointer (gitlink) in the superproject.
84
+ git add graphify-out 2>/dev/null || true
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ # Wrapper to invoke pre-commit from a custom git hooks path.
3
+ # Installed by the shell hook when global core.hooksPath is set to a
4
+ # non-default location; pre-commit itself cannot target a custom path.
5
+ exec pre-commit run --hook-stage pre-commit "$@"
@@ -0,0 +1,24 @@
1
+ ---
2
+ # ansible-lint config for AOM test playbooks
3
+ # These playbooks are intentionally minimal test fixtures for a monitoring tool,
4
+ # not production roles. Rules are lenient accordingly.
5
+
6
+ schema: basic
7
+
8
+ offline: true
9
+
10
+ warn_list:
11
+ - name[missing]
12
+ - name[casing]
13
+ - name[template]
14
+ - var-naming[no-role-prefix]
15
+
16
+ skip_list:
17
+ - no-changed-when # test tasks use debug/command intentionally
18
+ - no-handler # test playbooks don't need handler patterns
19
+ - risky-shell-pipe # test shell tasks are intentionally simple
20
+ - command-instead-of-shell # test tasks favor simplicity over best practice
21
+ - command-instead-of-module # test tasks use command for predictability
22
+
23
+ exclude_paths:
24
+ - tests/playbooks/32-large-playbook/ # generated playbook
@@ -0,0 +1,37 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv sync:*)",
5
+ "Bash(uv run:*)",
6
+ "Bash(uv pip:*)",
7
+ "Bash(git:*)",
8
+ "Bash(ansible-galaxy:*)",
9
+ "Bash(ansible-playbook:*)",
10
+ "Bash(mkdir:*)",
11
+ "Bash(rm:*)",
12
+ "Read",
13
+ "Write",
14
+ "Edit",
15
+ "Glob",
16
+ "Grep",
17
+ "WebSearch",
18
+ "WebFetch"
19
+ ]
20
+ },
21
+ "hooks": {
22
+ "PostToolUse": [
23
+ {
24
+ "matcher": "Edit|Write",
25
+ "hooks": [
26
+ {
27
+ "type": "command",
28
+ "command": "f=$(jq -r '.tool_input.file_path // .tool_response.filePath // empty'); case \"$f\" in *.py) uv run ruff format --check \"$f\" >/dev/null 2>&1 && uv run ruff check \"$f\" >/dev/null 2>&1 ;; esac"
29
+ }
30
+ ]
31
+ }
32
+ ]
33
+ },
34
+ "env": {
35
+ "ANSIBLE_STDOUT_CALLBACK": "ansible.posix.jsonl"
36
+ }
37
+ }
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: verify
3
+ description: How to verify aom compact-renderer changes end-to-end — run aom on a real playbook under a PTY, capture raw bytes, count DEC-2026 frames and log lines.
4
+ ---
5
+
6
+ # Verifying aom at the terminal surface
7
+
8
+ The compact renderer's surface is raw stdout bytes on a TTY. Unit tests
9
+ capture strings; real verification needs a PTY with a controlled size
10
+ and a capture of the raw escape-sequence stream.
11
+
12
+ ## Recipe
13
+
14
+ ```bash
15
+ # 1. A storm playbook (loop → rapid v2_runner_item_on_* events):
16
+ cat > /tmp/storm.yml <<'EOF'
17
+ - hosts: localhost
18
+ gather_facts: false
19
+ tasks:
20
+ - name: storm
21
+ ansible.builtin.debug: {msg: "item {{ item }}"}
22
+ loop: "{{ range(0, 120) | list }}"
23
+ EOF
24
+
25
+ # 2. Run under a PTY with forced size, capture raw bytes.
26
+ # `script` gives a real PTY; stty inside sets the winsize (without it
27
+ # the size is 0x0 → aom falls into degraded plain-log mode).
28
+ cd /tmp && script -qec "stty rows 40 cols 120; \
29
+ uv run --project /path/to/ansible-aom aom --no-record -y /tmp/storm.yml" \
30
+ /tmp/aom_raw.bin >/dev/null 2>&1
31
+
32
+ # 3. Analyze: frames = count of BSU (\x1b[?2026h); log lines via regex.
33
+ python3 -c "
34
+ data = open('/tmp/aom_raw.bin', 'rb').read().decode(errors='replace')
35
+ print('frames:', data.count('\x1b[?2026h'))
36
+ print('cursor restored:', '\x1b[?25h' in data)
37
+ "
38
+ ```
39
+
40
+ ## What to check
41
+
42
+ - **Frame budget**: log-batching caps repaints at ~30 Hz. A 120-item
43
+ storm finishing in ~1s should produce **~15–30 frames**, not 120+.
44
+ - **No lost/reordered lines**: every loop item appears exactly once, in
45
+ order. Items render as `ok: [localhost] => (item=N)`.
46
+ - **Cursor restored** (`\x1b[?25h`) and final status line present after
47
+ both clean completion and Ctrl-C.
48
+ - **Degraded mode**: `stty rows 10 cols 60` → "terminal too small"
49
+ warning, zero BSU frames, all log lines still printed plainly.
50
+
51
+ ## Gotchas
52
+
53
+ - **Ctrl-C probe**: send SIGINT to the *aom python process only*
54
+ (`ps -ef | grep bin/aom`), never `pkill -f` a pattern matching the
55
+ `uv run` wrapper — killing the wrapper skips aom's cleanup AND leaks
56
+ orphaned `ansible-playbook` children that keep running. Expect exit
57
+ 130 + `✖ cancelled by user` + cursor restore.
58
+ - `script` must run with cwd outside the repo or it happily works either
59
+ way, but the capture file lands wherever you point it; use /tmp.
60
+ - Known pre-existing quirks (don't blame your diff): loop item `0`
61
+ renders as `(item=)` (falsy-zero formatting), and localhost runs emit
62
+ a `[WARNING]: Callback dispatch 'v2_runner_on_start' failed for
63
+ plugin 'aom_connection'` warning.
@@ -0,0 +1 @@
1
+ use flake
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ # post-commit: fold repo-generated artifacts into the just-created commit.
3
+ #
4
+ # The pre-commit framework stashes-then-restores the working tree around
5
+ # its pre-commit hooks, silently rolling back any `git add` (and any
6
+ # nested submodule commit) a pre-commit hook performs — so neither the
7
+ # version bump nor the graphify submodule refresh can run there.
8
+ # post-commit runs after that machinery; each step folds its result into
9
+ # the commit via `git commit --amend` (env-guarded against recursion).
10
+ set -euo pipefail
11
+
12
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
13
+ cd "$REPO_ROOT"
14
+
15
+ if [ -x scripts/bump_version.py ]; then
16
+ AOM_BUMP_HOOK_RUNNING="${AOM_BUMP_HOOK_RUNNING:-}" uv run scripts/bump_version.py || true
17
+ fi
18
+
19
+ if [ -x .githooks/post-commit-graphify ]; then
20
+ .githooks/post-commit-graphify || true
21
+ fi
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env bash
2
+ # graphify-post-commit: refresh the knowledge graph AFTER a commit lands.
3
+ #
4
+ # Why post-commit + amend and not a pre-commit hook: the pre-commit
5
+ # framework stashes-then-restores the working tree around its pre-commit
6
+ # hooks, which silently rolls back both the graphify-out submodule commit
7
+ # and the gitlink `git add` this script performs. post-commit runs after
8
+ # that machinery is done, so the regeneration can safely commit the
9
+ # submodule and fold the new pointer into the same commit via
10
+ # `git commit --amend`.
11
+ #
12
+ # Only runs when the commit touched graph-relevant files (source, tests,
13
+ # docs, pyproject) so unrelated commits don't trigger a wasteful
14
+ # regeneration. Recursion from the amend is blocked by the
15
+ # AOM_GRAPHIFY_POST_COMMIT env var.
16
+ set -euo pipefail
17
+
18
+ if [ -n "${AOM_GRAPHIFY_POST_COMMIT:-}" ]; then
19
+ exit 0
20
+ fi
21
+
22
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || exit 0)"
23
+ cd "$REPO_ROOT"
24
+
25
+ if [ ! -d graphify-out ] || [ ! -f graphify-out/graph.json ]; then
26
+ exit 0
27
+ fi
28
+ if ! command -v graphify >/dev/null 2>&1; then
29
+ exit 0
30
+ fi
31
+
32
+ # Bail out mid-rebase / mid-merge / mid-cherry-pick — an amend during
33
+ # those would scramble the in-flight sequencing.
34
+ for marker in REBASE_HEAD MERGE_HEAD CHERRY_PICK_HEAD BISECT_LOG; do
35
+ if [ -f "$REPO_ROOT/.git/$marker" ]; then
36
+ exit 0
37
+ fi
38
+ done
39
+
40
+ # git sets GIT_DIR / GIT_INDEX_FILE when it runs hooks, which makes
41
+ # `git -C graphify-out ...` resolve the superproject's gitdir instead of
42
+ # the submodule's. Unset them so submodule commands address the right
43
+ # repo.
44
+ unset GIT_DIR GIT_INDEX_FILE GIT_WORK_TREE 2>/dev/null || true
45
+
46
+ # Only regenerate when HEAD touched graph-relevant files.
47
+ GRAPH_RELEVANT='^(src/.*\.py|tests/.*\.py|docs/.*\.md|ARCHITECTURE\.md|SPECIFICATION\.md|pyproject\.toml)$'
48
+ if ! git show --name-only --pretty=format: HEAD | grep -qE "$GRAPH_RELEVANT"; then
49
+ exit 0
50
+ fi
51
+
52
+ git submodule update --init graphify-out 2>/dev/null || true
53
+
54
+ export GRAPHIFY_VIZ_NODE_LIMIT="${GRAPHIFY_VIZ_NODE_LIMIT:-20000}"
55
+ if ! python3 -c "import numpy" 2>/dev/null; then
56
+ _LIBSTDCXX="$(gcc -print-file-name=libstdc++.so.6 2>/dev/null || true)"
57
+ if [ -n "$_LIBSTDCXX" ] && [ -f "$_LIBSTDCXX" ]; then
58
+ export LD_LIBRARY_PATH="$(dirname "$_LIBSTDCXX")${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
59
+ fi
60
+ fi
61
+
62
+ graphify install 2>/dev/null || true
63
+ graphify update . 2>/dev/null || true
64
+ graphify cluster-only . 2>/dev/null || true
65
+ graphify tree 2>/dev/null || true
66
+ [ -f graphify-out/graph.json ] && graphify export wiki 2>/dev/null || true
67
+
68
+ # Commit + push the refreshed artifacts inside the submodule.
69
+ if git -C graphify-out rev-parse --git-dir >/dev/null 2>&1 \
70
+ && git -C graphify-out remote >/dev/null 2>&1; then
71
+ if ! git -C graphify-out diff --quiet; then
72
+ # -u stages modified tracked artifacts; -A also picks up newly
73
+ # generated wiki pages so the submodule stays clean.
74
+ git -C graphify-out add -u graph.json .graphify_labels.json \
75
+ .graphify_analysis.json .graphify_semantic_marker GRAPH_TREE.html \
76
+ GRAPH_REPORT.md graph.html wiki/ 2>/dev/null || true
77
+ git -C graphify-out add -A wiki/ 2>/dev/null || true
78
+ git -C graphify-out commit -m "chore: regenerate graph artifacts" >/dev/null 2>&1 || true
79
+ # Submodules sit on a detached HEAD, so a bare `git push` pushes
80
+ # nothing. Push the detached HEAD explicitly to the main branch.
81
+ git -C graphify-out push origin HEAD:main 2>/dev/null \
82
+ || echo "graphify: submodule push skipped (no reachable remote)"
83
+ fi
84
+ fi
85
+
86
+ # Fold the new submodule pointer into the just-created commit. Guarded so
87
+ # the post-commit fire from the amend itself returns immediately.
88
+ if ! git -C "$REPO_ROOT" diff --quiet HEAD -- graphify-out; then
89
+ git -C "$REPO_ROOT" add graphify-out
90
+ AOM_GRAPHIFY_POST_COMMIT=1 \
91
+ git -C "$REPO_ROOT" commit --amend --no-edit --no-verify >/dev/null 2>&1 \
92
+ || true
93
+ fi
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # pre-commit hook: delegates to pre-commit framework
3
+ # See .pre-commit-config.yaml for configured hooks
4
+ set -e
5
+
6
+ echo "[pre-commit] running pre-commit checks..."
7
+ uv run pre-commit run "$@"
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env bash
2
+ # pre-push: run only the tests affected by what's being pushed.
3
+ #
4
+ # Two phases, deliberately asymmetric about the working tree:
5
+ #
6
+ # 1. SELECTION (~2-3s, tree briefly stashed): testmon --collect-only
7
+ # against the COMMITTED state. Everything — including untracked
8
+ # files — is stashed so concurrent agent sessions' WIP (red TDD
9
+ # tests, uncommitted fixes) can't leak into the selection. The
10
+ # stash is popped before any test runs.
11
+ #
12
+ # 2. EXECUTION (live tree, no stash): the selected node IDs run
13
+ # against the tree as-is, so a long test run never holds other
14
+ # sessions' files hostage. testmon stays enabled so .testmondata
15
+ # keeps draining; it may further deselect tests already proven
16
+ # green on byte-identical code (testmon always re-selects prior
17
+ # failures, so a deselect implies a prior pass).
18
+ #
19
+ # pytest intentionally does NOT live in .pre-commit-config.yaml's
20
+ # pre-push stage: the pre-commit framework stashes tracked-but-not-
21
+ # untracked files around the WHOLE hook run, which both races
22
+ # concurrent sessions and produces false failures (a session's
23
+ # untracked red test stays visible while its uncommitted fix is
24
+ # stashed away).
25
+ #
26
+ # --no-cov (not -p no:cov): keeps pytest-cov loaded so addopts'
27
+ # --cov-fail-under still parses, while stopping the coverage
28
+ # measurement that silently breaks testmon's DB updates.
29
+ set -euo pipefail
30
+ cd "$(git rev-parse --show-toplevel)"
31
+
32
+ PYTEST=(uv run --extra dev --extra integration pytest --testmon --no-cov -q)
33
+
34
+ # --- phase 1: selection against committed state -----------------------
35
+ stashed=0
36
+ restore_tree() {
37
+ if (( stashed )); then
38
+ stashed=0
39
+ # --index also restores staged-ness; plain pop is the fallback
40
+ # (content preserved, index state lost).
41
+ git stash pop --index --quiet 2>/dev/null \
42
+ || git stash pop --quiet \
43
+ || {
44
+ echo "pre-push: FAILED to restore stashed WIP — recover it" \
45
+ "from 'git stash list' (pre-push-test-selection)" >&2
46
+ return 1
47
+ }
48
+ fi
49
+ }
50
+ trap restore_tree EXIT
51
+
52
+ # Git exports GIT_DIR / GIT_INDEX_FILE etc. into hook processes; strip them
53
+ # now that we're in the worktree root so pytest fixtures spawning `git` in
54
+ # temp directories cannot accidentally target the real repository.
55
+ unset "${!GIT_@}"
56
+
57
+ if [[ -n "$(git status --porcelain)" ]]; then
58
+ git stash push --include-untracked --quiet -m "pre-push-test-selection"
59
+ stashed=1
60
+ fi
61
+
62
+ collect_rc=0
63
+ collected="$("${PYTEST[@]}" tests/ --collect-only -n0 2>&1)" || collect_rc=$?
64
+ restore_tree # pop as soon as selection is done; the trap stays as backstop
65
+
66
+ # exit 5 = "no tests collected" = nothing affected. Anything else
67
+ # non-zero is a real collection error in the committed state: block.
68
+ if (( collect_rc != 0 && collect_rc != 5 )); then
69
+ echo "$collected" >&2
70
+ echo "pre-push: test collection failed against the committed state" >&2
71
+ exit "$collect_rc"
72
+ fi
73
+
74
+ mapfile -t selected < <(grep -E '^tests/.*::' <<<"$collected" || true)
75
+ if (( ${#selected[@]} == 0 )); then
76
+ echo "pre-push: no tests affected by the pushed changes"
77
+ exit 0
78
+ fi
79
+
80
+ # --- phase 2: run the selection against the live tree -----------------
81
+ echo "pre-push: running ${#selected[@]} affected test(s) against the live tree"
82
+ run_rc=0
83
+ "${PYTEST[@]}" --tb=short "${selected[@]}" || run_rc=$?
84
+ # exit 5 here means testmon deselected everything we passed in — all of
85
+ # it already passed on identical code. That is a pass.
86
+ if (( run_rc == 5 )); then run_rc=0; fi
87
+ exit "$run_rc"
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "uv"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+
8
+ - package-ecosystem: "nix"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+
13
+ - package-ecosystem: "github-actions"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
@@ -0,0 +1,80 @@
1
+ # CI workflow for ansible-aom
2
+ # Runs lint (ruff) → type-check (mypy) → test (pytest with xdist)
3
+ # on push to main/master and on every pull_request (incl. stacked PRs
4
+ # whose base is another feature branch).
5
+ #
6
+ # Uses uv for Python dependency management (matching the project's
7
+ # existing tooling). Python 3.14 only — no matrix builds.
8
+
9
+ name: CI
10
+
11
+ env:
12
+ UV_LOCKED: "true"
13
+
14
+ on:
15
+ push:
16
+ branches: [main, master]
17
+ pull_request:
18
+
19
+ jobs:
20
+ ci:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v7
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v7
29
+
30
+ - name: Set up Python 3.14
31
+ uses: actions/setup-python@v7
32
+ with:
33
+ python-version: "3.14"
34
+
35
+ - name: Install dependencies
36
+ run: uv sync --all-extras --group release
37
+
38
+ - name: Check software version bump
39
+ run: uv run --no-sync python scripts/check_version_bump.py
40
+
41
+ - name: Lint (ruff format check)
42
+ run: uv run --no-sync ruff format --check src/
43
+
44
+ - name: Lint (ruff check)
45
+ run: uv run --no-sync ruff check src/
46
+
47
+ - name: Type-check (mypy)
48
+ run: uv run --no-sync mypy src/ansible_aom
49
+
50
+ - name: Test (pytest with xdist)
51
+ run: uv run --no-sync pytest tests/unit tests/compact tests/tui -q -n auto
52
+
53
+ - name: Build distributions
54
+ run: uv build --no-build-isolation
55
+
56
+ - name: Validate distributions
57
+ run: |
58
+ uv run --no-sync twine check dist/*
59
+ python -m venv /tmp/aom-ci-smoke
60
+ /tmp/aom-ci-smoke/bin/python -m pip install dist/*.whl
61
+ cd /tmp
62
+ /tmp/aom-ci-smoke/bin/aom --version
63
+ /tmp/aom-ci-smoke/bin/aom --help >/dev/null
64
+ /tmp/aom-ci-smoke/bin/python -c 'from pathlib import Path; import ansible_aom.ansible.runner as r; assert (Path(r.__file__).parent / "callback" / "aom_jsonl.py").is_file()'
65
+
66
+ nix:
67
+ runs-on: ubuntu-24.04
68
+ permissions:
69
+ contents: read
70
+ steps:
71
+ - uses: actions/checkout@v7
72
+ - uses: cachix/install-nix-action@v31
73
+ - name: Build Nix package
74
+ run: nix build .#default --no-update-lock-file
75
+ - name: Validate Nix package
76
+ run: |
77
+ ./result/bin/aom --version
78
+ ./result/bin/aom --help >/dev/null
79
+ - name: Evaluate development shell
80
+ run: nix eval --raw .#devShells.x86_64-linux.default.drvPath --no-update-lock-file
@@ -0,0 +1,135 @@
1
+ name: Release
2
+
3
+ env:
4
+ UV_LOCKED: "true"
5
+
6
+ on:
7
+ push:
8
+ branches:
9
+ - main
10
+ tags:
11
+ - "v*"
12
+
13
+ jobs:
14
+ check:
15
+ runs-on: ubuntu-24.04
16
+ outputs:
17
+ should_release: ${{ steps.evaluate.outputs.should_release }}
18
+ tag: ${{ steps.evaluate.outputs.tag }}
19
+ version: ${{ steps.evaluate.outputs.version }}
20
+ steps:
21
+ - uses: actions/checkout@v7
22
+ with:
23
+ fetch-depth: 0
24
+ - uses: actions/setup-python@v7
25
+ with:
26
+ python-version: "3.14"
27
+ - name: Evaluate release trigger
28
+ id: evaluate
29
+ run: python scripts/check_version_bump.py --check-release
30
+
31
+ build:
32
+ needs: check
33
+ if: needs.check.outputs.should_release == 'true'
34
+ runs-on: ubuntu-24.04
35
+ permissions:
36
+ contents: read
37
+ outputs:
38
+ tag: ${{ steps.validate.outputs.tag }}
39
+ version: ${{ steps.validate.outputs.version }}
40
+ steps:
41
+ - uses: actions/checkout@v7
42
+ - uses: actions/setup-python@v7
43
+ with:
44
+ python-version: "3.14"
45
+ - uses: astral-sh/setup-uv@v7
46
+ - name: Validate tag and project version
47
+ id: validate
48
+ env:
49
+ RELEASE_TAG: ${{ needs.check.outputs.tag || github.ref_name }}
50
+ run: |
51
+ python - <<'PY'
52
+ import os
53
+ import re
54
+ import tomllib
55
+ from pathlib import Path
56
+
57
+ tag = os.environ["RELEASE_TAG"]
58
+ if not re.fullmatch(r"v\d+\.\d+\.\d+", tag):
59
+ raise SystemExit(f"invalid release tag: {tag!r}; expected vX.Y.Z")
60
+ version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"]
61
+ if tag[1:] != version:
62
+ raise SystemExit(f"tag {tag} does not match project version {version}")
63
+ print(f"Releasing ansible-aom {version} ({tag})")
64
+ if "GITHUB_OUTPUT" in os.environ:
65
+ with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
66
+ f.write(f"tag={tag}\n")
67
+ f.write(f"version={version}\n")
68
+ PY
69
+ - name: Install locked runtime and release tools
70
+ run: uv sync --no-default-groups --group release --no-install-project
71
+ - name: Build Python distributions
72
+ run: uv build --no-build-isolation
73
+ - name: Validate Python distributions
74
+ run: |
75
+ uv run --no-sync twine check dist/*
76
+ python -m venv /tmp/aom-wheel-smoke
77
+ /tmp/aom-wheel-smoke/bin/python -m pip install dist/*.whl
78
+ cd /tmp
79
+ /tmp/aom-wheel-smoke/bin/aom --version
80
+ /tmp/aom-wheel-smoke/bin/aom --help >/dev/null
81
+ /tmp/aom-wheel-smoke/bin/python -c 'from pathlib import Path; import ansible_aom.ansible.runner as r; assert (Path(r.__file__).parent / "callback" / "aom_jsonl.py").is_file()'
82
+ - name: Build Linux standalone bundle
83
+ run: |
84
+ uv pip install --no-deps dist/*.whl
85
+ uv run --no-sync pyinstaller --clean --noconfirm --distpath build-dist --workpath build-work packaging/aom.spec
86
+ test -x build-dist/aom/aom
87
+ tar -C build-dist -czf dist/aom-linux-x86_64.tar.gz aom
88
+ - name: Validate standalone bundle
89
+ run: |
90
+ test -f build-dist/aom/aom
91
+ test -f build-dist/aom/_internal/ansible_aom/ansible/callback/aom_jsonl.py
92
+ test -f build-dist/aom/_internal/ansible_aom/callbacks/aom_connection.py
93
+ test -f build-dist/aom/_internal/ansible_aom/core/default_config.yaml
94
+ build-dist/aom/aom --version
95
+ build-dist/aom/aom --help >/dev/null
96
+ - uses: actions/upload-artifact@v7
97
+ with:
98
+ name: release-artifacts
99
+ path: dist/
100
+ if-no-files-found: error
101
+
102
+ github-release:
103
+ needs: [check, build]
104
+ runs-on: ubuntu-24.04
105
+ permissions:
106
+ contents: write
107
+ steps:
108
+ - uses: actions/download-artifact@v8
109
+ with:
110
+ name: release-artifacts
111
+ path: dist
112
+ - name: Create GitHub Release
113
+ env:
114
+ GH_TOKEN: ${{ github.token }}
115
+ GH_REPO: ${{ github.repository }}
116
+ run: gh release create "${{ needs.build.outputs.tag || needs.check.outputs.tag }}" dist/* --generate-notes --target "${{ github.sha }}"
117
+
118
+ pypi:
119
+ needs: [check, build]
120
+ runs-on: ubuntu-24.04
121
+ permissions:
122
+ id-token: write
123
+ environment:
124
+ name: pypi
125
+ url: https://pypi.org/p/ansible-aom
126
+ steps:
127
+ - uses: actions/download-artifact@v8
128
+ with:
129
+ name: release-artifacts
130
+ path: dist
131
+ - name: Keep only Python distributions
132
+ run: rm dist/aom-linux-x86_64.tar.gz
133
+ - uses: pypa/gh-action-pypi-publish@release/v1
134
+ with:
135
+ packages-dir: dist