agentic-dev-loop 0.14.5__tar.gz → 0.15.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.
- {agentic_dev_loop-0.14.5/src/agentic_dev_loop.egg-info → agentic_dev_loop-0.15.0}/PKG-INFO +31 -25
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/README.md +30 -24
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/pyproject.toml +1 -1
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/cli.py +169 -20
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/hostboundary.py +1 -2
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/doctor.py +8 -4
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/init.py +10 -12
- agentic_dev_loop-0.15.0/src/agentic_dev_loop/engine/onboarding/templates/env.example +13 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/templates.py +1 -1
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/upgrade.py +8 -4
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/run_status.py +6 -2
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/viz/runs_view.py +11 -7
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/viz/server.py +21 -6
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0/src/agentic_dev_loop.egg-info}/PKG-INFO +31 -25
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop.egg-info/SOURCES.txt +0 -3
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_init.py +1 -1
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_templates.py +0 -22
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_cli.py +189 -11
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_hostboundary.py +2 -3
- agentic_dev_loop-0.15.0/tests/test_source_resolution.py +36 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit12_reporting.py +66 -6
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_viz_demo.py +1 -1
- agentic_dev_loop-0.14.5/src/agentic_dev_loop/engine/onboarding/templates/env.example +0 -11
- agentic_dev_loop-0.14.5/src/agentic_dev_loop/engine/onboarding/templates/trigger-agentic-dev-loop.sh +0 -97
- agentic_dev_loop-0.14.5/src/agentic_dev_loop/viz/__main__.py +0 -59
- agentic_dev_loop-0.14.5/tests/test_source_resolution.py +0 -62
- agentic_dev_loop-0.14.5/tests/test_trigger_script.py +0 -306
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/LICENSE +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/setup.cfg +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/config.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/failure.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/paths.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/profiles/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/profiles/data/dotnet-node.yaml +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/profiles/data/python.yaml +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/results.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/core/verdict.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/actions.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/agent_error_guide.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/agent_error_guide.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/agents.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/allowlist.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/brief_coverage.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/brief_prompt.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/brief_prompt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/completion.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/containers.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/copilot_auth.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/deps.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/dryrun.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/egress_policy.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/egress_proxy.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/extensions/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/extensions/aidlc.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/forbidden.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/graph.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/isolation.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/llm.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/loaders.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/mounts.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/checks.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/recipes/dotnet-node.yaml +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/recipes/python.yaml +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/recipes.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/templates/dev.agent.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/templates/qa.agent.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/templates/review.agent.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/outputs.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/presets.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/proc.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/provider_wire.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/registry.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/run_status_command.md +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/seccomp/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/seccomp/chromium-userns.json +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/secrets.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/stages.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/step_workspace.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/sync_back.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/py.typed +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/reporting/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/reporting/metrics.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/reporting/render.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/reporting/sources.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/viz/__init__.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/viz/layout.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/viz/page.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop.egg-info/dependency_links.txt +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop.egg-info/entry_points.txt +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop.egg-info/requires.txt +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop.egg-info/top_level.txt +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_029_merge_on_conflict.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_033_brief_step.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_035_finalize_nudge.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_036_banned_commands_and_lane_boundary.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_041_brief_coverage.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_046_brief_prompt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_cli.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_doctor.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_profile_loading.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_profiles.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_recipes.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_schema_lock.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_055_upgrade.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_actions.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_agent_error_guide.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_agents.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_aidlc.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_build_viz_page.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_config.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_containers.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_copilot_auth.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_copilot_cli.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_deps.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_dry_run.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_e2e_fixtures.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_egress_proxy.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_graph.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_hostboundary_integration.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_isolation.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_isolation_integration.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_isolation_pbt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_llm.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_loaders.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_module_contract.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_outputs.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_outputs_pbt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_proc.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_provider_wire.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_publish.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_qa_prompt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_registry.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_repo_ascii.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_results.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_run_status.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_runs_js_filters.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_runs_js_key_stats.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_runs_js_metrics.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_runs_layout.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_runs_layout_key_stats.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_sdk_compat.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_secrets.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_secrets_integration.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_secrets_pipeline.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_stages.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_step_workspace.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_sync_back.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit11.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit11_pbt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit13_runs_viz.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit5_config.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit5_pbt.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_unit5_pure.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_verdict.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/tests/test_viz.py +0 -0
- {agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.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.
|
|
3
|
+
Version: 0.15.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
|
|
@@ -126,8 +126,13 @@ agentic-dev-loop agentic-dev-loop/pipeline.yaml # run it
|
|
|
126
126
|
| `--dry-run` | Full load-and-validate pass, then print the resolved plan. No LLM, no Docker, no state writes, no API key. Exit `0` on a clean load. |
|
|
127
127
|
| `--resume <thread-id>` | Continue the latest checkpoint of a previous run (crash, Ctrl-C, exhaustion) with all accumulated notes intact. |
|
|
128
128
|
| `--max-attempts <n>` | Override the pipeline's `max_attempts`. |
|
|
129
|
+
| `--env <file>` | Load secrets from a host env file outside the workspace. Optional: the process environment is the default, a named-but-missing file is a loud error, and values already set in the environment win. |
|
|
129
130
|
| `--no-viz` / `--viz-port <port>` | Suppress the live graph view / set a preferred port (default 8321; falls back to a free port when busy). |
|
|
130
131
|
|
|
132
|
+
`PIPELINE` is optional and defaults to `agentic-dev-loop/pipeline.yaml`
|
|
133
|
+
(relative to the current directory). Run flags without a positional use that
|
|
134
|
+
default; a missing default fails loudly instead of falling back.
|
|
135
|
+
|
|
131
136
|
Exit code is `0` on pipeline success, `1` otherwise.
|
|
132
137
|
|
|
133
138
|
Other commands:
|
|
@@ -136,18 +141,19 @@ Other commands:
|
|
|
136
141
|
mermaid flowchart with the current step highlighted, reading the run-state
|
|
137
142
|
checkpoint database directly. `run-status --install` installs the bundled
|
|
138
143
|
`/run-status` command into OpenCode.
|
|
139
|
-
- `agentic-dev-loop report
|
|
140
|
-
|
|
144
|
+
- `agentic-dev-loop report` serves the **historical runs view** in the
|
|
145
|
+
browser (default port 8321, falling back to a free port when busy; blocks
|
|
146
|
+
until ctrl+c and prints the URL). It reads the same run records as the
|
|
147
|
+
markdown report and lists past runs with since / until / status filters,
|
|
148
|
+
an aggregate metrics panel, and a per-run detail page carrying the brief,
|
|
149
|
+
implementation summary, review findings, and QA report. The live viz also
|
|
150
|
+
links to it from the **History** button in the graph page header (or
|
|
151
|
+
`/runs`).
|
|
152
|
+
- `agentic-dev-loop report --markdown [<run-id>]` renders the same history
|
|
153
|
+
as ASCII markdown instead: an aggregate dashboard (loop health, TDD,
|
|
141
154
|
review, and QA metrics with provenance labels) or a deep dive for one
|
|
142
155
|
12-hex run directory. `--since` / `--until` / `--status` filter the set.
|
|
143
|
-
|
|
144
|
-
- The live viz also serves a **historical runs view**: click **History** in
|
|
145
|
-
the graph page header (or open `/runs`), or launch it standalone with
|
|
146
|
-
`python -m agentic_dev_loop.viz --history`, which needs no pipeline file
|
|
147
|
-
(default port 8321, falling back to a free port when busy). It lists past
|
|
148
|
-
runs with since / until / status filters, an aggregate metrics panel, and
|
|
149
|
-
a per-run detail page carrying the brief, implementation summary, review
|
|
150
|
-
findings, and QA report.
|
|
156
|
+
`--markdown` cannot be combined with `--port`.
|
|
151
157
|
- `agentic-dev-loop containers` inspects the engine's sandbox containers and
|
|
152
158
|
networks from the host; `containers --reap` removes registry-owned orphans
|
|
153
159
|
whose owner process is dead. A SIGTERM to a running pipeline still closes
|
|
@@ -489,20 +495,20 @@ agentic-dev-loop init --profile python # or: --profile dotnet-node
|
|
|
489
495
|
```
|
|
490
496
|
|
|
491
497
|
`init` writes the onboarding surface from a bundled toolchain profile:
|
|
492
|
-
`agentic-dev-loop/pipeline.yaml`, the three agent files,
|
|
493
|
-
`
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
hard failures abort the run (engine pin mismatch, engine runtime
|
|
498
|
+
`agentic-dev-loop/pipeline.yaml`, the three agent files,
|
|
499
|
+
`agentic-dev-loop/.engine-version` (the exact installed engine version), any
|
|
500
|
+
missing premise files, gitignore additions, and an env-file template. It
|
|
501
|
+
detects solution files, `package.json` directories, lockfiles, README, and
|
|
502
|
+
AGENTS.md, asks only what detection cannot answer, and refuses to overwrite
|
|
503
|
+
an existing `agentic-dev-loop/` directory. A consumer-authored profile file
|
|
504
|
+
can be passed by path instead of a bundled name.
|
|
505
|
+
|
|
506
|
+
`agentic-dev-loop doctor --fast` probes the host and repo before you run:
|
|
507
|
+
hard failures stop you here (engine pin mismatch, engine runtime
|
|
503
508
|
availability, API version, git repo, `.env*` files); warnings print and
|
|
504
|
-
continue.
|
|
505
|
-
|
|
509
|
+
continue. `agentic-dev-loop upgrade` installs the latest engine release and
|
|
510
|
+
rewrites the pin, so the host install and the committed pin converge in one
|
|
511
|
+
explicit action. Run both yourself; the CLI never runs them for you.
|
|
506
512
|
|
|
507
513
|
A consumer repo needs a pipeline file and the agent files it names, both
|
|
508
514
|
committed before the first run. `init` writes them; the layout is:
|
|
@@ -615,7 +621,7 @@ export OPENAI_API_KEY=... # set your LLM key in the host env
|
|
|
615
621
|
python -m pytest tests/ -q # fast suite (in-repo .venv is for tests only)
|
|
616
622
|
python -m pytest tests/ -q -m "not docker" # skip engine-dependent tests
|
|
617
623
|
agentic-dev-loop agentic-dev-loop/pipeline.yaml --dry-run # run the shipped pipeline
|
|
618
|
-
|
|
624
|
+
.venv-sandbox/bin/python tests/smoke/viz_demo.py # viz demo - scripted replay, no pipeline needed
|
|
619
625
|
```
|
|
620
626
|
|
|
621
627
|
- `setup-venv.sh` builds the throwaway `.venv` for local `pytest` runs. The
|
|
@@ -81,8 +81,13 @@ agentic-dev-loop agentic-dev-loop/pipeline.yaml # run it
|
|
|
81
81
|
| `--dry-run` | Full load-and-validate pass, then print the resolved plan. No LLM, no Docker, no state writes, no API key. Exit `0` on a clean load. |
|
|
82
82
|
| `--resume <thread-id>` | Continue the latest checkpoint of a previous run (crash, Ctrl-C, exhaustion) with all accumulated notes intact. |
|
|
83
83
|
| `--max-attempts <n>` | Override the pipeline's `max_attempts`. |
|
|
84
|
+
| `--env <file>` | Load secrets from a host env file outside the workspace. Optional: the process environment is the default, a named-but-missing file is a loud error, and values already set in the environment win. |
|
|
84
85
|
| `--no-viz` / `--viz-port <port>` | Suppress the live graph view / set a preferred port (default 8321; falls back to a free port when busy). |
|
|
85
86
|
|
|
87
|
+
`PIPELINE` is optional and defaults to `agentic-dev-loop/pipeline.yaml`
|
|
88
|
+
(relative to the current directory). Run flags without a positional use that
|
|
89
|
+
default; a missing default fails loudly instead of falling back.
|
|
90
|
+
|
|
86
91
|
Exit code is `0` on pipeline success, `1` otherwise.
|
|
87
92
|
|
|
88
93
|
Other commands:
|
|
@@ -91,18 +96,19 @@ Other commands:
|
|
|
91
96
|
mermaid flowchart with the current step highlighted, reading the run-state
|
|
92
97
|
checkpoint database directly. `run-status --install` installs the bundled
|
|
93
98
|
`/run-status` command into OpenCode.
|
|
94
|
-
- `agentic-dev-loop report
|
|
95
|
-
|
|
99
|
+
- `agentic-dev-loop report` serves the **historical runs view** in the
|
|
100
|
+
browser (default port 8321, falling back to a free port when busy; blocks
|
|
101
|
+
until ctrl+c and prints the URL). It reads the same run records as the
|
|
102
|
+
markdown report and lists past runs with since / until / status filters,
|
|
103
|
+
an aggregate metrics panel, and a per-run detail page carrying the brief,
|
|
104
|
+
implementation summary, review findings, and QA report. The live viz also
|
|
105
|
+
links to it from the **History** button in the graph page header (or
|
|
106
|
+
`/runs`).
|
|
107
|
+
- `agentic-dev-loop report --markdown [<run-id>]` renders the same history
|
|
108
|
+
as ASCII markdown instead: an aggregate dashboard (loop health, TDD,
|
|
96
109
|
review, and QA metrics with provenance labels) or a deep dive for one
|
|
97
110
|
12-hex run directory. `--since` / `--until` / `--status` filter the set.
|
|
98
|
-
|
|
99
|
-
- The live viz also serves a **historical runs view**: click **History** in
|
|
100
|
-
the graph page header (or open `/runs`), or launch it standalone with
|
|
101
|
-
`python -m agentic_dev_loop.viz --history`, which needs no pipeline file
|
|
102
|
-
(default port 8321, falling back to a free port when busy). It lists past
|
|
103
|
-
runs with since / until / status filters, an aggregate metrics panel, and
|
|
104
|
-
a per-run detail page carrying the brief, implementation summary, review
|
|
105
|
-
findings, and QA report.
|
|
111
|
+
`--markdown` cannot be combined with `--port`.
|
|
106
112
|
- `agentic-dev-loop containers` inspects the engine's sandbox containers and
|
|
107
113
|
networks from the host; `containers --reap` removes registry-owned orphans
|
|
108
114
|
whose owner process is dead. A SIGTERM to a running pipeline still closes
|
|
@@ -444,20 +450,20 @@ agentic-dev-loop init --profile python # or: --profile dotnet-node
|
|
|
444
450
|
```
|
|
445
451
|
|
|
446
452
|
`init` writes the onboarding surface from a bundled toolchain profile:
|
|
447
|
-
`agentic-dev-loop/pipeline.yaml`, the three agent files,
|
|
448
|
-
`
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
hard failures abort the run (engine pin mismatch, engine runtime
|
|
453
|
+
`agentic-dev-loop/pipeline.yaml`, the three agent files,
|
|
454
|
+
`agentic-dev-loop/.engine-version` (the exact installed engine version), any
|
|
455
|
+
missing premise files, gitignore additions, and an env-file template. It
|
|
456
|
+
detects solution files, `package.json` directories, lockfiles, README, and
|
|
457
|
+
AGENTS.md, asks only what detection cannot answer, and refuses to overwrite
|
|
458
|
+
an existing `agentic-dev-loop/` directory. A consumer-authored profile file
|
|
459
|
+
can be passed by path instead of a bundled name.
|
|
460
|
+
|
|
461
|
+
`agentic-dev-loop doctor --fast` probes the host and repo before you run:
|
|
462
|
+
hard failures stop you here (engine pin mismatch, engine runtime
|
|
458
463
|
availability, API version, git repo, `.env*` files); warnings print and
|
|
459
|
-
continue.
|
|
460
|
-
|
|
464
|
+
continue. `agentic-dev-loop upgrade` installs the latest engine release and
|
|
465
|
+
rewrites the pin, so the host install and the committed pin converge in one
|
|
466
|
+
explicit action. Run both yourself; the CLI never runs them for you.
|
|
461
467
|
|
|
462
468
|
A consumer repo needs a pipeline file and the agent files it names, both
|
|
463
469
|
committed before the first run. `init` writes them; the layout is:
|
|
@@ -570,7 +576,7 @@ export OPENAI_API_KEY=... # set your LLM key in the host env
|
|
|
570
576
|
python -m pytest tests/ -q # fast suite (in-repo .venv is for tests only)
|
|
571
577
|
python -m pytest tests/ -q -m "not docker" # skip engine-dependent tests
|
|
572
578
|
agentic-dev-loop agentic-dev-loop/pipeline.yaml --dry-run # run the shipped pipeline
|
|
573
|
-
|
|
579
|
+
.venv-sandbox/bin/python tests/smoke/viz_demo.py # viz demo - scripted replay, no pipeline needed
|
|
574
580
|
```
|
|
575
581
|
|
|
576
582
|
- `setup-venv.sh` builds the throwaway `.venv` for local `pytest` runs. The
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentic-dev-loop"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.15.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"
|
|
@@ -22,6 +22,31 @@ from .loaders import mark_plan_completed
|
|
|
22
22
|
from .registry import Registry, default_registry, load_extensions
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
_DEFAULT_PIPELINE = Path("agentic-dev-loop") / "pipeline.yaml"
|
|
26
|
+
|
|
27
|
+
_TOP_HELP = """\
|
|
28
|
+
usage: agentic-dev-loop [PIPELINE] [--resume THREAD_ID] [--max-attempts N]
|
|
29
|
+
[--no-viz] [--viz-port PORT] [--dry-run] [--version]
|
|
30
|
+
|
|
31
|
+
Run an OpenHands agent pipeline defined in YAML. PIPELINE defaults to
|
|
32
|
+
agentic-dev-loop/pipeline.yaml; run `agentic-dev-loop <PIPELINE> --help`
|
|
33
|
+
for loader-contributed options (e.g. --plan, --aidlc-unit).
|
|
34
|
+
|
|
35
|
+
commands:
|
|
36
|
+
containers Inspect engine sandbox containers and networks.
|
|
37
|
+
copilot-login Run the GitHub device flow and store the Copilot OAuth token.
|
|
38
|
+
copilot-models List the Copilot models available to this token's tier.
|
|
39
|
+
report Serve the run-history browser view (--markdown for text).
|
|
40
|
+
run-status Report the latest agentic-dev-loop run.
|
|
41
|
+
init Write agentic-dev-loop pipeline and agent files.
|
|
42
|
+
doctor Probe this host and repo for onboarding prerequisites.
|
|
43
|
+
upgrade Install the latest engine release and rewrite the project pin.
|
|
44
|
+
help Show this list.
|
|
45
|
+
|
|
46
|
+
Run `agentic-dev-loop <command> --help` for per-command options.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
|
|
25
50
|
_sigterm_in_progress = False
|
|
26
51
|
|
|
27
52
|
|
|
@@ -79,8 +104,9 @@ def _core_parser() -> argparse.ArgumentParser:
|
|
|
79
104
|
"Document-loader flags contributed by the pipeline's "
|
|
80
105
|
"extensions appear once PIPELINE is known - see "
|
|
81
106
|
"`agentic-dev-loop PIPELINE --help`.")
|
|
82
|
-
parser.add_argument("pipeline", type=Path,
|
|
83
|
-
help="path to the pipeline YAML"
|
|
107
|
+
parser.add_argument("pipeline", type=Path, nargs="?", default=None,
|
|
108
|
+
help="path to the pipeline YAML (default: "
|
|
109
|
+
"agentic-dev-loop/pipeline.yaml)")
|
|
84
110
|
parser.add_argument("--resume", metavar="THREAD_ID", default=None,
|
|
85
111
|
help="resume a checkpointed run by thread id")
|
|
86
112
|
parser.add_argument("--max-attempts", type=int, default=None,
|
|
@@ -96,6 +122,9 @@ def _core_parser() -> argparse.ArgumentParser:
|
|
|
96
122
|
help="validate the pipeline and print a summary plan "
|
|
97
123
|
"without executing anything (no LLM, no "
|
|
98
124
|
"sandbox, no state writes)")
|
|
125
|
+
parser.add_argument("--env", metavar="FILE", default=None,
|
|
126
|
+
help="load secrets from a host env file outside the "
|
|
127
|
+
"workspace (default: the process environment)")
|
|
99
128
|
_add_version_flag(parser)
|
|
100
129
|
return parser
|
|
101
130
|
|
|
@@ -164,15 +193,19 @@ def _token_path(value: str | None) -> Path:
|
|
|
164
193
|
return Path(value).expanduser() if value else TOKEN_PATH.expanduser()
|
|
165
194
|
|
|
166
195
|
|
|
167
|
-
def
|
|
196
|
+
def _copilot_login_parser() -> argparse.ArgumentParser:
|
|
168
197
|
parser = argparse.ArgumentParser(
|
|
169
198
|
prog="agentic-dev-loop copilot-login",
|
|
170
199
|
description="Run the GitHub device flow and store the Copilot OAuth "
|
|
171
|
-
"token
|
|
200
|
+
"token.")
|
|
172
201
|
parser.add_argument("--token-file", default=None,
|
|
173
202
|
help="token path (default: "
|
|
174
203
|
"~/.agentic-dev-loop/auth/copilot.json)")
|
|
175
|
-
|
|
204
|
+
return parser
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _run_copilot_login(argv: list[str]) -> int:
|
|
208
|
+
args = _copilot_login_parser().parse_args(argv)
|
|
176
209
|
path = _token_path(args.token_file)
|
|
177
210
|
try:
|
|
178
211
|
login(token_path=path)
|
|
@@ -183,7 +216,7 @@ def _run_copilot_login(argv: list[str]) -> int:
|
|
|
183
216
|
return 0
|
|
184
217
|
|
|
185
218
|
|
|
186
|
-
def
|
|
219
|
+
def _copilot_models_parser() -> argparse.ArgumentParser:
|
|
187
220
|
parser = argparse.ArgumentParser(
|
|
188
221
|
prog="agentic-dev-loop copilot-models",
|
|
189
222
|
description="List the Copilot models available to this token's tier.")
|
|
@@ -192,7 +225,11 @@ def _run_copilot_models(argv: list[str]) -> int:
|
|
|
192
225
|
"~/.agentic-dev-loop/auth/copilot.json)")
|
|
193
226
|
parser.add_argument("--json", action="store_true",
|
|
194
227
|
help="emit the model list as JSON")
|
|
195
|
-
|
|
228
|
+
return parser
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _run_copilot_models(argv: list[str]) -> int:
|
|
232
|
+
args = _copilot_models_parser().parse_args(argv)
|
|
196
233
|
try:
|
|
197
234
|
models = list_copilot_models(read_token(_token_path(args.token_file)))
|
|
198
235
|
except CopilotAuthError as e:
|
|
@@ -209,11 +246,16 @@ def _run_copilot_models(argv: list[str]) -> int:
|
|
|
209
246
|
def _report_parser() -> argparse.ArgumentParser:
|
|
210
247
|
parser = argparse.ArgumentParser(
|
|
211
248
|
prog="agentic-dev-loop report",
|
|
212
|
-
description="
|
|
213
|
-
"read-only markdown.")
|
|
249
|
+
description="Serve the run-history browser view (--markdown for text).")
|
|
214
250
|
parser.add_argument("run_id", nargs="?", default=None,
|
|
215
251
|
help="12-hex run dir name for a deep dive "
|
|
216
|
-
"(
|
|
252
|
+
"(markdown mode only)")
|
|
253
|
+
parser.add_argument("--markdown", action="store_true",
|
|
254
|
+
help="render read-only markdown instead of serving "
|
|
255
|
+
"the browser view")
|
|
256
|
+
parser.add_argument("--port", type=int, default=None,
|
|
257
|
+
help="server port (default: 8321; falls back to a "
|
|
258
|
+
"free port when busy)")
|
|
217
259
|
parser.add_argument("--since", default=None,
|
|
218
260
|
help="only threads starting at or after this ISO "
|
|
219
261
|
"datetime")
|
|
@@ -234,11 +276,28 @@ def _report_parser() -> argparse.ArgumentParser:
|
|
|
234
276
|
|
|
235
277
|
|
|
236
278
|
def _run_report(argv: list[str]) -> int:
|
|
279
|
+
args = _report_parser().parse_args(argv)
|
|
280
|
+
if args.markdown:
|
|
281
|
+
if args.port is not None:
|
|
282
|
+
print("report: --markdown and --port are mutually exclusive",
|
|
283
|
+
file=sys.stderr)
|
|
284
|
+
return 2
|
|
285
|
+
return _render_report(args)
|
|
286
|
+
markdown_only = [flag for flag, value in (
|
|
287
|
+
("run_id", args.run_id), ("--since", args.since),
|
|
288
|
+
("--until", args.until), ("--status", args.status)) if value]
|
|
289
|
+
if markdown_only:
|
|
290
|
+
print(f"report: {markdown_only[0]} requires --markdown",
|
|
291
|
+
file=sys.stderr)
|
|
292
|
+
return 2
|
|
293
|
+
return _serve_report(args)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _render_report(args) -> int:
|
|
237
297
|
from agentic_dev_loop.reporting import (
|
|
238
298
|
apply_filters, build_run_records, discover, find_run_dir,
|
|
239
299
|
pure_metrics, read_audit, read_dir, render_markdown, runs_root)
|
|
240
300
|
|
|
241
|
-
args = _report_parser().parse_args(argv)
|
|
242
301
|
root = runs_root(args.runs_root)
|
|
243
302
|
notice = None
|
|
244
303
|
if args.run_id is not None:
|
|
@@ -271,6 +330,78 @@ def _run_report(argv: list[str]) -> int:
|
|
|
271
330
|
return 0
|
|
272
331
|
|
|
273
332
|
|
|
333
|
+
def _serve_report(args) -> int:
|
|
334
|
+
from agentic_dev_loop.viz import serve_history
|
|
335
|
+
|
|
336
|
+
port = 8321 if args.port is None else args.port
|
|
337
|
+
try:
|
|
338
|
+
httpd, _thread = serve_history(port, runs_root=args.runs_root,
|
|
339
|
+
audit_dir=args.audit_dir)
|
|
340
|
+
except OSError as exc:
|
|
341
|
+
print(f"report: {exc}", file=sys.stderr)
|
|
342
|
+
return 1
|
|
343
|
+
bound = httpd.server_address[1]
|
|
344
|
+
url = f"http://127.0.0.1:{bound}"
|
|
345
|
+
print(f"Run history viz: {url}", flush=True)
|
|
346
|
+
if port and bound != port:
|
|
347
|
+
print(f"report port {port} busy - serving on {url}", flush=True)
|
|
348
|
+
try:
|
|
349
|
+
_wait_for_interrupt()
|
|
350
|
+
except KeyboardInterrupt:
|
|
351
|
+
pass
|
|
352
|
+
finally:
|
|
353
|
+
httpd.shutdown()
|
|
354
|
+
return 0
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def _probe_parser() -> argparse.ArgumentParser:
|
|
358
|
+
"""Phase-1 parser: find PIPELINE (or the default) without loading any
|
|
359
|
+
extension or SDK module."""
|
|
360
|
+
probe = argparse.ArgumentParser(add_help=False)
|
|
361
|
+
probe.add_argument("pipeline", type=Path, nargs="?")
|
|
362
|
+
probe.add_argument("--resume", default=None)
|
|
363
|
+
probe.add_argument("--max-attempts", default=None)
|
|
364
|
+
probe.add_argument("--viz-port", default=None)
|
|
365
|
+
probe.add_argument("--env", default=None)
|
|
366
|
+
probe.add_argument("--no-viz", action="store_true")
|
|
367
|
+
probe.add_argument("--dry-run", action="store_true")
|
|
368
|
+
_add_version_flag(probe)
|
|
369
|
+
return probe
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _load_env_file(path: Path) -> str | None:
|
|
373
|
+
"""Load KEY=VALUE lines from a host file into the process environment.
|
|
374
|
+
|
|
375
|
+
The file must live outside the workspace (doctor refuses workspace
|
|
376
|
+
``.env*`` files; the run path uses the same boundary). Values already set
|
|
377
|
+
in the environment win, so a file never overrides the operator's shell.
|
|
378
|
+
Returns an error message, or ``None`` on success.
|
|
379
|
+
"""
|
|
380
|
+
target = path.expanduser().resolve()
|
|
381
|
+
workspace = Path.cwd().resolve()
|
|
382
|
+
if target == workspace or target.is_relative_to(workspace):
|
|
383
|
+
return (f"--env file {target} is inside the workspace {workspace}; "
|
|
384
|
+
"secret files must live outside the workspace")
|
|
385
|
+
if not target.is_file():
|
|
386
|
+
return f"--env file not found: {target}"
|
|
387
|
+
for raw in target.read_text(encoding="utf-8").splitlines():
|
|
388
|
+
line = raw.strip()
|
|
389
|
+
if not line or line.startswith("#"):
|
|
390
|
+
continue
|
|
391
|
+
if line.startswith("export "):
|
|
392
|
+
line = line[len("export "):].strip()
|
|
393
|
+
key, sep, value = line.partition("=")
|
|
394
|
+
key = key.strip()
|
|
395
|
+
if not sep or not key:
|
|
396
|
+
continue
|
|
397
|
+
value = value.strip()
|
|
398
|
+
if len(value) >= 2 and value[0] == value[-1] and value[0] in "'\"":
|
|
399
|
+
value = value[1:-1]
|
|
400
|
+
if key not in os.environ:
|
|
401
|
+
os.environ[key] = value
|
|
402
|
+
return None
|
|
403
|
+
|
|
404
|
+
|
|
274
405
|
def build_parser(cfg_path) -> argparse.ArgumentParser:
|
|
275
406
|
"""The full parser for one pipeline: core flags + loader-contributed."""
|
|
276
407
|
registry, _ = _registry_for(cfg_path)
|
|
@@ -285,6 +416,12 @@ def main(argv: list[str] | None = None, *, keep_alive: bool = True) -> int:
|
|
|
285
416
|
argv = sys.argv[1:]
|
|
286
417
|
else:
|
|
287
418
|
argv = list(argv)
|
|
419
|
+
if argv and argv[0] == "help":
|
|
420
|
+
if len(argv) > 1:
|
|
421
|
+
print("error: help takes no arguments", file=sys.stderr)
|
|
422
|
+
return 2
|
|
423
|
+
print(_TOP_HELP)
|
|
424
|
+
return 0
|
|
288
425
|
if argv and argv[0] == "containers":
|
|
289
426
|
return _run_containers(argv[1:])
|
|
290
427
|
if argv and argv[0] == "copilot-login":
|
|
@@ -305,20 +442,32 @@ def main(argv: list[str] | None = None, *, keep_alive: bool = True) -> int:
|
|
|
305
442
|
if argv and argv[0] == "upgrade":
|
|
306
443
|
from .onboarding.upgrade import run_upgrade
|
|
307
444
|
return run_upgrade(argv[1:])
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
known, _ =
|
|
445
|
+
if not argv:
|
|
446
|
+
print(_TOP_HELP)
|
|
447
|
+
return 0
|
|
448
|
+
known, _ = _probe_parser().parse_known_args(argv)
|
|
312
449
|
if known.pipeline is None:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
450
|
+
if "-h" in argv or "--help" in argv:
|
|
451
|
+
print(_TOP_HELP)
|
|
452
|
+
return 0
|
|
453
|
+
if not _DEFAULT_PIPELINE.is_file():
|
|
454
|
+
print(f"agentic-dev-loop: no pipeline at {_DEFAULT_PIPELINE} "
|
|
455
|
+
"and none given", file=sys.stderr)
|
|
456
|
+
return 1
|
|
457
|
+
pipeline = _DEFAULT_PIPELINE
|
|
458
|
+
else:
|
|
459
|
+
pipeline = known.pipeline
|
|
460
|
+
if known.env is not None:
|
|
461
|
+
error = _load_env_file(Path(known.env))
|
|
462
|
+
if error is not None:
|
|
463
|
+
print(f"agentic-dev-loop: {error}", file=sys.stderr)
|
|
464
|
+
return 1
|
|
465
|
+
registry, cfg = _registry_for(pipeline)
|
|
318
466
|
parser = _core_parser()
|
|
319
467
|
for loader in registry.document_loaders:
|
|
320
468
|
loader.add_cli_args(parser)
|
|
321
469
|
args = parser.parse_args(argv)
|
|
470
|
+
args.pipeline = pipeline
|
|
322
471
|
if args.dry_run:
|
|
323
472
|
from .dryrun import dry_run
|
|
324
473
|
return dry_run(args.pipeline, args, registry)
|
{agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/hostboundary.py
RENAMED
|
@@ -32,8 +32,7 @@ if TYPE_CHECKING:
|
|
|
32
32
|
# the dogfood pipeline and the consumer repo use); the other tooling paths are config- or
|
|
33
33
|
# pipeline-file-relative.
|
|
34
34
|
TOOLING_DIR_NAMES = ("aidlc-docs", "tools")
|
|
35
|
-
TOOLING_FILE_NAMES = ("
|
|
36
|
-
"agentic-dev-loop/.engine-version")
|
|
35
|
+
TOOLING_FILE_NAMES = ("agentic-dev-loop/.engine-version",)
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
class HostBoundaryError(RuntimeError):
|
{agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/doctor.py
RENAMED
|
@@ -38,9 +38,7 @@ def _print_failures(checks: list[Check]) -> None:
|
|
|
38
38
|
print(f" fix: {check.fix_text}")
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def
|
|
42
|
-
probes: HostProbes | None = None,
|
|
43
|
-
installed: str | None = None) -> int:
|
|
41
|
+
def _doctor_parser() -> argparse.ArgumentParser:
|
|
44
42
|
parser = argparse.ArgumentParser(
|
|
45
43
|
prog="agentic-dev-loop doctor",
|
|
46
44
|
description="Probe this host and repo for onboarding prerequisites.")
|
|
@@ -49,7 +47,13 @@ def run_doctor(argv: list[str], *, workspace: Path | None = None,
|
|
|
49
47
|
"round trip")
|
|
50
48
|
parser.add_argument("--json", action="store_true",
|
|
51
49
|
help="emit machine-readable JSON results")
|
|
52
|
-
|
|
50
|
+
return parser
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def run_doctor(argv: list[str], *, workspace: Path | None = None,
|
|
54
|
+
probes: HostProbes | None = None,
|
|
55
|
+
installed: str | None = None) -> int:
|
|
56
|
+
args = _doctor_parser().parse_args(argv)
|
|
53
57
|
|
|
54
58
|
root = Path(workspace or Path.cwd()).resolve()
|
|
55
59
|
probes = probes or HostProbes()
|
{agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/onboarding/init.py
RENAMED
|
@@ -308,11 +308,6 @@ def _write(root: Path, profile: Profile, pipeline: dict, texts: dict,
|
|
|
308
308
|
(agents / f"{name}.agent.md").write_text(
|
|
309
309
|
load_template(f"{name}.agent.md"), encoding="utf-8")
|
|
310
310
|
|
|
311
|
-
trigger = root / "trigger-agentic-dev-loop.sh"
|
|
312
|
-
trigger.write_text(load_template("trigger-agentic-dev-loop.sh"),
|
|
313
|
-
encoding="utf-8")
|
|
314
|
-
trigger.chmod(0o755)
|
|
315
|
-
|
|
316
311
|
(out / ".engine-version").write_text(installed + "\n", encoding="utf-8")
|
|
317
312
|
|
|
318
313
|
for premise in profile.premise_files:
|
|
@@ -368,11 +363,10 @@ def _answers(root: Path, profile_ref: str, yes: bool) -> dict:
|
|
|
368
363
|
}
|
|
369
364
|
|
|
370
365
|
|
|
371
|
-
def
|
|
366
|
+
def _init_parser() -> argparse.ArgumentParser:
|
|
372
367
|
parser = argparse.ArgumentParser(
|
|
373
368
|
prog="agentic-dev-loop init",
|
|
374
|
-
description="Write agentic-dev-loop pipeline
|
|
375
|
-
"files for this repo.")
|
|
369
|
+
description="Write agentic-dev-loop pipeline and agent files.")
|
|
376
370
|
parser.add_argument("--profile", default="python",
|
|
377
371
|
help="bundled profile name or path (default: python)")
|
|
378
372
|
parser.add_argument("--recipe", default=None,
|
|
@@ -382,7 +376,11 @@ def run_init(argv: list[str]) -> int:
|
|
|
382
376
|
help="accept defaults without prompting")
|
|
383
377
|
parser.add_argument("--dir", default=".",
|
|
384
378
|
help="repo root to write into (default: .)")
|
|
385
|
-
|
|
379
|
+
return parser
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def run_init(argv: list[str]) -> int:
|
|
383
|
+
args = _init_parser().parse_args(argv)
|
|
386
384
|
root = Path(args.dir).resolve()
|
|
387
385
|
try:
|
|
388
386
|
pipeline_path = root / "agentic-dev-loop" / "pipeline.yaml"
|
|
@@ -423,10 +421,10 @@ def _print_next_steps(pipeline_path: Path) -> None:
|
|
|
423
421
|
Wrote {pipeline_path}
|
|
424
422
|
Next steps:
|
|
425
423
|
1. Export the LLM key named by api_key_env in the host environment
|
|
426
|
-
(or
|
|
424
|
+
(or pass --env FILE, a host env file outside the workspace).
|
|
427
425
|
2. Review agentic-dev-loop/pipeline.yaml and the agent files under
|
|
428
426
|
agentic-dev-loop/sdk_agents/.
|
|
429
427
|
3. Validate: agentic-dev-loop agentic-dev-loop/pipeline.yaml --dry-run
|
|
430
|
-
4. Run:
|
|
431
|
-
or --resume).
|
|
428
|
+
4. Run: agentic-dev-loop agentic-dev-loop/pipeline.yaml --plan <path>
|
|
429
|
+
(or --aidlc-unit, or --resume).
|
|
432
430
|
"""))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Host environment file for agentic-dev-loop.
|
|
2
|
+
#
|
|
3
|
+
# Copy it outside the workspace (for example to
|
|
4
|
+
# ~/.config/<repo-name>/agentic-dev-loop.env) and fill in values there.
|
|
5
|
+
# Pass it to a run with --env FILE. Never commit a filled copy: the engine
|
|
6
|
+
# refuses a run when the workspace contains a .env* file, and this template
|
|
7
|
+
# carries no secret values. Values already set in the process environment
|
|
8
|
+
# win over the file.
|
|
9
|
+
#
|
|
10
|
+
# OPENAI_API_KEY=...
|
|
11
|
+
#
|
|
12
|
+
# Optional: override the toolchain image for a local build.
|
|
13
|
+
# AGENTIC_DEV_LOOP_DEV_IMAGE=...
|
|
@@ -24,13 +24,17 @@ def _resolve(name: str, env: dict | None) -> str | None:
|
|
|
24
24
|
return shutil.which(name)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
env: dict | None = None) -> int:
|
|
27
|
+
def _upgrade_parser() -> argparse.ArgumentParser:
|
|
29
28
|
parser = argparse.ArgumentParser(
|
|
30
29
|
prog="agentic-dev-loop upgrade",
|
|
31
30
|
description="Install the latest engine release and rewrite the "
|
|
32
|
-
"project pin
|
|
33
|
-
parser
|
|
31
|
+
"project pin.")
|
|
32
|
+
return parser
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run_upgrade(argv: list[str], *, workspace: Path | None = None,
|
|
36
|
+
env: dict | None = None) -> int:
|
|
37
|
+
_upgrade_parser().parse_args(argv)
|
|
34
38
|
|
|
35
39
|
root = Path(workspace or Path.cwd()).resolve()
|
|
36
40
|
pipx = _resolve("pipx", env)
|
{agentic_dev_loop-0.14.5 → agentic_dev_loop-0.15.0}/src/agentic_dev_loop/engine/run_status.py
RENAMED
|
@@ -311,7 +311,7 @@ def install_command(dest_dir: Path | None = None) -> Path:
|
|
|
311
311
|
return target
|
|
312
312
|
|
|
313
313
|
|
|
314
|
-
def
|
|
314
|
+
def _run_status_parser() -> argparse.ArgumentParser:
|
|
315
315
|
parser = argparse.ArgumentParser(
|
|
316
316
|
prog="agentic-dev-loop run-status",
|
|
317
317
|
description="Report the latest agentic-dev-loop run.",
|
|
@@ -330,7 +330,11 @@ def _run_status(argv: list[str]) -> int:
|
|
|
330
330
|
help="install the /run-status OpenCode command into the consumer "
|
|
331
331
|
"commands directory and exit",
|
|
332
332
|
)
|
|
333
|
-
|
|
333
|
+
return parser
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _run_status(argv: list[str]) -> int:
|
|
337
|
+
args = _run_status_parser().parse_args(argv)
|
|
334
338
|
|
|
335
339
|
if args.install:
|
|
336
340
|
target = install_command()
|