misterdev 0.2.2__tar.gz → 0.3.1__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.
- {misterdev-0.2.2/misterdev.egg-info → misterdev-0.3.1}/PKG-INFO +22 -2
- {misterdev-0.2.2 → misterdev-0.3.1}/README.md +21 -1
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/__init__.py +1 -1
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/agent.py +186 -39
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/__init__.py +2 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/detection.py +104 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/config.py +37 -5
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/__init__.py +14 -0
- misterdev-0.3.1/misterdev/core/context/contracts/c_tree_sitter.py +183 -0
- misterdev-0.3.1/misterdev/core/context/contracts/cpp_tree_sitter.py +344 -0
- misterdev-0.3.1/misterdev/core/context/contracts/csharp_tree_sitter.py +191 -0
- misterdev-0.3.1/misterdev/core/context/contracts/extraction.py +68 -0
- misterdev-0.3.1/misterdev/core/context/contracts/javascript_tree_sitter.py +198 -0
- misterdev-0.3.1/misterdev/core/context/contracts/kotlin_tree_sitter.py +272 -0
- misterdev-0.3.1/misterdev/core/context/contracts/swift_tree_sitter.py +256 -0
- misterdev-0.3.1/misterdev/core/context/contracts/typescript_tree_sitter.py +377 -0
- misterdev-0.3.1/misterdev/core/context/guidance/__init__.py +137 -0
- misterdev-0.3.1/misterdev/core/context/guidance/_rules.py +51 -0
- misterdev-0.3.1/misterdev/core/context/guidance/cpp.py +78 -0
- misterdev-0.3.1/misterdev/core/context/guidance/csharp.py +103 -0
- misterdev-0.3.1/misterdev/core/context/guidance/css.py +133 -0
- misterdev-0.3.1/misterdev/core/context/guidance/elixir.py +92 -0
- misterdev-0.3.1/misterdev/core/context/guidance/html.py +91 -0
- misterdev-0.3.1/misterdev/core/context/guidance/kotlin.py +119 -0
- misterdev-0.3.1/misterdev/core/context/guidance/python.py +110 -0
- misterdev-0.3.1/misterdev/core/context/guidance/react.py +98 -0
- misterdev-0.3.1/misterdev/core/context/guidance/rust.py +208 -0
- misterdev-0.3.1/misterdev/core/context/guidance/swift.py +104 -0
- misterdev-0.3.1/misterdev/core/context/guidance/typescript.py +97 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/lsp.py +49 -0
- misterdev-0.3.1/misterdev/core/context/lsp_swift.py +412 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/__init__.py +1 -2
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/cache.py +1 -1
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/graph.py +93 -8
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/nodes.py +12 -4
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/context_budget.py +4 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_selector.py +9 -3
- misterdev-0.3.1/misterdev/core/evolution/__init__.py +54 -0
- misterdev-0.3.1/misterdev/core/evolution/__main__.py +161 -0
- misterdev-0.3.1/misterdev/core/evolution/adapters.py +295 -0
- misterdev-0.3.1/misterdev/core/evolution/archive.py +158 -0
- misterdev-0.3.1/misterdev/core/evolution/attribution.py +92 -0
- misterdev-0.3.1/misterdev/core/evolution/driver.py +293 -0
- misterdev-0.3.1/misterdev/core/evolution/fitness.py +96 -0
- misterdev-0.3.1/misterdev/core/evolution/guardrail.py +81 -0
- misterdev-0.3.1/misterdev/core/evolution/holdout.py +103 -0
- misterdev-0.3.1/misterdev/core/evolution/loop.py +172 -0
- misterdev-0.3.1/misterdev/core/evolution/prior.py +84 -0
- misterdev-0.3.1/misterdev/core/evolution/proposer.py +181 -0
- misterdev-0.3.1/misterdev/core/evolution/sandbox.py +79 -0
- misterdev-0.3.1/misterdev/core/evolution/screen.py +149 -0
- misterdev-0.3.1/misterdev/core/evolution/tool_library.py +184 -0
- misterdev-0.3.1/misterdev/core/execution/compile_view.py +118 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/error_classifier.py +8 -6
- misterdev-0.3.1/misterdev/core/execution/error_log_compressor.py +135 -0
- misterdev-0.3.1/misterdev/core/execution/failure_view.py +433 -0
- misterdev-0.3.1/misterdev/core/execution/governance.py +403 -0
- misterdev-0.3.1/misterdev/core/execution/probe.py +178 -0
- misterdev-0.3.1/misterdev/core/learning/__init__.py +31 -0
- misterdev-0.3.1/misterdev/core/learning/failure_log.py +289 -0
- misterdev-0.3.1/misterdev/core/learning/failure_taxonomy.py +146 -0
- misterdev-0.3.1/misterdev/core/learning/reproduction.py +213 -0
- misterdev-0.3.1/misterdev/core/learning/targeting.py +103 -0
- misterdev-0.3.1/misterdev/core/learning/warm_start.py +204 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/assessment.py +1 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/decomposer.py +16 -2
- misterdev-0.3.1/misterdev/core/planning/lesson_store.py +407 -0
- misterdev-0.3.1/misterdev/core/planning/metacognition.py +111 -0
- misterdev-0.3.1/misterdev/core/planning/verifier_decomposition.py +357 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/report.py +31 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/__init__.py +37 -2
- misterdev-0.3.1/misterdev/core/verification/reflection.py +105 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/spec_tests.py +10 -2
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/base.py +54 -3
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/commands_mixin.py +20 -7
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/critic_spec_mixin.py +78 -21
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/edits_mixin.py +10 -2
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/execute_mixin.py +141 -8
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/gates_mixin.py +175 -10
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/helpers.py +67 -9
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/__init__.py +3 -1
- misterdev-0.3.1/misterdev/tools/dependency.py +68 -0
- {misterdev-0.2.2 → misterdev-0.3.1/misterdev.egg-info}/PKG-INFO +22 -2
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/SOURCES.txt +108 -1
- {misterdev-0.2.2 → misterdev-0.3.1}/pyproject.toml +4 -0
- misterdev-0.3.1/tests/test_audit_gate.py +104 -0
- misterdev-0.3.1/tests/test_compile_view.py +57 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_contracts.py +1 -1
- misterdev-0.3.1/tests/test_contracts_c.py +71 -0
- misterdev-0.3.1/tests/test_contracts_cpp.py +196 -0
- misterdev-0.3.1/tests/test_contracts_csharp_ts.py +69 -0
- misterdev-0.3.1/tests/test_contracts_javascript.py +82 -0
- misterdev-0.3.1/tests/test_contracts_kotlin.py +142 -0
- misterdev-0.3.1/tests/test_contracts_swift.py +169 -0
- misterdev-0.3.1/tests/test_contracts_typescript.py +200 -0
- misterdev-0.3.1/tests/test_dependency_tool.py +61 -0
- misterdev-0.3.1/tests/test_detect_lint_deps.py +91 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_error_classifier.py +3 -1
- misterdev-0.3.1/tests/test_error_log_compressor.py +90 -0
- misterdev-0.3.1/tests/test_evolution_adapters.py +99 -0
- misterdev-0.3.1/tests/test_evolution_archive.py +89 -0
- misterdev-0.3.1/tests/test_evolution_attribution.py +73 -0
- misterdev-0.3.1/tests/test_evolution_driver.py +194 -0
- misterdev-0.3.1/tests/test_evolution_fitness.py +68 -0
- misterdev-0.3.1/tests/test_evolution_guardrail.py +54 -0
- misterdev-0.3.1/tests/test_evolution_holdout.py +95 -0
- misterdev-0.3.1/tests/test_evolution_holdout_wiring.py +98 -0
- misterdev-0.3.1/tests/test_evolution_loop.py +152 -0
- misterdev-0.3.1/tests/test_evolution_prior.py +49 -0
- misterdev-0.3.1/tests/test_evolution_proposer.py +124 -0
- misterdev-0.3.1/tests/test_evolution_sandbox.py +107 -0
- misterdev-0.3.1/tests/test_evolution_screen.py +125 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_executor.py +163 -1
- misterdev-0.3.1/tests/test_failure_log.py +155 -0
- misterdev-0.3.1/tests/test_failure_targeting.py +66 -0
- misterdev-0.3.1/tests/test_failure_taxonomy.py +81 -0
- misterdev-0.3.1/tests/test_failure_view.py +235 -0
- misterdev-0.3.1/tests/test_gates_error_context.py +66 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_governance.py +56 -0
- misterdev-0.3.1/tests/test_grounded_spec.py +82 -0
- misterdev-0.3.1/tests/test_guidance.py +47 -0
- misterdev-0.3.1/tests/test_guidance_cpp.py +37 -0
- misterdev-0.3.1/tests/test_guidance_csharp.py +28 -0
- misterdev-0.3.1/tests/test_guidance_css.py +29 -0
- misterdev-0.3.1/tests/test_guidance_elixir.py +31 -0
- misterdev-0.3.1/tests/test_guidance_html.py +32 -0
- misterdev-0.3.1/tests/test_guidance_kotlin.py +33 -0
- misterdev-0.3.1/tests/test_guidance_python.py +33 -0
- misterdev-0.3.1/tests/test_guidance_react.py +37 -0
- misterdev-0.3.1/tests/test_guidance_rust.py +47 -0
- misterdev-0.3.1/tests/test_guidance_swift.py +29 -0
- misterdev-0.3.1/tests/test_guidance_typescript.py +33 -0
- misterdev-0.3.1/tests/test_learning_semantic.py +135 -0
- misterdev-0.3.1/tests/test_lesson_efficacy.py +146 -0
- misterdev-0.3.1/tests/test_lesson_store.py +146 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_llm_client.py +13 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_lsp.py +0 -20
- misterdev-0.3.1/tests/test_lsp_context.py +52 -0
- misterdev-0.3.1/tests/test_lsp_integration.py +72 -0
- misterdev-0.3.1/tests/test_lsp_swift.py +155 -0
- misterdev-0.3.1/tests/test_metacognition.py +94 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_selector.py +19 -1
- misterdev-0.3.1/tests/test_native_harness.py +148 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_orchestrator_fixes.py +4 -3
- misterdev-0.3.1/tests/test_polyglot_harness.py +190 -0
- misterdev-0.3.1/tests/test_probe.py +150 -0
- misterdev-0.3.1/tests/test_reflection.py +54 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_report.py +54 -0
- misterdev-0.3.1/tests/test_reproduction_corpus.py +104 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_spec_tests.py +145 -4
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_swebench_harness.py +4 -0
- misterdev-0.3.1/tests/test_tool_library.py +165 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_topography.py +85 -1
- misterdev-0.3.1/tests/test_verifier_decomposition.py +223 -0
- misterdev-0.3.1/tests/test_wiring_probe_staging.py +126 -0
- misterdev-0.2.2/misterdev/core/context/contracts/extraction.py +0 -30
- misterdev-0.2.2/misterdev/core/execution/governance.py +0 -283
- misterdev-0.2.2/misterdev/core/planning/metacognition.py +0 -103
- misterdev-0.2.2/tests/test_metacognition.py +0 -116
- {misterdev-0.2.2 → misterdev-0.3.1}/COMMERCIAL_LICENSE.md +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/LICENSE +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/agent_helpers.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/merge.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/overview.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/prompts.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/cli.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/audit.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/config.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/change_tracker.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/_log.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/_text.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/python_generic.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/registry.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/rust_line.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/rust_tree_sitter.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/scratchpad.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/_log.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/engine.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/parsers.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/syntax.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/embeddings.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/free_models.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/llm_cache.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_catalog.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_ledger.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/bounded.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/container.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/error_resolver.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/outcomes.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/progress.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/project.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/registry.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/runtime.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/gitcmd.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/mcp.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/mcp_gather.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/models.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/modes.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/advisor.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/sovereign.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/targets.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/report_view.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/task.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/claim_verifier.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/critic.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/constants.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/helpers.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/goal_check.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/independent.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/mutation_gate.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/preflight.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/validator.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/vision_verify.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/web_verify.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/base_env.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/container_env.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/venv_env.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/edits.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/embeddings.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/errors.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/providers.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/response.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/prompt_manager.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/apply.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/json_extract.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/models.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/parsing.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/logging_setup.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/mcp_server.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/nl_cli.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/plugins.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/py.typed +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/base_executor.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/context_mixin.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/git_mixin.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/llm_mixin.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/results_mixin.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/base_tool.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/command.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/file_io.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/formatter.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/git_tool.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/__init__.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/file_utils.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/process.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/dependency_links.txt +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/entry_points.txt +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/requires.txt +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/top_level.txt +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/setup.cfg +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_advisor.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_agent_helpers.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_assessment.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_audit.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_bounded.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_budget_halt.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_change_tracker.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_claim_verifier.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_command_tool.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_config.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_container.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_context_budget.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_critic.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_decomposer.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_dynamic_model_integration.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_embeddings.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_error_resolver.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_executor_git.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_extensibility.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_file_utils.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_free_models.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_gatekeeper.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_gitcmd.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_goal_check.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_goal_check_wiring.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_hms_integration.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_independent.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_integration_gate_count.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_llm_cache.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp_remote.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp_server.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_catalog.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_ledger.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_modes.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mutation_gate.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_nl_cli.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_orchestrator_config.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_outcomes.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_plugins.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_preflight.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_process.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_progress.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_prompt_manager.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_registry.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_report_view.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_responses.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_runtime.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_scratchpad.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_security.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_sovereign.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_targets.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_task_manager.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_topography_cache.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_validator.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_vision_verify.py +0 -0
- {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_web_verify.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: misterdev
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: An autonomous, extensible LLM build orchestrator that plans, edits, and verifies code across languages.
|
|
5
5
|
Author-email: David Condrey <david@writerslogic.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -138,12 +138,20 @@ Every change runs through an ordered gate sequence: **build → lint → tests
|
|
|
138
138
|
|
|
139
139
|
### Dynamic model selection
|
|
140
140
|
|
|
141
|
-
misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar
|
|
141
|
+
misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar across the **full breadth of OpenRouter** — routing each task up a **capability ladder** (harvested free / cheap → a strong mid-tier → a frontier tier) and **escalating to a stronger model only when a cheaper one can't clear the gates**. The strongest tier is reserved for the final attempt, so frontier spend is the rare safety net, not the default; a hard task that a mid model stalls on is finished by a frontier model, while easy tasks resolve on free/cheap ones. Quality never drops because a weak model that writes bad code fails the gate and the policy climbs. It runs against **OpenRouter or Anthropic** with automatic failover, caches responses to avoid paying twice, and token budgeting keeps spend inside the ceiling you set.
|
|
142
142
|
|
|
143
143
|
### Parallel worktrees
|
|
144
144
|
|
|
145
145
|
Disjoint tasks run concurrently, each in its own **isolated git worktree**, so independent work doesn't contend for the tree. An **integration gate** re-checks each wave against the full suite and reverts any task that regresses it — parallelism without cross-contamination.
|
|
146
146
|
|
|
147
|
+
### Self-improving
|
|
148
|
+
|
|
149
|
+
misterdev keeps a durable, fingerprinted stream of its own real failures and runs an **AlphaEvolve-style keep-if-better loop** over its own source: it attributes what breaks, classifies *why* (harness artifact vs observation gap vs capability), proposes a targeted structural self-edit, and promotes it only when it beats the champion on a **held-out task set it never optimized against** — with zero regressions. A reward-hacking guardrail walls off the tests and benchmark. The result is a loop that removes whole failure classes over time **without overfitting** to any one benchmark. See [docs/path-to-100.md](docs/path-to-100.md).
|
|
150
|
+
|
|
151
|
+
On the correctness side, misterdev works **reproduction-first**: for an issue-driven task it synthesizes a failing test from the acceptance criteria, **validates that the test actually fails on the clean tree** (a test that reproduces nothing is discarded rather than trusted), then drives the fix to turn it green — so the model edits toward a concrete, verified target instead of a description.
|
|
152
|
+
|
|
153
|
+
**Two-timescale evolution** *(design; see [docs/two-timescale-evolution.md](docs/two-timescale-evolution.md))* takes the self-improvement further than a memoryless runtime agent can: the agent invents task-specific tools at runtime, and the ones that **prove they generalize** are consolidated — through the same held-out promotion gate — into a **persistent, best-per-capability tool library that future runs start from**. Fast loop explores; slow loop keeps the winners; the held-out gate keeps the library general rather than benchmark-overfit. Capability compounds across runs instead of being reinvented each task.
|
|
154
|
+
|
|
147
155
|
### Extensibility
|
|
148
156
|
|
|
149
157
|
Tools, gates, and targets **self-register through Python entry points**. `pip install misterdev-plugin-x` adds a capability with **zero edits to the core** — misterdev discovers the entry point at runtime and wires it in. A working example lives at [`examples/misterdev-plugin-hello`](examples/misterdev-plugin-hello). See [Extending misterdev](#extending-misterdev).
|
|
@@ -152,6 +160,18 @@ Tools, gates, and targets **self-register through Python entry points**. `pip in
|
|
|
152
160
|
|
|
153
161
|
misterdev can connect to **Model Context Protocol** servers and let the model call their discovered tools mid-build — bounded, opt-in, and constrained by a tool allowlist. Transports include stdio and **remote streamable-http with auth**, so you can point it at a hosted MCP gateway like **Glama** and give the build access to a whole catalog of tools without running any of them locally.
|
|
154
162
|
|
|
163
|
+
## Benchmarks
|
|
164
|
+
|
|
165
|
+
Gate-verified pass@1 on [Aider's polyglot benchmark](https://github.com/Aider-AI/polyglot-benchmark) (Exercism exercises with hidden test suites), `anthropic/claude-sonnet-4-6`:
|
|
166
|
+
|
|
167
|
+
| Language | Solved | Rate |
|
|
168
|
+
| --- | --- | --- |
|
|
169
|
+
| JavaScript | 9 / 10 | **90%** |
|
|
170
|
+
| Python | 8 / 10 | **80%** |
|
|
171
|
+
| Rust | 7 / 10 | **70%** |
|
|
172
|
+
|
|
173
|
+
A continuous stress run has solved **20/20** across the three languages with zero failures — including the exercises usually cited as hard (bowling, forth, arbitrary-precision decimal). Every solve is judged by the exercise's own hidden tests, not the model's say-so. Full numbers, methodology, and how to reproduce: **[docs/benchmark-results.md](docs/benchmark-results.md)**. Test suite: **1,897 passing** — **[docs/TESTING.md](docs/TESTING.md)**.
|
|
174
|
+
|
|
155
175
|
## CLI reference
|
|
156
176
|
|
|
157
177
|
**Don't want to remember flags?** If the first argument isn't a subcommand,
|
|
@@ -85,12 +85,20 @@ Every change runs through an ordered gate sequence: **build → lint → tests
|
|
|
85
85
|
|
|
86
86
|
### Dynamic model selection
|
|
87
87
|
|
|
88
|
-
misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar
|
|
88
|
+
misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar across the **full breadth of OpenRouter** — routing each task up a **capability ladder** (harvested free / cheap → a strong mid-tier → a frontier tier) and **escalating to a stronger model only when a cheaper one can't clear the gates**. The strongest tier is reserved for the final attempt, so frontier spend is the rare safety net, not the default; a hard task that a mid model stalls on is finished by a frontier model, while easy tasks resolve on free/cheap ones. Quality never drops because a weak model that writes bad code fails the gate and the policy climbs. It runs against **OpenRouter or Anthropic** with automatic failover, caches responses to avoid paying twice, and token budgeting keeps spend inside the ceiling you set.
|
|
89
89
|
|
|
90
90
|
### Parallel worktrees
|
|
91
91
|
|
|
92
92
|
Disjoint tasks run concurrently, each in its own **isolated git worktree**, so independent work doesn't contend for the tree. An **integration gate** re-checks each wave against the full suite and reverts any task that regresses it — parallelism without cross-contamination.
|
|
93
93
|
|
|
94
|
+
### Self-improving
|
|
95
|
+
|
|
96
|
+
misterdev keeps a durable, fingerprinted stream of its own real failures and runs an **AlphaEvolve-style keep-if-better loop** over its own source: it attributes what breaks, classifies *why* (harness artifact vs observation gap vs capability), proposes a targeted structural self-edit, and promotes it only when it beats the champion on a **held-out task set it never optimized against** — with zero regressions. A reward-hacking guardrail walls off the tests and benchmark. The result is a loop that removes whole failure classes over time **without overfitting** to any one benchmark. See [docs/path-to-100.md](docs/path-to-100.md).
|
|
97
|
+
|
|
98
|
+
On the correctness side, misterdev works **reproduction-first**: for an issue-driven task it synthesizes a failing test from the acceptance criteria, **validates that the test actually fails on the clean tree** (a test that reproduces nothing is discarded rather than trusted), then drives the fix to turn it green — so the model edits toward a concrete, verified target instead of a description.
|
|
99
|
+
|
|
100
|
+
**Two-timescale evolution** *(design; see [docs/two-timescale-evolution.md](docs/two-timescale-evolution.md))* takes the self-improvement further than a memoryless runtime agent can: the agent invents task-specific tools at runtime, and the ones that **prove they generalize** are consolidated — through the same held-out promotion gate — into a **persistent, best-per-capability tool library that future runs start from**. Fast loop explores; slow loop keeps the winners; the held-out gate keeps the library general rather than benchmark-overfit. Capability compounds across runs instead of being reinvented each task.
|
|
101
|
+
|
|
94
102
|
### Extensibility
|
|
95
103
|
|
|
96
104
|
Tools, gates, and targets **self-register through Python entry points**. `pip install misterdev-plugin-x` adds a capability with **zero edits to the core** — misterdev discovers the entry point at runtime and wires it in. A working example lives at [`examples/misterdev-plugin-hello`](examples/misterdev-plugin-hello). See [Extending misterdev](#extending-misterdev).
|
|
@@ -99,6 +107,18 @@ Tools, gates, and targets **self-register through Python entry points**. `pip in
|
|
|
99
107
|
|
|
100
108
|
misterdev can connect to **Model Context Protocol** servers and let the model call their discovered tools mid-build — bounded, opt-in, and constrained by a tool allowlist. Transports include stdio and **remote streamable-http with auth**, so you can point it at a hosted MCP gateway like **Glama** and give the build access to a whole catalog of tools without running any of them locally.
|
|
101
109
|
|
|
110
|
+
## Benchmarks
|
|
111
|
+
|
|
112
|
+
Gate-verified pass@1 on [Aider's polyglot benchmark](https://github.com/Aider-AI/polyglot-benchmark) (Exercism exercises with hidden test suites), `anthropic/claude-sonnet-4-6`:
|
|
113
|
+
|
|
114
|
+
| Language | Solved | Rate |
|
|
115
|
+
| --- | --- | --- |
|
|
116
|
+
| JavaScript | 9 / 10 | **90%** |
|
|
117
|
+
| Python | 8 / 10 | **80%** |
|
|
118
|
+
| Rust | 7 / 10 | **70%** |
|
|
119
|
+
|
|
120
|
+
A continuous stress run has solved **20/20** across the three languages with zero failures — including the exercises usually cited as hard (bowling, forth, arbitrary-precision decimal). Every solve is judged by the exercise's own hidden tests, not the model's say-so. Full numbers, methodology, and how to reproduce: **[docs/benchmark-results.md](docs/benchmark-results.md)**. Test suite: **1,897 passing** — **[docs/TESTING.md](docs/TESTING.md)**.
|
|
121
|
+
|
|
102
122
|
## CLI reference
|
|
103
123
|
|
|
104
124
|
**Don't want to remember flags?** If the first argument isn't a subcommand,
|
|
@@ -38,6 +38,7 @@ from misterdev.core.planning.sovereign import (
|
|
|
38
38
|
ProbeGenerator,
|
|
39
39
|
)
|
|
40
40
|
from misterdev.core.planning.metacognition import SessionAuditor
|
|
41
|
+
from misterdev.core.learning import FailureLog, SolvedTaskIndex
|
|
41
42
|
from misterdev.core.context.contracts import ContractRegistry
|
|
42
43
|
from misterdev.core.verification.preflight import PreflightValidator
|
|
43
44
|
from misterdev.core.execution.progress import (
|
|
@@ -51,6 +52,10 @@ from misterdev.core.models import Task
|
|
|
51
52
|
from misterdev.analyzers.project_analyzer import (
|
|
52
53
|
analyze_project,
|
|
53
54
|
)
|
|
55
|
+
from misterdev.analyzers.project_analyzer.detection import (
|
|
56
|
+
detect_lint_command,
|
|
57
|
+
detect_typecheck_command,
|
|
58
|
+
)
|
|
54
59
|
from misterdev.core.planning.advisor import recommend_work
|
|
55
60
|
from misterdev.llm.client import BudgetExceededError
|
|
56
61
|
from misterdev.task_executors.markdown_plan_executor import (
|
|
@@ -86,6 +91,7 @@ class ProjectOrchestrator:
|
|
|
86
91
|
def __init__(self):
|
|
87
92
|
self.registry = ProjectRegistry()
|
|
88
93
|
self.last_build_succeeded = True
|
|
94
|
+
self.last_build_cost = 0.0
|
|
89
95
|
|
|
90
96
|
def scan_directory(self, path: str | Path):
|
|
91
97
|
self.registry.discover_projects(path)
|
|
@@ -428,16 +434,40 @@ class ProjectOrchestrator:
|
|
|
428
434
|
)
|
|
429
435
|
report.key_decisions.append(f"Halted by budget ceiling: {error}")
|
|
430
436
|
report.finalize()
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
report.llm_tokens = usage.total_tokens
|
|
434
|
-
report.llm_prompt_tokens = getattr(usage, "prompt_tokens", 0)
|
|
435
|
-
report.llm_completion_tokens = getattr(usage, "completion_tokens", 0)
|
|
436
|
-
report.llm_cache_read_tokens = getattr(usage, "cache_read_tokens", 0)
|
|
437
|
-
report.llm_cost = usage.estimated_cost
|
|
437
|
+
report.apply_llm_usage(project.llm_client.cumulative_usage)
|
|
438
|
+
self._persist_learning(project, report)
|
|
438
439
|
report.save(project.path)
|
|
439
440
|
return report.to_markdown()
|
|
440
441
|
|
|
442
|
+
def _persist_learning(self, project: Project, report: BuildReport) -> None:
|
|
443
|
+
"""Record this build's spend, real failures, and solved tasks.
|
|
444
|
+
|
|
445
|
+
Runs on EVERY terminated build — normal completion and budget halt alike.
|
|
446
|
+
A budget-exhausted run spent the whole cap and still failed, so it is the
|
|
447
|
+
highest-signal failure; dropping it would blind the exact features
|
|
448
|
+
(evolution-from-failures, warm-start) that learn from real use. Each write
|
|
449
|
+
is best-effort so bookkeeping never turns a finished build into a crash.
|
|
450
|
+
"""
|
|
451
|
+
# Expose this build's spend so a caller (e.g. the benchmark runner) can
|
|
452
|
+
# attribute per-run cost without re-deriving it from the saved report.
|
|
453
|
+
self.last_build_cost = float(
|
|
454
|
+
getattr(project.llm_client.cumulative_usage, "estimated_cost", 0.0)
|
|
455
|
+
)
|
|
456
|
+
try:
|
|
457
|
+
FailureLog(
|
|
458
|
+
project.path / ".orchestrator" / "failures.jsonl"
|
|
459
|
+
).record_failures(report.failed_tasks)
|
|
460
|
+
except Exception as e:
|
|
461
|
+
logger.warning(f"Failure logging failed (non-fatal): {e}")
|
|
462
|
+
report.degraded_subsystems.append(f"Failure logging: {e}")
|
|
463
|
+
try:
|
|
464
|
+
SolvedTaskIndex(
|
|
465
|
+
project.path / ".orchestrator" / "solved_tasks.jsonl"
|
|
466
|
+
).record(report.completed_tasks)
|
|
467
|
+
except Exception as e:
|
|
468
|
+
logger.warning(f"Solved-task indexing failed (non-fatal): {e}")
|
|
469
|
+
report.degraded_subsystems.append(f"Solved-task indexing: {e}")
|
|
470
|
+
|
|
441
471
|
def interactive_plan(self, project_path: str | Path, args: str = "") -> str:
|
|
442
472
|
"""Analyze the project, recommend work, and compose a plan with the user.
|
|
443
473
|
|
|
@@ -649,15 +679,33 @@ class ProjectOrchestrator:
|
|
|
649
679
|
# Sovereign enhancements (metacognition, AB-MCTS) are best-effort: they
|
|
650
680
|
# refine the spec but must not crash the build, so each degrades to the
|
|
651
681
|
# current spec on failure rather than aborting before any work is done.
|
|
652
|
-
|
|
682
|
+
# One embedder, shared by lesson retrieval and warm-start, so a similar
|
|
683
|
+
# lesson/task surfaces by MEANING, not just shared tokens. Best-effort:
|
|
684
|
+
# None (no fastembed / disabled) degrades both to lexical ranking.
|
|
685
|
+
embedder = self._learning_embedder(project)
|
|
686
|
+
auditor = SessionAuditor(project.path, project.llm_client, embedder=embedder)
|
|
653
687
|
try:
|
|
654
|
-
lessons
|
|
688
|
+
# Bias retrieval toward lessons relevant to this build's goal.
|
|
689
|
+
lessons = auditor.get_lessons_context(prompt)
|
|
655
690
|
if lessons:
|
|
656
691
|
spec = f"{lessons}\n\n{spec}"
|
|
657
692
|
except Exception as e:
|
|
658
693
|
logger.warning(f"Lesson injection failed (non-fatal): {e}")
|
|
659
694
|
report.degraded_subsystems.append(f"Lesson injection: {e}")
|
|
660
695
|
|
|
696
|
+
# Warm-start: seed the spec with how similar tasks were solved before, so a
|
|
697
|
+
# recurring shape starts from a proven approach instead of cold.
|
|
698
|
+
solved_index = SolvedTaskIndex(
|
|
699
|
+
project.path / ".orchestrator" / "solved_tasks.jsonl", embedder=embedder
|
|
700
|
+
)
|
|
701
|
+
try:
|
|
702
|
+
priors = solved_index.context(prompt)
|
|
703
|
+
if priors:
|
|
704
|
+
spec = f"{priors}\n\n{spec}"
|
|
705
|
+
except Exception as e:
|
|
706
|
+
logger.warning(f"Warm-start injection failed (non-fatal): {e}")
|
|
707
|
+
report.degraded_subsystems.append(f"Warm-start injection: {e}")
|
|
708
|
+
|
|
661
709
|
# AB-MCTS branch-and-evaluate is off by default: it fires several serial
|
|
662
710
|
# LLM calls before any work begins (observed ~30 min on one build) for
|
|
663
711
|
# marginal spec refinement. Opt in with orchestrator.enable_ab_mcts.
|
|
@@ -690,6 +738,7 @@ class ProjectOrchestrator:
|
|
|
690
738
|
max_tasks=max_tasks,
|
|
691
739
|
file_map=file_map,
|
|
692
740
|
targets=targets,
|
|
741
|
+
staging_hint=self._staging_hint(project),
|
|
693
742
|
)
|
|
694
743
|
tasks = topological_sort(tasks)
|
|
695
744
|
|
|
@@ -760,7 +809,11 @@ class ProjectOrchestrator:
|
|
|
760
809
|
commands = {
|
|
761
810
|
"build_command": assessment.structure.build_command,
|
|
762
811
|
"test_command": assessment.structure.test_command,
|
|
763
|
-
"lint_command": assessment.structure.lint_command
|
|
812
|
+
"lint_command": assessment.structure.lint_command
|
|
813
|
+
or detect_lint_command(project.path),
|
|
814
|
+
"audit_command": assessment.structure.audit_command,
|
|
815
|
+
"typecheck_command": project.config.get("typecheck_command")
|
|
816
|
+
or detect_typecheck_command(project.path),
|
|
764
817
|
"golden_command": get_setting(
|
|
765
818
|
project.config, "orchestrator", "golden_command"
|
|
766
819
|
),
|
|
@@ -863,18 +916,31 @@ class ProjectOrchestrator:
|
|
|
863
916
|
logger.warning(f"Session audit failed (non-fatal): {e}")
|
|
864
917
|
report.degraded_subsystems.append(f"Session audit: {e}")
|
|
865
918
|
|
|
866
|
-
|
|
867
|
-
report.llm_calls = usage.call_count
|
|
868
|
-
report.llm_tokens = usage.total_tokens
|
|
869
|
-
report.llm_prompt_tokens = getattr(usage, "prompt_tokens", 0)
|
|
870
|
-
report.llm_completion_tokens = getattr(usage, "completion_tokens", 0)
|
|
871
|
-
report.llm_cache_read_tokens = getattr(usage, "cache_read_tokens", 0)
|
|
872
|
-
report.llm_cost = usage.estimated_cost
|
|
919
|
+
report.apply_llm_usage(project.llm_client.cumulative_usage)
|
|
873
920
|
report.cost_by_task = dict(getattr(project.llm_client, "cost_by_task", {}))
|
|
921
|
+
# Learning writes + spend accounting, shared with the budget-halt path so
|
|
922
|
+
# a budget-exhausted run (the highest-signal failure) is not silently
|
|
923
|
+
# dropped from the streams the self-improvement features learn from.
|
|
924
|
+
self._persist_learning(project, report)
|
|
874
925
|
|
|
875
926
|
report.save(project.path)
|
|
876
927
|
return report.to_markdown()
|
|
877
928
|
|
|
929
|
+
def _learning_embedder(self, project: Project):
|
|
930
|
+
"""A shared embedder for lesson/warm-start retrieval, or None.
|
|
931
|
+
|
|
932
|
+
Reuses the project's embedding-backend config (which prefers a free,
|
|
933
|
+
offline local model and honours "none"), so semantic ranking is opt-in via
|
|
934
|
+
the same setting that governs context ranking. Any failure returns None,
|
|
935
|
+
degrading retrieval to lexical rather than breaking the build."""
|
|
936
|
+
try:
|
|
937
|
+
from misterdev.llm.client.embeddings import create_embedding_client
|
|
938
|
+
|
|
939
|
+
return create_embedding_client(project.config)
|
|
940
|
+
except Exception as e:
|
|
941
|
+
logger.debug(f"Learning embedder unavailable, using lexical ranking: {e}")
|
|
942
|
+
return None
|
|
943
|
+
|
|
878
944
|
def _capture_head(self, project: Project) -> Optional[str]:
|
|
879
945
|
"""Best-effort current HEAD sha, or None outside a git repo / on error."""
|
|
880
946
|
if not (project.path / ".git").exists():
|
|
@@ -1723,6 +1789,108 @@ class ProjectOrchestrator:
|
|
|
1723
1789
|
choice = Prompt.ask("Proceed?", choices=["y", "n", "s", "q"], default="y")
|
|
1724
1790
|
return {"y": "proceed", "q": "quit", "s": "skip", "n": "quit"}[choice]
|
|
1725
1791
|
|
|
1792
|
+
def _staging_hint(self, project: Project) -> str:
|
|
1793
|
+
"""Dense-reward staging suggestion for a single complex source file.
|
|
1794
|
+
|
|
1795
|
+
Uses the already-built symbol graph: when every public symbol lives in ONE
|
|
1796
|
+
non-test source file, that is a single-file goal — synthesize ordered
|
|
1797
|
+
construction->mutation->query stages so the decomposer can split it into a
|
|
1798
|
+
few sequential, independently-verifiable sub-tasks (raises per-attempt
|
|
1799
|
+
success on state-heavy files). Empty for multi-file goals or when nothing
|
|
1800
|
+
stages; never raises.
|
|
1801
|
+
"""
|
|
1802
|
+
try:
|
|
1803
|
+
from misterdev.core.planning.verifier_decomposition import (
|
|
1804
|
+
render_stages,
|
|
1805
|
+
synthesize_stages,
|
|
1806
|
+
)
|
|
1807
|
+
|
|
1808
|
+
graph = getattr(getattr(project, "topography", None), "graph", None)
|
|
1809
|
+
symbols = list(getattr(graph, "symbols", {}).values()) if graph else []
|
|
1810
|
+
src = [
|
|
1811
|
+
s
|
|
1812
|
+
for s in symbols
|
|
1813
|
+
if getattr(s, "file_path", "") and "test" not in s.file_path.lower()
|
|
1814
|
+
]
|
|
1815
|
+
if len({s.file_path for s in src}) != 1:
|
|
1816
|
+
return "" # staging only applies to a single-file goal
|
|
1817
|
+
stages = synthesize_stages(src)
|
|
1818
|
+
if len(stages) < 2:
|
|
1819
|
+
return ""
|
|
1820
|
+
return (
|
|
1821
|
+
"\n## Suggested staging (dense-reward decomposition)\n"
|
|
1822
|
+
"This file's public API splits into ordered, independently-"
|
|
1823
|
+
"verifiable stages. Prefer ONE sequential sub-task per stage, in "
|
|
1824
|
+
"this order (each must compile and leave the suite no worse):\n"
|
|
1825
|
+
f"{render_stages(stages)}\n"
|
|
1826
|
+
)
|
|
1827
|
+
except Exception as e: # a staging hint must never break decomposition
|
|
1828
|
+
logger.debug(f"Staging hint skipped (non-fatal): {e}")
|
|
1829
|
+
return ""
|
|
1830
|
+
|
|
1831
|
+
def _ground_completion_spec(
|
|
1832
|
+
self, assessment: ProjectAssessment, project: Project
|
|
1833
|
+
) -> str:
|
|
1834
|
+
"""Build a COMPLETE-mode spec grounded in objective signals.
|
|
1835
|
+
|
|
1836
|
+
A vague "complete everything" goal on a real codebase otherwise churns:
|
|
1837
|
+
the completeness analyzer flags "incomplete"/"stub" items from a lossy
|
|
1838
|
+
overview and mislabels deliberate design (graceful degradation, platform
|
|
1839
|
+
no-ops) as work, so the spec becomes a pile of speculative tasks. Instead
|
|
1840
|
+
lead with HARD signals — a failing build, failing tests, located
|
|
1841
|
+
TODO/FIXME markers, broken references — which are objective and
|
|
1842
|
+
verifiable, add features the docs promise but are absent, and demote the
|
|
1843
|
+
analyzer's guesses to an explicit "do NOT task these unless corroborated"
|
|
1844
|
+
advisory. When nothing hard or documented exists, the goal is ill-posed:
|
|
1845
|
+
emit zero-task guidance rather than fabricate work.
|
|
1846
|
+
"""
|
|
1847
|
+
h = assessment.health
|
|
1848
|
+
f = assessment.features
|
|
1849
|
+
hard: list[str] = []
|
|
1850
|
+
if not h.builds and h.build_output:
|
|
1851
|
+
hard.append(
|
|
1852
|
+
f"- The build is FAILING; fix it first:\n{h.build_output[:400]}"
|
|
1853
|
+
)
|
|
1854
|
+
if not h.tests_pass and h.test_output:
|
|
1855
|
+
hard.append(f"- Tests are FAILING:\n{h.test_output[:400]}")
|
|
1856
|
+
hard.extend(f"- Broken: {item}" for item in f.broken)
|
|
1857
|
+
hard.extend(
|
|
1858
|
+
f"- {t.get('file', '?')}:{t.get('line', '?')} {t.get('text', '')}"
|
|
1859
|
+
for t in f.todos[:20]
|
|
1860
|
+
)
|
|
1861
|
+
documented = [f"- {m.name}: {m.description}" for m in f.missing]
|
|
1862
|
+
speculative = [f"- {i.name}: {i.description}" for i in f.incomplete]
|
|
1863
|
+
speculative += [f"- Stub: {s}" for s in f.stubs]
|
|
1864
|
+
|
|
1865
|
+
parts = [f"# Completion Spec\n## Project: {project.name}\n"]
|
|
1866
|
+
if hard:
|
|
1867
|
+
parts.append(
|
|
1868
|
+
"## Must Fix — objective, verifiable failures\n" + "\n".join(hard)
|
|
1869
|
+
)
|
|
1870
|
+
if documented:
|
|
1871
|
+
parts.append(
|
|
1872
|
+
"\n## Should Add — promised by the docs but absent\n"
|
|
1873
|
+
+ "\n".join(documented)
|
|
1874
|
+
)
|
|
1875
|
+
if not hard and not documented:
|
|
1876
|
+
parts.append(
|
|
1877
|
+
"## No concrete objective found\n"
|
|
1878
|
+
"The build and tests pass and there are no TODO/FIXME markers or "
|
|
1879
|
+
"documented-but-missing features. A vague 'complete everything' goal "
|
|
1880
|
+
"has no well-posed work here. Do NOT fabricate tasks from speculation: "
|
|
1881
|
+
"produce ZERO tasks and report that a specific objective (a feature, a "
|
|
1882
|
+
"bug to fix, or --focus <area>) is required."
|
|
1883
|
+
)
|
|
1884
|
+
if speculative:
|
|
1885
|
+
parts.append(
|
|
1886
|
+
"\n## Advisory — analyzer guesses, NOT tasks\n"
|
|
1887
|
+
"Inferred as incomplete/stub from a lossy overview; these often "
|
|
1888
|
+
"mislabel deliberate design. Do NOT create a task for any of these "
|
|
1889
|
+
"unless a failing test or build error above corroborates it.\n"
|
|
1890
|
+
+ "\n".join(speculative[:15])
|
|
1891
|
+
)
|
|
1892
|
+
return "\n".join(parts)
|
|
1893
|
+
|
|
1726
1894
|
def _generate_spec(
|
|
1727
1895
|
self,
|
|
1728
1896
|
mode: BuildMode,
|
|
@@ -1751,28 +1919,7 @@ class ProjectOrchestrator:
|
|
|
1751
1919
|
return "\n".join(parts)
|
|
1752
1920
|
|
|
1753
1921
|
if mode == BuildMode.COMPLETE:
|
|
1754
|
-
|
|
1755
|
-
f"# Completion Spec\n## Project: {project.name}",
|
|
1756
|
-
"## Goal: Complete all work\n",
|
|
1757
|
-
"### Must Complete",
|
|
1758
|
-
]
|
|
1759
|
-
for f in assessment.features.incomplete:
|
|
1760
|
-
parts.append(f"- {f.name}: {f.description}")
|
|
1761
|
-
parts.append("\n### Must Fix")
|
|
1762
|
-
for item in assessment.features.broken:
|
|
1763
|
-
parts.append(f"- {item}")
|
|
1764
|
-
for item in assessment.features.stubs:
|
|
1765
|
-
parts.append(f"- Stub: {item}")
|
|
1766
|
-
parts.append("\n### Should Add")
|
|
1767
|
-
for f in assessment.features.missing:
|
|
1768
|
-
parts.append(f"- {f.name}: {f.description}")
|
|
1769
|
-
if assessment.features.todos:
|
|
1770
|
-
parts.append(f"\n### TODOs ({len(assessment.features.todos)} items)")
|
|
1771
|
-
for todo in assessment.features.todos[:20]:
|
|
1772
|
-
parts.append(
|
|
1773
|
-
f"- {todo.get('file', '?')}:{todo.get('line', '?')} {todo.get('text', '')}"
|
|
1774
|
-
)
|
|
1775
|
-
return "\n".join(parts)
|
|
1922
|
+
return self._ground_completion_spec(assessment, project)
|
|
1776
1923
|
|
|
1777
1924
|
if mode == BuildMode.SPEC:
|
|
1778
1925
|
spec_path = project.path / prompt.strip()
|
|
@@ -17,6 +17,7 @@ from misterdev.llm.client import BaseLLMClient
|
|
|
17
17
|
from misterdev.logging_setup import setup_logger
|
|
18
18
|
|
|
19
19
|
from .detection import (
|
|
20
|
+
detect_audit_command,
|
|
20
21
|
detect_build_command,
|
|
21
22
|
detect_test_command,
|
|
22
23
|
has_test_files,
|
|
@@ -109,6 +110,7 @@ def analyze_project(
|
|
|
109
110
|
)
|
|
110
111
|
assessment.structure.build_command = bc
|
|
111
112
|
assessment.structure.test_command = tc
|
|
113
|
+
assessment.structure.audit_command = detect_audit_command(project_path)
|
|
112
114
|
health_ground = _health_ground_truth(assessment.health)
|
|
113
115
|
|
|
114
116
|
def analyze_structure():
|
|
@@ -131,6 +131,110 @@ def detect_build_command(project_path: Path) -> Optional[str]:
|
|
|
131
131
|
return None
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
def detect_audit_command(project_path: Path) -> Optional[str]:
|
|
135
|
+
"""Detect a dependency/security-audit command from project markers.
|
|
136
|
+
|
|
137
|
+
Supply-chain scanning (the layer above lint): surfaces known-vulnerable
|
|
138
|
+
dependencies. Returns a runnable command, or None when no recognized
|
|
139
|
+
ecosystem is found. The audit gate is advisory and SKIPs when the tool is
|
|
140
|
+
absent, so returning a command the environment may lack is safe.
|
|
141
|
+
"""
|
|
142
|
+
p = project_path
|
|
143
|
+
if (p / "Cargo.toml").exists():
|
|
144
|
+
return "cargo audit"
|
|
145
|
+
if (p / "package.json").exists():
|
|
146
|
+
return "npm audit --omit=dev"
|
|
147
|
+
if (p / "pyproject.toml").exists() or (p / "requirements.txt").exists():
|
|
148
|
+
return "uv run pip-audit" if (p / "uv.lock").exists() else "pip-audit"
|
|
149
|
+
if any(p.glob("*.sln")) or any(p.glob("*.csproj")):
|
|
150
|
+
return "dotnet list package --vulnerable --include-transitive"
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def detect_lint_command(project_path: Path) -> Optional[str]:
|
|
155
|
+
"""Detect a strict linter command from project markers.
|
|
156
|
+
|
|
157
|
+
Fallback used when no ``lint_command`` is configured — so the strict tools
|
|
158
|
+
the guidance recommends actually run in the G2 gate. Conservative: only
|
|
159
|
+
returns a command when the tool is standard for the ecosystem (clippy ships
|
|
160
|
+
with rustup) or a config file proves it is set up, so an absent linter never
|
|
161
|
+
produces a false lint failure.
|
|
162
|
+
"""
|
|
163
|
+
p = project_path
|
|
164
|
+
if (p / "Cargo.toml").exists():
|
|
165
|
+
return "cargo clippy --all-targets --all-features -- -D warnings"
|
|
166
|
+
ruff_cfg = (p / "ruff.toml").exists() or (p / ".ruff.toml").exists()
|
|
167
|
+
if ruff_cfg or (
|
|
168
|
+
(p / "pyproject.toml").exists() and _file_mentions(p / "pyproject.toml", "ruff")
|
|
169
|
+
):
|
|
170
|
+
return "uv run ruff check ." if (p / "uv.lock").exists() else "ruff check ."
|
|
171
|
+
if (p / "package.json").exists() and any(
|
|
172
|
+
any(p.glob(pat)) for pat in ("eslint.config.*", ".eslintrc", ".eslintrc.*")
|
|
173
|
+
):
|
|
174
|
+
return "npx --no-install eslint . --max-warnings 0"
|
|
175
|
+
if (p / "Package.swift").exists() and (p / ".swiftlint.yml").exists():
|
|
176
|
+
return "swiftlint --strict"
|
|
177
|
+
if (p / "detekt.yml").exists() or (p / "detekt-config.yml").exists():
|
|
178
|
+
return "detekt"
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def detect_typecheck_command(project_path: Path) -> Optional[str]:
|
|
183
|
+
"""Detect a standalone type-check command, distinct from the build.
|
|
184
|
+
|
|
185
|
+
Only for ecosystems where type-checking is separate from compilation
|
|
186
|
+
(TypeScript's ``tsc --noEmit``, Python's mypy/pyright) — for compiled
|
|
187
|
+
languages the build gate already type-checks, so returning one would just
|
|
188
|
+
duplicate G1. Gated on a config file; the G4 gate SKIPs when the tool is
|
|
189
|
+
absent, so an uninstalled checker never blocks.
|
|
190
|
+
"""
|
|
191
|
+
p = project_path
|
|
192
|
+
if (p / "tsconfig.json").exists():
|
|
193
|
+
return "npx --no-install tsc --noEmit"
|
|
194
|
+
mypy_cfg = (
|
|
195
|
+
(p / "mypy.ini").exists()
|
|
196
|
+
or (p / ".mypy.ini").exists()
|
|
197
|
+
or (
|
|
198
|
+
(p / "pyproject.toml").exists()
|
|
199
|
+
and _file_mentions(p / "pyproject.toml", "[tool.mypy]")
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
if mypy_cfg:
|
|
203
|
+
return "uv run mypy ." if (p / "uv.lock").exists() else "mypy ."
|
|
204
|
+
if (p / "pyrightconfig.json").exists():
|
|
205
|
+
return "pyright"
|
|
206
|
+
return None
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def dependency_add_command(project_path: Path, package: str) -> Optional[str]:
|
|
210
|
+
"""Return the command to add a dependency, respecting the lock/manager in use.
|
|
211
|
+
|
|
212
|
+
None when the ecosystem edits its manifest by hand (SwiftPM) or is
|
|
213
|
+
unrecognized. Callers use this for deliberate dependency additions; a
|
|
214
|
+
refactor must not touch the lock file, only a genuine add.
|
|
215
|
+
"""
|
|
216
|
+
p = project_path
|
|
217
|
+
if (p / "Cargo.toml").exists():
|
|
218
|
+
return f"cargo add {package}"
|
|
219
|
+
if (p / "package.json").exists():
|
|
220
|
+
if (p / "pnpm-lock.yaml").exists():
|
|
221
|
+
return f"pnpm add {package}"
|
|
222
|
+
if (p / "yarn.lock").exists():
|
|
223
|
+
return f"yarn add {package}"
|
|
224
|
+
if (p / "bun.lockb").exists():
|
|
225
|
+
return f"bun add {package}"
|
|
226
|
+
return f"npm install {package}"
|
|
227
|
+
if (p / "pyproject.toml").exists():
|
|
228
|
+
return (
|
|
229
|
+
f"uv add {package}"
|
|
230
|
+
if (p / "uv.lock").exists()
|
|
231
|
+
else f"pip install {package}"
|
|
232
|
+
)
|
|
233
|
+
if any(p.glob("*.csproj")):
|
|
234
|
+
return f"dotnet add package {package}"
|
|
235
|
+
return None
|
|
236
|
+
|
|
237
|
+
|
|
134
238
|
def _file_mentions(path: Path, needle: str) -> bool:
|
|
135
239
|
try:
|
|
136
240
|
return needle in path.read_text(encoding="utf-8")
|
|
@@ -41,7 +41,23 @@ class LLMSettings:
|
|
|
41
41
|
# models maps tier name -> model id (or a list of candidate ids). Empty =
|
|
42
42
|
# use the default model.
|
|
43
43
|
routing: Dict[str, Any] = field(default_factory=dict)
|
|
44
|
-
|
|
44
|
+
# Default capability ladder (grounded in the live OpenRouter catalog). The
|
|
45
|
+
# cheapest rung also receives auto-harvested free models (use_free_models);
|
|
46
|
+
# the strongest rung is reached ONLY on the final attempt (see ModelSelector),
|
|
47
|
+
# so frontier spend is the rare safety net, not the default. Each rung lists
|
|
48
|
+
# candidates cheapest-strong first so a quality-per-dollar tie breaks toward
|
|
49
|
+
# the cheaper option and the ledger learns which model wins each cell.
|
|
50
|
+
models: Dict[str, Any] = field(
|
|
51
|
+
default_factory=lambda: {
|
|
52
|
+
"cheap": ["deepseek/deepseek-r1-0528"],
|
|
53
|
+
"mid": ["anthropic/claude-sonnet-4.6"],
|
|
54
|
+
"frontier": [
|
|
55
|
+
"openai/gpt-5.1-codex",
|
|
56
|
+
"google/gemini-3.1-pro-preview",
|
|
57
|
+
"anthropic/claude-opus-4.8",
|
|
58
|
+
],
|
|
59
|
+
}
|
|
60
|
+
)
|
|
45
61
|
# Ledger-driven dynamic model selection. False = off (default), True = on
|
|
46
62
|
# using selection_posture, "auto" = self-activating: explore cheap/free
|
|
47
63
|
# models on easy tasks while a (category, complexity) cell is immature, then
|
|
@@ -51,7 +67,7 @@ class LLMSettings:
|
|
|
51
67
|
# resolves through `models`. The policy uses a cheaper model on early
|
|
52
68
|
# attempts and climbs to the strongest tier by the final attempt.
|
|
53
69
|
dynamic_selection: Any = "auto"
|
|
54
|
-
escalation: List[str] = field(default_factory=
|
|
70
|
+
escalation: List[str] = field(default_factory=lambda: ["cheap", "mid", "frontier"])
|
|
55
71
|
# A cheaper model is trusted for a first attempt only once it has at least
|
|
56
72
|
# min_observations recorded first-try attempts and a first-try success rate
|
|
57
73
|
# at or above first_try_floor.
|
|
@@ -228,9 +244,11 @@ class OrchestratorSettings:
|
|
|
228
244
|
# off by default (marginal value, large latency/cost).
|
|
229
245
|
enable_ab_mcts: bool = False
|
|
230
246
|
# Empirical probe discovery (SMART/CREATE Phase 1.5) runs an LLM call plus
|
|
231
|
-
# ephemeral scripts to verify facts before planning.
|
|
232
|
-
#
|
|
233
|
-
|
|
247
|
+
# ephemeral scripts to verify facts before planning. OFF by default: measured
|
|
248
|
+
# to balloon the pre-execution context (~900K tokens over ~9 calls on a
|
|
249
|
+
# trivial task) and exhaust the whole budget before any code is written. Worth
|
|
250
|
+
# enabling only for complex work against an unfamiliar live codebase.
|
|
251
|
+
enable_probes: bool = False
|
|
234
252
|
# Auto-detect polyglot sub-projects (targets) when none are declared, so a
|
|
235
253
|
# monorepo gets per-toolchain gate routing with zero config. Off by default
|
|
236
254
|
# (explicit ``targets`` is more precise); detected commands are best-effort.
|
|
@@ -301,6 +319,15 @@ class OrchestratorSettings:
|
|
|
301
319
|
critic_auto_categories: List[str] = field(
|
|
302
320
|
default_factory=lambda: ["refactor", "fix", "integration"]
|
|
303
321
|
)
|
|
322
|
+
# Self-reflection on a failed attempt (the Reflexion pattern). When on, a
|
|
323
|
+
# failed gate triggers a short model reflection on the ROOT CAUSE and what to
|
|
324
|
+
# do differently, accumulated across attempts and fed into the next one — so a
|
|
325
|
+
# retry debugs the underlying problem instead of re-patching the symptom. On
|
|
326
|
+
# by default: it only ADDS guidance on a failure (never on a first attempt or
|
|
327
|
+
# a success), is timeout-bounded, and SKIPs cleanly with no client. Costs one
|
|
328
|
+
# extra short call per failed attempt; set false to disable entirely.
|
|
329
|
+
reflection: bool = True
|
|
330
|
+
reflection_timeout: int = 45
|
|
304
331
|
# Independent completeness-claim verifier. Before a build composes its spec
|
|
305
332
|
# and tasks, each feature the analyzer flagged "incomplete" and each "stub"
|
|
306
333
|
# file is rechecked against the REAL file + tests by a second component
|
|
@@ -314,6 +341,11 @@ class OrchestratorSettings:
|
|
|
314
341
|
# claim's judgment.
|
|
315
342
|
verify_claims: bool = True
|
|
316
343
|
verify_claims_timeout: int = 45
|
|
344
|
+
# Failure-triggered probe: on a red test gate, re-run ONLY the first failing
|
|
345
|
+
# test in isolation and append its fresh, uncluttered trace to the retry
|
|
346
|
+
# context. Off by default — the re-run costs a test invocation (cheap for
|
|
347
|
+
# pytest/jest, a full compile for cargo/swift/dotnet), so it is opt-in.
|
|
348
|
+
failure_probe: bool = False
|
|
317
349
|
|
|
318
350
|
|
|
319
351
|
PROMPT_TEMPLATES = {
|
|
@@ -34,6 +34,13 @@ from .rust_tree_sitter import (
|
|
|
34
34
|
_ts_variant_names,
|
|
35
35
|
_walk_rust_ts,
|
|
36
36
|
)
|
|
37
|
+
from .c_tree_sitter import _extract_c_symbols_ts
|
|
38
|
+
from .cpp_tree_sitter import _extract_cpp_symbols_ts
|
|
39
|
+
from .csharp_tree_sitter import _extract_csharp_symbols_ts
|
|
40
|
+
from .javascript_tree_sitter import _extract_javascript_symbols_ts
|
|
41
|
+
from .kotlin_tree_sitter import _extract_kotlin_symbols_ts
|
|
42
|
+
from .swift_tree_sitter import _extract_swift_symbols_ts
|
|
43
|
+
from .typescript_tree_sitter import _extract_typescript_symbols_ts
|
|
37
44
|
|
|
38
45
|
__all__ = [
|
|
39
46
|
"logger",
|
|
@@ -60,4 +67,11 @@ __all__ = [
|
|
|
60
67
|
"_ts_pub_members",
|
|
61
68
|
"_ts_variant_names",
|
|
62
69
|
"_ts_trait_methods",
|
|
70
|
+
"_extract_swift_symbols_ts",
|
|
71
|
+
"_extract_kotlin_symbols_ts",
|
|
72
|
+
"_extract_typescript_symbols_ts",
|
|
73
|
+
"_extract_javascript_symbols_ts",
|
|
74
|
+
"_extract_cpp_symbols_ts",
|
|
75
|
+
"_extract_c_symbols_ts",
|
|
76
|
+
"_extract_csharp_symbols_ts",
|
|
63
77
|
]
|