codeframe-ai 0.9.2__tar.gz → 0.9.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. {codeframe_ai-0.9.2/codeframe_ai.egg-info → codeframe_ai-0.9.3}/PKG-INFO +4 -6
  2. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/README.md +1 -1
  3. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/__init__.py +7 -1
  4. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/mock.py +55 -3
  5. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/manager.py +2 -1
  6. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/proof_commands.py +63 -102
  7. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/config/rate_limits.py +0 -4
  8. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/__init__.py +0 -2
  9. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/config.py +11 -218
  10. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/env_provenance.py +0 -1
  11. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/runner.py +197 -3
  12. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/runtime.py +36 -4
  13. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/workspace.py +27 -37
  14. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/rate_limiter.py +9 -17
  15. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/database.py +3 -3
  16. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/schema_manager.py +22 -65
  17. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/dependencies.py +5 -7
  18. codeframe_ai-0.9.3/codeframe/ui/models.py +107 -0
  19. codeframe_ai-0.9.3/codeframe/ui/response_models.py +128 -0
  20. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/prd_v2.py +1 -1
  21. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/tasks_v2.py +40 -9
  22. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/server.py +1 -36
  23. codeframe_ai-0.9.3/codeframe/ui/shared.py +83 -0
  24. codeframe_ai-0.9.2/codeframe/ui/routers/streaming_v2.py → codeframe_ai-0.9.3/codeframe/ui/streaming_utils.py +9 -19
  25. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3/codeframe_ai.egg-info}/PKG-INFO +4 -6
  26. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe_ai.egg-info/SOURCES.txt +2 -1
  27. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe_ai.egg-info/requires.txt +2 -4
  28. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/pyproject.toml +14 -6
  29. codeframe_ai-0.9.3/tests/test_deploy_audit_gate_1131.py +143 -0
  30. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_deploy_config.py +166 -59
  31. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_lifecycle_gates_948.py +169 -35
  32. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_pm2_scoping_912.py +61 -20
  33. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_root_docs_950.py +14 -0
  34. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_workflow_lint_wiring_1122.py +84 -19
  35. codeframe_ai-0.9.2/codeframe/ui/models.py +0 -999
  36. codeframe_ai-0.9.2/codeframe/ui/response_models.py +0 -241
  37. codeframe_ai-0.9.2/codeframe/ui/shared.py +0 -252
  38. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/LICENSE +0 -0
  39. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/__main__.py +0 -0
  40. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/__init__.py +0 -0
  41. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/e2b/__init__.py +0 -0
  42. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/e2b/adapter.py +0 -0
  43. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/e2b/budget.py +0 -0
  44. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/e2b/credential_scanner.py +0 -0
  45. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/__init__.py +0 -0
  46. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/anthropic.py +0 -0
  47. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/base.py +0 -0
  48. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/errors.py +0 -0
  49. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/adapters/llm/openai.py +0 -0
  50. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/agents/__init__.py +0 -0
  51. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/agents/dependency_resolver.py +0 -0
  52. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/__init__.py +0 -0
  53. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/api_key_router.py +0 -0
  54. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/api_keys.py +0 -0
  55. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/dependencies.py +0 -0
  56. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/models.py +0 -0
  57. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/router.py +0 -0
  58. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/schemas.py +0 -0
  59. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/scopes.py +0 -0
  60. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/auth/stream_tickets.py +0 -0
  61. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/__init__.py +0 -0
  62. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/__main__.py +0 -0
  63. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/api_client.py +0 -0
  64. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/app.py +0 -0
  65. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/auth.py +0 -0
  66. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/auth_commands.py +0 -0
  67. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/commands/__init__.py +0 -0
  68. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/config_commands.py +0 -0
  69. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/dashboard_commands.py +0 -0
  70. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/engines_commands.py +0 -0
  71. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/env_commands.py +0 -0
  72. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/helpers.py +0 -0
  73. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/hooks_commands.py +0 -0
  74. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/import_commands.py +0 -0
  75. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/pr_commands.py +0 -0
  76. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/stats_commands.py +0 -0
  77. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/telemetry_runtime.py +0 -0
  78. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/cli/validators.py +0 -0
  79. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/__init__.py +0 -0
  80. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/agent_adapter.py +0 -0
  81. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/builtin.py +0 -0
  82. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/claude_code.py +0 -0
  83. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/codex.py +0 -0
  84. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/git_utils.py +0 -0
  85. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/kilocode.py +0 -0
  86. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/opencode.py +0 -0
  87. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/streaming_chat.py +0 -0
  88. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/subprocess_adapter.py +0 -0
  89. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/adapters/verification_wrapper.py +0 -0
  90. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/agent.py +0 -0
  91. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/agent_env.py +0 -0
  92. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/agents_config.py +0 -0
  93. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/api_key_service.py +0 -0
  94. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/artifacts.py +0 -0
  95. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/atomic_io.py +0 -0
  96. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/blocker_detection.py +0 -0
  97. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/blockers.py +0 -0
  98. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/checkpoints.py +0 -0
  99. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/claude_code_guard.py +0 -0
  100. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/conductor.py +0 -0
  101. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/config_watcher.py +0 -0
  102. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/context.py +0 -0
  103. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/context_packager.py +0 -0
  104. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/cost_tracker.py +0 -0
  105. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/credentials.py +0 -0
  106. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/dangerous_commands.py +0 -0
  107. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/dependency_analyzer.py +0 -0
  108. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/dependency_graph.py +0 -0
  109. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/diagnostic_agent.py +0 -0
  110. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/diagnostics.py +0 -0
  111. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/editor.py +0 -0
  112. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/engine_registry.py +0 -0
  113. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/engine_stats.py +0 -0
  114. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/environment.py +0 -0
  115. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/events.py +0 -0
  116. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/executor.py +0 -0
  117. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/fix_tracker.py +0 -0
  118. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/gates.py +0 -0
  119. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/git.py +0 -0
  120. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/github_connect_service.py +0 -0
  121. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/github_integration_config.py +0 -0
  122. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/github_issues_service.py +0 -0
  123. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/hook_trust.py +0 -0
  124. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/hooks.py +0 -0
  125. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/importers/__init__.py +0 -0
  126. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/importers/ralph.py +0 -0
  127. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/installer.py +0 -0
  128. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/llm_json.py +0 -0
  129. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/llm_resolution.py +0 -0
  130. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/models.py +0 -0
  131. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/notifications_config.py +0 -0
  132. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/path_safety.py +0 -0
  133. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/planner.py +0 -0
  134. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/prd.py +0 -0
  135. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/prd_discovery.py +0 -0
  136. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/prd_stress_test.py +0 -0
  137. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/progress.py +0 -0
  138. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/__init__.py +0 -0
  139. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/capture.py +0 -0
  140. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/evidence.py +0 -0
  141. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/ledger.py +0 -0
  142. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/models.py +0 -0
  143. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/obligations.py +0 -0
  144. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/scope.py +0 -0
  145. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/proof/stubs.py +0 -0
  146. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/quick_fixes.py +0 -0
  147. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/react_agent.py +0 -0
  148. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/reconciliation.py +0 -0
  149. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/replay.py +0 -0
  150. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/review.py +0 -0
  151. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/sandbox/__init__.py +0 -0
  152. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/sandbox/context.py +0 -0
  153. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/sandbox/worktree.py +0 -0
  154. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/schedule.py +0 -0
  155. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/stall_detector.py +0 -0
  156. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/stall_monitor.py +0 -0
  157. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/state_machine.py +0 -0
  158. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/streaming.py +0 -0
  159. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/task_tree.py +0 -0
  160. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/tasks.py +0 -0
  161. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/telemetry.py +0 -0
  162. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/templates.py +0 -0
  163. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/tools.py +0 -0
  164. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/core/worktrees.py +0 -0
  165. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/git/__init__.py +0 -0
  166. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/git/github_integration.py +0 -0
  167. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/__init__.py +0 -0
  168. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/audit_logger.py +0 -0
  169. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/metrics_tracker.py +0 -0
  170. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/quality/__init__.py +0 -0
  171. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/quality/complexity_analyzer.py +0 -0
  172. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/quality/owasp_patterns.py +0 -0
  173. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/lib/quality/security_scanner.py +0 -0
  174. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/notifications/__init__.py +0 -0
  175. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/notifications/webhook.py +0 -0
  176. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/planning/__init__.py +0 -0
  177. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/planning/prd_templates.py +0 -0
  178. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/planning/task_scheduler.py +0 -0
  179. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/planning/task_templates.py +0 -0
  180. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/__init__.py +0 -0
  181. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/__init__.py +0 -0
  182. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/api_key_repository.py +0 -0
  183. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/audit_repository.py +0 -0
  184. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/base.py +0 -0
  185. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/interactive_sessions.py +0 -0
  186. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/token_repository.py +0 -0
  187. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/platform_store/repositories/workspace_registry_repository.py +0 -0
  188. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/templates/AGENTS.md.default +0 -0
  189. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/tui/__init__.py +0 -0
  190. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/tui/app.py +0 -0
  191. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/tui/data_service.py +0 -0
  192. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/__init__.py +0 -0
  193. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/__init__.py +0 -0
  194. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/_helpers.py +0 -0
  195. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/batches_v2.py +0 -0
  196. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/blockers_v2.py +0 -0
  197. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/checkpoints_v2.py +0 -0
  198. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/costs_v2.py +0 -0
  199. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/diagnose_v2.py +0 -0
  200. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/discovery_v2.py +0 -0
  201. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/environment_v2.py +0 -0
  202. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/events_v2.py +0 -0
  203. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/gates_v2.py +0 -0
  204. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/git_v2.py +0 -0
  205. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/github_integrations_v2.py +0 -0
  206. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/interactive_sessions_v2.py +0 -0
  207. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/pr_v2.py +0 -0
  208. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/proof_v2.py +0 -0
  209. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/review_v2.py +0 -0
  210. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/schedule_v2.py +0 -0
  211. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/session_chat_ws.py +0 -0
  212. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/settings_v2.py +0 -0
  213. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/templates_v2.py +0 -0
  214. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/terminal_ws.py +0 -0
  215. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe/ui/routers/workspace_v2.py +0 -0
  216. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe_ai.egg-info/dependency_links.txt +0 -0
  217. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe_ai.egg-info/entry_points.txt +0 -0
  218. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/codeframe_ai.egg-info/top_level.txt +0 -0
  219. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/setup.cfg +0 -0
  220. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_ambient_workspace_guard.py +0 -0
  221. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_claude_review_workflow_1011.py +0 -0
  222. {codeframe_ai-0.9.2 → codeframe_ai-0.9.3}/tests/test_offline_default_946.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeframe-ai
