codeprobe 0.3.3__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.
Files changed (172) hide show
  1. {codeprobe-0.3.3 → codeprobe-0.3.4}/PKG-INFO +1 -1
  2. {codeprobe-0.3.3 → codeprobe-0.3.4}/pyproject.toml +1 -1
  3. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/claude.py +20 -10
  4. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/PKG-INFO +1 -1
  5. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_adapters.py +22 -5
  6. {codeprobe-0.3.3 → codeprobe-0.3.4}/LICENSE +0 -0
  7. {codeprobe-0.3.3 → codeprobe-0.3.4}/README.md +0 -0
  8. {codeprobe-0.3.3 → codeprobe-0.3.4}/setup.cfg +0 -0
  9. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/__init__.py +0 -0
  10. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/__main__.py +0 -0
  11. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/__init__.py +0 -0
  12. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/_base.py +0 -0
  13. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/codex.py +0 -0
  14. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/copilot.py +0 -0
  15. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/openai_compat.py +0 -0
  16. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/protocol.py +0 -0
  17. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/session.py +0 -0
  18. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/adapters/telemetry.py +0 -0
  19. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/analysis/__init__.py +0 -0
  20. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/analysis/ranking.py +0 -0
  21. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/analysis/report.py +0 -0
  22. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/analysis/stats.py +0 -0
  23. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/api.py +0 -0
  24. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/assess/__init__.py +0 -0
  25. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/assess/heuristics.py +0 -0
  26. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/__init__.py +0 -0
  27. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/assess_cmd.py +0 -0
  28. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/doctor_cmd.py +0 -0
  29. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/experiment_cmd.py +0 -0
  30. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/init_cmd.py +0 -0
  31. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/interpret_cmd.py +0 -0
  32. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/json_display.py +0 -0
  33. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/mine_cmd.py +0 -0
  34. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/preamble_cmd.py +0 -0
  35. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/probe_cmd.py +0 -0
  36. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/ratings_cmd.py +0 -0
  37. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/rich_display.py +0 -0
  38. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/run_cmd.py +0 -0
  39. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/scaffold_cmd.py +0 -0
  40. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/validate_cmd.py +0 -0
  41. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/wizard.py +0 -0
  42. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/cli/yaml_writer.py +0 -0
  43. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/config/__init__.py +0 -0
  44. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/config/loader.py +0 -0
  45. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/__init__.py +0 -0
  46. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/_shared.py +0 -0
  47. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/adaptive.py +0 -0
  48. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/counterfactual.py +0 -0
  49. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/debate.py +0 -0
  50. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/decision_tree.py +0 -0
  51. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/elo.py +0 -0
  52. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/fingerprint.py +0 -0
  53. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/mutation.py +0 -0
  54. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/pareto.py +0 -0
  55. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/sprt.py +0 -0
  56. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/contrib/tournament.py +0 -0
  57. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/__init__.py +0 -0
  58. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/__main__.py +0 -0
  59. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/checkpoint.py +0 -0
  60. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/events.py +0 -0
  61. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/executor.py +0 -0
  62. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/experiment.py +0 -0
  63. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/isolation.py +0 -0
  64. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/llm.py +0 -0
  65. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/mcp_discovery.py +0 -0
  66. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/preamble.py +0 -0
  67. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/registry.py +0 -0
  68. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/sandbox.py +0 -0
  69. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/core/scoring.py +0 -0
  70. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/loaders/__init__.py +0 -0
  71. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/loaders/suite.py +0 -0
  72. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/__init__.py +0 -0
  73. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/_graph.py +0 -0
  74. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/_lang.py +0 -0
  75. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/comprehension.py +0 -0
  76. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/comprehension_writer.py +0 -0
  77. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/curator.py +0 -0
  78. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/curator_backends.py +0 -0
  79. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/curator_tiers.py +0 -0
  80. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/extractor.py +0 -0
  81. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale.py +0 -0
  82. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_families.py +0 -0
  83. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_oracle.py +0 -0
  84. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_scanner.py +0 -0
  85. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/org_scale_validate.py +0 -0
  86. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/sg_ground_truth.py +0 -0
  87. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/sources.py +0 -0
  88. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/mining/writer.py +0 -0
  89. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/__init__.py +0 -0
  90. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/evalrc.py +0 -0
  91. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/experiment.py +0 -0
  92. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/preamble.py +0 -0
  93. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/suite.py +0 -0
  94. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/models/task.py +0 -0
  95. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/preambles/__init__.py +0 -0
  96. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/preambles/github.md +0 -0
  97. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/preambles/sourcegraph.md +0 -0
  98. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/probe/__init__.py +0 -0
  99. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/probe/adapter.py +0 -0
  100. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/probe/generator.py +0 -0
  101. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/probe/writer.py +0 -0
  102. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/ratings/__init__.py +0 -0
  103. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/ratings/collector.py +0 -0
  104. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/scaffold/__init__.py +0 -0
  105. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/scaffold/writer.py +0 -0
  106. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/templates/__init__.py +0 -0
  107. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-mcp-comparison.yaml +0 -0
  108. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-model-comparison.yaml +0 -0
  109. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe/templates/evalrc-prompt-comparison.yaml +0 -0
  110. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/SOURCES.txt +0 -0
  111. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/dependency_links.txt +0 -0
  112. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/entry_points.txt +0 -0
  113. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/requires.txt +0 -0
  114. {codeprobe-0.3.3 → codeprobe-0.3.4}/src/codeprobe.egg-info/top_level.txt +0 -0
  115. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_adapter_contracts.py +0 -0
  116. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_analysis.py +0 -0
  117. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_api.py +0 -0
  118. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_artifact_scorer.py +0 -0
  119. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_assess.py +0 -0
  120. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_changed_symbols.py +0 -0
  121. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_checkpoint.py +0 -0
  122. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_checkpoint_scoring.py +0 -0
  123. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_cli.py +0 -0
  124. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_comprehension.py +0 -0
  125. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_config_loader.py +0 -0
  126. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_contrib.py +0 -0
  127. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_ctrlc_integration.py +0 -0
  128. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_curator_backends.py +0 -0
  129. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_curator_core.py +0 -0
  130. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_curator_integration.py +0 -0
  131. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_curator_tiers.py +0 -0
  132. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_doctor_cmd.py +0 -0
  133. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_events.py +0 -0
  134. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_executor.py +0 -0
  135. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_executor_events.py +0 -0
  136. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_experiment_cmd.py +0 -0
  137. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_experiment_core.py +0 -0
  138. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_init_wizard.py +0 -0
  139. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_json_display.py +0 -0
  140. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_llm.py +0 -0
  141. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_loaders.py +0 -0
  142. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mcp_families_mining.py +0 -0
  143. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mcp_validate.py +0 -0
  144. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mine_goals.py +0 -0
  145. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mine_presets.py +0 -0
  146. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mine_profiles.py +0 -0
  147. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_mining.py +0 -0
  148. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_models.py +0 -0
  149. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_new_families.py +0 -0
  150. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_openai_compat.py +0 -0
  151. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_oracle_types.py +0 -0
  152. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_org_scale.py +0 -0
  153. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_pipeline_integration.py +0 -0
  154. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_preamble.py +0 -0
  155. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_preamble_cmd.py +0 -0
  156. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_probe.py +0 -0
  157. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_probe_adapter.py +0 -0
  158. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_ratings.py +0 -0
  159. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_ratings_cmd.py +0 -0
  160. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_registry.py +0 -0
  161. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_run_config_resolution.py +0 -0
  162. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_scaffold.py +0 -0
  163. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_scanner_refactor.py +0 -0
  164. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_scoring.py +0 -0
  165. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_session.py +0 -0
  166. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_sg_ground_truth.py +0 -0
  167. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_shell_shim.py +0 -0
  168. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_show_prompt.py +0 -0
  169. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_suite.py +0 -0
  170. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_telemetry.py +0 -0
  171. {codeprobe-0.3.3 → codeprobe-0.3.4}/tests/test_validate_cmd.py +0 -0
  172. {codeprobe-0.3.3 → 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
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codeprobe"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "Benchmark AI coding agents against your own codebase. Mine real tasks from repo history, run agents, interpret results."
5
5
  readme = "README.md"
6
6
  license = "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
- # Copy auth credentials from the user's real config dir.
89
- # Without these the subprocess gets "Not logged in".
90
- real_config = Path.home() / ".claude"
91
- if real_config.is_dir():
92
- for name in ("credentials.json", ".credentials.json"):
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeprobe
3
- Version: 0.3.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
- env = adapter.isolate_session(0)
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
- env0 = adapter.isolate_session(0)
1158
- env1 = adapter.isolate_session(1)
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