agent-scaffold-cli 0.2.255__tar.gz → 0.3.556__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.
- agent_scaffold_cli-0.3.556/.github/workflows/ci.yml +85 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/.github/workflows/publish.yml +5 -2
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/.gitignore +7 -3
- agent_scaffold_cli-0.3.556/.pre-commit-config.yaml +22 -0
- agent_scaffold_cli-0.3.556/CHANGELOG.md +217 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/CLAUDE.md +4 -2
- agent_scaffold_cli-0.3.556/Makefile +25 -0
- agent_scaffold_cli-0.2.255/README.md → agent_scaffold_cli-0.3.556/PKG-INFO +125 -17
- agent_scaffold_cli-0.2.255/PKG-INFO → agent_scaffold_cli-0.3.556/README.md +71 -52
- agent_scaffold_cli-0.3.556/install.sh +160 -0
- agent_scaffold_cli-0.3.556/pyproject.toml +176 -0
- agent_scaffold_cli-0.3.556/scripts/build_hooks.py +56 -0
- agent_scaffold_cli-0.3.556/scripts/embed_catalog.py +65 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/_embedded_catalog.json +1 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/auth.py +170 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/auth_browser.py +77 -14
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/branding.py +11 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/capabilities.py +770 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/capability_emit.py +282 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/catalog.py +625 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/cli.py +2487 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/cli_doctor.py +78 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/cli_interactive.py +190 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/cli_secrets.py +138 -9
- agent_scaffold_cli-0.3.556/src/agent_scaffold/cli_shared.py +75 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/cli_update.py +591 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/config.py +12 -3
- agent_scaffold_cli-0.3.556/src/agent_scaffold/context.py +861 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/contract.py +907 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/deploy/__init__.py +55 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/deploy/_common.py +118 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/deploy/fly.py +89 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/deploy/railway.py +86 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/deploy/vercel.py +88 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/discovery.py +833 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/envfile.py +122 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/eval/__init__.py +49 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/eval/_common.py +108 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/eval/promptfoo.py +182 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/framework_versions.py +157 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/generator.py +263 -9
- agent_scaffold_cli-0.3.556/src/agent_scaffold/language_hints.py +125 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/languages/python.yaml +4 -10
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/languages/typescript.yaml +6 -9
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/manifest.py +28 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/orchestrator.py +69 -4
- agent_scaffold_cli-0.3.556/src/agent_scaffold/pipeline.py +1319 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/plan.py +8 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/preflight.py +482 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/probes.py +340 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/progress.py +175 -4
- agent_scaffold_cli-0.3.556/src/agent_scaffold/prompts/system.md +95 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/prompts/system_strict.md +33 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/prompts/user_template.md +1 -1
- agent_scaffold_cli-0.3.556/src/agent_scaffold/prompts/validation_repair.md +46 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/_capabilities.py +67 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/commands.py +1241 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/drafts.py +305 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/readiness.py +117 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/repl/refine.py +159 -1
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/render.py +304 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/repl/session.py +100 -5
- agent_scaffold_cli-0.3.556/src/agent_scaffold/repl/shell.py +1692 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/report.py +260 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/run_log.py +310 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/run_summary.py +166 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/sources.py +108 -14
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/__init__.py +172 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/_subprocess.py +12 -8
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_evals.py +177 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_kafka.py +307 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_langfuse.py +174 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_langsmith.py +215 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_observability.py +282 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/bootstrap_vector_db.py +321 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/docker_up.py +550 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/emit_deploy_configs.py +152 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/install_deps.py +5 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/launch_backend.py +407 -0
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/launch_frontend.py +428 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/migrations.py +8 -7
- agent_scaffold_cli-0.3.556/src/agent_scaffold/steps/open_editor.py +178 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/seed.py +1 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/smoke_test.py +1 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/wire_credentials.py +44 -62
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/template_snapshot.py +2 -2
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/validator.py +87 -33
- agent_scaffold_cli-0.3.556/src/agent_scaffold/welcome.py +320 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/writer.py +79 -0
- agent_scaffold_cli-0.3.556/tests/conftest.py +84 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/catalog_minimal.yaml +132 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/README.md +5 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/SCHEMA.md +5 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/cache/redis.md +17 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/eval/promptfoo.md +14 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/frontend/nextjs-tiny.md +13 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/frontend/templates/nextjs-tiny/app/api/agent/route.ts +1 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/frontend/templates/nextjs-tiny/app/page.tsx +1 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/frontend/templates/nextjs-tiny/package.json +1 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/host/templates/vercel.json +1 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/host/vercel-single.md +15 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/host/vercel.md +18 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/malformed/no_frontmatter.md +3 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/malformed/wrong_path.md +10 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/obs/langfuse.md +18 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/obs/langsmith.md +15 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/capabilities/vector_db/qdrant.md +28 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/cross-cutting/multi-tenancy.md +4 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/cross-cutting/observability.md +4 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/frameworks/langgraph.md +11 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/frameworks/pydantic-ai.md +11 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/frameworks/vercel-ai-sdk.md +13 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/README.md +5 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/SCHEMA.md +4 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/framework-composes-override.md +10 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/framework-mixed-aliases.md +8 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/with-advanced-fields.md +37 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/with-capabilities.md +17 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/with-load-list-and-prose.md +14 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_deployments/docs/recipes/with-load-list.md +19 -0
- agent_scaffold_cli-0.3.556/tests/fixtures/mock_responses/patch_response.json +8 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_no_shell_true.py +4 -1
- agent_scaffold_cli-0.3.556/tests/security/test_secrets_never_reach_llm.py +222 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_secrets_purge.py +3 -1
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/conftest.py +2 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_evals.py +351 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_kafka.py +218 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_langfuse.py +102 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_langsmith.py +188 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_observability.py +159 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_bootstrap_vector_db.py +286 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_docker_up.py +444 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_emit_deploy_configs.py +124 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_launch_backend.py +436 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_launch_frontend.py +390 -0
- agent_scaffold_cli-0.3.556/tests/steps/test_open_editor.py +154 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_wire_credentials.py +39 -4
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_auth_browser.py +66 -0
- agent_scaffold_cli-0.3.556/tests/test_capabilities.py +427 -0
- agent_scaffold_cli-0.3.556/tests/test_capability_emit.py +185 -0
- agent_scaffold_cli-0.3.556/tests/test_capability_override.py +114 -0
- agent_scaffold_cli-0.3.556/tests/test_catalog.py +308 -0
- agent_scaffold_cli-0.3.556/tests/test_catalog_advanced_fields.py +287 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_cli_e2e.py +19 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_customize_and_layer.py +160 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_down_frontend.py +118 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_eval.py +319 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_lifecycle.py +255 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_logs_frontend.py +113 -0
- agent_scaffold_cli-0.3.556/tests/test_cmd_new_autorun.py +291 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_context.py +219 -33
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_context_blueprint_links.py +24 -2
- agent_scaffold_cli-0.3.556/tests/test_context_budget_prompt.py +88 -0
- agent_scaffold_cli-0.3.556/tests/test_context_cache_tiers.py +278 -0
- agent_scaffold_cli-0.3.556/tests/test_context_capability_tier.py +152 -0
- agent_scaffold_cli-0.3.556/tests/test_contract.py +280 -0
- agent_scaffold_cli-0.3.556/tests/test_contract_app_service.py +161 -0
- agent_scaffold_cli-0.3.556/tests/test_contract_compose_merge.py +175 -0
- agent_scaffold_cli-0.3.556/tests/test_contract_frontend_collision.py +96 -0
- agent_scaffold_cli-0.3.556/tests/test_contract_frontend_service.py +185 -0
- agent_scaffold_cli-0.3.556/tests/test_deploy_plugins.py +166 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_discovery.py +51 -1
- agent_scaffold_cli-0.3.556/tests/test_discovery_advanced_fields.py +108 -0
- agent_scaffold_cli-0.3.556/tests/test_discovery_capabilities.py +42 -0
- agent_scaffold_cli-0.3.556/tests/test_discovery_warning_dedup.py +62 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_doctor.py +8 -0
- agent_scaffold_cli-0.3.556/tests/test_eval_plugin_promptfoo.py +298 -0
- agent_scaffold_cli-0.3.556/tests/test_formatter_frontend.py +98 -0
- agent_scaffold_cli-0.3.556/tests/test_framework_versions.py +194 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_generator.py +30 -0
- agent_scaffold_cli-0.3.556/tests/test_language_hints.py +99 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_pipeline.py +39 -1
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_plan.py +23 -0
- agent_scaffold_cli-0.3.556/tests/test_preflight_gate.py +417 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_probes.py +84 -0
- agent_scaffold_cli-0.3.556/tests/test_probes_capabilities.py +217 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_progress.py +145 -0
- agent_scaffold_cli-0.3.556/tests/test_project_vault.py +160 -0
- agent_scaffold_cli-0.3.556/tests/test_prompts_capability_aware.py +88 -0
- agent_scaffold_cli-0.3.556/tests/test_recipe_tier_inference.py +106 -0
- agent_scaffold_cli-0.3.556/tests/test_repair_loop.py +496 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_autorun.py +217 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_commands.py +1112 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_drafts.py +239 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_lifecycle_commands.py +138 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_readiness.py +275 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_repl_refine.py +99 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_repl_session.py +70 -0
- agent_scaffold_cli-0.3.556/tests/test_repl_shell.py +1176 -0
- agent_scaffold_cli-0.3.556/tests/test_report.py +118 -0
- agent_scaffold_cli-0.3.556/tests/test_resolved_stack_by_kind.py +81 -0
- agent_scaffold_cli-0.3.556/tests/test_run_log.py +181 -0
- agent_scaffold_cli-0.3.556/tests/test_run_summary.py +124 -0
- agent_scaffold_cli-0.3.556/tests/test_run_up_inline.py +532 -0
- agent_scaffold_cli-0.3.556/tests/test_scaffold_alias.py +40 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_sources.py +72 -0
- agent_scaffold_cli-0.3.556/tests/test_sources_vendored.py +132 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_up_cli.py +103 -6
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_update_cli.py +4 -4
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_validator.py +45 -1
- agent_scaffold_cli-0.3.556/tests/test_welcome.py +356 -0
- agent_scaffold_cli-0.3.556/tests/test_wizard_layer_walk.py +146 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_writer.py +92 -0
- agent_scaffold_cli-0.3.556/uv.lock +2049 -0
- agent_scaffold_cli-0.2.255/.github/workflows/ci.yml +0 -38
- agent_scaffold_cli-0.2.255/CHANGELOG.md +0 -90
- agent_scaffold_cli-0.2.255/Makefile +0 -17
- agent_scaffold_cli-0.2.255/pyproject.toml +0 -110
- agent_scaffold_cli-0.2.255/scripts/sync_deployments.sh +0 -25
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/__init__.py +0 -15
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/README.md +0 -23
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/audit-logging.md +0 -258
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/auth-jwt.md +0 -242
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/authorization-rbac.md +0 -272
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/backpressure.md +0 -189
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/caching-strategies.md +0 -282
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/cost-tracking.md +0 -181
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/distributed-locking.md +0 -201
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/dlq-operations.md +0 -142
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/health-graceful-shutdown.md +0 -275
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/idempotency.md +0 -182
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/logging-structured.md +0 -196
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/model-routing.md +0 -171
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/multi-tenancy.md +0 -274
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/observability.md +0 -266
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/pii-gdpr.md +0 -235
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/rate-limiting.md +0 -171
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/resilience.md +0 -342
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/schema-evolution.md +0 -219
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/security-hardening.md +0 -197
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/testing-strategy.md +0 -261
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/cross-cutting/validation-strategy.md +0 -287
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/README.md +0 -22
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/crewai.md +0 -91
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/langgraph.md +0 -151
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/mastra.md +0 -74
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/pydantic-ai.md +0 -77
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/frameworks/vercel-ai-sdk.md +0 -83
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/README.md +0 -28
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/event-driven.md +0 -82
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/memory.md +0 -82
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/multi-agent-flat.md +0 -72
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/multi-agent-hierarchical.md +0 -83
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/parallel-calls.md +0 -73
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/plan-execute-reflect.md +0 -77
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/prompt-chaining.md +0 -73
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/rag.md +0 -84
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/react.md +0 -77
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/patterns/routing-tool-use.md +0 -69
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/README.md +0 -40
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/code-review-agent.md +0 -518
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/content-pipeline.md +0 -525
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/customer-support-triage.md +0 -1704
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/docs-rag-qa.md +0 -1254
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/hierarchical-agent.md +0 -554
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/memory-assistant.md +0 -499
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/ops-crew.md +0 -457
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/parallel-enricher.md +0 -457
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/research-assistant.md +0 -1096
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/recipes/restaurant-rebooking.md +0 -1056
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/README.md +0 -19
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/api-fastapi.md +0 -112
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/api-hono.md +0 -108
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/background-jobs.md +0 -255
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/cache-redis.md +0 -190
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/connection-pooling-pgbouncer.md +0 -155
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/eval-deepeval-ragas-promptfoo.md +0 -164
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/feature-flags.md +0 -207
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/kafka.md +0 -238
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/kubernetes-helm.md +0 -346
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/llm-claude.md +0 -105
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/log-aggregation.md +0 -198
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/opentelemetry.md +0 -248
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/prometheus-grafana.md +0 -232
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/relational-postgres.md +0 -124
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/secrets-management.md +0 -230
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/terraform.md +0 -292
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/tool-protocol-mcp.md +0 -275
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/tracing-langfuse.md +0 -110
- agent_scaffold_cli-0.2.255/src/agent_scaffold/_bundled_deployments/docs/stack/vector-qdrant.md +0 -121
- agent_scaffold_cli-0.2.255/src/agent_scaffold/cli.py +0 -1884
- agent_scaffold_cli-0.2.255/src/agent_scaffold/cli_shared.py +0 -18
- agent_scaffold_cli-0.2.255/src/agent_scaffold/context.py +0 -538
- agent_scaffold_cli-0.2.255/src/agent_scaffold/contract.py +0 -145
- agent_scaffold_cli-0.2.255/src/agent_scaffold/discovery.py +0 -313
- agent_scaffold_cli-0.2.255/src/agent_scaffold/language_hints.py +0 -63
- agent_scaffold_cli-0.2.255/src/agent_scaffold/pipeline.py +0 -773
- agent_scaffold_cli-0.2.255/src/agent_scaffold/prompts/system.md +0 -21
- agent_scaffold_cli-0.2.255/src/agent_scaffold/repl/commands.py +0 -551
- agent_scaffold_cli-0.2.255/src/agent_scaffold/repl/render.py +0 -147
- agent_scaffold_cli-0.2.255/src/agent_scaffold/repl/shell.py +0 -706
- agent_scaffold_cli-0.2.255/src/agent_scaffold/steps/__init__.py +0 -109
- agent_scaffold_cli-0.2.255/src/agent_scaffold/steps/docker_up.py +0 -313
- agent_scaffold_cli-0.2.255/src/agent_scaffold/steps/open_editor.py +0 -124
- agent_scaffold_cli-0.2.255/tests/conftest.py +0 -32
- agent_scaffold_cli-0.2.255/tests/fixtures/mock_deployments/docs/frameworks/langgraph.md +0 -3
- agent_scaffold_cli-0.2.255/tests/fixtures/mock_deployments/docs/frameworks/pydantic-ai.md +0 -3
- agent_scaffold_cli-0.2.255/tests/fixtures/mock_deployments/docs/frameworks/vercel-ai-sdk.md +0 -3
- agent_scaffold_cli-0.2.255/tests/steps/test_docker_up.py +0 -205
- agent_scaffold_cli-0.2.255/tests/steps/test_open_editor.py +0 -113
- agent_scaffold_cli-0.2.255/tests/test_contract.py +0 -166
- agent_scaffold_cli-0.2.255/tests/test_language_hints.py +0 -36
- agent_scaffold_cli-0.2.255/tests/test_repl_commands.py +0 -543
- agent_scaffold_cli-0.2.255/tests/test_repl_shell.py +0 -443
- agent_scaffold_cli-0.2.255/uv.lock +0 -995
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/.env.example +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/CODE_OF_CONDUCT.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/CONTRIBUTING.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/LICENSE +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/SECURITY.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/docs/design/orchestrator.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/docs/design/security.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/__main__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/_filesec.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/_redact.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/_scaffold_dir.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/cache.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/cli_auth.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/costs.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/doctor.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/effort.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/imports.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/languages/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/merge.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/prompts/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/prompts/repair.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/prompts/single_file.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/repl/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/steps/commit_push.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/src/agent_scaffold/topology.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/cross-cutting/authorization-rbac.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/cross-cutting/logging-structured.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/cross-cutting/rate-limiting.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/cross-cutting/testing-strategy.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/patterns/event-driven.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/patterns/loop-a.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/patterns/loop-b.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/patterns/rag.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/patterns/react.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/bad-recipe-deps.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/bad-required-files.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/conflict-recipe-deps.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/customer-support-triage.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/cycle-recipe.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/docs-rag-qa.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/event-driven-recipe.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/lonely-recipe.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/missing-ref-recipe.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/no-h1-recipe.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/with-external-services.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/with-recipe-deps.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/recipes/with-required-files.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_deployments/docs/stack/vector-qdrant.md +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_responses/dirty_python.json +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_responses/malformed.txt +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_responses/valid_python.json +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/mock_responses/valid_python_fenced.txt +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/fixtures/steps.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_argv_no_secrets.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_filesec.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_gitignore_enforcement.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_no_input_for_secrets.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_redact.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/security/test_secret_typing.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/__init__.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_commit_push.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_install_deps.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_migrations.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_seed.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_smoke_test.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/steps/test_subprocess.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_auth.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_config.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_costs_preflight.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_effort.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_imports.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_manifest.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_merge.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_orchestrator.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_repl_render.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_template_snapshot.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_topology.py +0 -0
- {agent_scaffold_cli-0.2.255 → agent_scaffold_cli-0.3.556}/tests/test_up_cli_full.py +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
# Gates are independent jobs (no `needs:`) so they all run on every push and a
|
|
10
|
+
# PR author sees the full list of failures at once, not one-at-a-time.
|
|
11
|
+
jobs:
|
|
12
|
+
lint:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v3
|
|
18
|
+
- run: uv python install 3.12
|
|
19
|
+
- run: uv sync --dev
|
|
20
|
+
- name: Ruff lint
|
|
21
|
+
run: uv run ruff check src/ tests/
|
|
22
|
+
- name: Ruff format check
|
|
23
|
+
run: uv run ruff format --check src/ tests/
|
|
24
|
+
|
|
25
|
+
typecheck:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v3
|
|
31
|
+
- run: uv python install 3.12
|
|
32
|
+
- run: uv sync --dev
|
|
33
|
+
- name: mypy
|
|
34
|
+
run: uv run mypy src/
|
|
35
|
+
|
|
36
|
+
test:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
strategy:
|
|
39
|
+
fail-fast: false
|
|
40
|
+
matrix:
|
|
41
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- name: Install uv
|
|
45
|
+
uses: astral-sh/setup-uv@v3
|
|
46
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
47
|
+
run: uv python install ${{ matrix.python-version }}
|
|
48
|
+
- run: uv sync --dev
|
|
49
|
+
# `fail_under = 80` lives in [tool.coverage.report] (pyproject.toml), so
|
|
50
|
+
# pytest-cov exits non-zero if coverage regresses below the floor.
|
|
51
|
+
- name: Test + coverage gate
|
|
52
|
+
run: uv run pytest --cov=agent_scaffold --cov-report=term-missing
|
|
53
|
+
|
|
54
|
+
security:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- name: Install uv
|
|
59
|
+
uses: astral-sh/setup-uv@v3
|
|
60
|
+
- run: uv python install 3.12
|
|
61
|
+
# Audit the fully-resolved dependency tree (uv.lock) for known CVEs.
|
|
62
|
+
- name: Export locked dependencies
|
|
63
|
+
run: uv export --format requirements-txt --no-emit-project --no-hashes -o requirements.txt
|
|
64
|
+
- name: pip-audit
|
|
65
|
+
uses: pypa/gh-action-pip-audit@v1.1.0
|
|
66
|
+
with:
|
|
67
|
+
inputs: requirements.txt
|
|
68
|
+
|
|
69
|
+
build:
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v4
|
|
73
|
+
- name: Install uv
|
|
74
|
+
uses: astral-sh/setup-uv@v3
|
|
75
|
+
- run: uv python install 3.12
|
|
76
|
+
# Catch packaging breaks in PRs instead of at release time: build the
|
|
77
|
+
# wheel, install it clean, and confirm both console scripts resolve.
|
|
78
|
+
- name: Build wheel + sdist
|
|
79
|
+
run: uv build
|
|
80
|
+
- name: Smoke-install the wheel
|
|
81
|
+
run: |
|
|
82
|
+
python -m venv /tmp/smoke
|
|
83
|
+
/tmp/smoke/bin/pip install dist/*.whl
|
|
84
|
+
/tmp/smoke/bin/agent-scaffold --version
|
|
85
|
+
/tmp/smoke/bin/scaffold --help > /dev/null
|
|
@@ -22,8 +22,11 @@ jobs:
|
|
|
22
22
|
- name: Set up Python
|
|
23
23
|
run: uv python install 3.11
|
|
24
24
|
|
|
25
|
-
- name:
|
|
26
|
-
|
|
25
|
+
- name: Refresh embedded catalog
|
|
26
|
+
# Bakes the latest deployments catalog into _embedded_catalog.json
|
|
27
|
+
# for the offline fallback path. Idempotent; only updates if the
|
|
28
|
+
# upstream catalog has changed since the file was last committed.
|
|
29
|
+
run: uv run scripts/embed_catalog.py
|
|
27
30
|
|
|
28
31
|
- name: Build wheel and sdist
|
|
29
32
|
run: uv build
|
|
@@ -31,6 +31,10 @@ Thumbs.db
|
|
|
31
31
|
.env
|
|
32
32
|
.env.local
|
|
33
33
|
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
# Test cache artifacts — some tests use mock_deployments_path / ".cache" as
|
|
35
|
+
# a Config cache_dir, which triggers a real catalog fetch into the fixture
|
|
36
|
+
# tree. These files are byproducts; never commit them.
|
|
37
|
+
tests/fixtures/mock_deployments/.cache/
|
|
38
|
+
|
|
39
|
+
# Wheel build artifacts (the embedded catalog ships in the wheel itself).
|
|
40
|
+
dist/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Mirror the CI lint/type gates locally so issues surface before push.
|
|
2
|
+
# Install once with `uv run pre-commit install` (or `pipx run pre-commit install`).
|
|
3
|
+
# Keep `rev` in sync with the ruff pin in pyproject.toml's dev group.
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
6
|
+
rev: v0.6.9
|
|
7
|
+
hooks:
|
|
8
|
+
- id: ruff
|
|
9
|
+
args: [--fix]
|
|
10
|
+
- id: ruff-format
|
|
11
|
+
|
|
12
|
+
- repo: local
|
|
13
|
+
hooks:
|
|
14
|
+
# mypy runs through `uv run` so it sees the project's resolved env and the
|
|
15
|
+
# same strict config CI uses; it type-checks the whole package, not just
|
|
16
|
+
# staged files, so pass_filenames is off.
|
|
17
|
+
- id: mypy
|
|
18
|
+
name: mypy (strict, src/)
|
|
19
|
+
entry: uv run mypy src/
|
|
20
|
+
language: system
|
|
21
|
+
types: [python]
|
|
22
|
+
pass_filenames: false
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## 0.3.556 (2026-06-22)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **The chat sends you to a secure setup page instead of erroring.** Every chat agent checks readiness on load (`GET /ready` on the verbatim `agent_key_setup` module) and, if anything mandatory is missing, shows a full-screen **setup gate** (not the chat) listing the **mandatory** Anthropic key + any **tool/integration** credentials it needs, plus **optional** services (LangSmith, a managed `REDIS_URL`); a **Configure →** button does a full-page redirect to the backend's **CSRF-guarded `/setup`** page. The form and every value live **only on that backend page** — never on the chat surface (the BFF / OAuth-device-flow pattern) — and after saving it redirects back, where the chat re-checks and loops until the agent can actually communicate. A `/chat` that fails because a key is **missing or wrong** bounces back to `/setup` too (`credential_error_response`). The scaffold derives the field list + requiredness from the resolved stack (`build_setup_fields`: key + non-`obs` credentials required, observability + managed URLs optional, internal wiring excluded) and passes it as `AGENT_SETUP_FIELDS`. It also distinguishes **"can't reach the agent — is it running?"** from **"needs config"**. Works for **every recipe pattern**.
|
|
12
|
+
|
|
13
|
+
- **Connect a managed service over the sandbox default — `/config <VAR>`.** `/config` now takes an optional var name: `/config REDIS_URL` (or `/config LANGCHAIN_PROJECT`, etc.) captures just that one value through the same secure browser form (credentials) / no-echo prompt (config knobs) and exports it to the run env, so `up` forwards it and the in-sandbox container is simply unused. Lets you point an agent at an external/managed Redis or a custom LangSmith project without leaving the sandbox-by-default model. Hints added for `REDIS_URL` (the `rediss://` managed shape) and the LangSmith `LANGCHAIN_PROJECT`/`LANGCHAIN_ENDPOINT` knobs.
|
|
14
|
+
|
|
15
|
+
- **The chat can capture its API key at runtime.** A new `auth.key-bootstrap` capability (auto-included for Python chat agents) lets a freshly-cloned project `docker compose up` and start chatting after pasting a key once — no pre-wired env needed. When the backend has no `ANTHROPIC_API_KEY`, `POST /chat` returns `409 {"setup_url": "/setup"}`; the chat UI shows a "Connect API key" button that opens a CSRF-guarded `/setup` form served by the backend; the key is written to `.env.local` (mode 0600) and the process env — **never** sent to the browser, placed in a model prompt, or logged. The scaffold adds a new `auth` capability kind, auto-includes `auth.key-bootstrap` when a chat frontend is active on a Python backend (`resolve(..., default_key_bootstrap=True)`, inert-safe if absent), and the generation system prompt instructs the model to mount the emitted `agent_key_setup.py` router and gate `/chat` with it. `/setup` is dev-sandbox-only (default on; `AGENT_KEY_SETUP=0` disables it for production).
|
|
16
|
+
|
|
17
|
+
- **"Describe your agent" first step + a guaranteed chat contract.** The `/new` wizard now opens with a free-text *describe your agent* prompt. Claude Haiku turns it into (a) a **suggested recipe** (pre-selected, so the recipe step offers keep/change), (b) the agent's **system prompt** (`agent_role`), and (c) a short **title** (`agent_title`). The role flows through `SessionState` → `PipelineInputs` → `GenerationRequest` into the generation prompt (a new `# Agent role` block) and the cache key, so the generated backend adopts it as its system message; the title is passed as a `VITE_AGENT_TITLE` build arg to the containerized chat frontend so the test UI reflects the agent. Recipes can ship a default persona via a new `agent_role` frontmatter field (used when the user skips the step). The CLI gets `--describe` for parity. And the backend↔frontend **`POST /chat`** contract is now canonical and scaffold-guaranteed — non-streaming JSON `{"message"}` → `{"reply"}`: the system prompt requires it whenever a chat frontend is attached, and a new `assert_chat_endpoint` backstop feeds the repair loop when a generated backend forgets the route. Empty description skips cleanly (no API call); a Haiku hiccup degrades to the plain recipe picker.
|
|
18
|
+
|
|
19
|
+
- **The REPL prompt is a real input box.** Each turn now sits in its own space: a dim rule above (labeled with the active recipe) and a live bottom toolbar below showing the current recipe / model / docker mode plus the key hints. Input is **multiline** — `Enter` submits (or accepts a highlighted completion), `Alt+Enter` inserts a newline so a long refinement can span lines and the box grows with it. Ctrl-D still exits, Ctrl-L clears; the change stays line-based (no full-screen takeover), so Rich output and history scroll normally.
|
|
20
|
+
- **Credentials enter through a secure local browser form, not the terminal.** `/config` now opens the same `127.0.0.1` paste form the Anthropic `auth login` flow uses for *every* credential it needs — the value goes from the form straight to the keychain/0600 file (or the run env for non-key secrets) and is never typed or echoed in the REPL. The form names the credential and shows where to get one (the `/config` hints, now in-page); it stays CSRF-guarded and local-only. `browser_paste_flow` is generalized (`label` / `hint` / `placeholder`) and `fill_missing(..., secure=True)` drives it, falling back to no-echo getpass when no browser is available (headless / SSH).
|
|
21
|
+
- **Every agent ships a frontend by default.** When a recipe declares no `frontend.*` capability of its own, capability resolution now auto-includes the default `frontend.minimal-chat` (`resolve(..., default_frontend=True)` on the generation paths) — so every generated project gets a frontend + backend in the docker sandbox, no per-recipe authoring. A recipe that already declares a frontend keeps it; and the auto-include is **inert-safe** — if the catalog doesn't have `frontend.minimal-chat` yet, nothing is added and no "unresolved" warning fires.
|
|
22
|
+
- **`/up` and `/down` work inside the REPL.** They were print-only stubs ("exit the REPL to run this"). Now `/up` restarts the project's stack — it tears down this project's previous run first (reclaiming its ports, only this project's containers — never unrelated host processes), then brings it up fresh on the canonical ports and shows the live URLs; `/down` (`/down -v` to also drop volumes) stops all the project's containers via `docker compose down`. Both reuse the terminal `_run_up_inline` / teardown helpers (refactored into a shared `_down_inline`).
|
|
23
|
+
- **Frontend can run as a container in the sandbox.** A frontend capability that sets `serve_in_container: true` (it ships a `frontend/Dockerfile`) now gets a built `frontend` service in the generated `docker-compose.yml` — a new deterministic `normalize_frontend_service` pass (mirror of the backend one) adds `build: ./frontend`, the UI port, the backend URL wired to the **host-mapped** backend port (the browser runs on the host, so it reaches the backend at `localhost`, not the in-network name), and `depends_on` the backend. `LaunchFrontendStep` gains `served_by_docker`, skipping the local `pnpm dev` when the frontend is the container. So one `docker compose up` brings up frontend + backend as containers. The pass stays inert until a capability opts in (`serve_in_container`), so it never references a missing build — a frontend without a Dockerfile still runs locally.
|
|
24
|
+
- **One-click run: the wizard flows straight into generate + Docker.** After `/new` collects your selections it now auto-offers to generate — a single confirm (default yes) ships it, no separate `/generate` needed. The config gate still applies: if a required credential is missing the flow breaks with a "configure X via `/config`" directive instead of auto-running (and `/config` works inline in the wizard's refine loop). Post-generate, the stack defaults to **running in Docker** when Docker is usable — `use_docker` is now tri-state (`None` = auto, `/docker on|off` forces it) and resolves to containers-when-available, falling back to local processes otherwise — so generation flows into the whole multi-container stack coming up with one keystroke.
|
|
25
|
+
- **Named selection drafts in the REPL.** Your recipe/language/framework/capability picks now persist to `~/.cache/agent-scaffold/drafts/<name>.json` (atomic, schema-versioned — the `orchestrator.state.json` pattern), auto-saved on every selection change so an accidental exit loses nothing. `/drafts` lists them (most recent first, with relative timestamps); `/draft save [name]`, `/draft load <name>` (re-resolves the recipe from its slug against the current deployments, degrading gracefully if it was removed), and `/draft delete <name>` manage them. At most **3** drafts are kept — a new save beyond the cap evicts the oldest. Drafts hold selections only, never secrets. On shell open a one-line hint surfaces any saved drafts to resume.
|
|
26
|
+
- **REPL `/config`, a real `/status`, and a blocking generate-gate.** The `scaffold` shell is now the complete setup surface: `/config` walks the credentials the current selections need — the Anthropic key (stored to the keyring/file backend) plus any external service/tool secret — and prompts for the missing ones without echoing; docker-provided infra (postgres/redis) is never asked for since `up` wires it. `/status` is now a fast, local readiness check (Anthropic key, Docker availability, the selected stack's env vars) instead of a "run this outside the REPL" stub. And `/generate` gains a blocking pre-check: if a required credential is missing it refuses to spend tokens, names the gap, and points at `/config` — selections are kept, so nothing is lost. All three route through one `repl/readiness.py` module so they agree on what "configured" means.
|
|
27
|
+
- **Grouped `--help` + a REPL-first banner.** The terminal `--help` now groups commands into "Start here / Setup / Generate / Run & deploy" panels (Typer `rich_help_panel`) instead of one flat list, and the bare-command banner leads with `scaffold` as the one entry point — the `agent-scaffold <verb>` commands are framed as the scripting/CI layer.
|
|
28
|
+
|
|
29
|
+
- **Tiered prompt-cache breakpoints.** Recipes with a structured `load_list` now produce cache-tier context segments: stable docs (blueprints patterns, frameworks, stack, project-layout) form a **hot** block cached with Anthropic's 1-hour TTL; the recipe body, capabilities, and remaining docs form a **warm** block on the default 5-minute TTL; the per-run project tail stays uncached. With the system block (1h in tiered mode — the API requires 1h entries before 5m ones) that's 3 of the 4 allowed breakpoints. Hot-tier docs survive warm-tier churn between runs, so re-generating in the same hour re-reads the expensive pattern/framework corpus at 0.1× price. Blocks under the minimum cacheable size collapse into their neighbor; recipes without a `load_list` keep the existing single cached context block. `load_list[].cache_tier` is honored when authored, with the same path-based defaults the deployments catalog generator publishes.
|
|
30
|
+
- **Alias-scan demotion.** When a recipe declares a `load_list`, the alias and cross-cutting prose scans are skipped — the author's curated declaration wins over heuristics (a stray "redis" in a design-rationale paragraph no longer pulls in the whole stack doc). Explicit Composes links and the transitive walk still apply; recipes without a `load_list` keep today's heuristic behavior unchanged.
|
|
31
|
+
- **Post-`up` smoke repair (one round).** When the `smoke_test` step fails during `up`/autorun, interactive runs are offered a single model-driven repair round: the failure output and implicated files go through the same repair engine as the post-write loop, the patch is written atomically, and the smoke step re-runs. Hard-capped at one round, so worst-case LLM calls per golden-path run stay at generate + 2 validation repairs + 1 smoke repair. Never offered in `--yes`/non-interactive runs.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **`up` rebuilds the image, so the container never serves stale code.** `docker_up` ran `docker compose up -d --wait` without `--build`, so once an image existed Compose reused it — a regenerated backend (e.g. one that gained `POST /chat` from the canonical-chat work) kept serving the *old* routes. The browser's `POST /chat` then hit a 404, its CORS preflight 404'd with no headers, and the chat showed a bare **"Could not reach the agent: Failed to fetch"** (never the 409 setup flow). `up` now passes `--build` (both the whole-stack and declared-service paths); Docker's layer cache keeps it fast when nothing changed.
|
|
36
|
+
- **The "Ready" panel now shows the frontend URL, and cross-origin chat works.** Two issues made a generated chat agent look broken. (1) The post-`up` panel listed only the backend — `welcome.py:_frontend_row` read the port solely from `.scaffold/frontend.pid`, which the docker path never writes (the frontend runs as the compose `frontend` container), and unlike the backend row it had no fallback. It now surfaces **`http://localhost:3000`** whenever a `frontend.*` capability is in the manifest (and the browser-open prompt offers it too), so the reachable chat is always discoverable. (2) CORS wasn't guaranteed — the static frontend (`:3000`) calls the backend (`:8000`) cross-origin, but nothing instructed the generated backend to allow it, so a generation that omitted `CORSMiddleware` showed "could not reach the agent". The generation prompt now requires CORS, and a new `assert_cors` backstop (mirroring `assert_chat_endpoint`) feeds the repair loop when a containerized frontend ships without it.
|
|
37
|
+
- **Selecting Langfuse no longer dangles its `depends_on: postgres`.** Capability `requires:` (e.g. `obs.langfuse` requires `relational.postgres`) was parsed away by the catalog reader, so a recipe that selected Langfuse without postgres generated a compose with `depends_on: [postgres]` pointing at a service that was never added. `Capability` now carries `requires`, and `resolve()` auto-adds the dependency (transitively, honoring explicit removals; an unknown dep falls to `unresolved` like any id) — mirroring the default-frontend auto-include. So Langfuse pulls in postgres automatically and the stack comes up.
|
|
38
|
+
- **The containerized frontend now actually reaches the backend, and its image builds.** Two bugs broke the Docker-sandbox frontend end to end. (1) `normalize_frontend_service` wired the backend URL as a runtime `environment:` entry on the `frontend` service — but a static Vite build inlines `VITE_*` at **build time** and nginx serving the bundle ignores runtime env, so the URL did nothing and the UI always called the baked-in default. It's now passed as a **`build.args`** value, feeding the Dockerfile's `ARG VITE_AGENT_URL`, so the bundle points at the real host-mapped backend port. (2) The companion `frontend.minimal-chat` template (in agent-deployments) built with `npm ci` (which hard-fails with no committed `package-lock.json`) and `tsc -b && vite build` (composite/strict type-check could block the image) — now `npm install` + `vite build`, so `docker compose up` builds the frontend cleanly. Regenerate an affected project to pick up both.
|
|
39
|
+
- **No more phantom services in the welcome panel.** Every post-generate path (the panel, `up`, `status`, deploy-target resolution) re-derived the capability stack from the *recipe's declared* capabilities, discarding the user's REPL `/observability` swap — so a recipe defaulting to `obs.langfuse` showed a `Langfuse localhost:3001` row (langfuse's own port) even when the user chose langsmith and nothing langfuse was running. The stack is now resolved from the manifest's **chosen** capability ids (`_resolve_capability_stack_silently(recipe, capabilities=manifest.capabilities)`), so the panel reflects what was actually generated and launched.
|
|
40
|
+
- **`/config` prompts only real credentials, with hints.** Non-secret config knobs a capability declares (e.g. `LANGCHAIN_TRACING_V2`, `LANGCHAIN_PROJECT`, `LANGCHAIN_ENDPOINT` — flags/names/endpoints with sensible defaults) are now shown ✓ "config" and never prompted; only actual credentials (by a `KEY`/`TOKEN`/`SECRET`/`PASSWORD` name heuristic) are asked for — the required Anthropic key, then optional cloud credentials behind a default-no confirm. Each credential prompt shows where to get it (e.g. `LANGCHAIN_API_KEY → smith.langchain.com → Settings → API Keys`). No more being asked to "fill" four LangSmith vars when only one is a secret.
|
|
41
|
+
- **Only the Anthropic key blocks generation — the rest is "connect later".** The REPL gate previously demanded *every* env var a capability declared, so selecting `obs.langsmith` made all four `LANGCHAIN_*` vars required even though tracing is optional and only `LANGCHAIN_API_KEY` is a credential. Now the agent key is the sole hard requirement; docker-provided infra (postgres/redis) is shown ✓ "in sandbox" (the containers supply it — no longer a confusing unconfigured ✓), and external/cloud credentials are shown ○ optional. `/config` prompts for the key and lists optional cloud credentials behind a default-no "set now?" — no pestering. The minimal docker sandbox runs with just the key.
|
|
42
|
+
|
|
43
|
+
- **Generated backend boots with the resolved Anthropic key.** The per-run runtime env now injects `ANTHROPIC_API_KEY` from wherever the CLI itself resolves it — keyring or mode-0600 credentials file (e.g. set via `scaffold auth login`, as the installer does) — when it isn't already supplied by the shell env, `.env.local`, or the project vault. A generated agent that constructs its Anthropic client at startup no longer crashes with `Could not resolve authentication method`. Shell / `.env.local` / vault still take precedence.
|
|
44
|
+
- **`launch_backend` reports the real startup failure.** A backend that exits during boot is now detected immediately and reported as a crash with its exit code and log tail (with an API-key suggested fix when the tail shows the auth error), instead of waiting out the full readiness window and misattributing the failure to "backing services not running".
|
|
45
|
+
- **Docker mode runs the stack with zero env setup.** A deterministic post-generation pass (`contract.normalize_app_service`) now guarantees the backend container can boot: the app service gains `ANTHROPIC_API_KEY` (+ any capability secret var) via the no-value `${VAR:-}` passthrough Compose fills from the env it runs in (the resolved `runtime_env`), so the key reaches the container with no plaintext file; a dangling `env_file: .env` (a hard `docker compose up` error — that file is never generated) is rewritten to `{path, required: false}`. In-network connection strings (`DATABASE_URL`, `REDIS_URL`) and other services' config (`POSTGRES_*`) are left untouched. The generation prompts were tightened to emit this directly; the pass is the safety net.
|
|
46
|
+
- **Docker-mode backend crash is surfaced, not hidden.** The generated app service has no compose healthcheck, so `docker compose up --wait` reported "healthy" even when the backend crash-looped. `docker_up` now confirms the app container didn't exit on boot after `--wait` and fails with its `docker compose logs` tail (and the API-key suggested fix) — symmetry with the local-mode crash detection.
|
|
47
|
+
- **Frontend dev server reaches the backend automatically.** In Docker mode the backend runs containerized; `launch_frontend` now defaults the frontend capability's backend-URL var (`NEXT_PUBLIC_AGENT_URL` for nextjs-chat, `AGENT_URL` for streamlit) to `http://localhost:<backend-port>`, so the local `pnpm dev` server talks to it with no manual config. A user-set value still wins.
|
|
48
|
+
- **REPL canonicalizes the Python module name.** The `scaffold` REPL now passes the underscored module name (hyphens → underscores) to the pipeline like `agent-scaffold new` does, so a project named `research-assistant` no longer makes the contract demand the invalid Python path `src/research-assistant/main.py` and fail every generation. `raw_project_name` keeps the original.
|
|
49
|
+
- **Recipe-declared entry layout wins over the language default.** A recipe whose `required_files` declare their own application entry (e.g. an `app/` layout) no longer also has to satisfy the generic, model-invisible `src/<pkg>/main.py` entry-point requirement — the two were double-required and conflicting. The language default still applies to recipes that declare no entry of their own.
|
|
50
|
+
- **`launch_backend` detects a top-level `app/` layout.** Local-mode backend auto-start previously scanned only `src/<pkg>/`, so an `app/`-layout recipe (a real `app/__init__.py` package with `app/main.py`) skipped instead of launching. It now also resolves a top-level `app/` / `api/` / `backend/` / `server/` package and runs it as `uvicorn app.main:app` (or `python -m app.main`). A project carrying both layouts keeps prior behaviour — the `src/` package wins.
|
|
51
|
+
- **Required-files validation reports every gap at once.** `validate_required_files` previously raised on the *first* missing file, so the single repair round only ever learned about one — a recipe missing several files (e.g. an `app/` layout's `app/main.py`, `app/agent/researcher.py`, `app/tools/web_search.py`) could never be satisfied: repair added one, then generation failed on the next. It now collects **all** missing required files into one error, so the repair round adds them together. The error reads `missing required file(s): a, b, c` (manifest/entry-point roles still annotated).
|
|
52
|
+
- **The model is told recipe-required paths are exact.** The generation prompt's recipe-required block is now emphatic: emit each required file at its EXACT path, don't relocate (e.g. into `src/`) or rename, and — when the recipe's layout differs from the language's idiomatic one — a thin re-export shim at the required path is acceptable. This stops the model from silently substituting its preferred `src/<pkg>/` layout for a recipe's `app/` layout and failing the contract.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- New cache block boundaries invalidate previously warm Anthropic prompt caches once (one-time extra cache-write cost on the first run after upgrading). Hot-tier writes cost 2× base input (vs 1.25× for 5m) and pay for themselves on the second generation inside the hour.
|
|
57
|
+
|
|
58
|
+
- **Live validation output.** The validator now streams each subprocess line as a `bash_line` progress event instead of buffering everything until exit — a multi-minute `uv sync` or `tsc` run shows live output instead of a frozen spinner. The Rich panel renders the last 3 lines (redacted) under the active command, mirroring the provisioning step display; the plain non-TTY display prints each line; per-run logs record every line. Full combined output is still captured (chronologically interleaved now) for the repair loop. Validation tiers also gain the streaming runner's process-group timeout kill. On POSIX, smoke checks run via `/bin/sh -c` with `shell=False`; `shell=True` survives only in the buffered Windows fallback.
|
|
59
|
+
- `stream_subprocess` gains a `line_callback` parameter for callers outside the step framework.
|
|
60
|
+
|
|
61
|
+
- **`.scaffold/run-summary.md` in every generated project.** A durable, human-readable record that travels with the project: recipe + status, language/framework/model, deployments snapshot SHA, file count, validation outcome (including repair rounds), env var names with set/missing status (names only — values never appear), start instructions, and the run-log path. Each `agent-scaffold up` refreshes a Provisioning section with the latest step summary. The welcome panel and the "Next steps" footer both point at it.
|
|
62
|
+
- Welcome panel gains "Run summary" and "Run log" pointer rows.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **The plan-confirm panel now defaults ON for every interactive `new`** (previously only at `--effort high`) — one Y/n gate showing context size, cost estimate, and service readiness before any tokens are spent. `--no-plan` opts out; non-interactive runs are unaffected.
|
|
67
|
+
|
|
68
|
+
- **Project-scoped encrypted secrets vault.** Service credentials for generated projects (QDRANT_URL, LANGFUSE_SECRET_KEY, …) now live encrypted in the OS-native keyring, namespaced per project (`project:<name>-<pathhash>:<VAR>`); the plaintext-keyring refusal and mode-0600 file fallback from the Anthropic-key flow apply unchanged. A **names-only index** (never values) in the credentials file powers listing and presence checks without keyring consent prompts. `wire_credentials` stores to the vault first, `.env.local` only as a last-resort fallback; the manifest records `secrets_namespace`.
|
|
69
|
+
- **Runtime env injection.** `up` resolves one environment per run — shell env > vault > `.env.local` (vault read in a single batch) — and every step subprocess (docker compose, uv, alembic, seed, smoke, pnpm/frontend) receives it via `env=`. Docker `${VAR}` interpolation works without any plaintext file.
|
|
70
|
+
- **"LLMs can never read secrets" guarantee, enforced by tests.** Secret values are architecturally confined to subprocess environments; every outbound path now redacts: the generation progress panel (operation hints/summaries/errors), repair-prompt validation output, REPL free-text refinements and serialized state sent to Haiku, run logs, and events. `tests/security/test_secrets_never_reach_llm.py` plants credentials in env/.env.local, runs the full golden path (generate + repair + refine), and asserts no planted fragment appears in any recorded LLM payload, run artifact, or console output.
|
|
71
|
+
- `agent-scaffold secrets set/unset --project <dir>` manage individual vault entries (getpass, masked echo); `secrets list` shows per-project vaults (names + backend only); `secrets purge` clears vault namespaces along with the other backends (list `--json` schema_version bumped to 2 with a `projects` array).
|
|
72
|
+
- Tests now run against an in-memory keyring + throwaway credentials file by default (autouse fixture) — no test can touch the developer's real keychain.
|
|
73
|
+
|
|
74
|
+
- **Bounded validate→repair loop.** When post-generation validation fails, the pipeline now feeds the failing command's output (redacted, capped) plus the implicated files' current bodies back to the model for targeted fixes — up to 2 rounds. The model returns only changed files (`{"files": [{path, content}]}`); patches pass the same path-safety rules as generation plus a structural constraint (existing files, or new files inside directories the project already populates — no new directory trees). Patched files are written atomically, re-formatted, re-validated, and folded into the manifest/snapshot. Repair prompts carry the recipe body only (not the full assembled context) so repair calls stay cheap.
|
|
75
|
+
- **Validation now runs static + build tiers** on the golden path (`ruff check` + `uv sync` for Python, `tsc --noEmit` + `pnpm install` for TypeScript) instead of static only — a project that doesn't resolve its dependencies isn't "running in one go". `--skip-validation` still bypasses everything.
|
|
76
|
+
- **Unrecovered validation failures now exit non-zero.** After the repair rounds are exhausted, the run raises a pipeline error with the failing tier's output excerpt and recovery hints. The project and its manifest stay on disk so `validate` / `regenerate` / `update` work for manual recovery.
|
|
77
|
+
- **Run-cumulative token accounting.** The generation report now sums usage across every API call in the run (generate + JSON repair + validation-repair rounds) instead of reporting only the last call, and shows a `Repair: N round(s)` line when the loop fired.
|
|
78
|
+
- New prompt `prompts/validation_repair.md` (registered in the prompts signature, so response caches bust correctly), `generator.repair_validation()`, `contract.parse_file_patch()`, `validator.tier_command()`.
|
|
79
|
+
|
|
80
|
+
- **Pre-flight gate before the LLM call.** `agent-scaffold new` now checks, *before spending tokens*, that the env vars the run will eventually need are resolvable and that the recipe's external services respond. The required set is the union of three sources: the recipe's `external_services[].env_vars`, the catalog's auto-derived `env_contract` (entries with a `default` count as satisfied), and the resolved capability stack's `env_vars`. Missing values can be filled at the gate (getpass, no echo): `ANTHROPIC_API_KEY` persists to the auth backend immediately; project secrets are exported for the run and written to the project's `.env.local` (mode 0600) right after the write phase. The gate is warn-only — generation never blocks. Service probes now run for **every** interactive `new` (previously only with the plan panel at `--effort high`), and the plan panel reuses the gate's results instead of probing twice; failures against docker-managed services render as "not running — `up` starts it via docker compose" instead of an alarming ✗. Non-interactive runs print missing names (never values) to stderr and skip probing.
|
|
81
|
+
- New module `agent_scaffold.preflight` (`run_preflight`, `collect_env_requirements`, `persist_filled`, panel renderers) and `agent_scaffold.envfile` (`.env.local` read/write + presence helpers, extracted from the `wire_credentials` step so both stages share one definition of "present").
|
|
82
|
+
- `RecipeEntry.env_contract` parsing in the catalog model (`EnvContractEntry`: `name` / `source_capability` / `default`).
|
|
83
|
+
|
|
84
|
+
- **Persistent per-run logs.** Every `agent-scaffold new` run writes artifacts under `~/.cache/agent-scaffold/runs/<run_id>/`: `run.log` (human-readable, one timestamped line per event) and `events.jsonl` (machine-readable event stream covering generation, file writes, validation, and — when autorun fires — every provisioning step). Both sinks are secret-redacted before anything touches disk. Run directories are pruned to the 20 most recent. The generation report panel ends with the run-log path, and pipeline failures print `Full log: …` so the evidence survives the scrollback.
|
|
85
|
+
- **Plain progress output for non-TTY runs.** When stdout isn't an interactive terminal (CI, pipes), generation progress degrades from the Rich Live panel to flat, grep-able one-line-per-event output on stderr — matching the existing behavior of the provisioning step display.
|
|
86
|
+
- `GenerationDisplay` protocol in `progress.py`; `pipeline.run_generation` now accepts any conforming display (Rich, plain, null, or the run-log tee).
|
|
87
|
+
|
|
88
|
+
- **Catalog-driven loader.** New `agent_scaffold.catalog` module fetches the deployments catalog from a single hardcoded URL (`DEFAULT_CATALOG_URL`), validates it via Pydantic, caches it under `~/.cache/agent-scaffold/catalog/`, and falls back to an embedded JSON shipped in the wheel. The alias / cross-cutting / framework-gating maps and the blueprint URL pattern all come from the catalog — scaffold has zero hardcoded knowledge of the catalog's content. Override with `--catalog-url` or `$AGENT_SCAFFOLD_CATALOG_URL`. See `MANIFEST_SCHEMA.md` in agent-deployments for the catalog schema.
|
|
89
|
+
- New env: `AGENT_SCAFFOLD_CATALOG_URL`.
|
|
90
|
+
- New CLI flag: `--catalog-url` on `agent-scaffold new`.
|
|
91
|
+
- `scripts/embed_catalog.py` refreshes the embedded fallback JSON from the live catalog. Run before `uv build` (the `publish.yml` workflow does this automatically; `scripts/build_hooks.py` also wires this into local `uv build` via a hatch hook).
|
|
92
|
+
- **`launch_frontend` orchestrator step.** Spawns the frontend dev server as a detached background process after `install_deps`. Writes `<project>/.scaffold/frontend.pid` so subsequent `up` / `down` / `logs` runs find and manage the same process. SKIPs when the recipe ships no `frontend/package.json`.
|
|
93
|
+
- **Welcome panel after `agent-scaffold up`.** Lists every live local URL — frontend, backend, Grafana, Langfuse, Qdrant, Tempo, eval command — derived from the resolved capability stack, plus `agent-scaffold down` as the stop hint.
|
|
94
|
+
- `agent-scaffold logs frontend` tails the dev server's `.scaffold/frontend.log` via `tail -f`, with a pure-Python fallback when `tail` isn't on PATH.
|
|
95
|
+
- `default_port` field on `languages/python.yaml` (8000) and `languages/typescript.yaml` (3000), read by the welcome panel.
|
|
96
|
+
- `_open_browser_safe()` helper, swallows headless/CI failures.
|
|
97
|
+
- **`agent-scaffold new` autorun (default on for interactive runs).** After generation succeeds, chains into `up` + welcome panel + browser open. `--no-autorun` keeps the staged-by-hand flow; `--non-interactive` (CI shape) implicitly disables autorun so existing CI scripts don't suddenly start spinning up docker. `--no-open-browser` runs `up` without launching a browser.
|
|
98
|
+
- `/autorun on|off` slash command in the REPL — toggles the same chain after `/go`. `SessionState` gained an `autorun: bool = True` field.
|
|
99
|
+
- `_run_up_inline()` helper factored out of `cmd_up` so `cmd_new` and the REPL can share the orchestrator-run + welcome-panel code path without duplicating it.
|
|
100
|
+
- **`agent-scaffold eval` verb.** Runs the project's eval suite via the matching `eval.*` capability's plugin (default: Promptfoo via `npx`). Exits 1 on regression vs the stored baseline (per-case delta threshold ±0.01 to ignore sampling noise). `--update-baseline` persists the new total; `--json` for machine-readable output; recipes without `eval.*` exit 0 with a friendly note.
|
|
101
|
+
- **`bootstrap_evals` orchestrator step.** Runs the eval suite once during `up` (after `smoke_test`, before `emit_deploy_configs`) and stores `result.total` in `manifest.answers["eval_baseline"]`. SKIPs cleanly when no `eval.*` capability is declared or `npx` isn't on PATH.
|
|
102
|
+
- **Eval plugin system at `agent_scaffold.eval/`.** Lazy registry, `EvalResult` + `EvalCase` dataclasses, regression-noise floor constant. Ships one plugin (`promptfoo`) that parses Promptfoo's JSON output (both `results.results[]` and flatter top-level shapes), clamps runaway LLM-judged scores into `[0, 1]`, and computes the delta against an optional baseline.
|
|
103
|
+
- `update_manifest_answer(project_dir, key, value)` helper in `manifest.py` for round-tripping a single answers entry.
|
|
104
|
+
- `/eval` slash command in the REPL — prints the `agent-scaffold eval --cwd <dest>` command line (REPL never runs the eval itself; can take minutes).
|
|
105
|
+
- Welcome panel now includes the eval baseline on the Eval row when it's set.
|
|
106
|
+
- `eval = []` extra in `pyproject.toml` (placeholder — Promptfoo is Node-based, no pip dep needed).
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- Catalog loading no longer fails against catalogs published by generator 1.3+, which list `stack` / `cross_cutting_docs` / `pattern_docs` entries as `{path, tags, when_to_load}` mappings instead of bare path strings. Both shapes now parse; mapping entries normalize to their `path`.
|
|
111
|
+
|
|
112
|
+
### Changed
|
|
113
|
+
|
|
114
|
+
- The wheel ships ~320 KB (was ~1.2 MB). The 916 KB `_bundled_deployments/` snapshot has been removed in favor of the ~55 KB embedded catalog JSON.
|
|
115
|
+
- `assemble()` now requires `catalog: Catalog` as a keyword argument. Callers obtain it via `catalog.load_catalog_for_config(cfg)`.
|
|
116
|
+
- The CI / publish workflows no longer call `scripts/sync_deployments.sh`. Wheel artifacts now go through `scripts/embed_catalog.py` at publish time, and local `uv build` runs the same refresh via a hatch build hook (`scripts/build_hooks.py`).
|
|
117
|
+
- `agent-scaffold down` now stops the frontend dev server (SIGTERM the process group, remove the PID file, reset the step state) before tearing down docker compose.
|
|
118
|
+
- The legacy "Next steps" panel printed by `cmd_new` is suppressed when autorun fires (the welcome panel covers it). Still printed when `--no-autorun` or `--non-interactive`.
|
|
119
|
+
|
|
120
|
+
### Removed (breaking)
|
|
121
|
+
|
|
122
|
+
- `--deployments-source=bundled` flag value. The mode raises `typer.BadParameter` with a migration hint pointing at the catalog flow. The catalog + on-disk fetch cache replaces the bundled snapshot's offline-first-run role.
|
|
123
|
+
- `src/agent_scaffold/_bundled_deployments/` (entire tree, 916 KB).
|
|
124
|
+
- `scripts/sync_deployments.sh`.
|
|
125
|
+
- `ALIAS_TABLE`, `CROSS_CUTTING`, `FRAMEWORK_LANGUAGE`, `FRAMEWORK_DOC_TO_ID`, `_BLUEPRINT_URL_RE` constants from `context.py`. The catalog provides equivalent data via `catalog.aliases`, `catalog.cross_cutting`, `catalog.frameworks`, and `catalog.build_secondary_url_re()`.
|
|
126
|
+
|
|
127
|
+
### Migration
|
|
128
|
+
|
|
129
|
+
| If you were doing... | Do this instead |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `agent-scaffold new --deployments-source bundled` | Drop the flag; the catalog + cache covers offline runs after the first fetch. For air-gapped CI, pre-warm `~/.cache/agent-scaffold/` or pin `--catalog-url file://...`. |
|
|
132
|
+
| `from agent_scaffold.context import ALIAS_TABLE` | Load a `Catalog` via `catalog.load_catalog_for_config(cfg)`, then read `catalog.aliases`. |
|
|
133
|
+
| `from agent_scaffold.context import _BLUEPRINT_URL_RE` | Use `catalog.build_secondary_url_re(catalog)`. |
|
|
134
|
+
| `from agent_scaffold._bundled_deployments import bundled_docs_path` | No replacement. Bundle is gone. The runtime tarball cache at `~/.cache/agent-scaffold/deployments/<sha>/` covers offline docs once first-fetched. |
|
|
135
|
+
|
|
136
|
+
## 0.2.255 — 2026-05-28
|
|
137
|
+
|
|
138
|
+
The first minor since `0.1.1`. Headline change: the new **`agent-scaffold scaffold` REPL** — a persistent shell with a guided wizard, slash commands, LLM-interpreted refinements, pre-flight cost estimates, and a tab-completing prompt — replaces the one-shot prompt-for-each-input flow that `agent-scaffold new` used to drive. `new` still works for scripted / non-interactive runs. Also: deployments + blueprints now auto-fetch from GitHub (cached by SHA, ETag-conditional), and the CLI itself has been pulled apart into smaller focused modules (`cli_auth`, `cli_doctor`, `cli_secrets`, plus shared leafs `effort` + `language_hints` + `_scaffold_dir`).
|
|
139
|
+
|
|
140
|
+
### Highlights
|
|
141
|
+
|
|
142
|
+
- **Interactive REPL: `agent-scaffold scaffold`.** Persistent shell with the orange→red figlet banner, a `/new` wizard, free-text refinements ("swap to sonnet, add postgres, skip the smoke test"), pre-flight cost estimates, and tab-completion. Stays open until `/exit` so multiple projects can be scaffolded in one session.
|
|
143
|
+
- **Auto-fetched deployments + blueprints.** `agent-scaffold new` no longer prompts for a path. The CLI pulls the latest `main` commit from `jagguvarma15/agent-deployments` and `jagguvarma15/agent-blueprints`, caches each by SHA under `~/.cache/agent-scaffold/`, and uses ETag-conditional GETs so unchanged refs don't consume GitHub rate-limit quota. Falls back to the bundled deployments copy when offline.
|
|
144
|
+
- **Live bug fix:** REPL free-text refinements actually reach the generator now. Earlier preview builds collected them into `SessionState` and rendered them in the delta panel but never threaded them into `PipelineInputs` — so prose like `"add postgres, swap to sonnet"` was a silent no-op.
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- **`agent-scaffold scaffold` — interactive REPL.** Persistent shell with the orange→red figlet banner, slash commands (`/help`, `/recipe`, `/language`, `/framework`, `/name`, `/dest`, `/model`, `/effort`, `/plan`, `/cost`, `/reset`, `/go`, `/exit`), tab-completion for commands + recipe slugs, history at `~/.cache/agent-scaffold/repl_history`, Ctrl-D / Ctrl-L key bindings.
|
|
149
|
+
- **`/new` guided wizard with arrow-key selection.** Steps through recipe → language → framework → name → dest via questionary picks; each step has a `pause wizard` option that preserves selections so a follow-up `/new` resumes from the first unset field with a keep/change gate.
|
|
150
|
+
- **`/generate` (alias `/gen`)** — user-facing verb for the final confirm step; both route through the existing `cmd_go` validator.
|
|
151
|
+
- **`agent_scaffold.branding`** — shared figlet+gradient logo used by both the top-level `agent-scaffold` banner and the REPL welcome screen so they stay visually consistent.
|
|
152
|
+
- **`prompt-toolkit>=3.0,<4`** pinned as an explicit dependency (previously transitive via questionary; the shell drives `PromptSession`, `FileHistory`, and `patch_stdout` directly).
|
|
153
|
+
- **REPL slash-command dispatcher.** `agent_scaffold.repl.commands.CommandHandler` introspects its own `cmd_*` methods to register slash commands with bare-recipe-slug shortcuts and fuzzy "did you mean" matching on typos.
|
|
154
|
+
- **LLM-interpreted free-text refinements in the REPL.** Anything that isn't a slash command or a bare recipe slug goes through a Haiku-only `interpret_refinement` call that turns prose like `"swap to sonnet and skip the smoke test"` into a typed `StatePatch`. ~$0.002/call. Network failures, malformed JSON, and schema-mismatched values surface a yellow warning and leave state intact rather than crashing the loop.
|
|
155
|
+
- **Pre-flight cost estimate in the plan panel.** The plan-confirm panel now shows `Est. cost: $X (input $Y, output ~$Z ±$W)` before any LLM call, so you see what a run will cost before paying. Input cost is exact (from the assembled context size); output is a range bracketed by the configured `--max-tokens`.
|
|
156
|
+
- **Auto-fetch deployments + blueprints from GitHub.** `agent-scaffold new` no longer prompts for the deployments path. By default the CLI pulls the latest `main` commit from both `jagguvarma15/agent-deployments` and `jagguvarma15/agent-blueprints`, caches each by SHA under `~/.cache/agent-scaffold/`, and uses ETag-conditional GETs so unchanged refs don't consume GitHub rate-limit quota. Falls back to the bundled deployments copy when offline.
|
|
157
|
+
- **Blueprint URL rewriting in context assembly.** `https://github.com/jagguvarma15/agent-blueprints/(tree|blob|raw)/main/<path>` links in deployments docs now resolve to local files in the fetched blueprints tree, so the LLM actually reads the canonical pattern content the deployments docs point to (subject to the existing context budget).
|
|
158
|
+
- New flags on `agent-scaffold new`: `--blueprints-path`, `--deployments-source [auto|bundled]`, `--blueprints-source [auto|skip]`.
|
|
159
|
+
- New env vars: `AGENT_SCAFFOLD_BLUEPRINTS_PATH`, `AGENT_SCAFFOLD_DEPLOYMENTS_SOURCE`, `AGENT_SCAFFOLD_BLUEPRINTS_SOURCE`.
|
|
160
|
+
- New module `agent_scaffold.sources` with safe-extract tarball handling (rejects `..`, absolute paths, symlink escapes — Python 3.11 floor, no `tarfile.data_filter` dependency).
|
|
161
|
+
|
|
162
|
+
### Changed
|
|
163
|
+
|
|
164
|
+
- `Config.deployments_path` is now `Path | None` — empty means "use the resolver default" (auto-fetch). `load_config` no longer raises when no path is set; resolution is deferred to `sources.resolve_*`.
|
|
165
|
+
- Removed the "Path to agent-deployments repo:" interactive prompt from `agent-scaffold new`.
|
|
166
|
+
- **New leaf modules `agent_scaffold.effort` and `agent_scaffold.language_hints`** carry the shared effort-preset table and language-YAML loader respectively. `cli.py` and `repl/*.py` now import from them instead of each carrying a near-copy.
|
|
167
|
+
- **New `topology.resolve(recipe, ctx_body)` helper** returns the `(Topology, list[Role])` pair so `cmd_new`, `cmd_plan`, and `_build_pipeline_inputs` no longer duplicate the explicit-frontmatter / inference / `SINGLE` fallback dance verbatim.
|
|
168
|
+
- **Split `cli.py` (2615 LOC → 1883 LOC) into focused sibling modules.** `cli_auth.py` owns the `auth` sub-app + credentials commands; `cli_secrets.py` owns the `secrets list` / `secrets purge` survey + flow; `cli_doctor.py` owns the `doctor` sub-app, the `--explain` lookup, and the auth/service `Check` adapters. A new `cli_shared.py` holds the single `console = Console()` singleton imported by every sibling. `cli.py` keeps the project-generation pipeline (`cmd_new`, `cmd_update`, `cmd_regenerate`, `cmd_scaffold`, `cmd_up`, `cmd_validate`, `cmd_config`) and registers the sub-apps via `app.add_typer(...)`.
|
|
169
|
+
|
|
170
|
+
### Fixed
|
|
171
|
+
|
|
172
|
+
- **REPL free-text refinements now reach the generator.** `SessionState.extra_dependencies`, `extra_steps`, `removed_steps`, `removed_roles`, and `refinement_notes` were collected and rendered in the delta panel but never threaded into `PipelineInputs` or the LLM prompt — so prose like `"add postgres, swap to sonnet, skip docker_up"` was a silent no-op. Added the five fields to `PipelineInputs`, `GenerationRequest`, and the `cache_inputs` fingerprint; rendered them as a `# User refinements` block in the user-message tail (per-run, never cached); `_build_pipeline_inputs` now passes them through from `SessionState`.
|
|
173
|
+
- **`/effort high` in the REPL now matches `--effort high` on the CLI.** The two surfaces each carried their own `EFFORT_PRESETS` dict; the REPL's was missing `max_context_tokens`/`max_link_depth`/`max_tokens_per_doc`, so the same keyword silently produced different context budgets. Unified into a single `agent_scaffold.effort.EFFORT_PRESETS` mapping typed as `EffortPreset` frozen dataclasses.
|
|
174
|
+
- **REPL `/language` validation now picks up new language YAMLs automatically.** Replaced the `_VALID_LANGUAGES = ("python", "typescript")` constant with a call to `agent_scaffold.language_hints.available_languages()`, so dropping in `rust.yaml` is picked up by both `/language` validation and the wizard list without code changes.
|
|
175
|
+
|
|
176
|
+
### Performance
|
|
177
|
+
|
|
178
|
+
- **Cached the bundled prompt reads.** `generator._load_prompt` and `prompts_signature` are now wrapped in `functools.lru_cache` — the wheel-bundled prompt files don't change at runtime, so the prior behaviour of re-reading and re-hashing them on every `run_generation` was pure waste.
|
|
179
|
+
- **Per-state assemble cache in the REPL.** `repl/commands._assemble_for_state` wraps `context.assemble` with a small LRU keyed on every input that could change the output (recipe + paths + budgets). The `/plan` → `/cost` flow used to walk the blueprint tree twice; it now walks it once per state change.
|
|
180
|
+
|
|
181
|
+
### Typing
|
|
182
|
+
|
|
183
|
+
- **`pipeline._run_post_gen_formatter` renamed to `pipeline.run_post_gen_formatter`.** Drops the leading underscore on a function that was both re-exported via `__all__` and imported by `cli.cmd_regenerate` — the underscore was misleading public-vs-private signalling.
|
|
184
|
+
- **`pipeline.RunReport.report` is now typed `WriteReport | None`** instead of `Any | None`. The comment claiming the cycle ("typed Any to avoid an import cycle in writer") was incorrect — `writer.py` is a leaf module. `mypy --strict` still passes.
|
|
185
|
+
|
|
186
|
+
### Internal
|
|
187
|
+
|
|
188
|
+
- **New `agent_scaffold._scaffold_dir.SCAFFOLD_DIR = ".scaffold"`** centralises the per-project metadata directory name. Updated `manifest.py`, `orchestrator.py`, `template_snapshot.py`, `writer.py`, `cli.py`, and `steps/commit_push.py` to import it instead of spelling the literal six times.
|
|
189
|
+
- **REPL wizard step table.** `repl/shell._run_new_wizard` now drives its five steps (recipe / language / framework / name / dest) from a `_WIZARD_STEPS` tuple of `_WizardStep` dataclasses instead of five copy-pasted 7-line blocks. Adding a sixth step is now a single table row.
|
|
190
|
+
- **Dropped the `agent_scaffold.repl` package re-exports.** Every existing caller (in-tree and tests) already imports from the symbol's owning submodule; the `__init__.py` re-exports were pure noise.
|
|
191
|
+
|
|
192
|
+
### Versioning note
|
|
193
|
+
|
|
194
|
+
Patch number is the count of commits to `main` since `21dcbfa` (the `0.1.1` PyPI-rename commit). Future releases on the `0.2.x` line will keep this scheme until a breaking change moves to `0.3`.
|
|
195
|
+
|
|
196
|
+
## 0.1.1 — 2026-05-06
|
|
197
|
+
|
|
198
|
+
### Fixed
|
|
199
|
+
- Source `__version__` from installed package metadata so `agent-scaffold --version` matches the published wheel.
|
|
200
|
+
|
|
201
|
+
### Changed
|
|
202
|
+
- Renamed PyPI distribution to `agent-scaffold-cli` (CLI command remains `agent-scaffold`).
|
|
203
|
+
- Aligned `.gitignore` and wheel build with the `agent-scaffold` rename.
|
|
204
|
+
|
|
205
|
+
## 0.1.0 — 2026-05-03
|
|
206
|
+
|
|
207
|
+
### Added
|
|
208
|
+
- Initial public release on PyPI.
|
|
209
|
+
- `agent-scaffold new` interactive flow: pick a recipe, language, framework, project name, and destination.
|
|
210
|
+
- `agent-scaffold validate --tier {static,build,smoke}` reruns post-generation tiers without re-invoking the LLM.
|
|
211
|
+
- `agent-scaffold config` prints the resolved configuration with the API key masked.
|
|
212
|
+
- Pipeline: `config → discovery → context → generator → contract → writer → validator`.
|
|
213
|
+
- Bundled `agent-deployments` docs shipped inside the wheel; override with `AGENT_SCAFFOLD_DEPLOYMENTS_PATH` or `--deployments-path`.
|
|
214
|
+
- Pluggable language targets via YAML (`src/agent_scaffold/languages/`), with `python.yaml` and `typescript.yaml` shipped.
|
|
215
|
+
- Atomic writes via temp dir + `os.replace`; `--write-mode` choices: `abort` (default), `skip`, `diff`, `overwrite`.
|
|
216
|
+
- Path-safety validation in the contract layer (rejects absolute paths, parent traversal, symlink escapes).
|
|
217
|
+
- Failure capture: malformed contracts written to `~/.cache/agent-scaffold/failures/<timestamp>.json` with automatic repair-attempt round-trip.
|
|
@@ -11,16 +11,18 @@ uv run ruff check src/ tests/ # lint
|
|
|
11
11
|
uv run ruff format src/ tests/ # format
|
|
12
12
|
uv run mypy src/ # type check
|
|
13
13
|
uv run agent-scaffold --help # CLI usage
|
|
14
|
+
make install-dev # expose `scaffold` + `agent-scaffold` on PATH (editable)
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
## Architecture
|
|
17
18
|
|
|
18
|
-
Pipeline: `config → sources → discovery → context → pipeline.run_generation → cli`
|
|
19
|
+
Pipeline: `config → catalog → sources → discovery → context → pipeline.run_generation → cli`
|
|
19
20
|
|
|
20
21
|
| Module | Responsibility |
|
|
21
22
|
|--------|---------------|
|
|
22
23
|
| `config.py` | Load env vars + TOML config, resolve `Config`. Deployments / blueprints paths are optional hints. |
|
|
23
|
-
| `
|
|
24
|
+
| `catalog.py` | Fetch + validate the deployments catalog (one hardcoded URL: `DEFAULT_CATALOG_URL`). Pydantic models, ETag-cached fetch, embedded JSON fallback. Provides the alias / cross-cutting / framework-gating maps `context.assemble` consumes. |
|
|
25
|
+
| `sources.py` | Resolve where deployments + blueprints come from: GitHub auto-fetch (cached by SHA, ETag-conditional). Blueprints supports `skip` mode; deployments fetches or fails. |
|
|
24
26
|
| `discovery.py` | Scan `agent-deployments/docs/recipes/` for markdown recipe specs |
|
|
25
27
|
| `context.py` | Assemble recipe + linked docs into a single prompt context. Rewrites `github.com/.../agent-blueprints/...` URLs in deployments docs to local files in the fetched blueprints tree. |
|
|
26
28
|
| `generator.py` | Call Anthropic API with system/user prompts, retry on transient errors |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.PHONY: build test lint typecheck install-dev uninstall-dev
|
|
2
|
+
|
|
3
|
+
# `uv build` runs the hatch custom hook (scripts/build_hooks.py), which refreshes
|
|
4
|
+
# src/agent_scaffold/_embedded_catalog.json from the live catalog before the
|
|
5
|
+
# wheel is assembled. No pre-step needed.
|
|
6
|
+
build:
|
|
7
|
+
uv build
|
|
8
|
+
|
|
9
|
+
test:
|
|
10
|
+
uv run pytest --cov=agent_scaffold
|
|
11
|
+
|
|
12
|
+
lint:
|
|
13
|
+
uv run ruff check src/ tests/
|
|
14
|
+
uv run mypy src/
|
|
15
|
+
|
|
16
|
+
typecheck:
|
|
17
|
+
uv run mypy src/
|
|
18
|
+
|
|
19
|
+
# Install both `agent-scaffold` and `scaffold` binaries onto PATH as an editable
|
|
20
|
+
# tool, so changes to src/ are picked up without reinstalling.
|
|
21
|
+
install-dev:
|
|
22
|
+
uv tool install --force --editable .
|
|
23
|
+
|
|
24
|
+
uninstall-dev:
|
|
25
|
+
uv tool uninstall agent-scaffold-cli
|