agentic-dev-loop 0.12.3__tar.gz → 0.13.0__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 (151) hide show
  1. {agentic_dev_loop-0.12.3/src/agentic_dev_loop.egg-info → agentic_dev_loop-0.13.0}/PKG-INFO +6 -1
  2. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/README.md +5 -0
  3. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/pyproject.toml +1 -1
  4. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/cli.py +67 -0
  5. agentic_dev_loop-0.13.0/src/agentic_dev_loop/reporting/__init__.py +43 -0
  6. agentic_dev_loop-0.13.0/src/agentic_dev_loop/reporting/metrics.py +593 -0
  7. agentic_dev_loop-0.13.0/src/agentic_dev_loop/reporting/render.py +175 -0
  8. agentic_dev_loop-0.13.0/src/agentic_dev_loop/reporting/sources.py +770 -0
  9. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0/src/agentic_dev_loop.egg-info}/PKG-INFO +6 -1
  10. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop.egg-info/SOURCES.txt +5 -0
  11. agentic_dev_loop-0.13.0/tests/test_unit12_reporting.py +309 -0
  12. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/LICENSE +0 -0
  13. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/setup.cfg +0 -0
  14. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/__init__.py +0 -0
  15. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/__init__.py +0 -0
  16. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/config.py +0 -0
  17. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/failure.py +0 -0
  18. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/paths.py +0 -0
  19. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/profiles/__init__.py +0 -0
  20. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/profiles/data/dotnet-node.yaml +0 -0
  21. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/profiles/data/python.yaml +0 -0
  22. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/results.py +0 -0
  23. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/core/verdict.py +0 -0
  24. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/__init__.py +0 -0
  25. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/actions.py +0 -0
  26. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/agent_error_guide.md +0 -0
  27. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/agent_error_guide.py +0 -0
  28. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/agents.py +0 -0
  29. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/allowlist.py +0 -0
  30. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/brief_coverage.py +0 -0
  31. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/brief_prompt.md +0 -0
  32. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/brief_prompt.py +0 -0
  33. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/completion.py +0 -0
  34. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/containers.py +0 -0
  35. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/copilot_auth.py +0 -0
  36. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/deps.py +0 -0
  37. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/dryrun.py +0 -0
  38. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/egress_policy.py +0 -0
  39. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/egress_proxy.py +0 -0
  40. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/extensions/__init__.py +0 -0
  41. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/extensions/aidlc.py +0 -0
  42. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/forbidden.py +0 -0
  43. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/graph.py +0 -0
  44. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/hostboundary.py +0 -0
  45. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/isolation.py +0 -0
  46. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/llm.py +0 -0
  47. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/loaders.py +0 -0
  48. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/mounts.py +0 -0
  49. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/__init__.py +0 -0
  50. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/checks.py +0 -0
  51. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/doctor.py +0 -0
  52. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/init.py +0 -0
  53. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/recipes/dotnet-node.yaml +0 -0
  54. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/recipes/python.yaml +0 -0
  55. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/recipes.py +0 -0
  56. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates/dev.agent.md +0 -0
  57. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates/env.example +0 -0
  58. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates/qa.agent.md +0 -0
  59. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates/review.agent.md +0 -0
  60. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates/trigger-agentic-dev-loop.sh +0 -0
  61. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/templates.py +0 -0
  62. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/onboarding/upgrade.py +0 -0
  63. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/outputs.py +0 -0
  64. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/presets.py +0 -0
  65. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/proc.py +0 -0
  66. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/provider_wire.py +0 -0
  67. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/registry.py +0 -0
  68. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/run_status.py +0 -0
  69. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/run_status_command.md +0 -0
  70. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/seccomp/__init__.py +0 -0
  71. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/seccomp/chromium-userns.json +0 -0
  72. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/secrets.py +0 -0
  73. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/stages.py +0 -0
  74. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/step_workspace.py +0 -0
  75. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/engine/sync_back.py +0 -0
  76. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/py.typed +0 -0
  77. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/viz/__init__.py +0 -0
  78. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/viz/__main__.py +0 -0
  79. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/viz/layout.py +0 -0
  80. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/viz/page.py +0 -0
  81. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop/viz/server.py +0 -0
  82. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop.egg-info/dependency_links.txt +0 -0
  83. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop.egg-info/entry_points.txt +0 -0
  84. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop.egg-info/requires.txt +0 -0
  85. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/src/agentic_dev_loop.egg-info/top_level.txt +0 -0
  86. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_029_merge_on_conflict.py +0 -0
  87. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_033_brief_step.py +0 -0
  88. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_035_finalize_nudge.py +0 -0
  89. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_036_banned_commands_and_lane_boundary.py +0 -0
  90. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_041_brief_coverage.py +0 -0
  91. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_046_brief_prompt.py +0 -0
  92. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_cli.py +0 -0
  93. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_doctor.py +0 -0
  94. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_init.py +0 -0
  95. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_profile_loading.py +0 -0
  96. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_profiles.py +0 -0
  97. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_recipes.py +0 -0
  98. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_schema_lock.py +0 -0
  99. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_templates.py +0 -0
  100. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_055_upgrade.py +0 -0
  101. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_actions.py +0 -0
  102. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_agent_error_guide.py +0 -0
  103. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_agents.py +0 -0
  104. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_aidlc.py +0 -0
  105. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_build_viz_page.py +0 -0
  106. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_cli.py +0 -0
  107. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_config.py +0 -0
  108. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_containers.py +0 -0
  109. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_copilot_auth.py +0 -0
  110. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_copilot_cli.py +0 -0
  111. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_deps.py +0 -0
  112. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_dry_run.py +0 -0
  113. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_e2e_fixtures.py +0 -0
  114. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_egress_proxy.py +0 -0
  115. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_graph.py +0 -0
  116. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_hostboundary.py +0 -0
  117. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_hostboundary_integration.py +0 -0
  118. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_isolation.py +0 -0
  119. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_isolation_integration.py +0 -0
  120. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_isolation_pbt.py +0 -0
  121. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_llm.py +0 -0
  122. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_loaders.py +0 -0
  123. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_module_contract.py +0 -0
  124. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_outputs.py +0 -0
  125. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_outputs_pbt.py +0 -0
  126. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_proc.py +0 -0
  127. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_provider_wire.py +0 -0
  128. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_publish.py +0 -0
  129. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_qa_prompt.py +0 -0
  130. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_registry.py +0 -0
  131. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_repo_ascii.py +0 -0
  132. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_results.py +0 -0
  133. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_run_status.py +0 -0
  134. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_sdk_compat.py +0 -0
  135. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_secrets.py +0 -0
  136. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_secrets_integration.py +0 -0
  137. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_secrets_pipeline.py +0 -0
  138. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_source_resolution.py +0 -0
  139. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_stages.py +0 -0
  140. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_step_workspace.py +0 -0
  141. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_sync_back.py +0 -0
  142. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_trigger_script.py +0 -0
  143. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_unit11.py +0 -0
  144. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_unit11_pbt.py +0 -0
  145. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_unit5_config.py +0 -0
  146. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_unit5_pbt.py +0 -0
  147. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_unit5_pure.py +0 -0
  148. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_verdict.py +0 -0
  149. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_viz.py +0 -0
  150. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_viz_demo.py +0 -0
  151. {agentic_dev_loop-0.12.3 → agentic_dev_loop-0.13.0}/tests/test_viz_layout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-dev-loop
