misterdev 0.2.0__py3-none-any.whl

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 (136) hide show
  1. misterdev/__init__.py +3 -0
  2. misterdev/agent.py +2166 -0
  3. misterdev/agent_helpers.py +194 -0
  4. misterdev/analyzers/__init__.py +0 -0
  5. misterdev/analyzers/project_analyzer/__init__.py +246 -0
  6. misterdev/analyzers/project_analyzer/detection.py +146 -0
  7. misterdev/analyzers/project_analyzer/merge.py +137 -0
  8. misterdev/analyzers/project_analyzer/overview.py +312 -0
  9. misterdev/analyzers/project_analyzer/prompts.py +83 -0
  10. misterdev/cli.py +370 -0
  11. misterdev/config.py +521 -0
  12. misterdev/core/__init__.py +0 -0
  13. misterdev/core/audit.py +88 -0
  14. misterdev/core/config.py +10 -0
  15. misterdev/core/context/__init__.py +0 -0
  16. misterdev/core/context/change_tracker.py +218 -0
  17. misterdev/core/context/contracts/__init__.py +63 -0
  18. misterdev/core/context/contracts/_log.py +9 -0
  19. misterdev/core/context/contracts/_text.py +12 -0
  20. misterdev/core/context/contracts/extraction.py +30 -0
  21. misterdev/core/context/contracts/python_generic.py +42 -0
  22. misterdev/core/context/contracts/registry.py +127 -0
  23. misterdev/core/context/contracts/rust_line.py +225 -0
  24. misterdev/core/context/contracts/rust_tree_sitter.py +141 -0
  25. misterdev/core/context/lsp.py +174 -0
  26. misterdev/core/context/scratchpad.py +111 -0
  27. misterdev/core/context/topography/__init__.py +43 -0
  28. misterdev/core/context/topography/_log.py +10 -0
  29. misterdev/core/context/topography/cache.py +91 -0
  30. misterdev/core/context/topography/engine.py +172 -0
  31. misterdev/core/context/topography/graph.py +675 -0
  32. misterdev/core/context/topography/nodes.py +55 -0
  33. misterdev/core/context/topography/parsers.py +95 -0
  34. misterdev/core/context/topography/syntax.py +54 -0
  35. misterdev/core/economics/__init__.py +0 -0
  36. misterdev/core/economics/context_budget.py +175 -0
  37. misterdev/core/economics/embeddings.py +232 -0
  38. misterdev/core/economics/free_models.py +108 -0
  39. misterdev/core/economics/llm_cache.py +105 -0
  40. misterdev/core/economics/model_catalog.py +79 -0
  41. misterdev/core/economics/model_ledger.py +331 -0
  42. misterdev/core/economics/model_selector.py +281 -0
  43. misterdev/core/execution/__init__.py +0 -0
  44. misterdev/core/execution/bounded.py +50 -0
  45. misterdev/core/execution/container.py +221 -0
  46. misterdev/core/execution/error_classifier.py +366 -0
  47. misterdev/core/execution/error_resolver.py +201 -0
  48. misterdev/core/execution/governance.py +283 -0
  49. misterdev/core/execution/outcomes.py +50 -0
  50. misterdev/core/execution/progress.py +120 -0
  51. misterdev/core/execution/project.py +231 -0
  52. misterdev/core/execution/registry.py +97 -0
  53. misterdev/core/execution/runtime.py +279 -0
  54. misterdev/core/gitcmd.py +39 -0
  55. misterdev/core/integration/__init__.py +0 -0
  56. misterdev/core/integration/mcp.py +368 -0
  57. misterdev/core/integration/mcp_gather.py +186 -0
  58. misterdev/core/models.py +35 -0
  59. misterdev/core/modes.py +184 -0
  60. misterdev/core/planning/__init__.py +0 -0
  61. misterdev/core/planning/advisor.py +89 -0
  62. misterdev/core/planning/assessment.py +135 -0
  63. misterdev/core/planning/decomposer.py +387 -0
  64. misterdev/core/planning/metacognition.py +103 -0
  65. misterdev/core/planning/sovereign.py +308 -0
  66. misterdev/core/planning/targets.py +201 -0
  67. misterdev/core/reporting/__init__.py +0 -0
  68. misterdev/core/reporting/report.py +377 -0
  69. misterdev/core/reporting/report_view.py +151 -0
  70. misterdev/core/task.py +163 -0
  71. misterdev/core/verification/__init__.py +0 -0
  72. misterdev/core/verification/claim_verifier.py +210 -0
  73. misterdev/core/verification/critic.py +324 -0
  74. misterdev/core/verification/gatekeeper/__init__.py +631 -0
  75. misterdev/core/verification/gatekeeper/constants.py +138 -0
  76. misterdev/core/verification/gatekeeper/helpers.py +28 -0
  77. misterdev/core/verification/goal_check.py +219 -0
  78. misterdev/core/verification/independent.py +68 -0
  79. misterdev/core/verification/mutation_gate.py +221 -0
  80. misterdev/core/verification/preflight.py +95 -0
  81. misterdev/core/verification/spec_tests.py +175 -0
  82. misterdev/core/verification/validator.py +495 -0
  83. misterdev/core/verification/vision_verify.py +185 -0
  84. misterdev/core/verification/web_verify.py +408 -0
  85. misterdev/environments/__init__.py +0 -0
  86. misterdev/environments/base_env.py +18 -0
  87. misterdev/environments/container_env.py +87 -0
  88. misterdev/environments/venv_env.py +42 -0
  89. misterdev/llm/__init__.py +0 -0
  90. misterdev/llm/client/__init__.py +152 -0
  91. misterdev/llm/client/base.py +382 -0
  92. misterdev/llm/client/edits.py +70 -0
  93. misterdev/llm/client/embeddings.py +121 -0
  94. misterdev/llm/client/errors.py +134 -0
  95. misterdev/llm/client/providers.py +535 -0
  96. misterdev/llm/client/response.py +24 -0
  97. misterdev/llm/prompt_manager.py +82 -0
  98. misterdev/llm/responses/__init__.py +34 -0
  99. misterdev/llm/responses/apply.py +131 -0
  100. misterdev/llm/responses/json_extract.py +80 -0
  101. misterdev/llm/responses/models.py +43 -0
  102. misterdev/llm/responses/parsing.py +494 -0
  103. misterdev/logging_setup.py +20 -0
  104. misterdev/mcp_server.py +208 -0
  105. misterdev/nl_cli.py +149 -0
  106. misterdev/plugins.py +115 -0
  107. misterdev/py.typed +0 -0
  108. misterdev/task_executors/__init__.py +0 -0
  109. misterdev/task_executors/base_executor.py +10 -0
  110. misterdev/task_executors/markdown_plan_executor/__init__.py +90 -0
  111. misterdev/task_executors/markdown_plan_executor/commands_mixin.py +82 -0
  112. misterdev/task_executors/markdown_plan_executor/context_mixin.py +221 -0
  113. misterdev/task_executors/markdown_plan_executor/critic_spec_mixin.py +174 -0
  114. misterdev/task_executors/markdown_plan_executor/edits_mixin.py +251 -0
  115. misterdev/task_executors/markdown_plan_executor/execute_mixin.py +727 -0
  116. misterdev/task_executors/markdown_plan_executor/gates_mixin.py +203 -0
  117. misterdev/task_executors/markdown_plan_executor/git_mixin.py +219 -0
  118. misterdev/task_executors/markdown_plan_executor/helpers.py +521 -0
  119. misterdev/task_executors/markdown_plan_executor/llm_mixin.py +238 -0
  120. misterdev/task_executors/markdown_plan_executor/results_mixin.py +23 -0
  121. misterdev/tools/__init__.py +19 -0
  122. misterdev/tools/base_tool.py +14 -0
  123. misterdev/tools/command.py +75 -0
  124. misterdev/tools/file_io.py +69 -0
  125. misterdev/tools/formatter.py +26 -0
  126. misterdev/tools/git_tool.py +90 -0
  127. misterdev/utils/__init__.py +0 -0
  128. misterdev/utils/file_utils.py +169 -0
  129. misterdev/utils/process.py +23 -0
  130. misterdev-0.2.0.dist-info/METADATA +326 -0
  131. misterdev-0.2.0.dist-info/RECORD +136 -0
  132. misterdev-0.2.0.dist-info/WHEEL +5 -0
  133. misterdev-0.2.0.dist-info/entry_points.txt +3 -0
  134. misterdev-0.2.0.dist-info/licenses/COMMERCIAL_LICENSE.md +34 -0
  135. misterdev-0.2.0.dist-info/licenses/LICENSE +661 -0
  136. misterdev-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,169 @@
