claude-code-generator 0.4.6__tar.gz → 0.4.8__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.
- {claude_code_generator-0.4.6/src/claude_code_generator.egg-info → claude_code_generator-0.4.8}/PKG-INFO +1 -1
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/pyproject.toml +1 -1
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8/src/claude_code_generator.egg-info}/PKG-INFO +1 -1
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/__init__.py +1 -1
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/generate.py +9 -8
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/effort.py +10 -3
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/env.py +54 -14
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_effort.py +19 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_env.py +83 -18
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/LICENSE +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/README.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/setup.cfg +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/claude_code_generator.egg-info/SOURCES.txt +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/claude_code_generator.egg-info/requires.txt +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/claude_code_generator.egg-info/top_level.txt +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/agents.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/cli.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_bench_io.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_crash_recovery.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_detect.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_dispatch.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_resume.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_validators.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/bench.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/bench_compare.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/bench_export.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/init.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/optimize.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/review.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/status.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/core.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/issues.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/labels.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/milestones.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/git_ops.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/logging_setup.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/memory.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/_client_lifecycle.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/_comments.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/_memory_writers.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/_phase5_precommit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/cycle_loop.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/cycle_prompts.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/ollama_budget.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase0_complexity.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase1_plan.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase2_review.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase3_4_implement.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase5_closure.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase6_test.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/orchestrator/phase7_commit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/preflight.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/hashes.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-cycle-specializer.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-optimize-requirements.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-0-complexity.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-1-planning.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-2-batch-review.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-2-issue-review.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-3-implementation.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-5-final-review.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-6-test.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-phase-7-commit.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/prompt-review.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/repo_info.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/repomap.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/requirements_structure.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/_telemetry.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/batch.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/fake_runner.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/mcp.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/message_parsing.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/options.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/protocol.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/rate_limit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/retry.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/sdk_runner.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/soft_reset.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/state_guard.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/subprocess_runner.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/types.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/utils.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/state.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/state_retention.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/__init__.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/angular.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/base.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/fastapi.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/finance.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/fullstack.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/nestjs.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/python-cli.md +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_agents.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_bench.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_bench_compare.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_bench_export.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_bench_fixture.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_bench_regression.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_changelog.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_claude_md.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_client_lifecycle.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_comments.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_commit_message.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_crash_recovery.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_loop.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_loop_multicycle.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_ollama_model.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_prompts.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_delta_planning.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_dependencies.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_detect.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_docs_no_default_max_turns.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_docs_ollama_model_guide.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_docs_ollama_pro.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_effective_model_routing.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_generate.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_generate_ollama.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_generate_resume.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_gh.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_gh_labels.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_gh_milestones.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_gh_repo_threading.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_gh_submodules.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_git_ops.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_init.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_logging_setup.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_max_turns_cli_flag.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_mcp.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_memory.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_memory_writers.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_message_parsing.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_no_max_turns_in_call_sites.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_no_max_turns_literal.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_non_goals_grep_guard.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_ollama_budget.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_ollama_rate_limit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_optimize.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_options.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase0.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase1.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase2.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase2_batch.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase3_4.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase5.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase5_precommit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase6.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase7.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase_mcp_regression.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase_token_logging.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_preflight.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_preflight_ollama.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompt_drift.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompt_prefix_snapshots.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompt_prefix_stability.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompts.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_rate_limit.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_repo_info.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_repomap.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_requirements_structure.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_retry.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_review.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_runner_protocol.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_runner_protocol_annotations.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_runner_types.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_runner_utils.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_sdk_runner.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_sdk_runner_shared.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_session_mode.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_state.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_state_guard.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_state_retention.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_status.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_subprocess_runner.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_telemetry.py +0 -0
- {claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_version.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-code-generator"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.8"
|
|
8
8
|
description = "Orchestrator CLI that drives Claude Code end-to-end to generate whole projects from a requirements.md file."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/generate.py
RENAMED
|
@@ -396,19 +396,20 @@ def generate_ollama_command(
|
|
|
396
396
|
|
|
397
397
|
state_path = cg_dir / "state.json"
|
|
398
398
|
|
|
399
|
-
# (1) Strip any stray ANTHROPIC_* vars from the parent process env
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
#
|
|
399
|
+
# (1) Strip any stray ANTHROPIC_* vars from the parent process env AND
|
|
400
|
+
# install the scoped Ollama routing (ANTHROPIC_AUTH_TOKEN + BASE_URL +
|
|
401
|
+
# empty API_KEY) into os.environ so every in-process SDK session and
|
|
402
|
+
# every subprocess Claude Code spawns inherits the localhost daemon.
|
|
403
|
+
# Without this install step Claude Code rejects non-Claude model tags
|
|
404
|
+
# (e.g. ``glm-5.1:cloud``) — see the 0.4.8 fix.
|
|
403
405
|
env.assert_safe_environment_ollama()
|
|
404
406
|
|
|
405
407
|
# (2) Ollama preflight — cheap env-var checks then live-daemon probe.
|
|
406
408
|
_run_ollama_preflight_or_exit()
|
|
407
409
|
|
|
408
|
-
# (3)
|
|
409
|
-
#
|
|
410
|
-
#
|
|
411
|
-
# when it actually spawns SDK sessions.
|
|
410
|
+
# (3) Re-validate the #215 preconditions defensively. The returned dict is
|
|
411
|
+
# intentionally discarded — the SDK and subprocess runners now inherit the
|
|
412
|
+
# Ollama routing from os.environ (installed above in step 1).
|
|
412
413
|
env.build_agent_env(provider="ollama")
|
|
413
414
|
|
|
414
415
|
# (3) Resolve the effective model. --model wins; on --continue without it,
|
|
@@ -101,10 +101,14 @@ _OPUS_ONLY_EFFORTS: frozenset[str] = frozenset({"xhigh", "max"})
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def validate_effort(effort: str | None, model: str) -> None:
|
|
104
|
-
"""Raise ValueError when an Opus-only effort is paired with a non-Opus model.
|
|
104
|
+
"""Raise ValueError when an Opus-only effort is paired with a non-Opus Claude model.
|
|
105
105
|
|
|
106
106
|
``xhigh`` and ``max`` are gated to Opus 4.7+ (introduced in 4.7); Sonnet
|
|
107
|
-
and Haiku do not expose them.
|
|
107
|
+
and Haiku do not expose them. The constraint only applies to Anthropic
|
|
108
|
+
Claude models (IDs prefixed with ``"claude-"``); for other model families
|
|
109
|
+
— notably the Ollama single-model codepath (#218), which accepts tags like
|
|
110
|
+
``"glm-5.1:cloud"`` or ``"llama3.2:3b"`` — the effort flag is advisory and
|
|
111
|
+
validation is skipped.
|
|
108
112
|
|
|
109
113
|
Parameters
|
|
110
114
|
----------
|
|
@@ -112,8 +116,11 @@ def validate_effort(effort: str | None, model: str) -> None:
|
|
|
112
116
|
Effort level string (``"low"`` / ``"medium"`` / ``"high"`` / ``"xhigh"``
|
|
113
117
|
/ ``"max"``), or ``None`` (no-op).
|
|
114
118
|
model:
|
|
115
|
-
Anthropic model ID (e.g. ``"claude-opus-4-7"``)
|
|
119
|
+
Anthropic Claude model ID (e.g. ``"claude-opus-4-7"``) or a non-Claude
|
|
120
|
+
tag (Ollama, etc.). Non-Claude tags are not validated.
|
|
116
121
|
"""
|
|
122
|
+
if not model.startswith("claude-"):
|
|
123
|
+
return
|
|
117
124
|
if effort in _OPUS_ONLY_EFFORTS and model != _OPUS_MODEL:
|
|
118
125
|
raise ValueError(f"effort={effort!r} is only allowed with {_OPUS_MODEL!r}, got {model!r}.")
|
|
119
126
|
|
|
@@ -39,8 +39,19 @@ OLLAMA_BASE_URL = "http://localhost:11434"
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def strip_dangerous_env() -> None:
|
|
42
|
-
"""Remove every dangerous variable from the current process environment.
|
|
42
|
+
"""Remove every dangerous variable from the current process environment.
|
|
43
|
+
|
|
44
|
+
When ``ANTHROPIC_BASE_URL`` points at a ``http://localhost:*`` endpoint
|
|
45
|
+
(the Ollama single-model codepath — see #218), ``ANTHROPIC_AUTH_TOKEN`` is
|
|
46
|
+
preserved so the scoped Ollama routing installed by
|
|
47
|
+
:func:`assert_safe_environment_ollama` survives per-SDK-run strip calls
|
|
48
|
+
(``sdk_runner.run``, ``run_with_shared_client``).
|
|
49
|
+
"""
|
|
50
|
+
ollama_mode = _is_localhost_base_url(os.environ.get("ANTHROPIC_BASE_URL"))
|
|
51
|
+
protected = {"ANTHROPIC_AUTH_TOKEN"} if ollama_mode else set()
|
|
43
52
|
for var in DANGEROUS_VARS:
|
|
53
|
+
if var in protected:
|
|
54
|
+
continue
|
|
44
55
|
os.environ.pop(var, None)
|
|
45
56
|
|
|
46
57
|
|
|
@@ -71,8 +82,17 @@ def build_agent_env(provider: Provider = "anthropic-max") -> dict[str, str]:
|
|
|
71
82
|
|
|
72
83
|
|
|
73
84
|
def _build_anthropic_max_env() -> dict[str, str]:
|
|
74
|
-
"""Strip DANGEROUS_VARS — the default Anthropic Max subscription path.
|
|
75
|
-
|
|
85
|
+
"""Strip DANGEROUS_VARS — the default Anthropic Max subscription path.
|
|
86
|
+
|
|
87
|
+
When ``ANTHROPIC_BASE_URL`` in the parent env points at ``http://localhost:*``
|
|
88
|
+
(the Ollama single-model codepath, #218), ``ANTHROPIC_AUTH_TOKEN`` is
|
|
89
|
+
preserved in the returned dict so the subprocess inherits the Ollama
|
|
90
|
+
auth token. This keeps the default subprocess-runner codepath usable for
|
|
91
|
+
Ollama without threading a ``provider`` argument through every runner.
|
|
92
|
+
"""
|
|
93
|
+
ollama_mode = _is_localhost_base_url(os.environ.get("ANTHROPIC_BASE_URL"))
|
|
94
|
+
protected = {"ANTHROPIC_AUTH_TOKEN"} if ollama_mode else set()
|
|
95
|
+
return {k: v for k, v in os.environ.items() if k not in DANGEROUS_VARS or k in protected}
|
|
76
96
|
|
|
77
97
|
|
|
78
98
|
def _build_ollama_env() -> dict[str, str]:
|
|
@@ -247,24 +267,44 @@ def assert_safe_environment() -> None:
|
|
|
247
267
|
|
|
248
268
|
|
|
249
269
|
def assert_safe_environment_ollama() -> None:
|
|
250
|
-
"""Strip Anthropic env vars
|
|
270
|
+
"""Strip Anthropic env vars and install the scoped Ollama routing in place.
|
|
251
271
|
|
|
252
272
|
Mirrors :func:`assert_safe_environment` for the Ollama codepath: the user
|
|
253
273
|
does not have to ``unset ANTHROPIC_API_KEY`` in their shell. An Anthropic
|
|
254
274
|
credential in the parent env is not a safety hazard here — the scoped
|
|
255
275
|
Ollama env pins ``ANTHROPIC_BASE_URL`` to ``http://localhost:11434`` and
|
|
256
276
|
re-authenticates with ``OLLAMA_API_KEY``, so no traffic reaches Anthropic.
|
|
257
|
-
|
|
258
|
-
|
|
277
|
+
|
|
278
|
+
When ``OLLAMA_API_KEY`` is already present and ``ANTHROPIC_BASE_URL`` is
|
|
279
|
+
unset (or already pinned to localhost), ``ANTHROPIC_AUTH_TOKEN``,
|
|
280
|
+
``ANTHROPIC_BASE_URL``, and ``ANTHROPIC_API_KEY=""`` are written back
|
|
281
|
+
into ``os.environ`` so every in-process SDK session and every subprocess
|
|
282
|
+
Claude Code spawns inherits the Ollama routing. Without this install
|
|
283
|
+
step, the SDK rejects non-Claude model tags (e.g. ``glm-5.1:cloud``)
|
|
284
|
+
with *"There's an issue with the selected model"* — see the 0.4.8 fix.
|
|
285
|
+
|
|
286
|
+
Missing or mismatched preconditions are **not** raised here; the
|
|
287
|
+
downstream :func:`~code_generator.preflight.run_ollama_preflight` +
|
|
288
|
+
:func:`build_agent_env` pair produce the user-facing error messages
|
|
289
|
+
(with ``fix_command`` hints). Raising from this function would bypass
|
|
290
|
+
those surfaces.
|
|
259
291
|
"""
|
|
260
292
|
offenders = [var for var in DANGEROUS_VARS if var in os.environ]
|
|
261
|
-
if
|
|
293
|
+
if offenders:
|
|
294
|
+
listed = ", ".join(offenders)
|
|
295
|
+
print(
|
|
296
|
+
f"Using Ollama daemon at {OLLAMA_BASE_URL} (ignoring {listed} for this process).",
|
|
297
|
+
file=sys.stderr,
|
|
298
|
+
)
|
|
299
|
+
strip_dangerous_env()
|
|
300
|
+
|
|
301
|
+
token = os.environ.get("OLLAMA_API_KEY", "")
|
|
302
|
+
preset_base = os.environ.get("ANTHROPIC_BASE_URL")
|
|
303
|
+
if not token:
|
|
304
|
+
return
|
|
305
|
+
if preset_base and preset_base != OLLAMA_BASE_URL:
|
|
262
306
|
return
|
|
263
307
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
f"(ignoring {listed} for this process).",
|
|
268
|
-
file=sys.stderr,
|
|
269
|
-
)
|
|
270
|
-
strip_dangerous_env()
|
|
308
|
+
os.environ["ANTHROPIC_AUTH_TOKEN"] = token
|
|
309
|
+
os.environ["ANTHROPIC_BASE_URL"] = OLLAMA_BASE_URL
|
|
310
|
+
os.environ["ANTHROPIC_API_KEY"] = ""
|
|
@@ -205,6 +205,25 @@ def test_validate_effort_none_always_passes(model: str) -> None:
|
|
|
205
205
|
validate_effort(None, model) # must not raise
|
|
206
206
|
|
|
207
207
|
|
|
208
|
+
@pytest.mark.parametrize(
|
|
209
|
+
("effort", "model"),
|
|
210
|
+
[
|
|
211
|
+
("xhigh", "glm-5.1:cloud"),
|
|
212
|
+
("max", "llama3.2:3b"),
|
|
213
|
+
("xhigh", "qwen2.5:7b"),
|
|
214
|
+
("max", "mistral:latest"),
|
|
215
|
+
],
|
|
216
|
+
)
|
|
217
|
+
def test_validate_effort_non_claude_models_skip_validation(effort: str, model: str) -> None:
|
|
218
|
+
"""Opus-only effort levels are no-ops for non-Claude models (Ollama path, #218).
|
|
219
|
+
|
|
220
|
+
The XHIGH / MAX ceiling only makes sense against Anthropic Claude models;
|
|
221
|
+
Ollama tags like ``glm-5.1:cloud`` do not expose the effort concept, so
|
|
222
|
+
``validate_effort`` must not raise for them.
|
|
223
|
+
"""
|
|
224
|
+
validate_effort(effort, model) # must not raise
|
|
225
|
+
|
|
226
|
+
|
|
208
227
|
# ---------------------------------------------------------------------------
|
|
209
228
|
# InvalidEffortInput guard — empty complexity in phases that depend on Phase 0
|
|
210
229
|
# ---------------------------------------------------------------------------
|
|
@@ -35,12 +35,29 @@ class TestStripDangerousEnv:
|
|
|
35
35
|
"""strip_dangerous_env removes every DANGEROUS_VAR that is present."""
|
|
36
36
|
for var in DANGEROUS_VARS:
|
|
37
37
|
monkeypatch.setenv(var, "value")
|
|
38
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
38
39
|
|
|
39
40
|
strip_dangerous_env()
|
|
40
41
|
|
|
41
42
|
for var in DANGEROUS_VARS:
|
|
42
43
|
assert var not in os.environ
|
|
43
44
|
|
|
45
|
+
def test_preserves_auth_token_on_localhost_base_url(
|
|
46
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
47
|
+
) -> None:
|
|
48
|
+
"""ANTHROPIC_AUTH_TOKEN survives strip when BASE_URL points at localhost (Ollama)."""
|
|
49
|
+
for var in DANGEROUS_VARS:
|
|
50
|
+
monkeypatch.delenv(var, raising=False)
|
|
51
|
+
monkeypatch.setenv("ANTHROPIC_AUTH_TOKEN", "ollama-token")
|
|
52
|
+
monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-evil")
|
|
53
|
+
monkeypatch.setenv("ANTHROPIC_BASE_URL", "http://localhost:11434")
|
|
54
|
+
|
|
55
|
+
strip_dangerous_env()
|
|
56
|
+
|
|
57
|
+
# AUTH_TOKEN preserved; API_KEY still stripped.
|
|
58
|
+
assert os.environ.get("ANTHROPIC_AUTH_TOKEN") == "ollama-token"
|
|
59
|
+
assert "ANTHROPIC_API_KEY" not in os.environ
|
|
60
|
+
|
|
44
61
|
def test_no_error_when_vars_absent(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
45
62
|
"""strip_dangerous_env must not raise when vars are not present."""
|
|
46
63
|
for var in DANGEROUS_VARS:
|
|
@@ -64,6 +81,7 @@ class TestBuildAgentEnv:
|
|
|
64
81
|
"""build_agent_env returns a copy with no dangerous vars."""
|
|
65
82
|
for var in DANGEROUS_VARS:
|
|
66
83
|
monkeypatch.setenv(var, "should-be-stripped")
|
|
84
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
67
85
|
|
|
68
86
|
env = build_agent_env()
|
|
69
87
|
|
|
@@ -134,6 +152,7 @@ class TestAssertSafeEnvironment:
|
|
|
134
152
|
|
|
135
153
|
def test_strips_each_dangerous_var(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
136
154
|
"""assert_safe_environment strips any individual dangerous var."""
|
|
155
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
137
156
|
for dangerous_var in DANGEROUS_VARS:
|
|
138
157
|
for v in DANGEROUS_VARS:
|
|
139
158
|
monkeypatch.delenv(v, raising=False)
|
|
@@ -144,25 +163,34 @@ class TestAssertSafeEnvironment:
|
|
|
144
163
|
|
|
145
164
|
|
|
146
165
|
class TestAssertSafeEnvironmentOllama:
|
|
147
|
-
"""The Ollama bypass auto-strips parent ANTHROPIC_* vars
|
|
166
|
+
"""The Ollama bypass auto-strips parent ANTHROPIC_* vars then installs scoped routing."""
|
|
148
167
|
|
|
149
|
-
def
|
|
150
|
-
"""assert_safe_environment_ollama
|
|
168
|
+
def test_installs_auth_token_and_base_url(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
169
|
+
"""assert_safe_environment_ollama installs the Ollama routing into os.environ."""
|
|
151
170
|
for var in DANGEROUS_VARS:
|
|
152
171
|
monkeypatch.delenv(var, raising=False)
|
|
172
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
173
|
+
monkeypatch.setenv("OLLAMA_API_KEY", "ollama-token-xyz")
|
|
153
174
|
|
|
154
|
-
assert_safe_environment_ollama()
|
|
175
|
+
assert_safe_environment_ollama()
|
|
176
|
+
|
|
177
|
+
assert os.environ["ANTHROPIC_AUTH_TOKEN"] == "ollama-token-xyz"
|
|
178
|
+
assert os.environ["ANTHROPIC_BASE_URL"] == OLLAMA_BASE_URL
|
|
179
|
+
assert os.environ["ANTHROPIC_API_KEY"] == ""
|
|
155
180
|
|
|
156
181
|
def test_strips_anthropic_api_key(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
157
182
|
"""A stray ANTHROPIC_API_KEY is stripped from os.environ instead of aborting."""
|
|
158
183
|
monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-real-key")
|
|
184
|
+
monkeypatch.setenv("OLLAMA_API_KEY", "ollama-token")
|
|
185
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
159
186
|
for var in DANGEROUS_VARS:
|
|
160
187
|
if var != "ANTHROPIC_API_KEY":
|
|
161
188
|
monkeypatch.delenv(var, raising=False)
|
|
162
189
|
|
|
163
190
|
assert_safe_environment_ollama()
|
|
164
191
|
|
|
165
|
-
|
|
192
|
+
# API_KEY is rewritten to "", not preserved as "sk-real-key".
|
|
193
|
+
assert os.environ.get("ANTHROPIC_API_KEY") == ""
|
|
166
194
|
|
|
167
195
|
def test_warning_mentions_localhost_daemon(
|
|
168
196
|
self, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
@@ -170,6 +198,8 @@ class TestAssertSafeEnvironmentOllama:
|
|
|
170
198
|
"""The printed warning names the Ollama daemon and the offending vars."""
|
|
171
199
|
monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-abc")
|
|
172
200
|
monkeypatch.setenv("ANTHROPIC_AUTH_TOKEN", "tok")
|
|
201
|
+
monkeypatch.setenv("OLLAMA_API_KEY", "ollama-token")
|
|
202
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
173
203
|
for var in DANGEROUS_VARS:
|
|
174
204
|
if var not in ("ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"):
|
|
175
205
|
monkeypatch.delenv(var, raising=False)
|
|
@@ -181,15 +211,32 @@ class TestAssertSafeEnvironmentOllama:
|
|
|
181
211
|
assert "ANTHROPIC_API_KEY" in captured.err
|
|
182
212
|
assert "ANTHROPIC_AUTH_TOKEN" in captured.err
|
|
183
213
|
|
|
184
|
-
def
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
214
|
+
def test_skips_install_when_ollama_api_key_missing(
|
|
215
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
216
|
+
) -> None:
|
|
217
|
+
"""Without OLLAMA_API_KEY the installer silently skips — preflight surfaces the error."""
|
|
218
|
+
for var in DANGEROUS_VARS:
|
|
219
|
+
monkeypatch.delenv(var, raising=False)
|
|
220
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
221
|
+
monkeypatch.delenv("OLLAMA_API_KEY", raising=False)
|
|
189
222
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
223
|
+
assert_safe_environment_ollama() # must not raise
|
|
224
|
+
|
|
225
|
+
assert "ANTHROPIC_AUTH_TOKEN" not in os.environ
|
|
226
|
+
|
|
227
|
+
def test_skips_install_when_base_url_points_off_host(
|
|
228
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
229
|
+
) -> None:
|
|
230
|
+
"""Off-host ANTHROPIC_BASE_URL is left alone — preflight raises the user-facing error."""
|
|
231
|
+
for var in DANGEROUS_VARS:
|
|
232
|
+
monkeypatch.delenv(var, raising=False)
|
|
233
|
+
monkeypatch.setenv("OLLAMA_API_KEY", "ollama-token")
|
|
234
|
+
monkeypatch.setenv("ANTHROPIC_BASE_URL", "http://evil.example.com")
|
|
235
|
+
|
|
236
|
+
assert_safe_environment_ollama() # must not raise
|
|
237
|
+
|
|
238
|
+
assert os.environ["ANTHROPIC_BASE_URL"] == "http://evil.example.com"
|
|
239
|
+
assert "ANTHROPIC_AUTH_TOKEN" not in os.environ
|
|
193
240
|
|
|
194
241
|
|
|
195
242
|
class TestAssertSingleWorkspace:
|
|
@@ -201,8 +248,11 @@ class TestAssertSingleWorkspace:
|
|
|
201
248
|
|
|
202
249
|
assert_single_workspace(probe=probe) # must not raise
|
|
203
250
|
|
|
204
|
-
def test_two_workspace_mock_raises_workspace_mismatch_error(
|
|
251
|
+
def test_two_workspace_mock_raises_workspace_mismatch_error(
|
|
252
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
253
|
+
) -> None:
|
|
205
254
|
"""Two-workspace probe must raise WorkspaceMismatchError with workspace names."""
|
|
255
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
206
256
|
|
|
207
257
|
def probe() -> frozenset[str]:
|
|
208
258
|
return frozenset({"ws-a", "ws-b"})
|
|
@@ -215,9 +265,10 @@ class TestAssertSingleWorkspace:
|
|
|
215
265
|
assert issubclass(WorkspaceMismatchError, RuntimeError)
|
|
216
266
|
|
|
217
267
|
def test_sdk_without_probe_logs_info_exactly_once(
|
|
218
|
-
self, caplog: pytest.LogCaptureFixture
|
|
268
|
+
self, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch
|
|
219
269
|
) -> None:
|
|
220
270
|
"""When probe returns None (SDK lacks workspace probe), logs INFO exactly once."""
|
|
271
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
221
272
|
|
|
222
273
|
def probe() -> None:
|
|
223
274
|
return None
|
|
@@ -261,6 +312,7 @@ class TestBuildAgentEnvAnthropicMaxProvider:
|
|
|
261
312
|
"""build_agent_env() without provider kwarg uses anthropic-max."""
|
|
262
313
|
for var in DANGEROUS_VARS:
|
|
263
314
|
monkeypatch.setenv(var, "value")
|
|
315
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
264
316
|
|
|
265
317
|
env = build_agent_env() # no kwarg
|
|
266
318
|
|
|
@@ -271,12 +323,27 @@ class TestBuildAgentEnvAnthropicMaxProvider:
|
|
|
271
323
|
"""Explicit provider="anthropic-max" behaves identically to the default."""
|
|
272
324
|
for var in DANGEROUS_VARS:
|
|
273
325
|
monkeypatch.setenv(var, "value")
|
|
326
|
+
monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False)
|
|
274
327
|
|
|
275
328
|
env = build_agent_env(provider="anthropic-max")
|
|
276
329
|
|
|
277
330
|
for var in DANGEROUS_VARS:
|
|
278
331
|
assert var not in env
|
|
279
332
|
|
|
333
|
+
def test_anthropic_max_preserves_auth_token_on_localhost_base_url(
|
|
334
|
+
self, monkeypatch: pytest.MonkeyPatch
|
|
335
|
+
) -> None:
|
|
336
|
+
"""When BASE_URL points at localhost (Ollama codepath), AUTH_TOKEN survives."""
|
|
337
|
+
for var in DANGEROUS_VARS:
|
|
338
|
+
monkeypatch.delenv(var, raising=False)
|
|
339
|
+
monkeypatch.setenv("ANTHROPIC_AUTH_TOKEN", "ollama-token")
|
|
340
|
+
monkeypatch.setenv("ANTHROPIC_BASE_URL", "http://localhost:11434")
|
|
341
|
+
|
|
342
|
+
env = build_agent_env(provider="anthropic-max")
|
|
343
|
+
|
|
344
|
+
assert env.get("ANTHROPIC_AUTH_TOKEN") == "ollama-token"
|
|
345
|
+
assert env.get("ANTHROPIC_BASE_URL") == "http://localhost:11434"
|
|
346
|
+
|
|
280
347
|
def test_anthropic_max_preserves_unrelated_vars(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
281
348
|
"""anthropic-max path leaves unrelated env vars intact."""
|
|
282
349
|
monkeypatch.setenv("PATH", "/usr/bin")
|
|
@@ -338,9 +405,7 @@ class TestBuildAgentEnvOllamaProvider:
|
|
|
338
405
|
|
|
339
406
|
assert env["ANTHROPIC_AUTH_TOKEN"] == "ollama-wins"
|
|
340
407
|
|
|
341
|
-
def test_ollama_ignores_parent_anthropic_api_key(
|
|
342
|
-
self, monkeypatch: pytest.MonkeyPatch
|
|
343
|
-
) -> None:
|
|
408
|
+
def test_ollama_ignores_parent_anthropic_api_key(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
344
409
|
"""provider=ollama rewrites ANTHROPIC_API_KEY="" regardless of parent value.
|
|
345
410
|
|
|
346
411
|
The builder strips every ANTHROPIC_* var from the returned dict and pins
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/__init__.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_bench_io.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_detect.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_dispatch.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/_resume.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/bench.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/init.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/optimize.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/review.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/commands/status.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/gh/milestones.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/logging_setup.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/__init__.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/prompts/hashes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/__init__.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/_telemetry.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/batch.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/fake_runner.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/mcp.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/options.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/protocol.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/rate_limit.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/retry.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/sdk_runner.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/soft_reset.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/state_guard.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/types.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/runner/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/state_retention.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/__init__.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/angular.md
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/base.md
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/fastapi.md
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/finance.md
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/src/code_generator/templates/nestjs.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_loop_multicycle.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_cycle_ollama_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_docs_no_default_max_turns.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_docs_ollama_model_guide.py
RENAMED
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_effective_model_routing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_max_turns_cli_flag.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_no_max_turns_in_call_sites.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_no_max_turns_literal.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_non_goals_grep_guard.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase_mcp_regression.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_phase_token_logging.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompt_prefix_snapshots.py
RENAMED
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_prompt_prefix_stability.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_generator-0.4.6 → claude_code_generator-0.4.8}/tests/test_requirements_structure.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|