3
- Version: 0.9.2
3
+ Version: 0.9.3
4
4
  Summary: A project delivery system that orchestrates frontier coding agents: Think, Build, Prove, Ship.
5
5
  Author-email: Frank Bria <hello@codeframe.sh>
6
6
  License: AGPL-3.0-or-later
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: anthropic>=0.18.0
20
+ Requires-Dist: anthropic<1.0,>=0.18.0
21
21
  Requires-Dist: bandit>=1.8.6
22
22
  Requires-Dist: tenacity>=8.2.0
23
23
  Requires-Dist: openai>=1.12.0
@@ -50,8 +50,7 @@ Requires-Dist: pytest-json-report>=1.5.0
50
50
  Requires-Dist: hypothesis>=6.148.0
51
51
  Requires-Dist: fastapi-users[sqlalchemy]>=15.0.2
52
52
  Requires-Dist: filelock>=3.0
53
- Requires-Dist: python-jose[cryptography]>=3.4.0
54
- Requires-Dist: passlib[argon2]>=1.7.4
53
+ Requires-Dist: bcrypt>=4.2.0
55
54
  Requires-Dist: keyring>=24.0.0
56
55
  Requires-Dist: jinja2>=3.1.6
57
56
  Requires-Dist: slowapi>=0.1.9
