codeframe-ai 0.9.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 (197) hide show
  1. codeframe/__init__.py +11 -0
  2. codeframe/__main__.py +20 -0
  3. codeframe/adapters/__init__.py +5 -0
  4. codeframe/adapters/e2b/__init__.py +13 -0
  5. codeframe/adapters/e2b/adapter.py +342 -0
  6. codeframe/adapters/e2b/budget.py +71 -0
  7. codeframe/adapters/e2b/credential_scanner.py +134 -0
  8. codeframe/adapters/llm/__init__.py +92 -0
  9. codeframe/adapters/llm/anthropic.py +414 -0
  10. codeframe/adapters/llm/base.py +444 -0
  11. codeframe/adapters/llm/mock.py +281 -0
  12. codeframe/adapters/llm/openai.py +483 -0
  13. codeframe/agents/__init__.py +8 -0
  14. codeframe/agents/dependency_resolver.py +714 -0
  15. codeframe/auth/__init__.py +16 -0
  16. codeframe/auth/api_key_router.py +238 -0
  17. codeframe/auth/api_keys.py +156 -0
  18. codeframe/auth/dependencies.py +358 -0
  19. codeframe/auth/manager.py +178 -0
  20. codeframe/auth/models.py +30 -0
  21. codeframe/auth/router.py +93 -0
  22. codeframe/auth/schemas.py +15 -0
  23. codeframe/auth/scopes.py +53 -0
  24. codeframe/cli/__init__.py +12 -0
  25. codeframe/cli/__main__.py +20 -0
  26. codeframe/cli/api_client.py +275 -0
  27. codeframe/cli/app.py +5688 -0
  28. codeframe/cli/auth.py +122 -0
  29. codeframe/cli/auth_commands.py +958 -0
  30. codeframe/cli/commands/__init__.py +5 -0
  31. codeframe/cli/config_commands.py +79 -0
  32. codeframe/cli/dashboard_commands.py +67 -0
  33. codeframe/cli/engines_commands.py +205 -0
  34. codeframe/cli/env_commands.py +409 -0
  35. codeframe/cli/helpers.py +56 -0
  36. codeframe/cli/hooks_commands.py +208 -0
  37. codeframe/cli/import_commands.py +129 -0
  38. codeframe/cli/pr_commands.py +549 -0
  39. codeframe/cli/proof_commands.py +415 -0
  40. codeframe/cli/stats_commands.py +311 -0
  41. codeframe/cli/telemetry_runtime.py +153 -0
  42. codeframe/cli/validators.py +123 -0
  43. codeframe/config/rate_limits.py +165 -0
  44. codeframe/core/__init__.py +15 -0
  45. codeframe/core/adapters/__init__.py +43 -0
  46. codeframe/core/adapters/agent_adapter.py +114 -0
  47. codeframe/core/adapters/builtin.py +326 -0
  48. codeframe/core/adapters/claude_code.py +62 -0
  49. codeframe/core/adapters/codex.py +393 -0
  50. codeframe/core/adapters/git_utils.py +40 -0
  51. codeframe/core/adapters/kilocode.py +126 -0
  52. codeframe/core/adapters/opencode.py +48 -0
  53. codeframe/core/adapters/streaming_chat.py +483 -0
  54. codeframe/core/adapters/subprocess_adapter.py +213 -0
  55. codeframe/core/adapters/verification_wrapper.py +269 -0
  56. codeframe/core/agent.py +2183 -0
  57. codeframe/core/agents_config.py +569 -0
  58. codeframe/core/api_key_service.py +211 -0
  59. codeframe/core/artifacts.py +428 -0
  60. codeframe/core/blocker_detection.py +218 -0
  61. codeframe/core/blockers.py +433 -0
  62. codeframe/core/checkpoints.py +481 -0
  63. codeframe/core/conductor.py +2255 -0
  64. codeframe/core/config.py +827 -0
  65. codeframe/core/config_watcher.py +268 -0
  66. codeframe/core/context.py +542 -0
  67. codeframe/core/context_packager.py +234 -0
  68. codeframe/core/credentials.py +735 -0
  69. codeframe/core/dependency_analyzer.py +229 -0
  70. codeframe/core/dependency_graph.py +290 -0
  71. codeframe/core/diagnostic_agent.py +712 -0
  72. codeframe/core/diagnostics.py +616 -0
  73. codeframe/core/editor.py +556 -0
  74. codeframe/core/engine_registry.py +256 -0
  75. codeframe/core/engine_stats.py +231 -0
  76. codeframe/core/environment.py +697 -0
  77. codeframe/core/events.py +375 -0
  78. codeframe/core/executor.py +1005 -0
  79. codeframe/core/fix_tracker.py +480 -0
  80. codeframe/core/gates.py +1322 -0
  81. codeframe/core/git.py +477 -0
  82. codeframe/core/github_connect_service.py +178 -0
  83. codeframe/core/github_integration_config.py +118 -0
  84. codeframe/core/github_issues_service.py +449 -0
  85. codeframe/core/hooks.py +184 -0
  86. codeframe/core/importers/__init__.py +1 -0
  87. codeframe/core/importers/ralph.py +540 -0
  88. codeframe/core/installer.py +650 -0
  89. codeframe/core/models.py +1026 -0
  90. codeframe/core/notifications_config.py +183 -0
  91. codeframe/core/planner.py +437 -0
  92. codeframe/core/prd.py +670 -0
  93. codeframe/core/prd_discovery.py +1118 -0
  94. codeframe/core/prd_stress_test.py +499 -0
  95. codeframe/core/progress.py +126 -0
  96. codeframe/core/proof/__init__.py +34 -0
  97. codeframe/core/proof/capture.py +79 -0
  98. codeframe/core/proof/evidence.py +56 -0
  99. codeframe/core/proof/ledger.py +574 -0
  100. codeframe/core/proof/models.py +162 -0
  101. codeframe/core/proof/obligations.py +103 -0
  102. codeframe/core/proof/runner.py +233 -0
  103. codeframe/core/proof/scope.py +81 -0
  104. codeframe/core/proof/stubs.py +156 -0
  105. codeframe/core/quick_fixes.py +558 -0
  106. codeframe/core/react_agent.py +1650 -0
  107. codeframe/core/reconciliation.py +183 -0
  108. codeframe/core/replay.py +788 -0
  109. codeframe/core/review.py +285 -0
  110. codeframe/core/runtime.py +1134 -0
  111. codeframe/core/sandbox/__init__.py +27 -0
  112. codeframe/core/sandbox/context.py +98 -0
  113. codeframe/core/sandbox/worktree.py +20 -0
  114. codeframe/core/schedule.py +396 -0
  115. codeframe/core/stall_detector.py +71 -0
  116. codeframe/core/stall_monitor.py +134 -0
  117. codeframe/core/state_machine.py +121 -0
  118. codeframe/core/streaming.py +502 -0
  119. codeframe/core/task_tree.py +400 -0
  120. codeframe/core/tasks.py +1022 -0
  121. codeframe/core/telemetry.py +232 -0
  122. codeframe/core/templates.py +221 -0
  123. codeframe/core/tools.py +942 -0
  124. codeframe/core/workspace.py +887 -0
  125. codeframe/core/worktrees.py +276 -0
  126. codeframe/git/__init__.py +5 -0
  127. codeframe/git/github_integration.py +505 -0
  128. codeframe/lib/__init__.py +0 -0
  129. codeframe/lib/audit_logger.py +248 -0
  130. codeframe/lib/metrics_tracker.py +800 -0
  131. codeframe/lib/quality/__init__.py +7 -0
  132. codeframe/lib/quality/complexity_analyzer.py +316 -0
  133. codeframe/lib/quality/owasp_patterns.py +284 -0
  134. codeframe/lib/quality/security_scanner.py +250 -0
  135. codeframe/lib/rate_limiter.py +312 -0
  136. codeframe/notifications/__init__.py +0 -0
  137. codeframe/notifications/webhook.py +380 -0
  138. codeframe/planning/__init__.py +30 -0
  139. codeframe/planning/issue_generator.py +219 -0
  140. codeframe/planning/prd_template_functions.py +137 -0
  141. codeframe/planning/prd_templates.py +975 -0
  142. codeframe/planning/task_scheduler.py +511 -0
  143. codeframe/planning/task_templates.py +533 -0
  144. codeframe/platform_store/__init__.py +5 -0
  145. codeframe/platform_store/database.py +277 -0
  146. codeframe/platform_store/repositories/__init__.py +24 -0
  147. codeframe/platform_store/repositories/api_key_repository.py +245 -0
  148. codeframe/platform_store/repositories/audit_repository.py +67 -0
  149. codeframe/platform_store/repositories/base.py +295 -0
  150. codeframe/platform_store/repositories/interactive_sessions.py +165 -0
  151. codeframe/platform_store/repositories/token_repository.py +598 -0
  152. codeframe/platform_store/repositories/workspace_registry_repository.py +175 -0
  153. codeframe/platform_store/schema_manager.py +321 -0
  154. codeframe/templates/AGENTS.md.default +94 -0
  155. codeframe/tui/__init__.py +5 -0
  156. codeframe/tui/app.py +256 -0
  157. codeframe/tui/data_service.py +103 -0
  158. codeframe/ui/__init__.py +0 -0
  159. codeframe/ui/dependencies.py +103 -0
  160. codeframe/ui/models.py +999 -0
  161. codeframe/ui/response_models.py +201 -0
  162. codeframe/ui/routers/__init__.py +5 -0
  163. codeframe/ui/routers/_helpers.py +29 -0
  164. codeframe/ui/routers/batches_v2.py +315 -0
  165. codeframe/ui/routers/blockers_v2.py +320 -0
  166. codeframe/ui/routers/checkpoints_v2.py +310 -0
  167. codeframe/ui/routers/costs_v2.py +322 -0
  168. codeframe/ui/routers/diagnose_v2.py +225 -0
  169. codeframe/ui/routers/discovery_v2.py +417 -0
  170. codeframe/ui/routers/environment_v2.py +284 -0
  171. codeframe/ui/routers/events_v2.py +75 -0
  172. codeframe/ui/routers/gates_v2.py +166 -0
  173. codeframe/ui/routers/git_v2.py +284 -0
  174. codeframe/ui/routers/github_integrations_v2.py +532 -0
  175. codeframe/ui/routers/interactive_sessions_v2.py +238 -0
  176. codeframe/ui/routers/pr_v2.py +709 -0
  177. codeframe/ui/routers/prd_v2.py +695 -0
  178. codeframe/ui/routers/proof_v2.py +755 -0
  179. codeframe/ui/routers/review_v2.py +360 -0
  180. codeframe/ui/routers/schedule_v2.py +214 -0
  181. codeframe/ui/routers/session_chat_ws.py +354 -0
  182. codeframe/ui/routers/settings_v2.py +562 -0
  183. codeframe/ui/routers/streaming_v2.py +155 -0
  184. codeframe/ui/routers/tasks_v2.py +1098 -0
  185. codeframe/ui/routers/templates_v2.py +232 -0
  186. codeframe/ui/routers/terminal_ws.py +267 -0
  187. codeframe/ui/routers/workspace_v2.py +527 -0
  188. codeframe/ui/server.py +568 -0
  189. codeframe/ui/shared.py +241 -0
  190. codeframe/workspace/__init__.py +5 -0
  191. codeframe/workspace/manager.py +249 -0
  192. codeframe_ai-0.9.0.dist-info/METADATA +517 -0
  193. codeframe_ai-0.9.0.dist-info/RECORD +197 -0
  194. codeframe_ai-0.9.0.dist-info/WHEEL +5 -0
  195. codeframe_ai-0.9.0.dist-info/entry_points.txt +3 -0
  196. codeframe_ai-0.9.0.dist-info/licenses/LICENSE +661 -0
  197. codeframe_ai-0.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,234 @@
