agentic-dev-loop 1.0.0b1__tar.gz → 1.0.0rc2__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-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/PKG-INFO +2 -2
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/README.md +1 -1
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/pyproject.toml +1 -1
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/hostboundary.py +2 -1
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/upgrade.py +5 -1
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/run_status_command.md +1 -1
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/PKG-INFO +2 -2
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/SOURCES.txt +1 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_upgrade.py +19 -1
- agentic_dev_loop-1.0.0rc2/tests/test_pypi_yank.py +339 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/LICENSE +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/setup.cfg +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/config.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/failure.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/paths.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/profiles/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/profiles/data/dotnet-node.yaml +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/profiles/data/python.yaml +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/results.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/verdict.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/actions.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/agent_error_guide.md +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/agent_error_guide.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/agents.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/allowlist.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_coverage.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_prompt.md +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_prompt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/cli.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/completion.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/containers.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/copilot_auth.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/deps.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/dryrun.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/egress_policy.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/egress_proxy.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/extensions/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/extensions/aidlc.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/forbidden.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/graph.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/isolation.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/llm.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/loaders.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/mounts.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/checks.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/doctor.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/init.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/recipes/dotnet-node.yaml +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/recipes/python.yaml +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/recipes.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/templates/dev.agent.md +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/templates/env.example +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/templates/qa.agent.md +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/templates/review.agent.md +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/onboarding/templates.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/outputs.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/presets.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/proc.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/provider_wire.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/registry.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/run_status.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/seccomp/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/seccomp/chromium-userns.json +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/secrets.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/stages.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/step_workspace.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/sync_back.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/py.typed +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/metrics.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/render.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/sources.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/__init__.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/layout.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/page.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/runs_view.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/server.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-1pKPtbcx.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-2lMgbefg.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-B0WgRfVg.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-B3fCnGwv.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-Bm3KyEZC.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-DIfh6y3Q.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/16-DxEg5YJZ.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/20-CdViZ4xF.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/accordion.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/button-rSg_K8yf.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/button-skeleton-i-vqINhS.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/button.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/carbon-element-Bi7pQHAl.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/checkbox-D7PSLQCq.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/checkbox.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/class-map-t9xXbTFr.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/code-snippet.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/collection-helpers-BOkEorAG.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/copy-button.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/copy-tonlUGaV.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/data-table.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/decorate-1Ivfrp93.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/decorators-CNcdZSLL.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/deep-shadow-contains-Cs2rSnhr.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/definition-tooltip-FYe4J71p.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/directive-xDpGnViN.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/feature-flags-C7ZDYm5Q.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/floating-controller-DmTRVV0A.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/focus-D91D_iCB.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/form-Sg67yyAA.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/host-listener-CEd01uiB.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/host-listener-D_ODAJ3e.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/icon-button-Be2x1qrf.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/icon-loader-Cj1PggRN.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/icon-loader-utils-CVerE28u.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/if-defined-CV6i5LeB.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/if-non-empty-B5mz8bH9.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/link-aD3OYHCu.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/link.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/manifest.json +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/notification.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/on-DP_Dnlgd.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/popover-content-fajgXUvu.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/popover.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/query-DJR3NpB4.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/query-all-BuL-eXl_.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/radio-button.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/radio-group-manager-BE85t4HN.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/search-CVX2VAop.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/settings-DlHDxgf_.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/skeleton-text-s5gA9_CO.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/skeleton-text.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/tag.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/themes.css +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/tile.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/tooltip-DYtXwn-o.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/tooltip-content-DDo9ICPL.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/tooltip.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/ui-shell.min.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/viz/vendor/unsafe-html-BDr7jYB8.js +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/dependency_links.txt +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/entry_points.txt +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/requires.txt +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/top_level.txt +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_029_merge_on_conflict.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_033_brief_step.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_035_finalize_nudge.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_036_banned_commands_and_lane_boundary.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_041_brief_coverage.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_046_brief_prompt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_cli.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_doctor.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_init.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_profile_loading.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_profiles.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_recipes.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_schema_lock.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_055_templates.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_actions.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_agent_error_guide.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_agents.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_aidlc.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_build_viz_page.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_cli.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_config.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_containers.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_copilot_auth.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_copilot_cli.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_deps.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_dry_run.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_e2e_fixtures.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_egress_proxy.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_graph.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_hostboundary.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_hostboundary_integration.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_isolation.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_isolation_integration.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_isolation_pbt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_llm.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_loaders.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_module_contract.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_outputs.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_outputs_pbt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_proc.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_provider_wire.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_publish.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_qa_prompt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_registry.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_repo_ascii.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_results.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_run_status.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_js_duration_charts.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_js_filters.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_js_key_stats.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_js_metrics.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_layout.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_runs_layout_key_stats.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_sdk_compat.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_secrets.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_secrets_integration.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_secrets_pipeline.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_source_resolution.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_stages.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_step_workspace.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_sync_back.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit11.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit11_pbt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit12_reporting.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit13_runs_viz.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit5_config.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit5_pbt.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_unit5_pure.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_vendor_carbon_wc.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_verdict.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_viz.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_viz_demo.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_viz_layout.py +0 -0
- {agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/tests/test_viz_wheel_contents.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentic-dev-loop
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0rc2
|
|
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
|
|
@@ -113,7 +113,7 @@ Docker engine does:
|
|
|
113
113
|
### Installation
|
|
114
114
|
|
|
115
115
|
```bash
|
|
116
|
-
pipx install agentic-dev-loop
|
|
116
|
+
pipx install --pip-args="--pre" agentic-dev-loop # latest release is currently a pre-release
|
|
117
117
|
agentic-dev-loop --version
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentic-dev-loop"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.0rc2"
|
|
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"
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/hostboundary.py
RENAMED
|
@@ -58,7 +58,8 @@ def check_orchestrator_install(workspace: str | Path,
|
|
|
58
58
|
raise HostBoundaryError(
|
|
59
59
|
f"agentic_dev_loop resolves to {resolved}, inside the workspace "
|
|
60
60
|
f"{ws} - the engine must be installed outside the workspace "
|
|
61
|
-
"(e.g. `pipx install agentic-dev-loop`);
|
|
61
|
+
"(e.g. `pipx install --pip-args=--pre agentic-dev-loop`); "
|
|
62
|
+
"refusing to run")
|
|
62
63
|
|
|
63
64
|
|
|
64
65
|
def tooling_rel_paths(cfg: "PipelineConfig", pipeline_path: str | Path,
|
|
@@ -43,8 +43,12 @@ def run_upgrade(argv: list[str], *, workspace: Path | None = None,
|
|
|
43
43
|
"pipx-managed", file=sys.stderr)
|
|
44
44
|
return 1
|
|
45
45
|
|
|
46
|
+
# --pre is required: the release process yanks superseded releases, and
|
|
47
|
+
# the current latest (1.0.0b1) is a pre-release, so a plain install has
|
|
48
|
+
# no satisfiable version. pipx translates --pre on both backends (pip and
|
|
49
|
+
# uv); dropping it here breaks upgrade until a stable release ships.
|
|
46
50
|
result = subprocess.run(
|
|
47
|
-
[pipx, "install", "--force", "agentic-dev-loop"],
|
|
51
|
+
[pipx, "install", "--force", "--pip-args=--pre", "agentic-dev-loop"],
|
|
48
52
|
capture_output=True, text=True, check=False, env=env)
|
|
49
53
|
if result.returncode != 0:
|
|
50
54
|
detail = (result.stderr or "unknown error").strip()
|
|
@@ -20,4 +20,4 @@ The command prints two sections: `===MERMAID===` then `===SUMMARY===`.
|
|
|
20
20
|
|
|
21
21
|
## Errors
|
|
22
22
|
|
|
23
|
-
- If `agentic-dev-loop` is not on PATH, report that the engine is not installed (`pipx install agentic-dev-loop`) and stop.
|
|
23
|
+
- If `agentic-dev-loop` is not on PATH, report that the engine is not installed (`pipx install --pip-args="--pre" agentic-dev-loop`) and stop.
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentic-dev-loop
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0rc2
|
|
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
|
|
@@ -113,7 +113,7 @@ Docker engine does:
|
|
|
113
113
|
### Installation
|
|
114
114
|
|
|
115
115
|
```bash
|
|
116
|
-
pipx install agentic-dev-loop
|
|
116
|
+
pipx install --pip-args="--pre" agentic-dev-loop # latest release is currently a pre-release
|
|
117
117
|
agentic-dev-loop --version
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -49,12 +49,30 @@ def test_upgrade_installs_latest_and_writes_pin(tmp_path, capsys):
|
|
|
49
49
|
code = run_upgrade([], workspace=tmp_path, env=_env_with(bin_dir))
|
|
50
50
|
|
|
51
51
|
assert code == 0
|
|
52
|
-
assert pipx_log.read_text().strip() ==
|
|
52
|
+
assert pipx_log.read_text().strip() == \
|
|
53
|
+
"install --force --pip-args=--pre agentic-dev-loop"
|
|
53
54
|
pin = tmp_path / "agentic-dev-loop" / ".engine-version"
|
|
54
55
|
assert pin.read_text(encoding="utf-8") == "0.10.4\n"
|
|
55
56
|
assert "upgraded agentic-dev-loop to 0.10.4" in capsys.readouterr().out
|
|
56
57
|
|
|
57
58
|
|
|
59
|
+
def test_upgrade_pins_pre_release_version(tmp_path):
|
|
60
|
+
# The PyPI index currently ships 1.0.0b1 as the only non-yanked release,
|
|
61
|
+
# so the pin step must accept pre-release versions (regression: upgrade
|
|
62
|
+
# failed because pipx never saw 1.0.0b1 as installable).
|
|
63
|
+
bin_dir = _stub_env(
|
|
64
|
+
tmp_path,
|
|
65
|
+
pipx_body="exit 0",
|
|
66
|
+
cli_body='echo "agentic-dev-loop 1.0.0b1"',
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
code = run_upgrade([], workspace=tmp_path, env=_env_with(bin_dir))
|
|
70
|
+
|
|
71
|
+
assert code == 0
|
|
72
|
+
pin = tmp_path / "agentic-dev-loop" / ".engine-version"
|
|
73
|
+
assert pin.read_text(encoding="utf-8") == "1.0.0b1\n"
|
|
74
|
+
|
|
75
|
+
|
|
58
76
|
def test_upgrade_overwrites_existing_pin(tmp_path):
|
|
59
77
|
out = tmp_path / "agentic-dev-loop"
|
|
60
78
|
out.mkdir()
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"""Tests for tools/pypi_yank.py - the PyPI release yank script.
|
|
2
|
+
|
|
3
|
+
PyPI has no public API for yanking releases, so the tool drives the same
|
|
4
|
+
HTML forms the web UI submits. The HTTP session is thin glue; everything
|
|
5
|
+
decision-shaped (which versions to yank, which form to fill, whether a
|
|
6
|
+
re-auth is being demanded, whether the release is already yanked) lives in
|
|
7
|
+
pure functions tested here.
|
|
8
|
+
|
|
9
|
+
The release fixture is a trimmed dump of the real PyPI JSON API response
|
|
10
|
+
for agentic-dev-loop, fetched 2026-11-11 (filenames and yanked flags are
|
|
11
|
+
the real ones). The HTML fixtures mirror the rendered warehouse manage
|
|
12
|
+
pages (yank form, un-yank form, re-auth form, two-factor form) field for
|
|
13
|
+
field, per warehouse/manage/views/__init__.py (POST triggered on
|
|
14
|
+
confirm_yank_version, require_reauth) and
|
|
15
|
+
warehouse/templates/manage/project/release.html.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
import pytest
|
|
21
|
+
from packaging.version import Version
|
|
22
|
+
|
|
23
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
24
|
+
YANK = REPO_ROOT / "tools" / "pypi_yank.py"
|
|
25
|
+
|
|
26
|
+
import importlib.util # noqa: E402
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _load_yank():
|
|
30
|
+
spec = importlib.util.spec_from_file_location("pypi_yank", YANK)
|
|
31
|
+
module = importlib.util.module_from_spec(spec)
|
|
32
|
+
spec.loader.exec_module(module)
|
|
33
|
+
return module
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
yank = _load_yank()
|
|
37
|
+
|
|
38
|
+
# Trimmed real dump: https://pypi.org/pypi/agentic-dev-loop/json
|
|
39
|
+
# (2026-11-11). Every 0.x release carries a wheel and an sdist, all
|
|
40
|
+
# unyanked. 1.0.0a1 (the keep target) had not been published yet at dump
|
|
41
|
+
# time, which the absent-keep tests exercise.
|
|
42
|
+
REAL_RELEASES = {
|
|
43
|
+
"0.3.0": [
|
|
44
|
+
{"filename": "agentic_dev_loop-0.3.0-py3-none-any.whl",
|
|
45
|
+
"yanked": False},
|
|
46
|
+
{"filename": "agentic_dev_loop-0.3.0.tar.gz", "yanked": False},
|
|
47
|
+
],
|
|
48
|
+
"0.10.0": [
|
|
49
|
+
{"filename": "agentic_dev_loop-0.10.0-py3-none-any.whl",
|
|
50
|
+
"yanked": False},
|
|
51
|
+
{"filename": "agentic_dev_loop-0.10.0.tar.gz", "yanked": False},
|
|
52
|
+
],
|
|
53
|
+
"0.15.7": [
|
|
54
|
+
{"filename": "agentic_dev_loop-0.15.7-py3-none-any.whl",
|
|
55
|
+
"yanked": False},
|
|
56
|
+
{"filename": "agentic_dev_loop-0.15.7.tar.gz", "yanked": False},
|
|
57
|
+
],
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Warehouse manage release page, unyanked release: the Yank release form
|
|
61
|
+
# (confirm_yank_version text input, optional yanked_reason, csrf) plus a
|
|
62
|
+
# per-file delete form, which must NOT be mistaken for the yank form.
|
|
63
|
+
YANK_PAGE = """<!DOCTYPE html>
|
|
64
|
+
<html><body>
|
|
65
|
+
<form method="POST" action="/manage/project/agentic-dev-loop/release/0.15.7/">
|
|
66
|
+
<input name="csrf_token" type="hidden" value="TOKEN123">
|
|
67
|
+
<input name="confirm_yank_version" type="text" value="">
|
|
68
|
+
<input name="yanked_reason" type="text" value="">
|
|
69
|
+
<button type="submit">Yank release</button>
|
|
70
|
+
</form>
|
|
71
|
+
<form method="POST" action="/manage/project/agentic-dev-loop/release/0.15.7/file/agentic_dev_loop-0.15.7.tar.gz/">
|
|
72
|
+
<input name="csrf_token" type="hidden" value="TOKEN777">
|
|
73
|
+
<input name="confirm_delete_version" type="text" value="">
|
|
74
|
+
<button type="submit">Delete file</button>
|
|
75
|
+
</form>
|
|
76
|
+
</body></html>"""
|
|
77
|
+
|
|
78
|
+
# Warehouse manage release page, yanked release: the Un-yank form replaces
|
|
79
|
+
# the yank form. This is both the post-yank verification signal and the
|
|
80
|
+
# idempotence signal on a re-run.
|
|
81
|
+
UNYANK_PAGE = """<!DOCTYPE html>
|
|
82
|
+
<html><body>
|
|
83
|
+
<form method="POST" action="/manage/project/agentic-dev-loop/release/0.15.7/">
|
|
84
|
+
<input name="csrf_token" type="hidden" value="TOKEN123">
|
|
85
|
+
<input name="confirm_unyank_version" type="text" value="">
|
|
86
|
+
<button type="submit">Un-yank release</button>
|
|
87
|
+
</form>
|
|
88
|
+
</body></html>"""
|
|
89
|
+
|
|
90
|
+
# Warehouse login page, for the session-expired guard in verification.
|
|
91
|
+
LOGIN_PAGE = """<!DOCTYPE html>
|
|
92
|
+
<html><body>
|
|
93
|
+
<form method="POST" action="/account/login/">
|
|
94
|
+
<input name="csrf_token" type="hidden" value="TOKEN000">
|
|
95
|
+
<input name="username" type="text" value="">
|
|
96
|
+
<input name="password" type="password" value="">
|
|
97
|
+
<button type="submit">Log in</button>
|
|
98
|
+
</form>
|
|
99
|
+
</body></html>"""
|
|
100
|
+
|
|
101
|
+
# Warehouse re-auth form, rendered when a destructive POST needs a password.
|
|
102
|
+
REAUTH_PAGE = """<!DOCTYPE html>
|
|
103
|
+
<html><body>
|
|
104
|
+
<form method="POST" action="/account/reauthenticate/">
|
|
105
|
+
<input name="csrf_token" type="hidden" value="TOKEN456">
|
|
106
|
+
<input name="next_route" type="hidden" value="manage.project.release">
|
|
107
|
+
<input name="next_route_matchdict" type="hidden"
|
|
108
|
+
value="{"project_name": "agentic-dev-loop",
|
|
109
|
+
"version": "0.15.7"}">
|
|
110
|
+
<input name="next_route_query" type="hidden" value="{}">
|
|
111
|
+
<input name="password" type="password" value="">
|
|
112
|
+
<button type="submit">Confirm password</button>
|
|
113
|
+
</form>
|
|
114
|
+
</body></html>"""
|
|
115
|
+
|
|
116
|
+
# Warehouse two-factor form, rendered at login when the account has 2FA.
|
|
117
|
+
TWO_FACTOR_PAGE = """<!DOCTYPE html>
|
|
118
|
+
<html><body>
|
|
119
|
+
<form method="POST" action="/account/two-factor/">
|
|
120
|
+
<input name="csrf_token" type="hidden" value="TOKEN789">
|
|
121
|
+
<input name="totp_value" type="text" value="">
|
|
122
|
+
<button type="submit">Verify</button>
|
|
123
|
+
</form>
|
|
124
|
+
</body></html>"""
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class TestVersionSelection:
|
|
128
|
+
def test_keep_survives_everything_else_is_selected(self):
|
|
129
|
+
plan = yank.versions_to_yank(REAL_RELEASES, "1.0.0a1")
|
|
130
|
+
assert "1.0.0a1" not in plan
|
|
131
|
+
assert "0.3.0" in plan
|
|
132
|
+
assert "0.10.0" in plan
|
|
133
|
+
assert "0.15.7" in plan
|
|
134
|
+
assert len(plan) == 3
|
|
135
|
+
|
|
136
|
+
def test_plan_is_oldest_first(self):
|
|
137
|
+
plan = yank.versions_to_yank(REAL_RELEASES, "1.0.0a1")
|
|
138
|
+
assert plan == sorted(plan, key=Version)
|
|
139
|
+
|
|
140
|
+
def test_multiple_keeps_all_survive(self):
|
|
141
|
+
plan = yank.versions_to_yank(REAL_RELEASES, "0.3.0,1.0.0a1")
|
|
142
|
+
assert "0.3.0" not in plan
|
|
143
|
+
assert "1.0.0a1" not in plan
|
|
144
|
+
assert plan == ["0.10.0", "0.15.7"]
|
|
145
|
+
|
|
146
|
+
def test_absent_keep_is_noted_and_ignored(self):
|
|
147
|
+
plan = yank.versions_to_yank(REAL_RELEASES, "1.0.0a1")
|
|
148
|
+
assert plan == ["0.3.0", "0.10.0", "0.15.7"]
|
|
149
|
+
assert yank.missing_keeps(REAL_RELEASES, "1.0.0a1") == ["1.0.0a1"]
|
|
150
|
+
|
|
151
|
+
def test_partially_missing_keep_list_keeps_the_rest(self):
|
|
152
|
+
plan = yank.versions_to_yank(REAL_RELEASES, "0.3.0,9.9.9")
|
|
153
|
+
assert "0.3.0" not in plan
|
|
154
|
+
assert "0.15.7" in plan
|
|
155
|
+
assert yank.missing_keeps(REAL_RELEASES, "0.3.0,9.9.9") == ["9.9.9"]
|
|
156
|
+
|
|
157
|
+
def test_empty_release_lists_are_skipped(self):
|
|
158
|
+
releases = {**REAL_RELEASES, "0.15.8": []}
|
|
159
|
+
plan = yank.versions_to_yank(releases, "1.0.0a1")
|
|
160
|
+
assert "0.15.8" not in plan
|
|
161
|
+
|
|
162
|
+
def test_keep_is_the_only_release(self):
|
|
163
|
+
plan = yank.versions_to_yank(
|
|
164
|
+
{"1.0.0a1": [{"filename": "agentic_dev_loop-1.0.0a1.tar.gz",
|
|
165
|
+
"yanked": False}]},
|
|
166
|
+
"1.0.0a1")
|
|
167
|
+
assert plan == []
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class TestFormParsing:
|
|
171
|
+
def test_yank_form_is_found(self):
|
|
172
|
+
forms = yank.parse_forms(YANK_PAGE)
|
|
173
|
+
form = yank.find_form(forms, "confirm_yank_version")
|
|
174
|
+
assert form is not None
|
|
175
|
+
assert form["action"] == \
|
|
176
|
+
"/manage/project/agentic-dev-loop/release/0.15.7/"
|
|
177
|
+
assert form["inputs"]["csrf_token"] == "TOKEN123"
|
|
178
|
+
|
|
179
|
+
def test_per_file_delete_form_is_not_the_yank_form(self):
|
|
180
|
+
forms = yank.parse_forms(YANK_PAGE)
|
|
181
|
+
form = yank.find_form(forms, "confirm_yank_version")
|
|
182
|
+
assert form["inputs"]["csrf_token"] == "TOKEN123"
|
|
183
|
+
assert "confirm_delete_version" not in form["inputs"]
|
|
184
|
+
|
|
185
|
+
def test_already_yanked_detected_via_unyank_form(self):
|
|
186
|
+
assert yank.already_yanked(yank.parse_forms(UNYANK_PAGE))
|
|
187
|
+
|
|
188
|
+
def test_already_yanked_false_on_yank_page(self):
|
|
189
|
+
assert not yank.already_yanked(yank.parse_forms(YANK_PAGE))
|
|
190
|
+
|
|
191
|
+
def test_reauth_detection(self):
|
|
192
|
+
forms = yank.parse_forms(REAUTH_PAGE)
|
|
193
|
+
assert yank.needs_reauth(forms)
|
|
194
|
+
form = yank.find_form(forms, "password")
|
|
195
|
+
assert form is not None
|
|
196
|
+
assert form["inputs"]["next_route"] == "manage.project.release"
|
|
197
|
+
assert form["action"] == "/account/reauthenticate/"
|
|
198
|
+
|
|
199
|
+
def test_reauth_not_detected_on_plain_pages(self):
|
|
200
|
+
assert not yank.needs_reauth(yank.parse_forms(YANK_PAGE))
|
|
201
|
+
|
|
202
|
+
def test_totp_form_is_found(self):
|
|
203
|
+
forms = yank.parse_forms(TWO_FACTOR_PAGE)
|
|
204
|
+
form = yank.find_form(forms, "totp_value")
|
|
205
|
+
assert form is not None
|
|
206
|
+
assert form["inputs"]["csrf_token"] == "TOKEN789"
|
|
207
|
+
|
|
208
|
+
def test_entities_in_inputs_are_unescaped(self):
|
|
209
|
+
html = ('<form method="POST" action="/x?a=1&b=2">'
|
|
210
|
+
'<input name="csrf_token" type="hidden" value=""q"">'
|
|
211
|
+
"</form>")
|
|
212
|
+
form = yank.parse_forms(html)[0]
|
|
213
|
+
assert form["action"] == "/x?a=1&b=2"
|
|
214
|
+
assert form["inputs"]["csrf_token"] == '"q"'
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class TestPostHeaders:
|
|
218
|
+
def test_posts_carry_the_origin_header(self):
|
|
219
|
+
# Load-bearing: warehouse checks the CSRF origin on every POST and
|
|
220
|
+
# answers HTTP 400 when neither Origin nor Referer is present,
|
|
221
|
+
# before any credential validation happens. Sending the Origin
|
|
222
|
+
# header is what makes the login POST survive long enough to ask
|
|
223
|
+
# for credentials.
|
|
224
|
+
headers = yank.post_headers()
|
|
225
|
+
assert headers["Origin"] == "https://pypi.org"
|
|
226
|
+
assert headers["Content-Type"] == "application/x-www-form-urlencoded"
|
|
227
|
+
assert headers["User-Agent"].startswith("agentic-dev-loop")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class TestYankPostBody:
|
|
231
|
+
def test_body_carries_version_reason_and_csrf(self):
|
|
232
|
+
form = yank.find_form(yank.parse_forms(YANK_PAGE),
|
|
233
|
+
"confirm_yank_version")
|
|
234
|
+
body = yank.yank_post_body(form, "0.15.7", "superseded")
|
|
235
|
+
assert body["confirm_yank_version"] == "0.15.7"
|
|
236
|
+
assert body["yanked_reason"] == "superseded"
|
|
237
|
+
assert body["csrf_token"] == "TOKEN123"
|
|
238
|
+
|
|
239
|
+
def test_body_without_reason_sends_empty_string(self):
|
|
240
|
+
form = yank.find_form(yank.parse_forms(YANK_PAGE),
|
|
241
|
+
"confirm_yank_version")
|
|
242
|
+
body = yank.yank_post_body(form, "0.15.7", "")
|
|
243
|
+
assert body["confirm_yank_version"] == "0.15.7"
|
|
244
|
+
assert body["yanked_reason"] == ""
|
|
245
|
+
assert body["csrf_token"] == "TOKEN123"
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class TestRedirectBackDetection:
|
|
249
|
+
def test_redirect_back_to_release_page_is_a_refusal(self):
|
|
250
|
+
location = "/manage/project/agentic-dev-loop/release/0.15.7/"
|
|
251
|
+
assert yank.yank_redirects_back(location, "agentic-dev-loop", "0.15.7")
|
|
252
|
+
|
|
253
|
+
def test_redirect_away_is_success(self):
|
|
254
|
+
location = "/manage/project/agentic-dev-loop/releases/"
|
|
255
|
+
assert not yank.yank_redirects_back(location, "agentic-dev-loop",
|
|
256
|
+
"0.15.7")
|
|
257
|
+
|
|
258
|
+
def test_absolute_location_is_parsed(self):
|
|
259
|
+
location = ("https://pypi.org/manage/project/agentic-dev-loop/"
|
|
260
|
+
"release/0.15.7/")
|
|
261
|
+
assert yank.yank_redirects_back(location, "agentic-dev-loop", "0.15.7")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
class TestLoginPageDetection:
|
|
265
|
+
def test_login_page_detected(self):
|
|
266
|
+
assert yank.is_login_page(yank.parse_forms(LOGIN_PAGE))
|
|
267
|
+
|
|
268
|
+
def test_reauth_page_is_not_login_page(self):
|
|
269
|
+
assert not yank.is_login_page(yank.parse_forms(REAUTH_PAGE))
|
|
270
|
+
|
|
271
|
+
def test_yank_page_is_not_login_page(self):
|
|
272
|
+
assert not yank.is_login_page(yank.parse_forms(YANK_PAGE))
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class TestPlanText:
|
|
276
|
+
def test_plan_names_every_version_to_yank(self):
|
|
277
|
+
text = yank.plan_text(REAL_RELEASES, "1.0.0a1", "agentic-dev-loop")
|
|
278
|
+
assert "agentic-dev-loop" in text
|
|
279
|
+
assert "keep: 1.0.0a1" in text
|
|
280
|
+
for version in ("0.3.0", "0.10.0", "0.15.7"):
|
|
281
|
+
assert version in text
|
|
282
|
+
|
|
283
|
+
def test_plan_notes_absent_keeps(self):
|
|
284
|
+
text = yank.plan_text(REAL_RELEASES, "0.3.0,9.9.9",
|
|
285
|
+
"agentic-dev-loop")
|
|
286
|
+
assert "note: keep '9.9.9' is not on PyPI" in text
|
|
287
|
+
|
|
288
|
+
def test_plan_notes_already_yanked_versions(self):
|
|
289
|
+
releases = {**REAL_RELEASES,
|
|
290
|
+
"0.15.0": [{"filename": "agentic_dev_loop-0.15.0.tar.gz",
|
|
291
|
+
"yanked": True}]}
|
|
292
|
+
text = yank.plan_text(releases, "1.0.0a1", "agentic-dev-loop")
|
|
293
|
+
assert "already fully yanked" in text
|
|
294
|
+
assert "0.15.0" in text
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class TestDefaultKeep:
|
|
298
|
+
def test_default_keep_is_the_pyproject_version(self):
|
|
299
|
+
import tomllib
|
|
300
|
+
|
|
301
|
+
data = tomllib.loads(
|
|
302
|
+
(REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
|
303
|
+
assert yank.default_keep() == data["project"]["version"]
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class TestDryRunCLI:
|
|
307
|
+
def test_dry_run_from_saved_dump_changes_nothing(self, tmp_path):
|
|
308
|
+
import json
|
|
309
|
+
import subprocess
|
|
310
|
+
import sys
|
|
311
|
+
|
|
312
|
+
dump = tmp_path / "dump.json"
|
|
313
|
+
dump.write_text(json.dumps({"releases": REAL_RELEASES}))
|
|
314
|
+
proc = subprocess.run(
|
|
315
|
+
[sys.executable, str(YANK), "--dry-run",
|
|
316
|
+
"--from-json", str(dump), "--keep", "1.0.0a1"],
|
|
317
|
+
capture_output=True, text=True,
|
|
318
|
+
)
|
|
319
|
+
assert proc.returncode == 0, proc.stderr
|
|
320
|
+
assert "dry run" in proc.stdout.lower()
|
|
321
|
+
assert "0.15.7" in proc.stdout
|
|
322
|
+
assert "0.3.0" in proc.stdout
|
|
323
|
+
assert "1.0.0a1" in proc.stdout
|
|
324
|
+
|
|
325
|
+
def test_dry_run_with_absent_keep_still_plans(self, tmp_path):
|
|
326
|
+
import json
|
|
327
|
+
import subprocess
|
|
328
|
+
import sys
|
|
329
|
+
|
|
330
|
+
dump = tmp_path / "dump.json"
|
|
331
|
+
dump.write_text(json.dumps({"releases": REAL_RELEASES}))
|
|
332
|
+
proc = subprocess.run(
|
|
333
|
+
[sys.executable, str(YANK), "--dry-run",
|
|
334
|
+
"--from-json", str(dump), "--keep", "9.9.9"],
|
|
335
|
+
capture_output=True, text=True,
|
|
336
|
+
)
|
|
337
|
+
assert proc.returncode == 0, proc.stderr
|
|
338
|
+
assert "not on PyPI" in proc.stdout
|
|
339
|
+
assert "0.15.7" in proc.stdout
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/__init__.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/actions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/agents.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/allowlist.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_coverage.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_prompt.md
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/brief_prompt.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/completion.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/containers.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/copilot_auth.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/dryrun.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/egress_policy.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/egress_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/forbidden.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/isolation.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/loaders.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/mounts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/outputs.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/presets.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/provider_wire.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/registry.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/run_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/secrets.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/stages.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/step_workspace.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/engine/sync_back.py
RENAMED
|
File without changes
|
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/__init__.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/metrics.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/render.py
RENAMED
|
File without changes
|
{agentic_dev_loop-1.0.0b1 → agentic_dev_loop-1.0.0rc2}/src/agentic_dev_loop/reporting/sources.py
RENAMED
|
File without changes
|