1
+ import fnmatch
2
+ import json
3
+ import os
4
+ import re
5
+ import tempfile
6
+ from pathlib import Path
7
+ from typing import Any, List
8
+
9
+
10
+ def ensure_artifact_dir(directory: Path) -> Path:
11
+ """Create an orchestrator artifact dir that git ignores.
12
+
13
+ Runtime artifacts (ledger, response cache, free-model list, reports) live
14
+ under ``.orchestrator/`` and must never dirty the user's working tree. The
15
+ dir self-ignores via a ``.gitignore`` containing ``*`` — the same trick
16
+ ``.pytest_cache`` uses — so users get clean behavior with zero setup.
17
+ """
18
+ directory = Path(directory)
19
+ directory.mkdir(parents=True, exist_ok=True)
20
+ # Place the guard at the .orchestrator root (parent of per-feature subdirs
21
+ # like llm_cache/, or alongside files written directly into .orchestrator).
22
+ root = directory.parent if directory.parent.name == ".orchestrator" else directory
23
+ gitignore = root / ".gitignore"
24
+ if not gitignore.exists():
25
+ try:
26
+ gitignore.write_text("*\n", encoding="utf-8")
27
+ except OSError:
28
+ pass
29
+ return directory
30
+
31
+
32
+ def is_golden_path(file_path: str, patterns) -> bool:
33
+ """True if a project-relative path is part of the golden (protected) suite.
34
+
35
+ Supports an exact path, a directory prefix (``tests/golden/`` matches
36
+ everything beneath it), and a glob (``tests/test_contract_*.py``). Shared
37
+ by the executor (conceal + reject edits) and the symbol graph (exclude from
38
+ indexing) so the model can neither see nor modify these files.
39
+ """
40
+ if not patterns:
41
+ return False
42
+ norm = file_path.replace("\\", "/").lstrip("./")
43
+ for pat in patterns:
44
+ p = str(pat).replace("\\", "/").lstrip("./")
45
+ if not p:
46
+ continue
47
+ if norm == p or norm.startswith(p.rstrip("/") + "/"):
48
+ return True
49
+ if fnmatch.fnmatch(norm, p):
50
+ return True
51
+ return False
52
+
53
+
54
+ def safe_ref_slug(value: str, fallback: str = "x", maxlen: int = 64) -> str:
55
+ """Filesystem- and git-ref-safe slug from an arbitrary (LLM-supplied) string.
56
+
57
+ Any LLM-generated identifier that becomes a branch name (``task/<id>``), a
58
+ script/tool filename, or a dict key passes through here first, so a stray
59
+ ``/``, space, or ``:`` can't crash a build (missing-subdir write) or produce
60
+ an invalid git ref. Replaces unsafe chars with ``_``, collapses runs, trims
61
+ leading/trailing separators, and falls back when nothing usable remains.
62
+ """
63
+ s = re.sub(r"[^A-Za-z0-9._-]", "_", str(value))
64
+ s = re.sub(r"_+", "_", s).strip("._-")
65
+ return s[:maxlen] or fallback
66
+
67
+
68
+ def orchestrator_state_file(project_path: str | Path, name: str) -> Path:
69
+ """Path to a JSON state file under the project's ``.orchestrator/`` dir.
70
+
71
+ Creates the parent directory and centralizes the state-dir convention shared
72
+ by the progress/contracts/change trackers so it lives in exactly one place.
73
+ """
74
+ f = Path(project_path) / ".orchestrator" / name
75
+ f.parent.mkdir(parents=True, exist_ok=True)
76
+ return f
77
+
78
+
79
+ def read_file(file_path: str | Path) -> str:
80
+ """Reads the content of a file."""
81
+ with open(file_path, "r", encoding="utf-8") as f:
82
+ return f.read()
83
+
84
+
85
+ # Cap a model-requested read: a multi-GB in-project file (build artifact, data
86
+ # dump) would otherwise load whole into memory and the LLM context, a token/cost
87
+ # blowout. 2 MB matches the gatekeeper scan bound.
88
+ _MAX_READ_CHARS = 2_000_000
89
+
90
+
91
+ def read_file_capped(file_path: str | Path, max_chars: int = _MAX_READ_CHARS) -> str:
92
+ """Read up to ``max_chars`` characters, appending a truncation marker when the
93
+ file is larger, so the caller (and the model) knows the content is partial."""
94
+ with open(file_path, "r", encoding="utf-8", errors="replace") as f:
95
+ data = f.read(max_chars + 1)
96
+ if len(data) > max_chars:
97
+ return data[:max_chars] + f"\n...[truncated: file exceeds {max_chars} chars]"
98
+ return data
99
+
100
+
101
+ def atomic_write(file_path: str | Path, content: str) -> None:
102
+ """Write content via a temp file + atomic rename.
103
+
104
+ Guarantees the destination is never left half-written if the process
105
+ crashes or two writers race: readers see either the old file or the new
106
+ one, never a truncated mix. The temp file is created in the destination
107
+ directory so os.replace stays within one filesystem (atomic on POSIX).
108
+ """
109
+ path = Path(file_path)
110
+ path.parent.mkdir(parents=True, exist_ok=True)
111
+ _atomic_replace(path, content)
112
+
113
+
114
+ def _atomic_replace(path: Path, content: str) -> None:
115
+ """Temp-file-then-rename core, assuming ``path.parent`` already exists.
116
+
117
+ Split out so callers that have already created the directory (e.g. via
118
+ ``ensure_artifact_dir``) don't mkdir it a second time.
119
+ """
120
+ fd, tmp_path = tempfile.mkstemp(dir=str(path.parent), suffix=".tmp")
121
+ try:
122
+ with os.fdopen(fd, "w", encoding="utf-8") as f:
123
+ f.write(content)
124
+ os.replace(tmp_path, str(path))
125
+ except BaseException:
126
+ try:
127
+ os.unlink(tmp_path)
128
+ except OSError:
129
+ pass
130
+ raise
131
+
132
+
133
+ def atomic_write_json(
134
+ file_path: str | Path,
135
+ obj: Any,
136
+ *,
137
+ indent: int | None = None,
138
+ sort_keys: bool = False,
139
+ ) -> None:
140
+ """Serialize ``obj`` to JSON and write it atomically into a gitignored
141
+ artifact dir.
142
+
143
+ Centralizes the ``ensure_artifact_dir`` + temp-file-then-rename that the
144
+ cache/ledger writers each reimplemented, reusing the crash-safe write core so
145
+ a partial JSON file is never observed. ``ensure_artifact_dir`` already
146
+ creates the directory, so the write core skips a redundant mkdir.
147
+ """
148
+ path = Path(file_path)
149
+ ensure_artifact_dir(path.parent)
150
+ _atomic_replace(path, json.dumps(obj, indent=indent, sort_keys=sort_keys))
151
+
152
+
153
+ def write_file(file_path: str | Path, content: str) -> None:
154
+ """Writes content to a file, creating parent directories if needed."""
155
+ path = Path(file_path)
156
+ path.parent.mkdir(parents=True, exist_ok=True)
157
+ with open(path, "w", encoding="utf-8") as f:
158
+ f.write(content)
159
+
160
+
161
+ def glob_files(directory: str | Path, pattern: str) -> List[Path]:
162
+ """Finds files matching a glob pattern within a directory."""
163
+ path = Path(directory)
164
+ return list(path.glob(pattern))
165
+
166
+
167
+ def ensure_directory(directory: str | Path) -> None:
168
+ """Ensures a directory exists."""
169
+ Path(directory).mkdir(parents=True, exist_ok=True)
@@ -0,0 +1,23 @@
1
+ import os
2
+ import signal
3
+ import subprocess
4
+
5
+
6
+ def kill_process_group(proc: subprocess.Popen) -> None:
7
+ """SIGKILL a timed-out command's whole process group so grandchildren
8
+ (build/test workers like rustc or pytest, servers, a backgrounded ``cmd &``)
9
+ don't outlive the caller and hold locks or keep running.
10
+
11
+ Falls back to killing just the direct child when the platform has no process
12
+ groups (Windows) or the group is already gone.
13
+ """
14
+ if hasattr(os, "killpg"):
15
+ try:
16
+ os.killpg(os.getpgid(proc.pid), signal.SIGKILL)
17
+ return
18
+ except (ProcessLookupError, PermissionError, OSError):
19
+ pass
20
+ try:
21
+ proc.kill()
22
+ except OSError:
23
+ pass
@@ -0,0 +1,326 @@
1
+ Metadata-Version: 2.4
2
+ Name: misterdev
3
+ Version: 0.2.0
4
+ Summary: An autonomous, extensible LLM build orchestrator that plans, edits, and verifies code across languages.
5
+ Author-email: David Condrey <david@writerslogic.com>
6
+ License-Expression: AGPL-3.0-or-later
7
+ Project-URL: Homepage, https://github.com/dcondrey/misterdev
8
+ Project-URL: Repository, https://github.com/dcondrey/misterdev
9
+ Project-URL: Issues, https://github.com/dcondrey/misterdev/issues
10
+ Project-URL: Changelog, https://github.com/dcondrey/misterdev/blob/main/CHANGELOG.md
11
+ Keywords: llm,ai-agent,code-generation,orchestration,developer-tools,mcp,model-context-protocol,tree-sitter
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Code Generators
20
+ Classifier: Topic :: Software Development :: Build Tools
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ License-File: COMMERCIAL_LICENSE.md
27
+ Requires-Dist: openai>=1.0.0
28
+ Requires-Dist: PyYAML>=6.0
29
+ Requires-Dist: pydantic>=2.0.0
30
+ Requires-Dist: python-frontmatter>=1.0.0
31
+ Requires-Dist: rich>=13.0.0
32
+ Requires-Dist: tree-sitter>=0.25.2
33
+ Requires-Dist: tree-sitter-python>=0.25.0
34
+ Requires-Dist: tree-sitter-rust>=0.24.2
35
+ Requires-Dist: tree-sitter-typescript>=0.23.2
36
+ Requires-Dist: tree-sitter-c>=0.24.1
37
+ Requires-Dist: tree-sitter-cpp>=0.23.4
38
+ Requires-Dist: tree-sitter-swift>=0.7.0
39
+ Requires-Dist: tree-sitter-c-sharp>=0.23.1
40
+ Requires-Dist: tree-sitter-javascript>=0.23.0
41
+ Requires-Dist: tree-sitter-kotlin>=1.1.0
42
+ Requires-Dist: tiktoken>=0.7.0
43
+ Provides-Extra: local-embeddings
44
+ Requires-Dist: fastembed>=0.3.0; extra == "local-embeddings"
45
+ Provides-Extra: lsp
46
+ Requires-Dist: multilspy>=0.0.1; extra == "lsp"
47
+ Provides-Extra: web
48
+ Requires-Dist: playwright>=1.40.0; extra == "web"
49
+ Requires-Dist: pillow>=10.0.0; extra == "web"
50
+ Provides-Extra: mcp
51
+ Requires-Dist: mcp>=1.0.0; extra == "mcp"
52
+ Dynamic: license-file
53
+
54
+ <p align="center">
55
+ <img src="assets/logo.gif" alt="misterdev" width="220">
56
+ </p>
57
+
58
+ <h1 align="center">misterdev</h1>
59
+
60
+ <p align="center">
61
+ <strong>An autonomous LLM build orchestrator that plans a goal into tasks, edits your code with surgical precision, and verifies every change through correctness gates before it ever reports done.</strong>
62
+ </p>
63
+
64
+ <p align="center">
65
+ <a href="https://pypi.org/project/misterdev/"><img src="https://img.shields.io/pypi/v/misterdev" alt="PyPI version"></a>
66
+ <a href="https://pypi.org/project/misterdev/"><img src="https://img.shields.io/pypi/pyversions/misterdev" alt="Python versions"></a>
67
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-blue" alt="License: AGPL-3.0"></a>
68
+ <a href="https://github.com/dcondrey/misterdev/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/dcondrey/misterdev/ci.yml?branch=main" alt="CI"></a>
69
+ <a href="https://glama.ai/mcp/servers/dcondrey/misterdev"><img src="https://glama.ai/mcp/servers/dcondrey/misterdev/badges/score.svg" alt="misterdev MCP server"></a>
70
+ </p>
71
+
72
+ <p align="center">
73
+ <a href="#install">Install</a> ·
74
+ <a href="#what-it-does">What it does</a> ·
75
+ <a href="#cli-reference">CLI</a> ·
76
+ <a href="#extending-misterdev">Extending</a> ·
77
+ <a href="#configuration">Configuration</a> ·
78
+ <a href="#development">Development</a> ·
79
+ <a href="#license">License</a>
80
+ </p>
81
+
82
+ ---
83
+
84
+ Point misterdev at a repository and a goal. It reads the codebase as a symbol graph, decomposes the goal into concrete tasks, and works each one in a try-edit-verify loop: it emits an anchored SEARCH/REPLACE edit, applies it against the file on disk, and runs the change through a sequence of correctness gates — build, tests, lint, typecheck, and any optional gates you enable. A gate that fails RED blocks the change; a gate that has nothing to check SKIPs and never blocks. When a change regresses the suite, misterdev reverts it through git. Nothing merges unless it stays green.
85
+
86
+ ```console
87
+ $ misterdev build . "add rate limiting to the public API"
88
+
89
+ planning goal → 3 tasks (model: anthropic/claude-sonnet-4-6, budget $100.00)
90
+ task 1/3 middleware: token-bucket limiter api/limiter.py
91
+ edit 1 hunk applied · syntax ok
92
+ gates build GREEN · tests GREEN (142 passed) · lint GREEN · typecheck GREEN
93
+ task 2/3 wire limiter into request pipeline api/app.py
94
+ edit 2 hunks applied
95
+ gates build GREEN · tests RED (1 failed) → rolling back, regenerating
96
+ edit 2 hunks applied (attempt 2)
97
+ gates build GREEN · tests GREEN (145 passed) · lint GREEN · typecheck GREEN
98
+ task 3/3 docs + config surface README.md, config.py
99
+ gates all GREEN
100
+
101
+ done 3/3 tasks · 145 tests green · $0.38 over 11 calls
102
+ ```
103
+
104
+ Because misterdev only trusts its gates, the loop is honest: "the model said it's done" is never the finish line — the build, the tests, and the diff are.
105
+
106
+ ## Install
107
+
108
+ ```bash
109
+ pip install misterdev
110
+ # or
111
+ uv pip install misterdev
112
+ ```
113
+
114
+ Python 3.10 – 3.13. Optional extras add capability without bloating the core install:
115
+
116
+ ```bash
117
+ pip install 'misterdev[local-embeddings]' # offline semantic context ranking (fastembed, no API key)
118
+ pip install 'misterdev[lsp]' # LSP semantic-diagnostics gate
119
+ pip install 'misterdev[web]' # headless-browser web verification gate (+ playwright install chromium)
120
+ pip install 'misterdev[mcp]' # Model Context Protocol tool-host substrate
121
+ ```
122
+
123
+ Extras are all opt-in and timeout-bounded. When an extra's runtime dependency is absent, the gate it powers SKIPs rather than failing.
124
+
125
+ ## What it does
126
+
127
+ ### Autonomous build loop
128
+
129
+ Give misterdev a goal and it drives the whole cycle: analyze the project, plan tasks, edit, and validate — repeating until the goal is met or the budget is spent. Edits are **anchored SEARCH/REPLACE** hunks: the model emits only the changed regions, which are applied against the on-disk file, so a 5,000-line module is edited without reprinting it and without hitting the output-token ceiling. Matching tries exact first, then tolerates whitespace and indentation drift, always requiring a single unique anchor so a partial file is never written.
130
+
131
+ ### Polyglot symbol-graph context
132
+
133
+ A tree-sitter symbol graph gives misterdev structural understanding of **Python, Rust, TypeScript/JavaScript, Go, Java, C/C++, C#, Swift, and Kotlin**. Per-file outlines plus a whole-project structural map feed planning and editing, and large files are sent as a symbol outline plus verbatim windows of the task-relevant symbols — so context and cost scale with the edit, not with the file.
134
+
135
+ ### Correctness gates
136
+
137
+ Every change runs through an ordered gate sequence: **build → lint → tests → typecheck**, with optional gates layered on top — an **adversarial critic** (an independent second model that reviews each diff before it is applied), **goal-check**, **claim-verifier**, **mutation** scoring, **runtime-smoke**, **web**, and **vision** verification. A gate that fails **RED** blocks the change; a gate with nothing to check **SKIPs** and never blocks. Regressions are reverted via git, so a working tree only ever moves forward.
138
+
139
+ ### Dynamic model selection
140
+
141
+ misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar, **harvests free models** where they hold up, and caches responses to avoid paying twice. It runs against **OpenRouter or Anthropic** with automatic failover, and token budgeting keeps spend inside the ceiling you set.
142
+
143
+ ### Parallel worktrees
144
+
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
+
147
+ ### Extensibility
148
+
149
+ 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).
150
+
151
+ ### Agentic MCP
152
+
153
+ 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
+
155
+ ## CLI reference
156
+
157
+ **Don't want to remember flags?** If the first argument isn't a subcommand,
158
+ misterdev treats the whole line as plain English, maps it to an action with its
159
+ own model, shows you a preview, and asks before anything mutating:
160
+
161
+ ```console
162
+ $ misterdev "fix the failing tests but keep it cheap, and run stuff in parallel"
163
+ → I'll run: misterdev build . fix the failing tests --budget 5 --parallel
164
+ proceed? [Y/n]
165
+ ```
166
+
167
+ The flag-based commands below still work exactly as written, for scripts and
168
+ power users. The `misterdev` command drives everything:
169
+
170
+ | Command | What it does |
171
+ | --- | --- |
172
+ | `misterdev scan <dir>` | Discover projects under a directory and register them. |
173
+ | `misterdev list` | List all registered projects. |
174
+ | `misterdev status [path]` | Show a project's tasks and their state. |
175
+ | `misterdev report [path]` | Summarize the latest build's cost/tokens, per-model ledger performance, and the audit trail. Read-only — nothing is re-run. |
176
+ | `misterdev run [path]` | Run pending (or a specific `--task`) tasks for a project. `--dry-run`, `--force`, `--status`. |
177
+ | `misterdev plan [path]` | Analyze the project, recommend work, and compose a plan interactively. `--budget`, `--no-rollback`. |
178
+ | `misterdev build [path] [prompt]` | The autonomous build/debug/complete workflow. See flags below. |
179
+
180
+ Plain `misterdev` with no subcommand launches interactive planning.
181
+
182
+ <details>
183
+ <summary><strong><code>misterdev build</code> flags</strong></summary>
184
+
185
+ | Flag | Effect |
186
+ | --- | --- |
187
+ | `--budget <float>` | Max dollar budget for the run (default 100). |
188
+ | `--commit` | Commit after each completed task. |
189
+ | `--parallel` | Execute independent tasks concurrently in isolated worktrees. |
190
+ | `--dry-run` | Plan only; show tasks without executing. |
191
+ | `--interactive`, `-i` | Wait for confirmation between tasks. |
192
+ | `--no-verify` | Skip the final validation phase. |
193
+ | `--no-suggest` | Skip the suggest scan. |
194
+ | `--no-rollback` | Disable auto-bisect/revert of a regressing task. |
195
+ | `--focus <area>` | Restrict work to a specific area. |
196
+ | `--allow-dirty` | Allow building over uncommitted changes. |
197
+ | `--max-tasks <n>` | Cap the tasks this run will plan/execute (bounds cost). |
198
+
199
+ The `prompt` is free text or a mode word — `debug`, `complete`, `review`, or `new <description>`.
200
+ </details>
201
+
202
+ ## Drive it from an AI client (MCP server)
203
+
204
+ misterdev also ships **as an MCP server** (`misterdev-mcp`), so you can drive it
205
+ in plain English from Claude Desktop, Claude Code, Cursor, or any MCP client —
206
+ no flags to remember. The client just calls a tool (`build`, `scan`, `status`,
207
+ `list_projects`, `run`); the **entire orchestration runs inside misterdev's own
208
+ process** with its own model and context budget, and only a short summary
209
+ returns to the client — your codebase never enters the client's context window.
210
+
211
+ ```jsonc
212
+ // Claude Desktop config (claude_desktop_config.json)
213
+ {
214
+ "mcpServers": {
215
+ "misterdev": {
216
+ "command": "misterdev-mcp",
217
+ "env": { "OPENROUTER_API_KEY": "sk-..." }
218
+ }
219
+ }
220
+ }
221
+ ```
222
+
223
+ Then just ask: *"Have misterdev add rate limiting to the API, keep it under $5."*
224
+ Mutating tools (`build`, `run`) refuse a dirty working tree and carry a
225
+ conservative default budget. Requires the `mcp` extra: `pip install 'misterdev[mcp]'`.
226
+
227
+ ## Extending misterdev
228
+
229
+ A plugin is an ordinary Python package that declares entry points in the `misterdev.*` groups. Install it, and misterdev picks it up — no core edits.
230
+
231
+ A **tool** is a class; a **gate** is a callable returning a `GateOutcome`:
232
+
233
+ ```python
234
+ # misterdev_plugin_hello.py
235
+ from misterdev.core.execution.outcomes import GateOutcome, GREEN, RED
236
+
237
+
238
+ class HelloTool:
239
+ gather_safe = True # opt into the agentic gathering loop
240
+ gather_description = "Return a friendly greeting for a name."
241
+
242
+ def __init__(self, config: dict):
243
+ self.name = config.get("name", "hello")
244
+
245
+ def execute(self, project, name: str = "world", **_ignored):
246
+ return True, f"Hello, {name}!"
247
+
248
+
249
+ def no_shouting_gate(ctx) -> GateOutcome:
250
+ build = (ctx.commands or {}).get("build_command") or ""
251
+ if build and build.isupper():
252
+ return GateOutcome(RED, "build_command is ALL CAPS; please calm down")
253
+ return GateOutcome(GREEN)
254
+ ```
255
+
256
+ ```toml
257
+ # pyproject.toml — the entry points are the whole contract
258
+ [project.entry-points."misterdev.tools"]
259
+ hello = "misterdev_plugin_hello:HelloTool"
260
+
261
+ [project.entry-points."misterdev.gates"]
262
+ no_shouting = "misterdev_plugin_hello:no_shouting_gate"
263
+ ```
264
+
265
+ Targets register the same way through the `misterdev.targets` group. The full, runnable example — tool, gate, `pyproject.toml`, and notes — is at [`examples/misterdev-plugin-hello`](examples/misterdev-plugin-hello).
266
+
267
+ ## Configuration
268
+
269
+ Drop a `project.yaml` in the repo root. A minimal config names the language and the build/test/lint commands; everything else has a sensible default.
270
+
271
+ ```yaml
272
+ name: "My App"
273
+ language: "python"
274
+ build_command: "python -m compileall -q ."
275
+ test_command: "pytest -q"
276
+ lint_command: "ruff check ."
277
+ llm:
278
+ provider: "openrouter" # openrouter | anthropic
279
+ model: "anthropic/claude-sonnet-4-6"
280
+ api_key_env_var: "OPENROUTER_API_KEY"
281
+ ```
282
+
283
+ Key knobs:
284
+
285
+ - **Model & budget** — `llm.model`, provider/failover, and the run's dollar ceiling (also `--budget`).
286
+ - **Gates** — optional gates (adversarial critic, mutation, runtime-smoke, web, vision, goal-check) are off by default and enabled under the `orchestrator.*` keys.
287
+ - **MCP** — declare servers under `mcp.servers` and enable tool use with `orchestrator.mcp_enabled` / `orchestrator.mcp_tool_use`; point at a remote gateway for hosted tool catalogs.
288
+ - **Targets** — a `targets:` block gives a polyglot monorepo per-language build/test/lint, routed per task.
289
+
290
+ **Guides:** [Getting started](docs/getting-started.md) · [Configuration](docs/configuration.md) · [Plugins](docs/plugins.md) · [MCP](docs/mcp.md). `project.yaml.example` documents every configuration key.
291
+
292
+ ## Requirements
293
+
294
+ - Python **3.10 – 3.13**
295
+ - **git** (branch-per-task, worktrees, and rollback all run through it)
296
+ - An API key for **OpenRouter** or **Anthropic**
297
+ - Optional per-gate toolchains — a Playwright browser for the web gate, a language server for the LSP gate, an MCP SDK for the tool-host substrate (all installed via the matching extra)
298
+
299
+ ## Development
300
+
301
+ ```bash
302
+ git clone https://github.com/dcondrey/misterdev
303
+ cd misterdev
304
+ uv sync
305
+ uv run ruff check .
306
+ uv run pytest -q
307
+ ```
308
+
309
+ Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md), and open an issue or a pull request on [GitHub](https://github.com/dcondrey/misterdev).
310
+
311
+ ## License
312
+
313
+ misterdev is **dual-licensed**:
314
+
315
+ - **[AGPL-3.0-or-later](LICENSE)** — free for open-source use under the terms of the GNU Affero General Public License.
316
+ - **[Commercial license](COMMERCIAL_LICENSE.md)** — for use in a closed-source or proprietary product without AGPL obligations.
317
+
318
+ Choose the one that fits your project.
319
+
320
+ ---
321
+
322
+ <p align="center">
323
+ Built by <strong>David Condrey</strong> ·
324
+ <a href="https://github.com/dcondrey/misterdev">github.com/dcondrey/misterdev</a><br>
325
+ <sub>The static mark lives at <code>assets/logo.svg</code>.</sub>
326
+ </p>
@@ -0,0 +1,136 @@
1
+ misterdev/__init__.py,sha256=2IG9Sq2Qb1W2YR0yFoCf7MYT05ecf8-cTdhUo9l0F-o,93
2
+ misterdev/agent.py,sha256=UkWx2jjcBFk7h7oOLPGmPwOW6VlibGzhOl96qRxNZvo,94416
3
+ misterdev/agent_helpers.py,sha256=FHhOPFplpLiO3xtV7bXJFp_ORoQTtGLZ94VP2PR9E9Q,7438
4
+ misterdev/cli.py,sha256=U9sr_YZXHoBmmdHQLmVx0dVjiPs3hrXYYnvfgOHoZFY,13562
5
+ misterdev/config.py,sha256=BsxeEwDefZ5mGBpoBJ8F8sjnsBjqtxIbFhSV4UApiic,28829
6
+ misterdev/logging_setup.py,sha256=aq4Qv3eOMJyp5JG2fPw3jlt8hHAnKGYYaDc-8f35GUs,571
7
+ misterdev/mcp_server.py,sha256=TdG1GEGnKW-j33amH2EIbEQHu-4UohGr4Zk_O-p88pM,6929
8
+ misterdev/nl_cli.py,sha256=yVqoYoQcJXpxYjDOHepfG0J1ty773zwnqJ_odRWodO0,5339
9
+ misterdev/plugins.py,sha256=M4Wxf2dQJNiOj_mCkJjviDuFM-a7TQ7-Ov9PrzBgscQ,4428
10
+ misterdev/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ misterdev/analyzers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ misterdev/analyzers/project_analyzer/__init__.py,sha256=Xh_HBTXH_Z8C6zBVOkr7uSsEWDZI68BxRor7deD565Q,8315
13
+ misterdev/analyzers/project_analyzer/detection.py,sha256=EM_ujd8rGd1xkKt1R_s5x5_4hst30AaMSNmuExglgeE,5691
14
+ misterdev/analyzers/project_analyzer/merge.py,sha256=8WRLmSWsRRRbk7AOL_EnItveFWEEZLlNCFRPULXHWCU,5300
15
+ misterdev/analyzers/project_analyzer/overview.py,sha256=hMw-RC7SW40B_6sOin70Rq2Lp8X-dPJxaIicW7nkDVs,10639
16
+ misterdev/analyzers/project_analyzer/prompts.py,sha256=9fFFHs3SVLhlE3cW6j4Z1aE1o3zcQNg5mLRNMY5nOQo,3050
17
+ misterdev/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ misterdev/core/audit.py,sha256=L3K7mUKF80nkt_sKCC_ZLLlXnoMeU4G5bQv_SFjbkfU,3608
19
+ misterdev/core/config.py,sha256=dv7kSyJzLr0pDxgTfFZxe4-qWHwv3UFaMry_yPNrnXw,377
20
+ misterdev/core/gitcmd.py,sha256=kKOOhGjpbcc7PBMYLsJ_8lTCcGmCn_gsvZuy0IK-4VE,1447
21
+ misterdev/core/models.py,sha256=wzgwXVt5JEGZNeaqId4camE4S36_avxiaQI40QeNTkI,1348
22
+ misterdev/core/modes.py,sha256=Xl7BVrsUCrXvgrrsB9BP1cOwZKtT02pK27wGfPnWPyg,5248
23
+ misterdev/core/task.py,sha256=pV9c4gYtMeVeV8Y8CMudKBpK1ehsoEQDtq-pT1n-As0,6737
24
+ misterdev/core/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ misterdev/core/context/change_tracker.py,sha256=WC53sZWdoZ3WrrJOkEFl0dWO8hFGZIJUdZ43omnoZmM,7712
26
+ misterdev/core/context/lsp.py,sha256=PEHI07j0X7JBSmf3Qmqqi_O5WIHjnEP7RrLHEh90a_0,6318
27
+ misterdev/core/context/scratchpad.py,sha256=gMCVjqH04GJfKI4jMeDq1mEUmZXfNe4ozo8ZswSYdm0,3556
28
+ misterdev/core/context/contracts/__init__.py,sha256=6L6JkxvMoIxdjc3axqxy-v_Fx_816HiWtpzUrPokKuc,1698
29
+ misterdev/core/context/contracts/_log.py,sha256=bCDJZ0dmSsQ9ahVDd3maWV4v1DXiKNmY4n1z2Hnssgk,271
30
+ misterdev/core/context/contracts/_text.py,sha256=RKMbP4fRt4h0QgUb786LIYyt38v5ruz3wqntnvHfDhc,345
31
+ misterdev/core/context/contracts/extraction.py,sha256=HxmZ38mW3BlucMad2S13cShV0AaqiKUuejnSXdEh_R0,1105
32
+ misterdev/core/context/contracts/python_generic.py,sha256=hABUjjsAanwuL1plEWkFNd0WSwIyNn3-YRB1zZruJk4,1580
33
+ misterdev/core/context/contracts/registry.py,sha256=AAGKbugp9R0Ve5VBRKCaPfqHnRrp8n-DT2LZBi7fs8Y,4302
34
+ misterdev/core/context/contracts/rust_line.py,sha256=HrMqbdIqSWRdksa5Km-w7PC-E_9WsmpCgFPPrLOcHaA,7814
35
+ misterdev/core/context/contracts/rust_tree_sitter.py,sha256=lNKTQ2qCEfyM0rKQ-3CYldfjPMNTdB9VKD5U9ZfoUS0,5244
36
+ misterdev/core/context/topography/__init__.py,sha256=AGkytS7zumeIBfdN6sQXmGRqkZgXjIENVBq4ypin1ao,1608
37
+ misterdev/core/context/topography/_log.py,sha256=zw9sQXAgc8USzVF40IMdQgX_idBs0vOvULExHCjojaQ,306
38
+ misterdev/core/context/topography/cache.py,sha256=SMNC7m4h5KW-gqnIO0AWbJwcuQRFQfP2Lrw5AjsOLHM,3531
39
+ misterdev/core/context/topography/engine.py,sha256=1coifdhb5Yhf1JE70xmea3s2My8h5oIFBwFWbOAmVN0,7101
40
+ misterdev/core/context/topography/graph.py,sha256=69Eqa-Bl3aNzqIVs-aYq7ZE-Z3obAehZnI97Gq0pp7w,28081
41
+ misterdev/core/context/topography/nodes.py,sha256=CQh-lVrY3iu_4UNV91ZgEPWKEgnopAGdZsC1AbtLLhE,1552
42
+ misterdev/core/context/topography/parsers.py,sha256=rCSZ5hcbSZ9QBm5iLAGwy-XzHojW7-BIfd3dpHr1Uc8,2963
43
+ misterdev/core/context/topography/syntax.py,sha256=d9YDMQNDX_2SOwUN-OxXyKiAXXIlDBVqhJ3GCWtlG10,1856
44
+ misterdev/core/economics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ misterdev/core/economics/context_budget.py,sha256=goDbTX8SueIs-kRLCentMc86xHVPWKEWjyi3p2vvi0Y,6195
46
+ misterdev/core/economics/embeddings.py,sha256=vmOnDiFtIUdmz75ErxJ7k_uvQEn73AyKhAe7oZKLof4,8753
47
+ misterdev/core/economics/free_models.py,sha256=BvTXH72x2giGDtGW394Qe1FZ29g8EJXS4YVa7JYDQvk,4101
48
+ misterdev/core/economics/llm_cache.py,sha256=9sRyBYRIjAmOr40J7Om1-1kTKnZiHCIaAY7SjMAIo54,3731
49
+ misterdev/core/economics/model_catalog.py,sha256=MBRInzM_1t__BCtX7tJ3D2ykgV2-wyoHp7KjN8k053A,2900
50
+ misterdev/core/economics/model_ledger.py,sha256=RqVsr_Y_bR-bfdO4_KTqaGGdqcAhiy4OtgCNOlMDCWw,13306
51
+ misterdev/core/economics/model_selector.py,sha256=BYqzi-vM6Z5akR22pVXFpm09eRbnwr2rbMrVSJqFCNI,13330
52
+ misterdev/core/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ misterdev/core/execution/bounded.py,sha256=Hx7AFefR_ccJprIQ9KcSIYH7UTv4MUKYZNdoxAIuMbg,1897
54
+ misterdev/core/execution/container.py,sha256=0ZljPXr87yxUgnfuBVAF5d8p2l3ULm_t9YT9hxCWuLs,9399
55
+ misterdev/core/execution/error_classifier.py,sha256=n4IhscLF0QuabRQT8w1lTIDxfUJkWxWcrkZcOFcQAzE,13292
56
+ misterdev/core/execution/error_resolver.py,sha256=RIUPC0OebkuFcRXcW5i38rKRU1S__Z5E1O9wkqBmbyo,7376
57
+ misterdev/core/execution/governance.py,sha256=8jk0_B1BAHjQihbwPPtAwcM0TldTxWHKlvuq5V4LUNg,12036
58
+ misterdev/core/execution/outcomes.py,sha256=td23Clw2dnBQ7dQZ9IsthHhTLirKJPiHYCgDcmQ2szs,1730
59
+ misterdev/core/execution/progress.py,sha256=QhtspsaTrkWbD3uHx20fj7cebuu4lNHbPBhncNsCtDQ,4141
60
+ misterdev/core/execution/project.py,sha256=2qZx3AZIBs7kTjAHbtJZoHSQKI8gEV3GlcADG_BBilY,9322
61
+ misterdev/core/execution/registry.py,sha256=0bTsoL_ADFkhX5Hr1QNFe4ouS2Eq3RnDhfY4J8TsYwY,3614
62
+ misterdev/core/execution/runtime.py,sha256=4M6VH17lUfPucBaIFINe65985ls5JSSInp2IljiIsWE,10208
63
+ misterdev/core/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ misterdev/core/integration/mcp.py,sha256=rFtVibM_whv78oXGCqXcThNGRcybLJvEeHMUeQIElic,14730
65
+ misterdev/core/integration/mcp_gather.py,sha256=kEX76V84c6xj-0A-zM4RccuRfZck0jxGD5nCTmNDCfE,7696
66
+ misterdev/core/planning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
+ misterdev/core/planning/advisor.py,sha256=MDi9BOrhw_AIVq0XXAzxm2ZBetHGVn6CS3puQac4zR8,2894
68
+ misterdev/core/planning/assessment.py,sha256=vnrG1O_nKqvLI_ztcvoRJDGPOErozTi-Xr-hxrFHYd4,4692
69
+ misterdev/core/planning/decomposer.py,sha256=U0tMT0WUdWYgw16dnA4Rv82btkLxKvv_L-gcRcMRIWA,14826
70
+ misterdev/core/planning/metacognition.py,sha256=GLAo_N0fczuUaS-yxLTGmlzFlhGXFB013-IPL5RqO4c,3816
71
+ misterdev/core/planning/sovereign.py,sha256=sqN310uriozLTi2je-ukXYk2CyQ94C0j5S8zWpNhcXg,11634
72
+ misterdev/core/planning/targets.py,sha256=4Y_PuNwgwyi4Opy1T8ZNxVKKkhzJlR-XNOtcbVf11eo,7039
73
+ misterdev/core/reporting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ misterdev/core/reporting/report.py,sha256=TcNusgG1m5bDoZfn0LkkGWw3B4EXArlnDZIfn2sIe28,16044
75
+ misterdev/core/reporting/report_view.py,sha256=84jz_Ov1Acho2hQaKVRjLXWiS0epq9hoAgOiYU9MtwA,5448
76
+ misterdev/core/verification/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ misterdev/core/verification/claim_verifier.py,sha256=iRn22OncBQ4Zg_a5r4xE6pQNJpnjsdlDT1ucdimDZwU,8587
78
+ misterdev/core/verification/critic.py,sha256=F75M_P3gm8ouVzphgawbSYJhEKSKQ22cC4usLmCIXLg,14046
79
+ misterdev/core/verification/goal_check.py,sha256=0IKIBobvdrhRF076KD43_kezNZbw3sbL4U7HcxuZk_Q,8766
80
+ misterdev/core/verification/independent.py,sha256=0EPjBIy3fvsUvSrZNbkawzcj2vDnU3v2eGtPZ2saI4Y,2918
81
+ misterdev/core/verification/mutation_gate.py,sha256=lrMv2N7gc1oPVsQBxbJzMMi1EkO3YB5vcXnMMAUC9yM,8241
82
+ misterdev/core/verification/preflight.py,sha256=dq2zAlkRxeR3izzJh98DW3diEffftKCqyJc-dDk_14o,3359
83
+ misterdev/core/verification/spec_tests.py,sha256=y6caJVdO3TGz9PAiLn8G6-UPUs3RRQMcRnXnqWrew0Q,6516
84
+ misterdev/core/verification/validator.py,sha256=CXloSy5Zx9OMDBZhti5fvbrKCuUu2jIVz_Nh5Lwxiss,17597
85
+ misterdev/core/verification/vision_verify.py,sha256=_0Oorz7OO0028o_yzmBlsoMW4ELygzNxMQSZF0fMSAU,7671
86
+ misterdev/core/verification/web_verify.py,sha256=QpE-Oa43EBqdQTugmdGL1ijNb-P1NhjSUuQR8DZpPFw,15308
87
+ misterdev/core/verification/gatekeeper/__init__.py,sha256=ohhIebUUXxLJUjU-cBpyYcUEZ9ho-qvdrYq9B7uE41w,27605
88
+ misterdev/core/verification/gatekeeper/constants.py,sha256=Z2xFoI-T1epKMYcHXuzY4CWRLJIZwX3aRmdFN_zhTl4,4266
89
+ misterdev/core/verification/gatekeeper/helpers.py,sha256=9W7iE6HO_RPCMDOIwzUKevjpiNie1bR_Fs0ZJDywAAc,1066
90
+ misterdev/environments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
+ misterdev/environments/base_env.py,sha256=VKeSbrTKXmW2BhnlwHbH-GKH206bF_jTHEHycire7WM,484
92
+ misterdev/environments/container_env.py,sha256=U0TPfBD1zt6r3LSYUfYTjpGLsrExmGLxDJV1OWlta5c,3463
93
+ misterdev/environments/venv_env.py,sha256=DuQTcdlVn3-kXXpb5Lhd8CH0siCq4AgVVTMn4V7am-I,1584
94
+ misterdev/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ misterdev/llm/prompt_manager.py,sha256=tkMcWmDKFlaWvyo-Z4RVPGpg3OVaXOx2YQmlkrY209k,2770
96
+ misterdev/llm/client/__init__.py,sha256=8cbU7YqZR_8YQ38vcUkqNS0NNG3CvhTRlbDfTKgHSqw,5228
97
+ misterdev/llm/client/base.py,sha256=qvyJ5sPRGaZZNoUYgzlTac3Gakqfo4_eikPcIeYQzgo,16021
98
+ misterdev/llm/client/edits.py,sha256=Gn8Xc4u6ay4Z9NUthxe-xsZeG2s_oLYLhyrVaGx9g8k,2458
99
+ misterdev/llm/client/embeddings.py,sha256=hEb6nsjkBHyBkAdfn3GffiD1C6kuPHjYBKT2FlsxMDE,4770
100
+ misterdev/llm/client/errors.py,sha256=1IdBwLNosUG-ItdcLbKXORMUJy5ONsnS3Hyo-rdIT-0,4644
101
+ misterdev/llm/client/providers.py,sha256=3uV6nYK-h2eybPDqT4WZCENR9xYVZiMwlDVRPNs44R8,22061
102
+ misterdev/llm/client/response.py,sha256=luKqYQFO2-ZM4ZXt5v3immKlB7IAL2Mtbvl2wW3xZL0,532
103
+ misterdev/llm/responses/__init__.py,sha256=hQhA5W7kI-IFo4Qavl0YFITQVatawrfEezJPZQtO4GM,1000
104
+ misterdev/llm/responses/apply.py,sha256=m89_NWqGINS2q2xQX-h7UeKPt169aqsKCZ-MO9LGp8o,5258
105
+ misterdev/llm/responses/json_extract.py,sha256=f5EXkSh3Mzp9YAbBnWbi0iKVuZ2-y9RS1IgEcTvabqo,2784
106
+ misterdev/llm/responses/models.py,sha256=Lphk0x8eVSb9QxnQeJnS5eCnFbSbTk6HMLY1VpSi5Ps,1129
107
+ misterdev/llm/responses/parsing.py,sha256=xO7I2_ruZ3wghRWtWGAXjKtjse3Sux0xFJe1VUxKLO8,15951
108
+ misterdev/task_executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
+ misterdev/task_executors/base_executor.py,sha256=GIc6nYEde4pN-stQCik-PEGL2DBajzL4fGBrfZMTfWo,353
110
+ misterdev/task_executors/markdown_plan_executor/__init__.py,sha256=UmekpbRPEbl3Xkr0IlhKoBMfyCOGmavWxGJxq8nHvEs,2595
111
+ misterdev/task_executors/markdown_plan_executor/commands_mixin.py,sha256=tIsPnD4RA1OqkMK7XSNGbNrMZRvcs3TUe7huqtox8Ao,3128
112
+ misterdev/task_executors/markdown_plan_executor/context_mixin.py,sha256=zzAmH32SpCE60awgzgoFlUKOWgyqmWmM9VpB1DMsPUs,9457
113
+ misterdev/task_executors/markdown_plan_executor/critic_spec_mixin.py,sha256=iTveKnuFJk32dKamPEYQE4QMapx8wSP0YCTrrk1nxqE,7807
114
+ misterdev/task_executors/markdown_plan_executor/edits_mixin.py,sha256=AcbK9kbWbZSEzdhG3UIRLIF4h_O_UKSflG_VSZhSTMY,11371
115
+ misterdev/task_executors/markdown_plan_executor/execute_mixin.py,sha256=VSHdySCJBnrGvrWxKdrteEZM7CpZbHunxsGs_-gBfe4,36202
116
+ misterdev/task_executors/markdown_plan_executor/gates_mixin.py,sha256=wtKvCCqzaEuOF8sjy4eG98JvCRJ8Y5jmxozuPgrgkdE,9010
117
+ misterdev/task_executors/markdown_plan_executor/git_mixin.py,sha256=_YwJFNdYi-IMh4ZFm1Dl3AbL3-6rIOJr6D5Z3cPZq8Q,9681
118
+ misterdev/task_executors/markdown_plan_executor/helpers.py,sha256=5h6IsaFRVD6p1Rr9Ah125VMGpvoMXG2BjoOV1veeFog,20126
119
+ misterdev/task_executors/markdown_plan_executor/llm_mixin.py,sha256=nzqZPruhCf_nUTpTH02r51ThUA4NqhFAN_3vDz6EbmE,10229
120
+ misterdev/task_executors/markdown_plan_executor/results_mixin.py,sha256=aYxjfWr4sNDTHtdVTeKvA7mjcy_nVIyXdADmmYdEb6w,1007
121
+ misterdev/tools/__init__.py,sha256=3htya4h7XV9ygAzkLNk4vwNJnNkdgO-RsAjWsZuzQNo,767
122
+ misterdev/tools/base_tool.py,sha256=SUKpTqUgIJe9CHYLJrZ2EoVxXjU4Xr-3Xl1m8DDkRNk,381
123
+ misterdev/tools/command.py,sha256=KyY9QWY0ADC2gGRjgtc1NVfXoUBgwOV0c-jpJ5oVI44,2832
124
+ misterdev/tools/file_io.py,sha256=B8KJm2-3LVdaV-5KxwybWsgQSXod7B8fNyqN_Hih5pI,2706
125
+ misterdev/tools/formatter.py,sha256=tw38QvoizB2581hFHj0xXjfxqma9OyT29lYVAOr9I2I,1002
126
+ misterdev/tools/git_tool.py,sha256=PQ13mFIMNrlnFOCOOg4unqlqvMUXlG4I6GaoICN-Tjs,3826
127
+ misterdev/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
+ misterdev/utils/file_utils.py,sha256=Do6LaF4yNZDUcCM6neuLhZMebPTvkshV8FFFu3FndXA,6406
129
+ misterdev/utils/process.py,sha256=vs2VrTEPR3IbSNpsw-GQx9e6oVtKGmF25pGsezO2g40,721
130
+ misterdev-0.2.0.dist-info/licenses/COMMERCIAL_LICENSE.md,sha256=rc2AccILDX6nAU_Hw-Ok0KmCAiIJy4kZZiJkfI9epsE,1245
131
+ misterdev-0.2.0.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
132
+ misterdev-0.2.0.dist-info/METADATA,sha256=r-S2kV87gD9ZvCDHEPjs4Y2wxj-fshP_XjrooF-TBPg,16196
133
+ misterdev-0.2.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
134
+ misterdev-0.2.0.dist-info/entry_points.txt,sha256=eFxdoJz8yme5Yut_A85oIBYzvUcQXBVNYIYYLQXHcSU,91
135
+ misterdev-0.2.0.dist-info/top_level.txt,sha256=wbuyW1pcCjcCy3KcLZJ5dkEI6rq8PxpO8tnqOoExtJI,10
136
+ misterdev-0.2.0.dist-info/RECORD,,