specsmith 0.19.2.dev738__tar.gz → 0.19.2.dev739__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 (369) hide show
  1. {specsmith-0.19.2.dev738/src/specsmith.egg-info → specsmith-0.19.2.dev739}/PKG-INFO +1 -1
  2. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/pyproject.toml +1 -1
  3. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/runner.py +10 -0
  4. specsmith-0.19.2.dev739/src/specsmith/agent/terminal_env.py +43 -0
  5. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/cli.py +64 -40
  6. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/__init__.py +7 -6
  7. specsmith-0.19.2.dev739/src/specsmith/integrations/warp.py +84 -0
  8. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/local_model.py +212 -0
  9. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/mcp_server.py +41 -0
  10. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739/src/specsmith.egg-info}/PKG-INFO +1 -1
  11. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith.egg-info/SOURCES.txt +4 -0
  12. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_integrations.py +8 -5
  13. specsmith-0.19.2.dev739/tests/test_integrations_warp.py +88 -0
  14. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_local_model.py +176 -0
  15. specsmith-0.19.2.dev739/tests/test_terminal_env.py +58 -0
  16. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/LICENSE +0 -0
  17. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/README.md +0 -0
  18. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/setup.cfg +0 -0
  19. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/__init__.py +0 -0
  20. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/belief.py +0 -0
  21. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/certainty.py +0 -0
  22. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/failure_graph.py +0 -0
  23. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/py.typed +0 -0
  24. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/recovery.py +0 -0
  25. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/session.py +0 -0
  26. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/stress_tester.py +0 -0
  27. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/epistemic/trace.py +0 -0
  28. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/__init__.py +0 -0
  29. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/__main__.py +0 -0
  30. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/__init__.py +0 -0
  31. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/broker.py +0 -0
  32. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/chat_runner.py +0 -0
  33. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/cleanup.py +0 -0
  34. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/context_seed.py +0 -0
  35. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/core.py +0 -0
  36. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/__init__.py +0 -0
  37. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/_status.py +0 -0
  38. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/dag.py +0 -0
  39. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
  40. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/events.py +0 -0
  41. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/dispatch/result.py +0 -0
  42. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/endpoints.py +0 -0
  43. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/events.py +0 -0
  44. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/execution_profiles.py +0 -0
  45. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/fallback.py +0 -0
  46. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/hf_leaderboard.py +0 -0
  47. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/hf_sync.py +0 -0
  48. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/indexer.py +0 -0
  49. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/llm_client.py +0 -0
  50. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/mcp.py +0 -0
  51. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/memory.py +0 -0
  52. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/model_intelligence.py +0 -0
  53. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/model_profiles.py +0 -0
  54. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/model_router.py +0 -0
  55. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/orchestrator.py +0 -0
  56. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/permissions.py +0 -0
  57. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/profiles.py +0 -0
  58. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/provider_registry.py +0 -0
  59. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/repl.py +0 -0
  60. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/router.py +0 -0
  61. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/rules.py +0 -0
  62. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/safety.py +0 -0
  63. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/spawner.py +0 -0
  64. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/suggester.py +0 -0
  65. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/teams.py +0 -0
  66. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/token_pricing.py +0 -0
  67. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/tools.py +0 -0
  68. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/verifier.py +0 -0
  69. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/agent/voice.py +0 -0
  70. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/approvals.py +0 -0
  71. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/architect.py +0 -0
  72. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/auditor.py +0 -0
  73. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/auth.py +0 -0
  74. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/block_export.py +0 -0
  75. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/channel.py +0 -0
  76. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/ci_manager.py +0 -0
  77. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/commands/__init__.py +0 -0
  78. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/commands/intelligence.py +0 -0
  79. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/commands/issues_policy.py +0 -0
  80. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/commands/reporting.py +0 -0
  81. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/__init__.py +0 -0
  82. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/_compat.py +0 -0
  83. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/checker.py +0 -0
  84. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/evidence.py +0 -0
  85. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/regulations.py +0 -0
  86. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compliance/reporter.py +0 -0
  87. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/compressor.py +0 -0
  88. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/config.py +0 -0
  89. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/console_utils.py +0 -0
  90. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/context_orchestrator.py +0 -0
  91. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/context_window.py +0 -0
  92. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/credit_analyzer.py +0 -0
  93. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/credits.py +0 -0
  94. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/dashboard.py +0 -0
  95. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/__init__.py +0 -0
  96. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/base.py +0 -0
  97. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/citations.py +0 -0
  98. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/fpd.py +0 -0
  99. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/odp.py +0 -0
  100. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/patentsview.py +0 -0
  101. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/pfw.py +0 -0
  102. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/ppubs.py +0 -0
  103. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/datasources/ptab.py +0 -0
  104. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/differ.py +0 -0
  105. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/doctor.py +0 -0
  106. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/drive.py +0 -0
  107. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/editor.py +0 -0
  108. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/efficiency.py +0 -0
  109. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/__init__.py +0 -0
  110. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/belief.py +0 -0
  111. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/certainty.py +0 -0
  112. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/failure_graph.py +0 -0
  113. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/recovery.py +0 -0
  114. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/epistemic/stress_tester.py +0 -0
  115. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb/__init__.py +0 -0
  116. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb/_license.py +0 -0
  117. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb/bridge.py +0 -0
  118. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb/sqlite_store.py +0 -0
  119. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb_sweep.py +0 -0
  120. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/esdb_writer.py +0 -0
  121. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/eval/__init__.py +0 -0
  122. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/eval/builtins.py +0 -0
  123. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/eval/runner.py +0 -0
  124. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/executor.py +0 -0
  125. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/exporter.py +0 -0
  126. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/governance_logic.py +0 -0
  127. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/governance_store.py +0 -0
  128. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/governance_yaml.py +0 -0
  129. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/governed_pr.py +0 -0
  130. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/__init__.py +0 -0
  131. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/app.py +0 -0
  132. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/main_window.py +0 -0
  133. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/session_tab.py +0 -0
  134. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/theme.py +0 -0
  135. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/__init__.py +0 -0
  136. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/chat_view.py +0 -0
  137. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/input_bar.py +0 -0
  138. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  139. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/token_meter.py +0 -0
  140. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  141. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/widgets/update_checker.py +0 -0
  142. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/gui/worker.py +0 -0
  143. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/history_search.py +0 -0
  144. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/importer.py +0 -0
  145. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/instinct.py +0 -0
  146. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/agent_skill.py +0 -0
  147. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/aider.py +0 -0
  148. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/base.py +0 -0
  149. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/claude_code.py +0 -0
  150. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/codity.py +0 -0
  151. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/copilot.py +0 -0
  152. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/cursor.py +0 -0
  153. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/gemini.py +0 -0
  154. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/integrations/windsurf.py +0 -0
  155. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/issue_reporter.py +0 -0
  156. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/languages.py +0 -0
  157. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/ledger.py +0 -0
  158. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/mcp_generator.py +0 -0
  159. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/__init__.py +0 -0
  160. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
  161. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m002_agents_slim.py +0 -0
  162. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m003_compliance_init.py +0 -0
  163. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
  164. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
  165. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m006_session_governance.py +0 -0
  166. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m007_yaml_first.py +0 -0
  167. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m008_esdb_full_coverage.py +0 -0
  168. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m009_esdb_first.py +0 -0
  169. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/m010_post_esdb_cleanup.py +0 -0
  170. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/migrations/runner.py +0 -0
  171. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/ollama_cmds.py +0 -0
  172. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/patent.py +0 -0
  173. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/paths.py +0 -0
  174. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/phase.py +0 -0
  175. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/plugins.py +0 -0
  176. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/policy.py +0 -0
  177. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/profiles.py +0 -0
  178. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/project_metrics.py +0 -0
  179. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/quality_report.py +0 -0
  180. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/rate_limits.py +0 -0
  181. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/recover.py +0 -0
  182. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/releaser.py +0 -0
  183. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/requirements.py +0 -0
  184. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/requirements_parser.py +0 -0
  185. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/retrieval.py +0 -0
  186. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/risk.py +0 -0
  187. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/safe_write.py +0 -0
  188. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/scaffolder.py +0 -0
  189. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/serve.py +0 -0
  190. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/session.py +0 -0
  191. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/session_init.py +0 -0
  192. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/session_store.py +0 -0
  193. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/__init__.py +0 -0
  194. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/ai_agents.py +0 -0
  195. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/cloud.py +0 -0
  196. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/corporate.py +0 -0
  197. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/cross_platform.py +0 -0
  198. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/data_engineering.py +0 -0
  199. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/devops.py +0 -0
  200. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/docs.py +0 -0
  201. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/embedded.py +0 -0
  202. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/governance.py +0 -0
  203. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/hardware.py +0 -0
  204. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/mobile.py +0 -0
  205. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/platform_engineering.py +0 -0
  206. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/productivity.py +0 -0
  207. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/software_engineering.py +0 -0
  208. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/specsmith_skills.py +0 -0
  209. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/ssh.py +0 -0
  210. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills/web_backend.py +0 -0
  211. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/skills_builder.py +0 -0
  212. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/sync.py +0 -0
  213. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/agents.md.j2 +0 -0
  214. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  215. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  216. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  217. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  218. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  219. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  220. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  221. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/community/security.md.j2 +0 -0
  222. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  223. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  224. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  225. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  226. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  227. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/editorconfig.j2 +0 -0
  228. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/gitattributes.j2 +0 -0
  229. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/gitignore.j2 +0 -0
  230. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/go/go.mod.j2 +0 -0
  231. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/go/main.go.j2 +0 -0
  232. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  233. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  234. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  235. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  236. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  237. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  238. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  239. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  240. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  241. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  242. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  243. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/js/package.json.j2 +0 -0
  244. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/ledger.md.j2 +0 -0
  245. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/python/cli.py.j2 +0 -0
  246. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/python/init.py.j2 +0 -0
  247. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  248. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/readme.md.j2 +0 -0
  249. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  250. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  251. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  252. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  253. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  254. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  255. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  256. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  257. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  258. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/tool_installer.py +0 -0
  259. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/toolrules.py +0 -0
  260. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/tools.py +0 -0
  261. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/trace.py +0 -0
  262. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/transcripts.py +0 -0
  263. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/updater.py +0 -0
  264. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/upgrader.py +0 -0
  265. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/validator.py +0 -0
  266. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs/__init__.py +0 -0
  267. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs/base.py +0 -0
  268. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs/bitbucket.py +0 -0
  269. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs/github.py +0 -0
  270. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs/gitlab.py +0 -0
  271. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/vcs_commands.py +0 -0
  272. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/wi_store.py +0 -0
  273. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/wireframes.py +0 -0
  274. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith/workspace.py +0 -0
  275. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith.egg-info/dependency_links.txt +0 -0
  276. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith.egg-info/entry_points.txt +0 -0
  277. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith.egg-info/requires.txt +0 -0
  278. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/src/specsmith.egg-info/top_level.txt +0 -0
  279. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_CMD_001.py +0 -0
  280. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_agent_profiles.py +0 -0
  281. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_agent_run_feedback.py +0 -0
  282. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_agent_runner_ready.py +0 -0
  283. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_ai_client.py +0 -0
  284. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_ai_intelligence.py +0 -0
  285. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_architect_interview.py +0 -0
  286. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_architect_v2.py +0 -0
  287. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_architecture.py +0 -0
  288. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_audit_governance.py +0 -0
  289. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_auditor.py +0 -0
  290. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_benchmark_harness.py +0 -0
  291. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_broker_scope.py +0 -0
  292. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_channel.py +0 -0
  293. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_chat_diff_decision.py +0 -0
  294. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_chat_runner_openai_compat.py +0 -0
  295. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_chat_stdin_protocol.py +0 -0
  296. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_cleanup_cmd.py +0 -0
  297. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_cli.py +0 -0
  298. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_cli_regressions.py +0 -0
  299. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_cli_workflows_history_drive.py +0 -0
  300. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_compliance.py +0 -0
  301. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_compliance_governance.py +0 -0
  302. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_compressor.py +0 -0
  303. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_deprecation_registry.py +0 -0
  304. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_dispatch.py +0 -0
  305. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_dual_write.py +0 -0
  306. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_e2e_nexus.py +0 -0
  307. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_efficiency.py +0 -0
  308. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_endpoints_cli.py +0 -0
  309. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_endpoints_store.py +0 -0
  310. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_epistemic.py +0 -0
  311. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_backend_switch.py +0 -0
  312. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_enforcement.py +0 -0
  313. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_integration.py +0 -0
  314. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_license.py +0 -0
  315. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_sqlite.py +0 -0
  316. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_status_integrity.py +0 -0
  317. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_status_output.py +0 -0
  318. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_sweep.py +0 -0
  319. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_verify_chain_cli.py +0 -0
  320. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_esdb_writer.py +0 -0
  321. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_fallback_chain.py +0 -0
  322. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_golden_path.py +0 -0
  323. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_importer.py +0 -0
  324. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_init_modes.py +0 -0
  325. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_integrations_codity.py +0 -0
  326. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_intelligence.py +0 -0
  327. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_issue_policy_features.py +0 -0
  328. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_issue_reporter.py +0 -0
  329. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_issues_263_264.py +0 -0
  330. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_markdown_deprecation.py +0 -0
  331. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_mcp_client.py +0 -0
  332. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_mcp_server.py +0 -0
  333. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_metrics_flush.py +0 -0
  334. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_migration_direction.py +0 -0
  335. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_model_router.py +0 -0
  336. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_new_modules.py +0 -0
  337. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_nexus.py +0 -0
  338. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_parallel_agents.py +0 -0
  339. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_permissions.py +0 -0
  340. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_phase1_4_new.py +0 -0
  341. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_phase34_completion.py +0 -0
  342. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_project_metrics.py +0 -0
  343. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_quality_report.py +0 -0
  344. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_rate_limits.py +0 -0
  345. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_releaser.py +0 -0
  346. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_repl.py +0 -0
  347. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_repl_extended.py +0 -0
  348. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_reporting_commands.py +0 -0
  349. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_req_248_262.py +0 -0
  350. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_req_358_359.py +0 -0
  351. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_resume_command.py +0 -0
  352. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_scaffolder.py +0 -0
  353. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_schema_migrations.py +0 -0
  354. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_skill_marketplace.py +0 -0
  355. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_skills_mcp.py +0 -0
  356. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_smoke.py +0 -0
  357. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_sqlite_parity.py +0 -0
  358. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_suggester.py +0 -0
  359. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_sync_reconcile.py +0 -0
  360. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_token_cost.py +0 -0
  361. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_tools.py +0 -0
  362. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_trace_vault_esdb.py +0 -0
  363. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_typing_guardrails.py +0 -0
  364. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_validator.py +0 -0
  365. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_vcs.py +0 -0
  366. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_warp_parity.py +0 -0
  367. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_warp_parity_followup.py +0 -0
  368. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_wi_lifecycle.py +0 -0
  369. {specsmith-0.19.2.dev738 → specsmith-0.19.2.dev739}/tests/test_wi_lifecycle_extended.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.19.2.dev738