@@ -61,7 +60,6 @@ Requires-Dist: python-multipart>=0.0.27
61
60
  Requires-Dist: pyjwt>=2.12.0
62
61
  Requires-Dist: cryptography>=46.0.7
63
62
  Requires-Dist: urllib3>=2.7.0
64
- Requires-Dist: pyasn1>=0.6.3
65
63
  Requires-Dist: mcp>=1.23.0
66
64
  Requires-Dist: idna>=3.15
67
65
  Provides-Extra: cloud
@@ -157,7 +155,7 @@ THE CLOSED LOOP
157
155
  ---
158
156
 
159
157
  > [!NOTE]
160
- > **CodeFRAME is in public beta (`0.9.2`).** The vision and the Golden Path CLI
158
+ > **CodeFRAME is in public beta (`0.9.3`).** The vision and the Golden Path CLI
161
159
  > (`cf init/prd/tasks/work/proof/pr`) and v2 API are stable enough to build on;
162
160
  > the web UI and anything marked "in progress" in
163
161
  > [`docs/PRODUCT_ROADMAP.md`](docs/PRODUCT_ROADMAP.md) are still moving, and
@@ -74,7 +74,7 @@ THE CLOSED LOOP
74
74
  ---
75
75
 
76
76
  > [!NOTE]