1
+ """Task context packager for assembling rich prompts for agent adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ from codeframe.core.adapters.agent_adapter import AgentContext
10
+ from codeframe.core.context import ContextLoader, TaskContext
11
+ from codeframe.core.workspace import Workspace
12
+
13
+
14
+ @dataclass
15
+ class PackagedContext:
16
+ """Packaged task context ready for an agent adapter."""
17
+
18
+ prompt: str
19
+ context: TaskContext
20
+
21
+
22
+ class TaskContextPackager:
23
+ """Assembles rich task prompts from CodeFRAME context for any agent adapter.
24
+
25
+ Wraps ContextLoader and appends gate requirements so external agents
26
+ know what verification criteria they must satisfy.
27
+ """
28
+
29
+ def __init__(self, workspace: Workspace) -> None:
30
+ self._workspace = workspace
31
+ self._loader = ContextLoader(workspace)
32
+
33
+ def build(
34
+ self,
35
+ task_id: str,
36
+ gate_names: Optional[list[str]] = None,
37
+ attempt: int = 0,
38
+ previous_errors: Optional[list[str]] = None,
39
+ ) -> PackagedContext:
40
+ """Build a rich prompt and context for the given task.
41
+
42
+ Args:
43
+ task_id: CodeFRAME task identifier.
44
+ gate_names: Optional list of gate names that will run post-execution.
45
+ If None, uses default gates (pytest, ruff).
46
+ attempt: Retry attempt number (0 = first attempt).
47
+ previous_errors: Errors from previous attempts.
48
+
49
+ Returns:
50
+ PackagedContext with assembled prompt and raw TaskContext.
51
+ """
52
+ context = self._loader.load(task_id)
53
+
54
+ prompt_parts = [context.to_prompt_context()]
55
+
56
+ # Add lineage context if available
57
+ if (
58
+ hasattr(context, "task")
59
+ and context.task
60
+ and hasattr(context.task, "lineage")
61
+ and context.task.lineage
62
+ ):
63
+ lineage_str = " \u2192 ".join(context.task.lineage)
64
+ prompt_parts.append(
65
+ f"\n## Task Lineage\nThis task is part of: {lineage_str}\n"
66
+ )
67
+
68
+ if attempt > 0 and previous_errors:
69
+ prompt_parts.append(self._build_retry_section(attempt, previous_errors))
70
+
71
+ gates = gate_names if gate_names is not None else ["pytest", "ruff"]
72
+ prompt_parts.append(self._build_gate_section(gates))
73
+ prompt_parts.append(self._build_instructions_section())
74
+
75
+ return PackagedContext(
76
+ prompt="\n".join(prompt_parts),
77
+ context=context,
78
+ )
79
+
80
+ def load_context(self, task_id: str) -> TaskContext:
81
+ """Load raw TaskContext for internal agent use.
82
+
83
+ Unlike build() (flat prompt for external engines) or build_agent_context()
84
+ (AgentContext protocol type), this returns the raw TaskContext that internal
85
+ agents like ReactAgent need for their own prompt rendering.
86
+ """
87
+ return self._loader.load(task_id)
88
+
89
+ def build_agent_context(
90
+ self,
91
+ task_id: str,
92
+ attempt: int = 0,
93
+ previous_errors: Optional[list[str]] = None,
94
+ gate_names: Optional[list[str]] = None,
95
+ ) -> AgentContext:
96
+ """Assemble an AgentContext from all CodeFrame sources.
97
+
98
+ Bridges TaskContext (internal, Python objects) to AgentContext
99
+ (protocol, all strings/primitives) for consumption by any adapter.
100
+
101
+ Args:
102
+ task_id: CodeFRAME task identifier.
103
+ attempt: Retry attempt number (0 = first attempt).
104
+ previous_errors: Errors from previous attempts.
105
+ gate_names: Optional gate names override.
106
+
107
+ Returns:
108
+ AgentContext populated from TaskContext fields.
109
+ """
110
+ context = self._loader.load(task_id)
111
+ gates = gate_names if gate_names is not None else ["pytest", "ruff"]
112
+
113
+ prd_content = None
114
+ if context.prd is not None:
115
+ prd_content = context.prd.content
116
+
117
+ project_preferences = None
118
+ if context.preferences and context.preferences.has_preferences():
119
+ section = context.preferences.to_prompt_section()
120
+ if section:
121
+ project_preferences = section
122
+
123
+ blocker_history = [
124
+ f"Q: {b.question}\nA: {b.answer}"
125
+ for b in context.answered_blockers
126
+ ]
127
+
128
+ relevant_files = [fi.path for fi in context.relevant_files]
129
+
130
+ file_contents = {f.path: f.content for f in context.loaded_files}
131
+
132
+ return AgentContext(
133
+ task_id=task_id,
134
+ task_title=context.task.title,
135
+ task_description=context.task.description or "",
136
+ prd_content=prd_content,
137
+ tech_stack=context.tech_stack,
138
+ project_preferences=project_preferences,
139
+ relevant_files=relevant_files,
140
+ file_contents=file_contents,
141
+ blocker_history=blocker_history,
142
+ verification_gates=gates,
143
+ attempt=attempt,
144
+ previous_errors=previous_errors or [],
145
+ )
146
+
147
+ def to_file_list(self, packaged: PackagedContext) -> list[str]:
148
+ """Extract the list of files the agent should focus on.
149
+
150
+ Args:
151
+ packaged: A previously built PackagedContext.
152
+
153
+ Returns:
154
+ List of relevant file paths in ContextLoader's relevance order.
155
+ """
156
+ return [fi.path for fi in packaged.context.relevant_files]
157
+
158
+ def to_task_file(self, packaged: PackagedContext, path: Path) -> Path:
159
+ """Write the assembled prompt to a file for file-based engines.
160
+
161
+ Args:
162
+ packaged: A previously built PackagedContext.
163
+ path: Where to write the task file.
164
+
165
+ Returns:
166
+ The path that was written to.
167
+ """
168
+ path.parent.mkdir(parents=True, exist_ok=True)
169
+ path.write_text(packaged.prompt, encoding="utf-8")
170
+ return path
171
+
172
+ def _build_retry_section(self, attempt: int, errors: list[str]) -> str:
173
+ """Build the retry context section."""
174
+ lines = [
175
+ "",
176
+ "## Previous Attempt Errors",
177
+ "",
178
+ f"**Attempt {attempt}** — previous attempt(s) failed with:",
179
+ "",
180
+ ]
181
+ for error in errors:
182
+ collapsed = error.replace("\n", " ").strip()
183
+ lines.append(f"- {collapsed}")
184
+ lines.append("")
185
+ lines.append(
186
+ "Review these errors carefully. Do NOT repeat the same approach "
187
+ "that caused them."
188
+ )
189
+ lines.append("")
190
+ return "\n".join(lines)
191
+
192
+ def _build_gate_section(self, gate_names: list[str]) -> str:
193
+ """Build the gate requirements section."""
194
+ lines = [
195
+ "",
196
+ "## Verification Gates",
197
+ "",
198
+ "After you complete the task, the following verification gates "
199
+ "will run automatically:",
200
+ "",
201
+ ]
202
+ for gate in gate_names:
203
+ if gate == "pytest":
204
+ lines.append(
205
+ "- **pytest**: All tests must pass. "
206
+ "Run `pytest` to verify before finishing."
207
+ )
208
+ elif gate == "ruff":
209
+ lines.append(
210
+ "- **ruff**: Code must pass linting. "
211
+ "Run `ruff check .` to verify."
212
+ )
213
+ else:
214
+ lines.append(f"- **{gate}**: Must pass.")
215
+ lines.append("")
216
+ lines.append(
217
+ "Ensure your changes satisfy ALL gates before reporting completion."
218
+ )
219
+ lines.append("")
220
+ return "\n".join(lines)
221
+
222
+ def _build_instructions_section(self) -> str:
223
+ """Build general execution instructions for the agent."""
224
+ return "\n".join(
225
+ [
226
+ "## Execution Instructions",
227
+ "",
228
+ "- Make only the changes necessary to complete the task",
229
+ "- Do not modify unrelated files",
230
+ "- Follow existing code patterns and conventions",
231
+ "- If you encounter a blocker you cannot resolve, report it clearly",
232
+ "",
233
+ ]
234
+ )