codeprobe 0.3.2__tar.gz → 0.3.4__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.
- {codeprobe-0.3.2 → codeprobe-0.3.4}/PKG-INFO +1 -1
- {codeprobe-0.3.2 → codeprobe-0.3.4}/pyproject.toml +1 -1
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/claude.py +20 -10
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/executor.py +3 -1
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/isolation.py +18 -5
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/PKG-INFO +1 -1
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_adapters.py +22 -5
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_executor.py +1 -1
- {codeprobe-0.3.2 → codeprobe-0.3.4}/LICENSE +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/README.md +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/setup.cfg +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/__main__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/_base.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/codex.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/copilot.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/openai_compat.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/protocol.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/session.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/adapters/telemetry.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/analysis/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/analysis/ranking.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/analysis/report.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/analysis/stats.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/api.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/assess/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/assess/heuristics.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/assess_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/doctor_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/experiment_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/init_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/interpret_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/json_display.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/mine_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/preamble_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/probe_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/ratings_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/rich_display.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/run_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/scaffold_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/validate_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/wizard.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/cli/yaml_writer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/config/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/config/loader.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/_shared.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/adaptive.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/counterfactual.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/debate.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/decision_tree.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/elo.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/fingerprint.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/mutation.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/pareto.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/sprt.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/contrib/tournament.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/__main__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/checkpoint.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/events.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/experiment.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/llm.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/mcp_discovery.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/preamble.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/registry.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/sandbox.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/core/scoring.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/loaders/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/loaders/suite.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/_graph.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/_lang.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/comprehension.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/comprehension_writer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/curator.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/curator_backends.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/curator_tiers.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/extractor.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_families.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_oracle.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_scanner.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_validate.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/sg_ground_truth.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/sources.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/mining/writer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/evalrc.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/experiment.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/preamble.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/suite.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/models/task.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/preambles/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/preambles/github.md +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/preambles/sourcegraph.md +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/probe/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/probe/adapter.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/probe/generator.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/probe/writer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/ratings/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/ratings/collector.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/scaffold/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/scaffold/writer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/templates/__init__.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-mcp-comparison.yaml +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-model-comparison.yaml +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-prompt-comparison.yaml +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/SOURCES.txt +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/dependency_links.txt +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/entry_points.txt +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/requires.txt +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/src/codeprobe.egg-info/top_level.txt +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_adapter_contracts.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_analysis.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_api.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_artifact_scorer.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_assess.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_changed_symbols.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_checkpoint.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_checkpoint_scoring.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_cli.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_comprehension.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_config_loader.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_contrib.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_ctrlc_integration.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_curator_backends.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_curator_core.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_curator_integration.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_curator_tiers.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_doctor_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_events.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_executor_events.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_experiment_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_experiment_core.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_init_wizard.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_json_display.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_llm.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_loaders.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mcp_families_mining.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mcp_validate.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mine_goals.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mine_presets.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mine_profiles.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_mining.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_models.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_new_families.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_openai_compat.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_oracle_types.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_org_scale.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_pipeline_integration.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_preamble.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_preamble_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_probe.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_probe_adapter.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_ratings.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_ratings_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_registry.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_run_config_resolution.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_scaffold.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_scanner_refactor.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_scoring.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_session.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_sg_ground_truth.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_shell_shim.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_show_prompt.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_suite.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_telemetry.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_validate_cmd.py +0 -0
- {codeprobe-0.3.2 → codeprobe-0.3.4}/tests/test_weighted_f1.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeprobe
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Benchmark AI coding agents against your own codebase. Mine real tasks from repo history, run agents, interpret results.
|
|
5
5
|
Author: codeprobe contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -78,22 +78,32 @@ class ClaudeAdapter(BaseAdapter):
|
|
|
78
78
|
"""Return a per-slot CLAUDE_CONFIG_DIR for session isolation.
|
|
79
79
|
|
|
80
80
|
Copies authentication credentials from the real ``~/.claude/``
|
|
81
|
-
directory so the agent subprocess can authenticate.
|
|
81
|
+
directory so the agent subprocess can authenticate. If no credential
|
|
82
|
+
files are found (e.g. auth lives in the system keychain), skips
|
|
83
|
+
isolation and lets the agent use the real config dir.
|
|
82
84
|
"""
|
|
85
|
+
real_config = Path.home() / ".claude"
|
|
86
|
+
_CRED_NAMES = ("credentials.json", ".credentials.json")
|
|
87
|
+
|
|
88
|
+
# Check whether any copyable credential files exist.
|
|
89
|
+
has_creds = real_config.is_dir() and any(
|
|
90
|
+
(real_config / name).is_file() for name in _CRED_NAMES
|
|
91
|
+
)
|
|
92
|
+
if not has_creds:
|
|
93
|
+
# No file-based credentials found — don't override config dir
|
|
94
|
+
# so the CLI can use keychain / default auth.
|
|
95
|
+
return {}
|
|
96
|
+
|
|
83
97
|
config_dir = (
|
|
84
98
|
Path(tempfile.gettempdir()) / "codeprobe-claude" / f"slot-{slot_id}"
|
|
85
99
|
)
|
|
86
100
|
config_dir.mkdir(parents=True, exist_ok=True)
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
src = real_config / name
|
|
94
|
-
dst = config_dir / name
|
|
95
|
-
if src.is_file():
|
|
96
|
-
shutil.copy2(src, dst)
|
|
102
|
+
for name in _CRED_NAMES:
|
|
103
|
+
src = real_config / name
|
|
104
|
+
dst = config_dir / name
|
|
105
|
+
if src.is_file():
|
|
106
|
+
shutil.copy2(src, dst)
|
|
97
107
|
|
|
98
108
|
return {"CLAUDE_CONFIG_DIR": str(config_dir)}
|
|
99
109
|
|
|
@@ -700,7 +700,9 @@ def execute_config(
|
|
|
700
700
|
owns_isolation = False
|
|
701
701
|
active_isolation = isolation
|
|
702
702
|
if active_isolation is None:
|
|
703
|
-
active_isolation = WorktreeIsolation(
|
|
703
|
+
active_isolation = WorktreeIsolation(
|
|
704
|
+
repo_path, pool_size=workers, namespace=experiment_config.label
|
|
705
|
+
)
|
|
704
706
|
owns_isolation = True
|
|
705
707
|
|
|
706
708
|
def _run_isolated(task_dir: Path, repeat_index: int) -> TaskResult:
|
|
@@ -53,7 +53,7 @@ def git_restore_clean(workdir: Path, *, extra_excludes: tuple[str, ...] = ()) ->
|
|
|
53
53
|
"-e",
|
|
54
54
|
".codeprobe",
|
|
55
55
|
"-e",
|
|
56
|
-
".codeprobe-worktrees",
|
|
56
|
+
".codeprobe-worktrees*",
|
|
57
57
|
]
|
|
58
58
|
# Auto-discover experiment directories inside the repo
|
|
59
59
|
for exp_dir in _discover_experiment_dirs(workdir):
|
|
@@ -91,12 +91,15 @@ class WorktreeIsolation:
|
|
|
91
91
|
slot is free, ``release()`` resets and returns the slot to the pool.
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
|
-
def __init__(self, repo_path: Path, pool_size: int) -> None:
|
|
94
|
+
def __init__(self, repo_path: Path, pool_size: int, namespace: str = "") -> None:
|
|
95
95
|
if pool_size < 1:
|
|
96
96
|
raise ValueError(f"pool_size must be >= 1, got {pool_size}")
|
|
97
97
|
self._repo_path = repo_path.resolve()
|
|
98
98
|
self._pool_size = pool_size
|
|
99
|
-
|
|
99
|
+
base_name = ".codeprobe-worktrees"
|
|
100
|
+
if namespace:
|
|
101
|
+
base_name = f"{base_name}-{namespace}"
|
|
102
|
+
self._base_dir = self._repo_path / base_name
|
|
100
103
|
self._available: queue.Queue[Path] = queue.Queue()
|
|
101
104
|
self._all_paths: list[Path] = []
|
|
102
105
|
self._lock = threading.Lock()
|
|
@@ -177,6 +180,8 @@ class WorktreeIsolation:
|
|
|
177
180
|
|
|
178
181
|
def cleanup(self) -> None:
|
|
179
182
|
"""Remove all managed worktrees."""
|
|
183
|
+
import shutil
|
|
184
|
+
|
|
180
185
|
for wt_path in self._all_paths:
|
|
181
186
|
try:
|
|
182
187
|
subprocess.run(
|
|
@@ -185,8 +190,16 @@ class WorktreeIsolation:
|
|
|
185
190
|
check=True,
|
|
186
191
|
capture_output=True,
|
|
187
192
|
)
|
|
188
|
-
except (subprocess.CalledProcessError, OSError)
|
|
189
|
-
|
|
193
|
+
except (subprocess.CalledProcessError, OSError):
|
|
194
|
+
# Force-remove failed — delete the directory and let prune
|
|
195
|
+
# clean up git's internal records.
|
|
196
|
+
try:
|
|
197
|
+
if wt_path.exists():
|
|
198
|
+
shutil.rmtree(wt_path)
|
|
199
|
+
except OSError as rm_exc:
|
|
200
|
+
logger.warning(
|
|
201
|
+
"Failed to remove worktree dir %s: %s", wt_path, rm_exc
|
|
202
|
+
)
|
|
190
203
|
self._all_paths.clear()
|
|
191
204
|
# Prune any stale records so future runs start clean
|
|
192
205
|
subprocess.run(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeprobe
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Benchmark AI coding agents against your own codebase. Mine real tasks from repo history, run agents, interpret results.
|
|
5
5
|
Author: codeprobe contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -1146,18 +1146,35 @@ class TestClaudeMcpConfig:
|
|
|
1146
1146
|
|
|
1147
1147
|
|
|
1148
1148
|
class TestIsolateSession:
|
|
1149
|
-
def test_claude_isolate_session_returns_config_dir(self) -> None:
|
|
1149
|
+
def test_claude_isolate_session_returns_config_dir(self, tmp_path: Path) -> None:
|
|
1150
1150
|
adapter = ClaudeAdapter()
|
|
1151
|
-
|
|
1151
|
+
fake_home = tmp_path / "home"
|
|
1152
|
+
(fake_home / ".claude").mkdir(parents=True)
|
|
1153
|
+
(fake_home / ".claude" / ".credentials.json").write_text("{}")
|
|
1154
|
+
with patch.object(Path, "home", return_value=fake_home):
|
|
1155
|
+
env = adapter.isolate_session(0)
|
|
1152
1156
|
assert "CLAUDE_CONFIG_DIR" in env
|
|
1153
1157
|
assert "slot-0" in env["CLAUDE_CONFIG_DIR"]
|
|
1154
1158
|
|
|
1155
|
-
def test_claude_isolate_session_different_slots(self) -> None:
|
|
1159
|
+
def test_claude_isolate_session_different_slots(self, tmp_path: Path) -> None:
|
|
1156
1160
|
adapter = ClaudeAdapter()
|
|
1157
|
-
|
|
1158
|
-
|
|
1161
|
+
fake_home = tmp_path / "home"
|
|
1162
|
+
(fake_home / ".claude").mkdir(parents=True)
|
|
1163
|
+
(fake_home / ".claude" / ".credentials.json").write_text("{}")
|
|
1164
|
+
with patch.object(Path, "home", return_value=fake_home):
|
|
1165
|
+
env0 = adapter.isolate_session(0)
|
|
1166
|
+
env1 = adapter.isolate_session(1)
|
|
1159
1167
|
assert env0["CLAUDE_CONFIG_DIR"] != env1["CLAUDE_CONFIG_DIR"]
|
|
1160
1168
|
|
|
1169
|
+
def test_claude_isolate_session_skips_when_no_creds(self, tmp_path: Path) -> None:
|
|
1170
|
+
"""When no credential files exist, returns empty dict."""
|
|
1171
|
+
adapter = ClaudeAdapter()
|
|
1172
|
+
fake_home = tmp_path / "home"
|
|
1173
|
+
(fake_home / ".claude").mkdir(parents=True)
|
|
1174
|
+
with patch.object(Path, "home", return_value=fake_home):
|
|
1175
|
+
env = adapter.isolate_session(0)
|
|
1176
|
+
assert env == {}
|
|
1177
|
+
|
|
1161
1178
|
def test_base_adapter_isolate_session_returns_empty(self) -> None:
|
|
1162
1179
|
adapter = _StubAdapter()
|
|
1163
1180
|
env = adapter.isolate_session(42)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|