77
- > **CodeFRAME is in public beta (`0.9.2`).** The vision and the Golden Path CLI
77
+ > **CodeFRAME is in public beta (`0.9.3`).** The vision and the Golden Path CLI
78
78
  > (`cf init/prd/tasks/work/proof/pr`) and v2 API are stable enough to build on;
79
79
  > the web UI and anything marked "in progress" in
80
80
  > [`docs/PRODUCT_ROADMAP.md`](docs/PRODUCT_ROADMAP.md) are still moving, and
@@ -5,7 +5,13 @@ An autonomous AI development system where multiple specialized agents
5
5
  collaborate to build software projects from requirements to deployment.
6
6
  """
7
7
 
8
- __version__ = "0.1.0"
8
+ from importlib.metadata import PackageNotFoundError, version
9
+
10
+ try:
11
+ __version__ = version("codeframe-ai")
12
+ except PackageNotFoundError: # source checkout, never installed
13
+ __version__ = "0.0.0+unknown"
14
+
9
15
  __author__ = "Frank Bria"
10
16
 
11
17
  __all__ = ["__version__", "__author__"]
@@ -18,11 +18,55 @@ from codeframe.adapters.llm.base import (
18
18
  )
19
19
 
20
20
 
21
+ #: The task-decomposition prompt asks for this exact shape (core/tasks.py).
22
+ #: Matched on a full sentence, not a keyword: a substring like "json" would
23
+ #: reshape unrelated calls, which is the classifier mistake #1113/#1116/#1064
24
+ #: each made in turn.
25
+ _TASK_DECOMPOSITION_MARKER = "Return ONLY a JSON array of objects with these fields."
26
+
27
+ #: What the mock answers that prompt with. Two tasks with a real dependency
28
+ #: edge, because a decomposition with an empty graph is one the prompt itself
29
+ #: calls wrong — and a lifecycle test that never exercises depends_on is not
30
+ #: exercising the decomposer.
31
+ _MOCK_DECOMPOSITION = """[
32
+ {
33
+ "title": "Implement the core function",
34
+ "description": "Add the function described by the PRD, with input validation.",
35
+ "depends_on_titles": [],
36
+ "complexity": 2,
37
+ "estimated_hours": 1.5,
38
+ "uncertainty": "low",
39
+ "files_to_modify": ["stats.py"]
40
+ },
41
+ {
42
+ "title": "Add a test for the core function",
43
+ "description": "Cover the happy path and one edge case.",
44
+ "depends_on_titles": ["Implement the core function"],
45
+ "complexity": 1,
46
+ "estimated_hours": 0.5,
47
+ "uncertainty": "low",
48
+ "files_to_modify": ["tests/test_stats.py"]
49
+ }
50
+ ]"""
51
+
52
+
21
53
  class MockProvider(LLMProvider):
22
54
  """Mock LLM provider for testing.
23
55
 
24
56
  Tracks all calls and returns configurable responses.
25
57
  Useful for unit tests and development without API costs.