3
+ Version: 0.19.2.dev739
4
4
  Summary: AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider.
5
5
  Author: Layer1Labs Silicon, Inc.
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "specsmith"
7
- version = "0.19.2.dev738"
7
+ version = "0.19.2.dev739"
8
8
  description = "AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -304,6 +304,12 @@ class AgentRunner:
304
304
  self.endpoint_id = (endpoint_id or "").strip() or None
305
305
  self.profile_id = (profile_id or "").strip() or None
306
306
 
307
+ # Host-terminal detection (REQ-444): when running inside Warp the
308
+ # banner/ready frame advertises native integration. Read-only.
309
+ from specsmith.agent.terminal_env import detect_terminal
310
+
311
+ self.terminal = detect_terminal()
312
+
307
313
  # Use a plain-text emitter in interactive mode so LLM tokens render
308
314
  # as readable prose instead of raw JSONL frames on the terminal.
309
315
  if emitter is not None:
@@ -374,6 +380,7 @@ class AgentRunner:
374
380
  profile_id=self.profile_id or "",
375
381
  capabilities=_capabilities(),
376
382
  endpoint_id=self.endpoint_id or "",
383
+ terminal=self.terminal.as_dict(),
377
384
  )
378
385
  else:
379
386
  statuses = check_providers()