3
- Version: 0.12.3
3
+ Version: 0.13.0
4
4
  Summary: Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase.
5
5
  Author: Luke Wilson
6
6
  License-Expression: Apache-2.0
@@ -136,6 +136,11 @@ Other commands:
136
136
  mermaid flowchart with the current step highlighted, reading the run-state
137
137
  checkpoint database directly. `run-status --install` installs the bundled
138
138
  `/run-status` command into OpenCode.
139
+ - `agentic-dev-loop report [<run-id>]` renders accumulated run history as
140
+ ASCII markdown: an aggregate dashboard by default (loop health, TDD,
141
+ review, and QA metrics with provenance labels) or a deep dive for one
142
+ 12-hex run directory. `--since` / `--until` / `--status` filter the set.
143
+ Reporting is strictly read-only.
139
144
  - `agentic-dev-loop containers` inspects the engine's sandbox containers and
140
145
  networks from the host; `containers --reap` removes registry-owned orphans
141
146
  whose owner process is dead. A SIGTERM to a running pipeline still closes
@@ -91,6 +91,11 @@ Other commands:
91
91
  mermaid flowchart with the current step highlighted, reading the run-state
92
92
  checkpoint database directly. `run-status --install` installs the bundled
93
93
  `/run-status` command into OpenCode.
94
+ - `agentic-dev-loop report [<run-id>]` renders accumulated run history as
95
+ ASCII markdown: an aggregate dashboard by default (loop health, TDD,
96
+ review, and QA metrics with provenance labels) or a deep dive for one
97
+ 12-hex run directory. `--since` / `--until` / `--status` filter the set.
98
+ Reporting is strictly read-only.
94
99
  - `agentic-dev-loop containers` inspects the engine's sandbox containers and
95
100
  networks from the host; `containers --reap` removes registry-owned orphans
96
101
  whose owner process is dead. A SIGTERM to a running pipeline still closes
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agentic-dev-loop"
7
- version = "0.12.3"
7
+ version = "0.13.0"
8
8
  description = "Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -206,6 +206,71 @@ def _run_copilot_models(argv: list[str]) -> int:
206
206
  return 0
207
207
 
208
208
 