58
+
59
+ The default response is the literal string ``"Mock response"``, which no
60
+ real caller can parse. That is fine for a provider nobody parses, but task
61
+ generation asks for a JSON array and #1115 correctly turned an unparseable
62
+ answer into a hard error — so `CODEFRAME_LLM_PROVIDER=mock` could not drive
63
+ the Golden Path's THINK step at all, and the lifecycle tests had to skip the
64
+ LLM branch entirely (#1068).
65
+
66
+ So the default is now shape-aware for exactly one prompt: the task
67
+ decomposition. Everything else is unchanged, and an explicitly queued
68
+ response or handler still wins — those are what a test uses to say what it
69
+ means.
26
70
  """
27
71
 
28
72
  def __init__(
@@ -140,12 +184,20 @@ class MockProvider(LLMProvider):
140
184
  self.response_index += 1
141
185
  return response
142
186
 
143
- # Default response
187
+ # Shape-aware default: answer the task-decomposition prompt with
188
+ # something its parser can actually read. Only when the caller left the
189
+ # default in place — a test that set default_response meant it.
190
+ content = self.default_response
191
+ if content == "Mock response" and any(
192
+ _TASK_DECOMPOSITION_MARKER in str(m.get("content", "")) for m in messages
193
+ ):
194
+ content = _MOCK_DECOMPOSITION
195
+
144
196
  return LLMResponse(
145
- content=self.default_response,
197
+ content=content,
146
198
  model=model,
147
199
  input_tokens=len(str(messages)),
148
- output_tokens=len(self.default_response),
200
+ output_tokens=len(content),
149
201
  )
150
202
 
151
203
  def stream(
@@ -362,7 +362,8 @@ def get_jwt_strategy() -> JWTStrategy:
362
362
  **Known limitation — logout does not revoke.** ``POST /auth/jwt/logout``
363
363
  only tells the client to drop its copy; the token itself stays valid until
364
364
  it expires, because verification is stateless signature-checking with no
365
- server-side denylist (the ``sessions`` table is unused). A leaked token is
365
+ server-side denylist (there is no session store at all — the vestigial
366
+ ``sessions`` table was dropped in #968). A leaked token is
366
367
  therefore usable for up to JWT_LIFETIME_SECONDS. The mitigating control is
367
368
  that lifetime — default 24h (#657), and now actually configurable — plus
368
369
  the web UI's CSP against XSS exfiltration. Real revocation needs a
@@ -160,8 +160,8 @@ def run(
160
160
  codeframe proof run --gate unit
161
161
  """
162
162
  from codeframe.core.workspace import get_workspace
163
- from codeframe.core.proof.models import Gate, GateOutcome
164
- from codeframe.core.proof.runner import run_proof
163
+ from codeframe.core.proof.models import PROOF_CONFIG_FILENAME, Gate, GateOutcome
164
+ from codeframe.core.proof.runner import EmptyReason, run_proof_with_diagnostics
165
165
 
166
166
  workspace_path = repo_path or Path.cwd()
167
167
  try:
@@ -182,115 +182,76 @@ def run(
182
182
  mode = "full" if full else "scope-filtered"
183
183
  console.print(f"[dim]Running proof obligations ({mode})...[/dim]")
184
184
 
185
- results = run_proof(workspace, full=full, gate_filter=gate_filter)
185
+ results, diagnostics = run_proof_with_diagnostics(
186
+ workspace, full=full, gate_filter=gate_filter
187
+ )
186
188
 
187
189
  if not results:
188
- # `run_proof` returning {} has three causes and they need different
189
- # answers. Two review rounds went by patching one branch at a time and
190
- # getting the reason wrong each time, so this asks the runner's own
191
- # selector instead of inferring it from the mode:
192
- #
193
- # ledger empty -> nothing to verify at all (the #1118 case)
194
- # nothing runnable -> requirements exist but all SATISFIED/WAIVED
195
- # for this mode; scope was never consulted,
196
- # because run_proof short-circuits first
197
- # nothing in scope -> runnable requirements existed and the scope
198
- # filter excluded every one
199
- from codeframe.core.proof import ledger as _ledger
200
- from codeframe.core.proof.models import ReqStatus
201
- from codeframe.core.proof.runner import _requirements_for_run
202
-
203
- try:
204
- all_reqs = _ledger.list_requirements(workspace)
205
- # Same selector the runner uses, so this cannot drift from it.
206
- runnable = _requirements_for_run(workspace, full=full)
207
- except Exception:
208
- # A ledger we cannot read is not evidence of an empty one; fall
209
- # through to the unverified case rather than inventing a reason.
210
- all_reqs, runnable = [], []
211
-
212
- if runnable:
213
- # Four review rounds went by asserting a specific reason here and
214
- # being wrong each time. The CLI genuinely cannot tell them apart:
215
- # run_proof returns only results, and discards the scope_skipped
216
- # list it computes internally (runner.py:334/435). With a non-empty
217
- # runnable set an empty result can mean the scope filter excluded
218
- # everything, --gate excluded every obligation, enabled_gates config
219
- # did, or a requirement simply has none.
190
+ # The runner now reports WHY (#1138). Before that, this block inferred
191
+ # the cause from the mode and the ledger, and four consecutive review
192
+ # rounds on #1137 caught it asserting a reason that was wrong — each
193
+ # time about a different one of the six causes. It ended up listing
194
+ # candidates instead, which was honest but useless. The runner is the
195
+ # only thing that knows, so ask it.
196
+ reason = diagnostics.reason
197
+
198
+ if reason is EmptyReason.NO_REQUIREMENTS:
199
+ # An empty ledger is not a pass (#1118). Exiting 0 here is what let
200
+ # the quickstart's PROVE step read as "PROOF9 gates passed" when
201
+ # nothing had been checked — and every new workspace is in exactly
202
+ # this state.
220
203
  #
221
- # So state what is known and list the candidates, rather than
222
- # asserting one and sending the user somewhere useless. #1138 tracks
223
- # having the runner report the reason so this can be precise.
224
- console.print(
225
- f"[yellow]Nothing was verified.[/yellow] "
226
- f"{len(runnable)} requirement(s) were eligible for this run, "
227
- f"but no obligations ran."
228
- )
229
- reasons = []
230
- if not full:
231
- # --full provably ignores scope (runner.py:339), so listing it
232
- # there would put an impossible cause in the candidate list.
233
- reasons.append("none of them cover the changed files")
234
- if gate_filter is not None:
235
- reasons.append(f"--gate {gate_filter.value} excluded their obligations")
236
- reasons.append("their obligations are disabled in proof_config.json")
237
- reasons.append("they have no obligations defined")
238
- console.print("Possible reasons: " + "; ".join(reasons) + ".")
239
- if not full:
240
- console.print(
241
- "Try [bold]cf proof run --full[/bold] to ignore scope, or "
242
- "[bold]cf proof status[/bold] for the ledger."
243
- )
244
- else:
245
- console.print("See [bold]cf proof status[/bold] for the ledger.")
246
- return
247
-
248
- if all_reqs:
249
- # This one IS knowable: the runnable set is empty while the ledger
250
- # is not, so every requirement was excluded by its status. WAIVED is
251
- # excluded from both modes; SATISFIED only from a scoped run.
252
- satisfied = sum(1 for r in all_reqs if r.status == ReqStatus.SATISFIED)
253
- waived = sum(1 for r in all_reqs if r.status == ReqStatus.WAIVED)
254
- detail = ", ".join(
255
- part
256
- for part in (
257
- f"{satisfied} satisfied" if satisfied else "",
258
- f"{waived} waived" if waived else "",
259
- )
260
- if part
261
- )
204
+ # Exit 2 rather than 1: this is not a failure either, and a script
205
+ # needs to tell "the gate failed" from "the gate had nothing to
206
+ # check". CI treats any non-zero as a stop, which is the point.
207
+ console.print("[yellow]Nothing was verified.[/yellow]")
262
208
  console.print(
263
- f"[yellow]Nothing was verified.[/yellow] "
264
- f"{len(all_reqs)} requirement(s) exist, but none are runnable"
265
- + (f" ({detail})." if detail else ".")
209
+ "There are no proof obligations in this workspace, so this run "
210
+ "checked nothing — it is not a pass."
266
211
  )
267
212
  console.print(
268
- "A waiver is an accepted risk that no run re-checks; "
269
- "[bold]cf proof run --full[/bold] also re-verifies satisfied "
270
- "ones. See [bold]cf proof status[/bold] for the ledger."
213
+ "\nCapture your first requirement with:\n"
214
+ " [bold]cf proof capture[/bold]"
271
215
  )
272
- return
273
-
274
- # An empty ledger is not a pass (#1118). Exiting 0 here is what let the
275
- # quickstart's PROVE step read as "PROOF9 gates passed" when nothing had
276
- # been checked — and every new workspace is in exactly this state.
277
- #
278
- # Exit 2 rather than 1: this is not a failure either, and a script needs
279
- # to tell "the gate failed" from "the gate had nothing to check". CI
280
- # treats any non-zero as a stop, which is the point.
281
- console.print("[yellow]Nothing was verified.[/yellow]")
282
- console.print(
283
- "There are no proof obligations in this workspace, so this run "
284
- "checked nothing — it is not a pass."
285
- )
216
+ if allow_empty:
217
+ console.print("\n[dim]--allow-empty: exiting 0 anyway.[/dim]")
218
+ return
219
+ raise typer.Exit(2)
220
+
286
221
  console.print(
287
- "\nCapture your first requirement with:\n"
288
- " [bold]cf proof capture[/bold]"
222
+ f"[yellow]Nothing was verified.[/yellow] {diagnostics.describe()}."
289
223
  )
290
- if allow_empty:
291
- console.print("\n[dim]--allow-empty: exiting 0 anyway.[/dim]")
292
- return
293
- raise typer.Exit(2)
224
+
225
+ hints = {
226
+ EmptyReason.EXCLUDED_BY_STATUS: (
227
+ "A waiver is an accepted risk that no run re-checks; "
228
+ "[bold]cf proof run --full[/bold] also re-verifies satisfied ones."
229
+ ),
230
+ EmptyReason.EXCLUDED_BY_SCOPE: (
231
+ "[bold]cf proof run --full[/bold] ignores scope entirely."
232
+ ),
233
+ EmptyReason.EXCLUDED_BY_GATE_FILTER: (
234
+ "Drop [bold]--gate[/bold] to run every obligation."
235
+ ),
236
+ EmptyReason.EXCLUDED_BY_CONFIG: (
237
+ "Check [bold]enabled_gates[/bold] in "
238
+ f"[bold].codeframe/{PROOF_CONFIG_FILENAME}[/bold]."
239
+ ),
240
+ EmptyReason.EXCLUDED_BY_FILTER_COMBINATION: (
241
+ "Drop [bold]--gate[/bold], or add that gate to "
242
+ f"[bold]enabled_gates[/bold] in [bold].codeframe/{PROOF_CONFIG_FILENAME}"
243
+ "[/bold] — each filter alone leaves work to do, but they do not "
244
+ "overlap."
245
+ ),
246
+ EmptyReason.NO_OBLIGATIONS: (
247
+ "Add obligations to those requirements, or they can never be "
248
+ "satisfied."
249
+ ),
250
+ }
251
+ if reason in hints:
252
+ console.print(hints[reason])
253
+ console.print("See [bold]cf proof status[/bold] for the ledger.")
254
+ return
294
255
 
295
256
  # Display results
296
257
  table = Table(title="Proof Results")
@@ -9,7 +9,6 @@ Environment Variables (via GlobalConfig):
9
9
  RATE_LIMIT_AUTH: Rate limit for authentication endpoints (default: 10/minute)
10
10
  RATE_LIMIT_STANDARD: Rate limit for standard API endpoints (default: 100/minute)
11
11
  RATE_LIMIT_AI: Rate limit for AI/expensive operations (default: 20/minute)
12
- RATE_LIMIT_WEBSOCKET: Rate limit for WebSocket connections (default: 30/minute)
13
12
  RATE_LIMIT_STORAGE: Storage backend - memory or redis (default: memory)
14
13
  RATE_LIMIT_TRUSTED_PROXIES: Comma-separated trusted proxy IPs/CIDRs
15
14
  REDIS_URL: Redis connection URL for distributed rate limiting (optional)
@@ -32,7 +31,6 @@ class RateLimitConfig:
32
31
  auth_limit: Rate limit for authentication endpoints
33
32
  standard_limit: Rate limit for standard API endpoints
34
33
  ai_limit: Rate limit for AI/expensive operations
35
- websocket_limit: Rate limit for WebSocket connections
36
34
  enabled: Whether rate limiting is enabled
37
35
  storage: Storage backend ('memory' or 'redis')
38
36
  redis_url: Redis connection URL for distributed rate limiting
@@ -42,7 +40,6 @@ class RateLimitConfig:
42
40
  auth_limit: str = "10/minute"
43
41
  standard_limit: str = "100/minute"
44
42
  ai_limit: str = "20/minute"
45
- websocket_limit: str = "30/minute"
46
43
  enabled: bool = True
47
44
  storage: str = "memory"
48
45
  redis_url: Optional[str] = None
@@ -128,7 +125,6 @@ class RateLimitConfig:
128
125
  auth_limit=global_config.rate_limit_auth,
129
126
  standard_limit=global_config.rate_limit_standard,
130
127
  ai_limit=global_config.rate_limit_ai,
131
- websocket_limit=global_config.rate_limit_websocket,
132
128
  enabled=enabled,
133
129
  storage=storage,
134
130
  redis_url=redis_url,
@@ -1,11 +1,9 @@
1
1
  """Core components for CodeFRAME orchestration."""
2
2
 
3
- from codeframe.core.config import Config
4
3
  from codeframe.core.models import Task, TaskStatus, AgentMaturity
5
4
  from codeframe.core.stall_detector import StallAction, StallDetectedError, StallDetector
6
5
 
7
6
  __all__ = [
8
- "Config",
9
7
  "Task",
10
8
  "TaskStatus",
11
9
  "AgentMaturity",