@@ -385,6 +392,9 @@ class AgentRunner:
385
392
  "",
386
393
  " LLM providers:",
387
394
  ]
395
+ if self.terminal.is_warp:
396
+ ver = f" {self.terminal.version}" if self.terminal.version else ""
397
+ lines.insert(3, f" terminal: Warp{ver} \u2014 native integration active")
388
398
  for s in statuses:
389
399
  if s.available:
390
400
  lines.append(
@@ -0,0 +1,43 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs Silicon, Inc. All rights reserved.
3
+ """Terminal-environment detection for specsmith (REQ-444).
4
+
5
+ Lets the interactive REPL (``specsmith run``) detect when it is running
6
+ inside Warp so it can adapt its banner / ``ready`` frame. Detection is
7
+ based on the standard ``TERM_PROGRAM`` signal Warp sets, plus any
8
+ ``WARP_*`` environment variables, and is purely read-only.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import os
14
+ from dataclasses import asdict, dataclass
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class TerminalInfo:
19
+ """Information about the host terminal."""
20
+
21
+ is_warp: bool
22
+ program: str
23
+ version: str
24
+
25
+ def as_dict(self) -> dict[str, object]:
26
+ """Return a flat dict suitable for the ``ready`` event frame."""
27
+ return asdict(self)
28
+
29
+
30
+ def detect_terminal(env: dict[str, str] | None = None) -> TerminalInfo:
31
+ """Detect the host terminal from environment variables.
32
+
33
+ Warp sets ``TERM_PROGRAM=WarpTerminal`` (and ``TERM_PROGRAM_VERSION``).
34
+ As a fallback we also treat the presence of any ``WARP_*`` variable as a
35
+ Warp signal. Pass *env* to override ``os.environ`` (used by tests).
36
+ """
37
+ source = os.environ if env is None else env
38
+ program = (source.get("TERM_PROGRAM") or "").strip()
39
+ version = (source.get("TERM_PROGRAM_VERSION") or "").strip()
40
+ is_warp = program == "WarpTerminal" or any(k.startswith("WARP_") for k in source)
41
+ if is_warp and not program:
42
+ program = "WarpTerminal"
43
+ return TerminalInfo(is_warp=is_warp, program=program, version=version)
@@ -5625,12 +5625,14 @@ def integrate_cmd(tool_name: str, project_dir: str, dry_run: bool) -> None:
5625
5625
  what belief artifacts this tool provides evidence for, what its
5626
5626
  uncertainty bounds are, and what failure modes it might introduce.
5627
5627
  """
5628
+ from specsmith.paths import find_requirements, find_scaffold
5629
+
5628
5630
  root = Path(project_dir).resolve()
5629
- req_path = root / "docs" / "REQUIREMENTS.md"
5631
+ req_path = find_requirements(root)
5630
5632
 
5631
5633
  console.print(f"[bold]Epistemic Impact Analysis[/bold]: {tool_name}\n")
5632
5634
 
5633
- if req_path.exists():
5635
+ if req_path is not None:
5634
5636
  from specsmith.epistemic.belief import parse_requirements_as_beliefs
5635
5637
 
5636
5638
  artifacts = parse_requirements_as_beliefs(req_path)
@@ -5669,19 +5671,23 @@ def integrate_cmd(tool_name: str, project_dir: str, dry_run: bool) -> None:
5669
5671
  from specsmith.integrations import get_adapter
5670
5672
 
5671
5673
  adapter = get_adapter(tool_name)
5672
- scaffold_path = root / "scaffold.yml"
5673
- if scaffold_path.exists():
5674
+ scaffold_file = find_scaffold(root)
5675
+ if scaffold_file is not None:
5674
5676
  import yaml
5675
5677
 
5676
- with open(scaffold_path) as f:
5678
+ from specsmith.config import _normalize_scaffold_raw
5679
+
5680
+ with open(scaffold_file) as f:
5677
5681
  raw = yaml.safe_load(f)
5678
- config = ProjectConfig(**raw)
5682
+ config = ProjectConfig(**_normalize_scaffold_raw(raw or {}))
5679
5683
  created = adapter.generate(config, root)
5680
5684
  for path in created:
5681
5685
  console.print(f" [green]✓[/green] {path.relative_to(root)}")
5682
5686
  console.print(f"\n[bold green]{len(created)} adapter file(s) generated.[/bold green]")
5683
5687
  else:
5684
- console.print("[yellow]No scaffold.yml found. Run specsmith import first.[/yellow]")
5688
+ console.print(
5689
+ "[yellow]No docs/SPECSMITH.yml found. Run specsmith import first.[/yellow]"
5690
+ )
5685
5691
  except ValueError:
5686
5692
  console.print(
5687
5693
  f"[yellow]No built-in adapter for '{tool_name}'.[/yellow] "
@@ -10592,41 +10598,10 @@ def mcp_install_warp_cmd(as_json: bool) -> None:
10592
10598
  to ``oz agent run --mcp '<json>'`` for a one-off cloud agent run.
10593
10599
  """
10594
10600
  import json as _json
10595
- import shutil
10596
- import sys
10597
10601
 
10598
- # Env vars the server needs regardless of how it is invoked.
10599
- # SPECSMITH_ALLOW_NON_PIPX=1 — prevents the pipx-enforcement gate from
10600
- # exiting before the MCP handshake when Warp starts the server directly.
10601
- # SPECSMITH_NO_AUTO_UPDATE / SPECSMITH_PYPI_CHECKED — suppress network
10602
- # calls on startup so the server responds immediately.
10603
- server_env = {
10604
- "SPECSMITH_ALLOW_NON_PIPX": "1",
10605
- "SPECSMITH_NO_AUTO_UPDATE": "1",
10606
- "SPECSMITH_PYPI_CHECKED": "1",
10607
- }
10602
+ from specsmith.mcp_server import build_warp_mcp_config
10608
10603
 
10609
- # Executable detection strategy (in priority order):
10610
- # 1. specsmith (or specsmith.exe) on PATH — covers pipx shims and system installs.
10611
- # 2. python -m specsmith via the current interpreter — reliable fallback
10612
- # for editable dev installs and venvs where the console script wrapper
10613
- # is absent or resolves incorrectly (e.g. some Windows pipx setups).
10614
- specsmith_exe = shutil.which("specsmith") or shutil.which("specsmith.exe")
10615
- if specsmith_exe:
10616
- cmd = specsmith_exe
10617
- args: list[str] = ["mcp", "serve"]
10618
- else:
10619
- # Fall back to `python -m specsmith` using the current interpreter.
10620
- cmd = sys.executable
10621
- args = ["-m", "specsmith", "mcp", "serve"]
10622
-
10623
- config = {
10624
- "specsmith-governance": {
10625
- "command": cmd,
10626
- "args": args,
10627
- "env": server_env,
10628
- }
10629
- }
10604
+ config = build_warp_mcp_config()
10630
10605
 
10631
10606
  if as_json:
10632
10607
  click.echo(_json.dumps(config, indent=2))
@@ -14152,6 +14127,55 @@ def local_model_detect_cmd(as_json: bool) -> None:
14152
14127
  )
14153
14128
 
14154
14129
 
14130
+ @local_model_group.command(name="recommend")
14131
+ @click.option("--json", "as_json", is_flag=True, default=False, help="Emit result as JSON.")
14132
+ def local_model_recommend_cmd(as_json: bool) -> None:
14133
+ """Recommend a full local model lineup based on detected GPU VRAM (REQ-445).
14134
+
14135
+ Detects the host GPU and prints a VRAM-aware role lineup (default / fast /
14136
+ harder pass / general) with a per-model fit assessment so you can see which
14137
+ models run fully on the GPU and which would spill to system RAM.
14138
+ """
14139
+ import json as _json
14140
+
14141
+ from specsmith.local_model import recommend_for_hardware
14142
+
14143
+ lineup = recommend_for_hardware()
14144
+
14145
+ if as_json:
14146
+ click.echo(
14147
+ _json.dumps(
14148
+ lineup.as_dict()
14149
+ if lineup is not None
14150
+ else {"hardware": None, "reason": "cpu-only or insufficient VRAM", "models": []}
14151
+ )
14152
+ )
14153
+ return
14154
+
14155
+ if lineup is None:
14156
+ console.print(
14157
+ "[yellow]\u2014[/yellow] No GPU / insufficient VRAM detected. "
14158
+ "Local model recommendations skipped (CPU-only would be too slow)."
14159
+ )
14160
+ return
14161
+
14162
+ console.print(
14163
+ f"[bold]Hardware:[/bold] {lineup.hardware} ([bold]{lineup.vram_gb:.1f} GB[/bold] VRAM)\n"
14164
+ )
14165
+ _fit_color = {"fits": "green", "tight": "yellow", "spills": "red"}
14166
+ for rec in lineup.models:
14167
+ color = _fit_color.get(rec.fit.value, "white")
14168
+ console.print(
14169
+ f" [bold]{rec.slot:<8}[/bold] [green]{rec.model:<22}[/green] "
14170
+ f"~{rec.footprint_gb:.1f} GB [{color}]{rec.fit_note}[/{color}]"
14171
+ )
14172
+ console.print(f" [dim]{rec.summary}[/dim]")
14173
+ console.print(
14174
+ "\n[dim]Pull all with [bold]specsmith local-model setup[/bold], or pull one with "
14175
+ "[bold]ollama pull <model>[/bold].[/dim]"
14176
+ )
14177
+
14178
+
14155
14179
  @local_model_group.command(name="setup")
14156
14180
  def local_model_setup_cmd() -> None:
14157
14181
  """Pull the recommended local model via Ollama (REQ-386).
@@ -15,12 +15,11 @@ ADAPTER_REGISTRY: dict[str, type[AgentAdapter]] = {}
15
15
  # canonical name. Lookups for legacy keys still succeed (backward compat for
16
16
  # existing scaffold.yml files) but only the canonical names are returned by
17
17
  # ``list_adapters()``.
18
- LEGACY_ALIASES: dict[str, str] = {
19
- # Pre-0.5.0 the agent-skill adapter shipped under the name ``warp`` and
20
- # wrote to ``.warp/skills/SKILL.md``. New scaffolds use ``agent-skill``
21
- # and ``.agents/skills/SKILL.md``.
22
- "warp": "agent-skill",
23
- }
18
+ #
19
+ # Note: ``warp`` is no longer an alias it now resolves to the dedicated
20
+ # :class:`~specsmith.integrations.warp.WarpAdapter`, which still emits the
21
+ # governance skill (via ``AgentSkillAdapter``) plus Warp-native artifacts.
22
+ LEGACY_ALIASES: dict[str, str] = {}
24
23
 
25
24
 
26
25
  def _load_adapters() -> None:
@@ -32,6 +31,7 @@ def _load_adapters() -> None:
32
31
  from specsmith.integrations.copilot import CopilotAdapter
33
32
  from specsmith.integrations.cursor import CursorAdapter
34
33
  from specsmith.integrations.gemini import GeminiAdapter
34
+ from specsmith.integrations.warp import WarpAdapter
35
35
  from specsmith.integrations.windsurf import WindsurfAdapter
36
36
 
37
37
  for cls in (
@@ -43,6 +43,7 @@ def _load_adapters() -> None:
43
43
  GeminiAdapter,
44
44
  WindsurfAdapter,
45
45
  AiderAdapter,
46
+ WarpAdapter,
46
47
  ):
47
48
  ADAPTER_REGISTRY[cls().name] = cls
48
49
 
@@ -0,0 +1,84 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs Silicon, Inc. All rights reserved.
3
+ """Warp integration adapter (REQ-444).
4
+
5
+ Generates Warp-native artifacts so Warp's agent is governed by specsmith:
6
+
7
+ * ``.warp/specsmith-mcp.json`` — governance MCP server config
8
+ * ``.warp/launch_configs/specsmith-governed.yaml`` — launch config for a governed session
9
+ * ``.agents/skills/SKILL.md`` — governance skill (shared with agent-skill)
10
+
11
+ ``AGENTS.md`` is already the governance hub Warp reads as project Rules, so the
12
+ adapter does not duplicate it.
13
+
14
+ This adapter supersedes the pre-0.5.0 ``warp`` name that previously aliased to
15
+ the generic ``agent-skill`` adapter; the skill is still emitted here (by reusing
16
+ ``AgentSkillAdapter``), so existing setups keep their ``.agents/skills/SKILL.md``.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import json
22
+ from pathlib import Path
23
+
24
+ from specsmith.config import ProjectConfig
25
+ from specsmith.integrations.agent_skill import AgentSkillAdapter
26
+ from specsmith.integrations.base import AgentAdapter
27
+
28
+
29
+ class WarpAdapter(AgentAdapter):
30
+ """Generate Warp-native governance integration files."""
31
+
32
+ @property
33
+ def name(self) -> str:
34
+ return "warp"
35
+
36
+ @property
37
+ def description(self) -> str:
38
+ return "Warp native integration (MCP server config, launch config, governance skill)"
39
+
40
+ def generate(self, config: ProjectConfig, target: Path) -> list[Path]:
41
+ created: list[Path] = []
42
+ warp_dir = target / ".warp"
43
+ warp_dir.mkdir(parents=True, exist_ok=True)
44
+
45
+ # 1. MCP governance server config (shared builder with `mcp install-warp`).
46
+ from specsmith.mcp_server import build_warp_mcp_config
47
+
48
+ mcp_path = warp_dir / "specsmith-mcp.json"
49
+ mcp_path.write_text(
50
+ json.dumps(build_warp_mcp_config(), indent=2) + "\n",
51
+ encoding="utf-8",
52
+ )
53
+ created.append(mcp_path)
54
+
55
+ # 2. Launch config for a governed `specsmith run` session.
56
+ launch_dir = warp_dir / "launch_configs"
57
+ launch_dir.mkdir(parents=True, exist_ok=True)
58
+ launch_path = launch_dir / "specsmith-governed.yaml"
59
+ launch_path.write_text(self._render_launch_config(config, target), encoding="utf-8")
60
+ created.append(launch_path)
61
+
62
+ # 3. Governance skill (reuse the agent-skill adapter; .agents/skills/SKILL.md).
63
+ created.extend(AgentSkillAdapter().generate(config, target))
64
+
65
+ return created
66
+
67
+ def _render_launch_config(self, config: ProjectConfig, target: Path) -> str:
68
+ cwd = str(target).replace("\\", "/")
69
+ return f"""\
70
+ # specsmith governed session — Warp launch configuration.
71
+ # Copy to your Warp launch configurations directory to use it:
72
+ # macOS/Linux: ~/.warp/launch_configurations/
73
+ # Windows: %APPDATA%/warp/Warp/data/launch_configurations/
74
+ # The governance MCP server config lives in .warp/specsmith-mcp.json — add it
75
+ # under Warp Settings -> Agents -> MCP servers so Warp's agent is governed.
76
+ name: {config.name} — specsmith governed
77
+ windows:
78
+ - tabs:
79
+ - title: specsmith
80
+ layout:
81
+ cwd: "{cwd}"
82
+ commands:
83
+ - exec: specsmith run
84
+ """
@@ -76,6 +76,9 @@ _REASON_14B = "deepseek-r1:14b"
76
76
  _REASON_8B = "deepseek-r1:8b"
77
77
  _REASON_7B = "deepseek-r1:7b"
78
78
 
79
+ # ── Heavier coder for the "harder pass" slot (deepseek-coder-v2, MoE) ───────
80
+ _DEEPSEEK_CODER_V2 = "deepseek-coder-v2:16b"
81
+
79
82
 
80
83
  @dataclass
81
84
  class LocalModelInfo:
@@ -394,6 +397,209 @@ def detect_local_model() -> LocalModelInfo | None:
394
397
  return None
395
398
 
396
399
 
400
+ # ---------------------------------------------------------------------------
401
+ # VRAM-aware recommendation engine (REQ-445)
402
+ # ---------------------------------------------------------------------------
403
+ #
404
+ # ``recommend_models`` turns a detected VRAM figure into a complete, first-class
405
+ # role lineup with per-model fit assessment, so recommendations always follow
406
+ # the GPU that was actually detected. ``recommend_for_hardware`` is the
407
+ # top-level entry point: it detects the host GPU (Apple Silicon or NVIDIA) and
408
+ # applies the same VRAM tiering used by ``detect_local_models``.
409
+
410
+ # Approximate on-GPU footprint (GB) for each model at its default Ollama
411
+ # quantization (Q4_K_M for dense models; MoE active-params for deepseek-coder-v2).
412
+ # Used purely to assess fit against detected VRAM — not an exact figure.
413
+ _MODEL_FOOTPRINT_GB: dict[str, float] = {
414
+ _MODEL_7B: 4.7,
415
+ _MODEL_14B: 9.0,
416
+ _MODEL_32B: 20.0,
417
+ _GEN_7B: 4.7,
418
+ _GEN_14B: 9.0,
419
+ _GEN_32B: 20.0,
420
+ _REASON_7B: 4.7,
421
+ _REASON_8B: 5.2,
422
+ _REASON_14B: 9.0,
423
+ _DEEPSEEK_CODER_V2: 8.9,
424
+ }
425
+
426
+ # Headroom (GB) reserved above a model's footprint for the KV cache / context.
427
+ _FIT_HEADROOM_GB = 2.0
428
+
429
+
430
+ class ModelFit(str, Enum):
431
+ """How well a model fits the detected VRAM."""
432
+
433
+ fits = "fits" # footprint + headroom <= VRAM → fully on GPU
434
+ tight = "tight" # footprint <= VRAM < footprint + headroom
435
+ spills = "spills" # footprint > VRAM → partial CPU offload (slow)
436
+
437
+
438
+ _FIT_NOTE: dict[ModelFit, str] = {
439
+ ModelFit.fits: "fits fully on GPU",
440
+ ModelFit.tight: "fits but tight — reduce context if slow",
441
+ ModelFit.spills: "exceeds VRAM — partial CPU offload, expect slowdown",
442
+ }
443
+
444
+
445
+ def assess_fit(model: str, vram_gb: float) -> ModelFit:
446
+ """Assess how *model* fits in *vram_gb* of VRAM (REQ-445).
447
+
448
+ Unknown models are treated optimistically as ``fits`` so a missing
449
+ footprint entry never blocks a recommendation.
450
+ """
451
+ footprint = _MODEL_FOOTPRINT_GB.get(model)
452
+ if footprint is None:
453
+ return ModelFit.fits
454
+ if footprint + _FIT_HEADROOM_GB <= vram_gb:
455
+ return ModelFit.fits
456
+ if footprint <= vram_gb:
457
+ return ModelFit.tight
458
+ return ModelFit.spills
459
+
460
+
461
+ @dataclass
462
+ class RecommendedModel:
463
+ """A single VRAM-aware model recommendation for one usage slot (REQ-445)."""
464
+
465
+ slot: str
466
+ """Usage slot: ``default`` | ``fast`` | ``harder`` | ``general``."""
467
+
468
+ role: ModelRole
469
+ """Router role this slot maps to (coding/general/reasoning)."""
470
+
471
+ model: str
472
+ """Ollama model tag."""
473
+
474
+ footprint_gb: float
475
+ """Approximate on-GPU footprint in GB."""
476
+
477
+ fit: ModelFit
478
+ """Fit against the detected VRAM."""
479
+
480
+ summary: str
481
+ """What this slot is for."""
482
+
483
+ @property
484
+ def pull_cmd(self) -> str:
485
+ return f"ollama pull {self.model}"
486
+
487
+ @property
488
+ def fit_note(self) -> str:
489
+ return _FIT_NOTE[self.fit]
490
+
491
+ def as_dict(self) -> dict[str, object]:
492
+ return {
493
+ "slot": self.slot,
494
+ "role": self.role.value,
495
+ "model": self.model,
496
+ "footprint_gb": self.footprint_gb,
497
+ "fit": self.fit.value,
498
+ "fit_note": self.fit_note,
499
+ "summary": self.summary,
500
+ "pull_cmd": self.pull_cmd,
501
+ }
502
+
503
+
504
+ @dataclass
505
+ class RecommendedLineup:
506
+ """A complete VRAM-aware lineup recommendation (REQ-445)."""
507
+
508
+ hardware: str
509
+ vram_gb: float
510
+ models: list[RecommendedModel]
511
+
512
+ def role_config(self) -> dict[str, str]:
513
+ """Return the role→tag mapping for ``.specsmith/local-models.yml``.
514
+
515
+ Maps the router's three roles to lineup slots:
516
+ ``coding`` → default, ``general`` → general, ``reasoning`` → harder.
517
+ """
518
+ by_role: dict[str, str] = {}
519
+ for rec in self.models:
520
+ # First write wins per role (slots are emitted in priority order).
521
+ by_role.setdefault(rec.role.value, rec.model)
522
+ return by_role
523
+
524
+ def as_dict(self) -> dict[str, object]:
525
+ return {
526
+ "hardware": self.hardware,
527
+ "vram_gb": self.vram_gb,
528
+ "models": [m.as_dict() for m in self.models],
529
+ }
530
+
531
+
532
+ def _tiered_tag(vram_gb: float, *, tag_32b: str, tag_14b: str, tag_7b: str) -> str:
533
+ """Select a dense-model tag for *vram_gb* using the NVIDIA VRAM tiers."""
534
+ if vram_gb >= _TIER_32B_GB:
535
+ return tag_32b
536
+ if vram_gb >= _TIER_14B_GB:
537
+ return tag_14b
538
+ return tag_7b
539
+
540
+
541
+ def recommend_models(vram_gb: float, hardware: str = "") -> RecommendedLineup | None:
542
+ """Recommend a full role lineup for *vram_gb* of VRAM (REQ-445).
543
+
544
+ Returns ``None`` below the minimum tier (``< _TIER_7B_GB``), where local
545
+ inference would be unusably slow. The lineup always follows the supplied
546
+ VRAM: the default/general slots scale with the VRAM tier (7b/14b/32b) while
547
+ the ``fast`` and ``harder`` slots are fixed picks whose fit is reported
548
+ relative to *vram_gb* so the caller can warn about CPU spillover.
549
+ """
550
+ if vram_gb < _TIER_7B_GB:
551
+ return None
552
+
553
+ default_tag = _tiered_tag(vram_gb, tag_32b=_MODEL_32B, tag_14b=_MODEL_14B, tag_7b=_MODEL_7B)
554
+ general_tag = _tiered_tag(vram_gb, tag_32b=_GEN_32B, tag_14b=_GEN_14B, tag_7b=_GEN_7B)
555
+
556
+ specs: list[tuple[str, ModelRole, str, str]] = [
557
+ ("default", ModelRole.coding, default_tag, "Default daily driver — balanced coding model."),
558
+ (
559
+ "fast",
560
+ ModelRole.coding,
561
+ _MODEL_7B,
562
+ "Fast scratch model — quick edits, big context headroom.",
563
+ ),
564
+ (
565
+ "harder",
566
+ ModelRole.reasoning,
567
+ _DEEPSEEK_CODER_V2,
568
+ "Harder C/Python pass — heavier reasoning-capable coder.",
569
+ ),
570
+ ("general", ModelRole.general, general_tag, "General chat / project management."),
571
+ ]
572
+
573
+ models = [
574
+ RecommendedModel(
575
+ slot=slot,
576
+ role=role,
577
+ model=tag,
578
+ footprint_gb=_MODEL_FOOTPRINT_GB.get(tag, 0.0),
579
+ fit=assess_fit(tag, vram_gb),
580
+ summary=summary,
581
+ )
582
+ for slot, role, tag, summary in specs
583
+ ]
584
+ return RecommendedLineup(hardware=hardware or "unknown", vram_gb=vram_gb, models=models)
585
+
586
+
587
+ def recommend_for_hardware() -> RecommendedLineup | None:
588
+ """Detect the host GPU and recommend a VRAM-aware lineup (REQ-445).
589
+
590
+ Mirrors the detection order of :func:`detect_local_models` (Apple Silicon
591
+ first, then NVIDIA) and applies the same VRAM tiering. Returns ``None`` on
592
+ CPU-only machines or when the detected VRAM is below the minimum tier.
593
+ """
594
+ as_gb = _detect_apple_silicon_gb()
595
+ if as_gb is not None:
596
+ return recommend_models(as_gb, hardware=f"apple-silicon-{int(as_gb)}gb")
597
+ nv_gb = _detect_nvidia_vram_gb()
598
+ if nv_gb is not None:
599
+ return recommend_models(nv_gb, hardware=f"nvidia-{int(nv_gb)}gb")
600
+ return None
601
+
602
+
397
603
  def ensure_local_model(model_tag: str) -> bool:
398
604
  """Pull *model_tag* via Ollama if it is not already present.
399
605
 
@@ -426,10 +632,16 @@ def ensure_local_model(model_tag: str) -> bool:
426
632
 
427
633
  __all__ = [
428
634
  "LocalModelInfo",
635
+ "ModelFit",
429
636
  "ModelRole",
637
+ "RecommendedLineup",
638
+ "RecommendedModel",
639
+ "assess_fit",
430
640
  "detect_local_model",
431
641
  "detect_local_models",
432
642
  "ensure_local_model",
433
643
  "load_local_models_config",
644
+ "recommend_for_hardware",
645
+ "recommend_models",
434
646
  "save_local_models_config",
435
647
  ]
@@ -122,6 +122,47 @@ def unregister_project(path: str = ".") -> bool:
122
122
  return True
123
123
 
124
124
 
125
+ def build_warp_mcp_config() -> dict[str, Any]:
126
+ """Build the Warp MCP server config snippet for the governance server.
127
+
128
+ Shared by ``specsmith mcp install-warp`` and the ``warp`` integration
129
+ adapter (REQ-444) so both emit an identical, registry-aware config.
130
+
131
+ Executable detection (in priority order):
132
+ 1. ``specsmith`` / ``specsmith.exe`` on PATH — covers pipx shims and
133
+ system installs.
134
+ 2. ``python -m specsmith`` via the current interpreter — reliable
135
+ fallback for editable dev installs and venvs where the console-script
136
+ wrapper is absent or resolves incorrectly (e.g. some Windows pipx setups).
137
+
138
+ The env vars keep the server starting cleanly when Warp launches it directly:
139
+ ``SPECSMITH_ALLOW_NON_PIPX`` prevents the pipx-enforcement gate from exiting
140
+ before the MCP handshake; ``SPECSMITH_NO_AUTO_UPDATE`` / ``SPECSMITH_PYPI_CHECKED``
141
+ suppress startup network calls so the server responds immediately.
142
+ """
143
+ import shutil
144
+
145
+ server_env = {
146
+ "SPECSMITH_ALLOW_NON_PIPX": "1",
147
+ "SPECSMITH_NO_AUTO_UPDATE": "1",
148
+ "SPECSMITH_PYPI_CHECKED": "1",
149
+ }
150
+ specsmith_exe = shutil.which("specsmith") or shutil.which("specsmith.exe")
151
+ if specsmith_exe:
152
+ cmd = specsmith_exe
153
+ args: list[str] = ["mcp", "serve"]
154
+ else:
155
+ cmd = sys.executable
156
+ args = ["-m", "specsmith", "mcp", "serve"]
157
+ return {
158
+ "specsmith-governance": {
159
+ "command": cmd,
160
+ "args": args,
161
+ "env": server_env,
162
+ }
163
+ }
164
+
165
+
125
166
  _TOOLS: list[dict[str, Any]] = [
126
167
  {
127
168
  "name": "governance_project_list",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.19.2.dev738
3
+ Version: 0.19.2.dev739
4
4
  Summary: AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider.
5
5
  Author: Layer1Labs Silicon, Inc.
6
6
  License-Expression: MIT