209
+ def _report_parser() -> argparse.ArgumentParser:
210
+ parser = argparse.ArgumentParser(
211
+ prog="agentic-dev-loop report",
212
+ description="Report accumulated agentic-dev-loop run history as "
213
+ "read-only markdown.")
214
+ parser.add_argument("run_id", nargs="?", default=None,
215
+ help="12-hex run dir name for a deep dive "
216
+ "(default: aggregate report)")
217
+ parser.add_argument("--since", default=None,
218
+ help="only threads starting at or after this ISO "
219
+ "datetime")
220
+ parser.add_argument("--until", default=None,
221
+ help="only threads starting before this ISO datetime")
222
+ parser.add_argument("--status", action="append", default=None,
223
+ help="filter by status (success/failed/interrupted/"
224
+ "running); repeatable or comma-separated")
225
+ parser.add_argument("--runs-root", default=None,
226
+ help="runs root (default: $AGENTIC_DEV_LOOP_RUNS_ROOT "
227
+ "or ~/.agentic-dev-loop/runs)")
228
+ parser.add_argument("--audit-dir", "--state-dir", dest="audit_dir",
229
+ default=None,
230
+ help="sandbox audit dir (default: "
231
+ "$AGENTIC_DEV_LOOP_STATE_DIR or "
232
+ "~/.agentic-dev-loop/state)")
233
+ return parser
234
+
235
+
236
+ def _run_report(argv: list[str]) -> int:
237
+ from agentic_dev_loop.reporting import (
238
+ apply_filters, build_run_records, discover, find_run_dir,
239
+ pure_metrics, read_audit, read_dir, render_markdown, runs_root)
240
+
241
+ args = _report_parser().parse_args(argv)
242
+ root = runs_root(args.runs_root)
243
+ notice = None
244
+ if args.run_id is not None:
245
+ run_dir = find_run_dir(args.run_id, root)
246
+ if run_dir is None:
247
+ print(f"report: unknown run id: {args.run_id}", file=sys.stderr)
248
+ return 1
249
+ dirs = [run_dir]
250
+ else:
251
+ dirs = discover(root)
252
+ if not root.is_dir():
253
+ notice = f"runs root not found: {root}"
254
+ audit_pool = read_audit(args.audit_dir)
255
+ records = build_run_records([read_dir(path) for path in dirs], audit_pool)
256
+ filters = {key: getattr(args, key)
257
+ for key in ("since", "until", "status") if getattr(args, key)}
258
+ try:
259
+ records = apply_filters(
260
+ records, since=args.since, until=args.until,
261
+ statuses=args.status)
262
+ except ValueError as exc:
263
+ print(f"report: {exc}", file=sys.stderr)
264
+ return 1
265
+ if not records and notice is None:
266
+ notice = "no runs recorded" if not dirs else "no runs matched filters"
267
+ metrics = pure_metrics(records)
268
+ sys.stdout.write(render_markdown(
269
+ records, metrics, deep_dive=args.run_id is not None,
270
+ filters=filters, notice=notice))
271
+ return 0
272
+
273
+
209
274
  def build_parser(cfg_path) -> argparse.ArgumentParser:
210
275
  """The full parser for one pipeline: core flags + loader-contributed."""
211
276
  registry, _ = _registry_for(cfg_path)
@@ -226,6 +291,8 @@ def main(argv: list[str] | None = None, *, keep_alive: bool = True) -> int:
226
291
  return _run_copilot_login(argv[1:])
227
292
  if argv and argv[0] == "copilot-models":
228
293
  return _run_copilot_models(argv[1:])
294
+ if argv and argv[0] == "report":
295
+ return _run_report(argv[1:])
229
296
  if argv and argv[0] == "run-status":
230
297
  from .run_status import _run_status
231
298
  return _run_status(argv[1:])
@@ -0,0 +1,43 @@
1
+ """Read-only run-history reporting (unit 12)."""
2
+
3
+ from .metrics import Metric, apply_filters, pure_metrics
4
+ from .render import render_markdown
5
+ from .sources import (
6
+ AuditRecord,
7
+ Attempt,
8
+ DirData,
9
+ ProseFacts,
10
+ RunRecord,
11
+ StepVerdict,
12
+ audit_dir,
13
+ build_run_records,
14
+ discover,
15
+ find_run_dir,
16
+ is_test_command,
17
+ parse_ts,
18
+ read_audit,
19
+ read_dir,
20
+ runs_root,
21
+ )
22
+
23
+ __all__ = [
24
+ "AuditRecord",
25
+ "Attempt",
26
+ "DirData",
27
+ "Metric",
28
+ "ProseFacts",
29
+ "RunRecord",
30
+ "StepVerdict",
31
+ "apply_filters",
32
+ "audit_dir",
33
+ "build_run_records",
34
+ "discover",
35
+ "find_run_dir",
36
+ "is_test_command",
37
+ "parse_ts",
38
+ "pure_metrics",
39
+ "read_audit",
40
+ "read_dir",
41
+ "render_markdown",
42
+ "runs_root",
43
+ ]