specsmith 0.12.0.dev494__tar.gz → 0.12.0.dev497__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 (294) hide show
  1. {specsmith-0.12.0.dev494/src/specsmith.egg-info → specsmith-0.12.0.dev497}/PKG-INFO +1 -1
  2. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/pyproject.toml +1 -1
  3. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/auditor.py +65 -4
  4. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/cli.py +186 -56
  5. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/config.py +66 -0
  6. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/importer.py +66 -0
  7. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/mcp_server.py +113 -15
  8. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/scaffolder.py +169 -0
  9. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/__init__.py +17 -0
  10. specsmith-0.12.0.dev497/src/specsmith/skills/ai_agents.py +1439 -0
  11. specsmith-0.12.0.dev497/src/specsmith/skills/data_engineering.py +960 -0
  12. specsmith-0.12.0.dev497/src/specsmith/skills/platform_engineering.py +1391 -0
  13. specsmith-0.12.0.dev497/src/specsmith/skills/software_engineering.py +1291 -0
  14. specsmith-0.12.0.dev497/src/specsmith/skills/web_backend.py +1427 -0
  15. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/tools.py +123 -0
  16. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497/src/specsmith.egg-info}/PKG-INFO +1 -1
  17. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith.egg-info/SOURCES.txt +5 -0
  18. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_auditor.py +89 -0
  19. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_mcp_server.py +99 -0
  20. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/LICENSE +0 -0
  21. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/README.md +0 -0
  22. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/setup.cfg +0 -0
  23. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/__init__.py +0 -0
  24. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/belief.py +0 -0
  25. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/certainty.py +0 -0
  26. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/failure_graph.py +0 -0
  27. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/py.typed +0 -0
  28. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/recovery.py +0 -0
  29. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/session.py +0 -0
  30. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/stress_tester.py +0 -0
  31. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/epistemic/trace.py +0 -0
  32. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/__init__.py +0 -0
  33. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/__main__.py +0 -0
  34. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/__init__.py +0 -0
  35. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/broker.py +0 -0
  36. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/chat_runner.py +0 -0
  37. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/cleanup.py +0 -0
  38. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/context_seed.py +0 -0
  39. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/core.py +0 -0
  40. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/__init__.py +0 -0
  41. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/_status.py +0 -0
  42. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/dag.py +0 -0
  43. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
  44. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/events.py +0 -0
  45. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/dispatch/result.py +0 -0
  46. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/endpoints.py +0 -0
  47. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/events.py +0 -0
  48. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/execution_profiles.py +0 -0
  49. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/fallback.py +0 -0
  50. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/hf_leaderboard.py +0 -0
  51. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/hf_sync.py +0 -0
  52. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/indexer.py +0 -0
  53. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/llm_client.py +0 -0
  54. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/mcp.py +0 -0
  55. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/memory.py +0 -0
  56. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/model_intelligence.py +0 -0
  57. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/model_profiles.py +0 -0
  58. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/orchestrator.py +0 -0
  59. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/permissions.py +0 -0
  60. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/profiles.py +0 -0
  61. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/provider_registry.py +0 -0
  62. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/repl.py +0 -0
  63. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/router.py +0 -0
  64. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/rules.py +0 -0
  65. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/runner.py +0 -0
  66. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/safety.py +0 -0
  67. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/spawner.py +0 -0
  68. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/suggester.py +0 -0
  69. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/teams.py +0 -0
  70. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/tools.py +0 -0
  71. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/verifier.py +0 -0
  72. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/agent/voice.py +0 -0
  73. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/architect.py +0 -0
  74. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/auth.py +0 -0
  75. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/block_export.py +0 -0
  76. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/channel.py +0 -0
  77. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/ci_manager.py +0 -0
  78. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/commands/__init__.py +0 -0
  79. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/commands/intelligence.py +0 -0
  80. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/__init__.py +0 -0
  81. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/_compat.py +0 -0
  82. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/checker.py +0 -0
  83. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/evidence.py +0 -0
  84. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/regulations.py +0 -0
  85. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compliance/reporter.py +0 -0
  86. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/compressor.py +0 -0
  87. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/console_utils.py +0 -0
  88. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/context_orchestrator.py +0 -0
  89. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/context_window.py +0 -0
  90. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/credit_analyzer.py +0 -0
  91. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/credits.py +0 -0
  92. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/__init__.py +0 -0
  93. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/base.py +0 -0
  94. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/citations.py +0 -0
  95. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/fpd.py +0 -0
  96. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/odp.py +0 -0
  97. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/patentsview.py +0 -0
  98. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/pfw.py +0 -0
  99. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/ppubs.py +0 -0
  100. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/datasources/ptab.py +0 -0
  101. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/differ.py +0 -0
  102. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/doctor.py +0 -0
  103. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/drive.py +0 -0
  104. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/editor.py +0 -0
  105. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/__init__.py +0 -0
  106. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/belief.py +0 -0
  107. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/certainty.py +0 -0
  108. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/failure_graph.py +0 -0
  109. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/recovery.py +0 -0
  110. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/epistemic/stress_tester.py +0 -0
  111. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/esdb/__init__.py +0 -0
  112. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/esdb/bridge.py +0 -0
  113. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/eval/__init__.py +0 -0
  114. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/eval/builtins.py +0 -0
  115. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/eval/runner.py +0 -0
  116. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/executor.py +0 -0
  117. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/exporter.py +0 -0
  118. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/governance_logic.py +0 -0
  119. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/governance_store.py +0 -0
  120. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/governance_yaml.py +0 -0
  121. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/__init__.py +0 -0
  122. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/app.py +0 -0
  123. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/main_window.py +0 -0
  124. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/session_tab.py +0 -0
  125. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/theme.py +0 -0
  126. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/__init__.py +0 -0
  127. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/chat_view.py +0 -0
  128. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/input_bar.py +0 -0
  129. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  130. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/token_meter.py +0 -0
  131. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  132. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/widgets/update_checker.py +0 -0
  133. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/gui/worker.py +0 -0
  134. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/history_search.py +0 -0
  135. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/instinct.py +0 -0
  136. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/__init__.py +0 -0
  137. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/agent_skill.py +0 -0
  138. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/aider.py +0 -0
  139. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/base.py +0 -0
  140. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/claude_code.py +0 -0
  141. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/codity.py +0 -0
  142. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/copilot.py +0 -0
  143. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/cursor.py +0 -0
  144. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/gemini.py +0 -0
  145. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/integrations/windsurf.py +0 -0
  146. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/issue_reporter.py +0 -0
  147. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/languages.py +0 -0
  148. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/ledger.py +0 -0
  149. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/mcp_generator.py +0 -0
  150. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/__init__.py +0 -0
  151. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
  152. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m002_agents_slim.py +0 -0
  153. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m003_compliance_init.py +0 -0
  154. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
  155. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
  156. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/m006_session_governance.py +0 -0
  157. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/migrations/runner.py +0 -0
  158. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/ollama_cmds.py +0 -0
  159. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/patent.py +0 -0
  160. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/paths.py +0 -0
  161. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/phase.py +0 -0
  162. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/plugins.py +0 -0
  163. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/profiles.py +0 -0
  164. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/rate_limits.py +0 -0
  165. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/releaser.py +0 -0
  166. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/requirements.py +0 -0
  167. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/requirements_parser.py +0 -0
  168. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/retrieval.py +0 -0
  169. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/safe_write.py +0 -0
  170. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/serve.py +0 -0
  171. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/session.py +0 -0
  172. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/session_init.py +0 -0
  173. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/session_store.py +0 -0
  174. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/cloud.py +0 -0
  175. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/corporate.py +0 -0
  176. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/cross_platform.py +0 -0
  177. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/devops.py +0 -0
  178. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/docs.py +0 -0
  179. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/embedded.py +0 -0
  180. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/governance.py +0 -0
  181. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/hardware.py +0 -0
  182. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/mobile.py +0 -0
  183. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/productivity.py +0 -0
  184. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/specsmith_skills.py +0 -0
  185. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills/ssh.py +0 -0
  186. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/skills_builder.py +0 -0
  187. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/sync.py +0 -0
  188. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/agents.md.j2 +0 -0
  189. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  190. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  191. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  192. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  193. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  194. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  195. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  196. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/community/security.md.j2 +0 -0
  197. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  198. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  199. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  200. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  201. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  202. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/editorconfig.j2 +0 -0
  203. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/gitattributes.j2 +0 -0
  204. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/gitignore.j2 +0 -0
  205. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/go/go.mod.j2 +0 -0
  206. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/go/main.go.j2 +0 -0
  207. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  208. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  209. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  210. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  211. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  212. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  213. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  214. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  215. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  216. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  217. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  218. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/js/package.json.j2 +0 -0
  219. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/ledger.md.j2 +0 -0
  220. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/python/cli.py.j2 +0 -0
  221. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/python/init.py.j2 +0 -0
  222. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  223. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/readme.md.j2 +0 -0
  224. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  225. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  226. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  227. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  228. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  229. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  230. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  231. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  232. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  233. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/tool_installer.py +0 -0
  234. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/toolrules.py +0 -0
  235. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/trace.py +0 -0
  236. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/updater.py +0 -0
  237. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/upgrader.py +0 -0
  238. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/validator.py +0 -0
  239. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs/__init__.py +0 -0
  240. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs/base.py +0 -0
  241. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs/bitbucket.py +0 -0
  242. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs/github.py +0 -0
  243. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs/gitlab.py +0 -0
  244. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/vcs_commands.py +0 -0
  245. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/wireframes.py +0 -0
  246. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith/workspace.py +0 -0
  247. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith.egg-info/dependency_links.txt +0 -0
  248. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith.egg-info/entry_points.txt +0 -0
  249. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith.egg-info/requires.txt +0 -0
  250. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/src/specsmith.egg-info/top_level.txt +0 -0
  251. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_CMD_001.py +0 -0
  252. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_agent_profiles.py +0 -0
  253. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_agent_run_feedback.py +0 -0
  254. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_agent_runner_ready.py +0 -0
  255. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_ai_client.py +0 -0
  256. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_ai_intelligence.py +0 -0
  257. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_channel.py +0 -0
  258. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_chat_diff_decision.py +0 -0
  259. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_chat_runner_openai_compat.py +0 -0
  260. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_chat_stdin_protocol.py +0 -0
  261. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_cli.py +0 -0
  262. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_cli_workflows_history_drive.py +0 -0
  263. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_compliance.py +0 -0
  264. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_compressor.py +0 -0
  265. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_dispatch.py +0 -0
  266. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_e2e_nexus.py +0 -0
  267. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_endpoints_cli.py +0 -0
  268. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_endpoints_store.py +0 -0
  269. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_epistemic.py +0 -0
  270. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_fallback_chain.py +0 -0
  271. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_importer.py +0 -0
  272. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_integrations.py +0 -0
  273. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_integrations_codity.py +0 -0
  274. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_intelligence.py +0 -0
  275. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_issue_reporter.py +0 -0
  276. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_mcp_client.py +0 -0
  277. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_new_modules.py +0 -0
  278. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_nexus.py +0 -0
  279. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_permissions.py +0 -0
  280. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_phase1_4_new.py +0 -0
  281. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_phase34_completion.py +0 -0
  282. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_rate_limits.py +0 -0
  283. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_req_248_262.py +0 -0
  284. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_req_358_359.py +0 -0
  285. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_scaffolder.py +0 -0
  286. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_skill_marketplace.py +0 -0
  287. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_skills_mcp.py +0 -0
  288. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_smoke.py +0 -0
  289. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_suggester.py +0 -0
  290. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_tools.py +0 -0
  291. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_validator.py +0 -0
  292. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_vcs.py +0 -0
  293. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_warp_parity.py +0 -0
  294. {specsmith-0.12.0.dev494 → specsmith-0.12.0.dev497}/tests/test_warp_parity_followup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.12.0.dev494
3
+ Version: 0.12.0.dev497
4
4
  Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
5
5
  Author: BitConcepts
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.12.0.dev494"
7
+ version = "0.12.0.dev497"
8
8
  description = "Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -441,9 +441,11 @@ def check_ledger_health(root: Path) -> list[AuditResult]:
441
441
  )
442
442
  )
443
443
 
444
- # Open TODOs
445
- open_todos = sum(1 for line in lines if "- [ ]" in line)
446
- closed_todos = sum(1 for line in lines if "- [x]" in line)
444
+ # Open TODOs — only count lines where the checklist marker is at the
445
+ # start of the trimmed line, not prose references such as:
446
+ # "- TODO closure: all 109 - [ ] items changed to - [x]"
447
+ open_todos = sum(1 for line in lines if line.lstrip().startswith("- [ ]"))
448
+ closed_todos = sum(1 for line in lines if line.lstrip().startswith("- [x]"))
447
449
  if open_todos > 20:
448
450
  results.append(
449
451
  AuditResult(
@@ -715,8 +717,53 @@ def check_tool_configuration(root: Path) -> list[AuditResult]:
715
717
  return results
716
718
 
717
719
 
720
+ # Types that require explicit configuration and cannot be reliably inferred
721
+ # from file-extension counts alone. When a project declares one of these,
722
+ # auto-detection is skipped so that auxiliary tooling languages (e.g. Python
723
+ # verification scripts in an FPGA project) do not produce a false-positive
724
+ # mismatch. See GitHub issue #194.
725
+ _EXPLICIT_ONLY_TYPES: frozenset[str] = frozenset(
726
+ [
727
+ # Hardware / vendor-specific types that cannot be auto-detected from
728
+ # file extensions (Python/C tooling dominates file counts).
729
+ "fpga-rtl",
730
+ "fpga-rtl-amd",
731
+ "fpga-rtl-intel",
732
+ "fpga-rtl-lattice",
733
+ "mixed-fpga-embedded",
734
+ "mixed-fpga-firmware",
735
+ "embedded-hardware",
736
+ "pcb-hardware",
737
+ "yocto-bsp",
738
+ # Infrastructure types where auxiliary Python/JS glue code dominates
739
+ # and a generic detection pass would misclassify the primary type.
740
+ "kubernetes-operator",
741
+ "streaming-pipeline",
742
+ "serverless",
743
+ # AI / agent types: an LLM app is indistinguishable from a regular
744
+ # Python library unless dependency signals are present. Suppress
745
+ # false-positive mismatches when the type is set explicitly.
746
+ "agent-orchestration",
747
+ "mcp-server",
748
+ "rag-pipeline",
749
+ "mlops-platform",
750
+ # Game engines: Unity / Godot projects often have Python tooling alongside.
751
+ "game-unity",
752
+ "game-godot",
753
+ # Data warehouse: dbt + SQL projects have no primary-language file bias.
754
+ "data-warehouse",
755
+ ]
756
+ )
757
+
758
+
718
759
  def check_type_mismatch(root: Path) -> list[AuditResult]:
719
- """Check if scaffold.yml type matches actual detected project type."""
760
+ """Check if scaffold.yml type matches actual detected project type.
761
+
762
+ For hardware / vendor-specific types that cannot be auto-detected from
763
+ file-extension counts (see ``_EXPLICIT_ONLY_TYPES``), the detection step
764
+ is skipped entirely so that auxiliary languages (e.g. Python scripts in an
765
+ FPGA project) never produce a false-positive mismatch.
766
+ """
720
767
  results: list[AuditResult] = []
721
768
  scaffold_path = root / "scaffold.yml"
722
769
  if not scaffold_path.exists():
@@ -731,6 +778,20 @@ def check_type_mismatch(root: Path) -> list[AuditResult]:
731
778
  with open(scaffold_path) as f:
732
779
  raw = yaml.safe_load(f)
733
780
  config = ProjectConfig(**raw)
781
+
782
+ # Skip auto-detection for types that must be specified explicitly.
783
+ if config.type in _EXPLICIT_ONLY_TYPES:
784
+ results.append(
785
+ AuditResult(
786
+ name="type-mismatch",
787
+ passed=True,
788
+ message=(
789
+ f"Project type {config.type} is explicitly set; auto-detection skipped"
790
+ ),
791
+ )
792
+ )
793
+ return results
794
+
734
795
  detected = detect_project(root)
735
796
  if detected.inferred_type and detected.inferred_type != config.type:
736
797
  results.append(
@@ -350,6 +350,16 @@ def init(config_path: str | None, output_dir: str, no_git: bool, guided: bool) -
350
350
 
351
351
  write_phase(target, "inception")
352
352
 
353
+ # Auto-register with the MCP governance server (best-effort, never blocks)
354
+ with contextlib.suppress(Exception):
355
+ from specsmith.mcp_server import register_project
356
+
357
+ if register_project(str(target)):
358
+ console.print(
359
+ " [dim]\u2713 Registered with MCP server "
360
+ "([bold]specsmith mcp projects[/bold] to view)[/dim]"
361
+ )
362
+
353
363
 
354
364
  def _load_config_with_inheritance(config_path: str) -> dict[str, object]:
355
365
  """Load scaffold.yml, merging parent config if `extends` is set."""
@@ -1746,6 +1756,16 @@ def import_project(
1746
1756
  console.print(f"\n[bold green]Done.[/bold green] {len(created)} governance files generated.")
1747
1757
  console.print("Governance files generated. Review project configuration.")
1748
1758
 
1759
+ # Auto-register with the MCP governance server (best-effort, never blocks)
1760
+ with contextlib.suppress(Exception):
1761
+ from specsmith.mcp_server import register_project
1762
+
1763
+ if register_project(str(root)):
1764
+ console.print(
1765
+ " [dim]\u2713 Registered with MCP server "
1766
+ "([bold]specsmith mcp projects[/bold] to view)[/dim]"
1767
+ )
1768
+
1749
1769
 
1750
1770
  def _run_guided_architecture(cfg: ProjectConfig, target: Path) -> list[Path]:
1751
1771
  """Run interactive architecture definition and generate REQ/TEST stubs."""
@@ -9049,46 +9069,44 @@ def mcp_list_cmd(project_dir: str, as_json: bool) -> None:
9049
9069
 
9050
9070
 
9051
9071
  @mcp_group.command(name="serve")
9052
- @click.option("--project-dir", type=click.Path(), default=".", show_default=True)
9072
+ @click.option(
9073
+ "--project-dir",
9074
+ type=click.Path(),
9075
+ default=None,
9076
+ help=(
9077
+ "Set this path as the *primary* project (first slot / default for tool calls "
9078
+ "that omit project_dir). Omit to use the registry automatically."
9079
+ ),
9080
+ )
9053
9081
  @click.option(
9054
9082
  "--project-dirs",
9055
9083
  default="",
9056
9084
  help=(
9057
- "Additional project directories to register (comma-separated absolute paths). "
9058
- "All registered projects are accessible to any tool call via their "
9059
- "absolute path as the project_dir argument."
9085
+ "Extra project directories to add on top of the registry (comma-separated absolute paths)."
9060
9086
  ),
9061
9087
  )
9062
- def mcp_serve_cmd(project_dir: str, project_dirs: str) -> None:
9088
+ def mcp_serve_cmd(project_dir: str | None, project_dirs: str) -> None:
9063
9089
  """Start the native governance MCP stdio server (REQ-363).
9064
9090
 
9065
9091
  Implements MCP 2024-11-05 over stdin/stdout (JSON-RPC 2.0).
9066
- Exposes seven governance tools to any MCP client:
9092
+ Exposes seven governance tools to any MCP client.
9067
9093
 
9068
9094
  \b
9069
- governance_project_list List all registered projects
9070
- governance_audit Run governance audit
9071
- governance_checkpoint Emit GOVERNANCE ANCHOR JSON
9072
- governance_preflight Preflight a change intent
9073
- governance_phase Current AEE phase + readiness %
9074
- governance_req_list List all requirements
9075
- governance_trace_seal Seal a milestone/decision
9095
+ Recommended Warp config (set once, never touch again)::
9096
+
9097
+ {"specsmith-governance": {"command": "specsmith", "args": ["mcp", "serve"]}}
9076
9098
 
9077
9099
  \b
9078
- Single-project Warp config (Settings Agents MCP servers)::
9100
+ Then register each project once from inside that project::
9079
9101
 
9080
- {"specsmith-governance": {"command": "specsmith",
9081
- "args": ["mcp", "serve", "--project-dir", "/path/to/project"]}}
9102
+ specsmith mcp register
9082
9103
 
9083
9104
  \b
9084
- Multi-project Warp config::
9085
-
9086
- {"specsmith-governance": {"command": "specsmith",
9087
- "args": ["mcp", "serve", "--project-dir", "/path/to/proj1",
9088
- "--project-dirs", "/path/to/proj2,/path/to/proj3"]}}
9105
+ The server reads the registry at startup and serves all registered
9106
+ projects automatically — no config changes needed for new projects.
9089
9107
 
9090
9108
  \b
9091
- Or pass inline to oz (use ``specsmith mcp install-warp`` for the full snippet)::
9109
+ Or pass inline to oz (use ``specsmith mcp install-warp`` for the snippet)::
9092
9110
 
9093
9111
  oz agent run --mcp "$(specsmith mcp install-warp --json)" --prompt "..."
9094
9112
  """
@@ -9099,42 +9117,52 @@ def mcp_serve_cmd(project_dir: str, project_dirs: str) -> None:
9099
9117
 
9100
9118
 
9101
9119
  @mcp_group.command(name="install-warp")
9102
- @click.option("--project-dir", type=click.Path(), default=".", show_default=True)
9103
- @click.option(
9104
- "--project-dirs",
9105
- default="",
9106
- help="Additional project dirs (comma-separated) to include in the multi-project config.",
9107
- )
9108
9120
  @click.option("--json", "as_json", is_flag=True, default=False, help="Emit JSON config only.")
9109
- def mcp_install_warp_cmd(project_dir: str, project_dirs: str, as_json: bool) -> None:
9121
+ def mcp_install_warp_cmd(as_json: bool) -> None:
9110
9122
  """Print the Warp MCP config snippet for the governance server (REQ-363).
9111
9123
 
9124
+ Generates a minimal, registry-aware config — paste it into Warp once
9125
+ and never change it again. Register new projects with::
9126
+
9127
+ specsmith mcp register # in the project directory
9128
+
9112
9129
  Copy the output into Warp Settings → Agents → MCP servers, or pass it
9113
9130
  to ``oz agent run --mcp '<json>'`` for a one-off cloud agent run.
9114
-
9115
- For multi-project setups pass ``--project-dirs`` with comma-separated
9116
- absolute paths; one server instance will serve all projects.
9117
9131
  """
9118
9132
  import json as _json
9119
9133
  import shutil
9120
9134
  import sys
9121
9135
 
9122
- # Resolve the specsmith CLI executable: prefer the one on PATH, then
9123
- # fall back to deriving it from the current interpreter (dev installs).
9124
- specsmith_exe = shutil.which("specsmith") or str(
9125
- Path(sys.executable).parent / ("specsmith.exe" if sys.platform == "win32" else "specsmith")
9126
- )
9127
- default_dir = str(Path(project_dir).resolve())
9128
- args: list[str] = ["mcp", "serve", "--project-dir", default_dir]
9136
+ # Env vars the server needs regardless of how it is invoked.
9137
+ # SPECSMITH_ALLOW_NON_PIPX=1 — prevents the pipx-enforcement gate from
9138
+ # exiting before the MCP handshake when Warp starts the server directly.
9139
+ # SPECSMITH_NO_AUTO_UPDATE / SPECSMITH_PYPI_CHECKED — suppress network
9140
+ # calls on startup so the server responds immediately.
9141
+ server_env = {
9142
+ "SPECSMITH_ALLOW_NON_PIPX": "1",
9143
+ "SPECSMITH_NO_AUTO_UPDATE": "1",
9144
+ "SPECSMITH_PYPI_CHECKED": "1",
9145
+ }
9129
9146
 
9130
- extra_dirs = [p.strip() for p in project_dirs.split(",") if p.strip()] if project_dirs else []
9131
- if extra_dirs:
9132
- args += ["--project-dirs", ",".join(extra_dirs)]
9147
+ # Executable detection strategy (in priority order):
9148
+ # 1. specsmith (or specsmith.exe) on PATH — covers pipx shims and system installs.
9149
+ # 2. python -m specsmith via the current interpreter — reliable fallback
9150
+ # for editable dev installs and venvs where the console script wrapper
9151
+ # is absent or resolves incorrectly (e.g. some Windows pipx setups).
9152
+ specsmith_exe = shutil.which("specsmith") or shutil.which("specsmith.exe")
9153
+ if specsmith_exe:
9154
+ cmd = specsmith_exe
9155
+ args: list[str] = ["mcp", "serve"]
9156
+ else:
9157
+ # Fall back to `python -m specsmith` using the current interpreter.
9158
+ cmd = sys.executable
9159
+ args = ["-m", "specsmith", "mcp", "serve"]
9133
9160
 
9134
9161
  config = {
9135
9162
  "specsmith-governance": {
9136
- "command": specsmith_exe,
9163
+ "command": cmd,
9137
9164
  "args": args,
9165
+ "env": server_env,
9138
9166
  }
9139
9167
  }
9140
9168
 
@@ -9148,22 +9176,124 @@ def mcp_install_warp_cmd(project_dir: str, project_dirs: str, as_json: bool) ->
9148
9176
  "or pass inline to [bold]oz agent run --mcp '<json>'[/bold]:\n"
9149
9177
  )
9150
9178
  console.print(_json.dumps(config, indent=2))
9151
- if extra_dirs:
9152
- console.print(
9153
- f"\n[dim]Serving {1 + len(extra_dirs)} projects. "
9154
- "Call [bold]governance_project_list[/bold] to see all registered paths,\n"
9155
- "then pass any path as [bold]project_dir[/bold] to target a specific project.[/dim]"
9156
- )
9179
+ console.print(
9180
+ "\n[dim][bold]One-time setup[/bold] — paste this config into Warp once," # noqa: E501
9181
+ " then never touch it again.\n"
9182
+ "\nTo add each project, run this inside the project directory:\n"
9183
+ " [bold]specsmith mcp register[/bold]\n"
9184
+ "\nThe server reads [bold]~/.specsmith/mcp-projects.json[/bold] at startup\n"
9185
+ "and serves all registered projects automatically.\n"
9186
+ "\nView registered projects: [bold]specsmith mcp projects[/bold]\n"
9187
+ "\nVerify server: specsmith mcp serve (then send an initialize message).[/dim]"
9188
+ )
9189
+
9190
+
9191
+ @mcp_group.command(name="register")
9192
+ @click.argument("path", default=".", required=False)
9193
+ def mcp_register_cmd(path: str) -> None:
9194
+ """Register a project directory with the MCP server registry.
9195
+
9196
+ Run once inside a project directory to add it to
9197
+ ``~/.specsmith/mcp-projects.json``. The next ``specsmith mcp serve``
9198
+ invocation will automatically include it — no Warp config changes needed.
9199
+
9200
+ \b
9201
+ Examples::
9202
+
9203
+ specsmith mcp register # register current directory
9204
+ specsmith mcp register /path/to/myproject
9205
+ """
9206
+ from specsmith.mcp_server import register_project
9207
+
9208
+ root = Path(path).resolve()
9209
+ if not root.exists():
9210
+ console.print(f"[red]\u2717[/red] Path does not exist: {root}")
9211
+ raise SystemExit(1)
9212
+
9213
+ added = register_project(str(root))
9214
+ if added:
9215
+ console.print(f"[green]\u2713[/green] Registered: [bold]{root}[/bold]")
9216
+ if not (root / ".specsmith").exists():
9217
+ console.print(
9218
+ " [yellow]\u26a0[/yellow] No .specsmith/ found. "
9219
+ "Run [bold]specsmith init[/bold] or [bold]specsmith import[/bold] first."
9220
+ )
9157
9221
  else:
9222
+ console.print(f"[dim]Already registered: {root}[/dim]")
9223
+ console.print(
9224
+ " [dim]specsmith mcp projects ← view all registered[/dim]\n"
9225
+ " [dim]specsmith mcp serve ← start the server[/dim]"
9226
+ )
9227
+
9228
+
9229
+ @mcp_group.command(name="unregister")
9230
+ @click.argument("path", default=".", required=False)
9231
+ def mcp_unregister_cmd(path: str) -> None:
9232
+ """Remove a project directory from the MCP server registry.
9233
+
9234
+ \b
9235
+ Examples::
9236
+
9237
+ specsmith mcp unregister # unregister current directory
9238
+ specsmith mcp unregister /path/to/myproject
9239
+ """
9240
+ from specsmith.mcp_server import unregister_project
9241
+
9242
+ root = Path(path).resolve()
9243
+ removed = unregister_project(str(root))
9244
+ if removed:
9245
+ console.print(f"[green]\u2713[/green] Unregistered: [bold]{root}[/bold]")
9246
+ else:
9247
+ console.print(f"[yellow]Not registered: {root}[/yellow]")
9248
+
9249
+
9250
+ @mcp_group.command(name="projects")
9251
+ @click.option("--json", "as_json", is_flag=True, default=False, help="Emit as JSON.")
9252
+ def mcp_projects_cmd(as_json: bool) -> None:
9253
+ """List all projects registered with the MCP server.
9254
+
9255
+ Shows each registered project path and whether it still exists on disk.
9256
+ The first entry is the default (used when a tool call omits project_dir).
9257
+ """
9258
+ import json as _json
9259
+ import os
9260
+
9261
+ from specsmith.mcp_server import _registry_file, read_registry
9262
+
9263
+ projects = read_registry()
9264
+ reg_path = _registry_file()
9265
+
9266
+ if as_json:
9267
+ entries = [
9268
+ {"path": p, "exists": Path(p).exists(), "is_default": i == 0}
9269
+ for i, p in enumerate(projects)
9270
+ ]
9271
+ click.echo(_json.dumps({"registry": str(reg_path), "projects": entries}, indent=2))
9272
+ return
9273
+
9274
+ if not projects:
9275
+ console.print("[yellow]No projects registered.[/yellow]")
9158
9276
  console.print(
9159
- "\n[dim]After adding, Warp/Oz can call governance_project_list, "
9160
- "governance_audit, governance_preflight,\n"
9161
- "governance_checkpoint, governance_phase, governance_req_list, and\n"
9162
- "governance_trace_seal as structured MCP tool calls.\n"
9163
- "\nFor multiple projects add --project-dirs /path/a,/path/b to serve them "
9164
- "all from one server instance.\n"
9165
- "\nVerify with: specsmith mcp serve (then send an initialize message).[/dim]"
9277
+ "[dim]Run [bold]specsmith mcp register[/bold] inside a project to add it.[/dim]"
9166
9278
  )
9279
+ return
9280
+
9281
+ console.print(
9282
+ f"[bold]Registered MCP projects[/bold] ({len(projects)}) [dim]{reg_path}[/dim]\n"
9283
+ )
9284
+ for i, p in enumerate(projects):
9285
+ exists = Path(p).exists()
9286
+ default_tag = " [bold cyan][default][/bold cyan]" if i == 0 else ""
9287
+ health = "[green]\u2713 exists[/green]" if exists else "[red]\u2717 not found[/red]"
9288
+ # Abbreviate long paths using ~ for home
9289
+ display = p.replace(os.path.expanduser("~"), "~")
9290
+ console.print(f" {health} {display}{default_tag}")
9291
+
9292
+ console.print(
9293
+ "\n[dim] specsmith mcp register [path] ← add a project"
9294
+ "\n specsmith mcp unregister [path] ← remove a project"
9295
+ "\n specsmith mcp serve ← start the server[/dim]"
9296
+ )
9167
9297
 
9168
9298
 
9169
9299
  main.add_command(mcp_group)
@@ -74,6 +74,28 @@ class ProjectType(str, Enum):
74
74
  SVELTEKIT_APP = "sveltekit-app" # SvelteKit app
75
75
  REMIX_APP = "remix-app" # Remix full-stack React app
76
76
  ASTRO_SITE = "astro-site" # Astro static/SSR site
77
+ # AI / LLM / Agents
78
+ LLM_APP = "llm-app" # LLM-powered app (LangChain / LlamaIndex / custom SDK)
79
+ AGENT_ORCHESTRATION = "agent-orchestration" # Multi-agent system (AutoGen/CrewAI/LangGraph)
80
+ MCP_SERVER = "mcp-server" # Model Context Protocol server
81
+ RAG_PIPELINE = "rag-pipeline" # RAG + embedding pipeline
82
+ MLOPS_PLATFORM = "mlops-platform" # MLOps platform (MLflow / BentoML / Ray Serve)
83
+ # JVM
84
+ JAVA_SPRING = "java-spring" # Spring Boot application
85
+ JAVA_LIBRARY = "java-library" # Java library / SDK
86
+ # Cloud / Infrastructure
87
+ SERVERLESS = "serverless" # FaaS (Lambda / GCP Functions / Cloudflare Workers)
88
+ KUBERNETES_OPERATOR = "kubernetes-operator" # K8s controller / operator
89
+ STREAMING_PIPELINE = "streaming-pipeline" # Kafka / Flink / Beam / Spark Streaming
90
+ DATA_WAREHOUSE = "data-warehouse" # dbt / Snowflake / BigQuery / Redshift
91
+ # Game development
92
+ GAME_UNITY = "game-unity" # Unity game project
93
+ GAME_GODOT = "game-godot" # Godot game project
94
+ # Web3 / blockchain
95
+ SMART_CONTRACT = "smart-contract" # Solidity / EVM smart contracts
96
+ # Desktop
97
+ DESKTOP_ELECTRON = "desktop-electron" # Electron desktop app
98
+ DESKTOP_TAURI = "desktop-tauri" # Tauri desktop app (Rust + WebView)
77
99
 
78
100
 
79
101
  class Platform(str, Enum):
@@ -548,6 +570,28 @@ _TYPE_LABELS: dict[str, str] = {
548
570
  ProjectType.SVELTEKIT_APP: "SvelteKit application",
549
571
  ProjectType.REMIX_APP: "Remix application (React + full-stack)",
550
572
  ProjectType.ASTRO_SITE: "Astro site (static / SSR)",
573
+ # AI / LLM / Agents
574
+ ProjectType.LLM_APP: "LLM-powered application (LangChain / LlamaIndex / custom)",
575
+ ProjectType.AGENT_ORCHESTRATION: "Multi-agent orchestration (AutoGen / CrewAI / LangGraph)",
576
+ ProjectType.MCP_SERVER: "MCP server (Model Context Protocol)",
577
+ ProjectType.RAG_PIPELINE: "RAG / embedding pipeline",
578
+ ProjectType.MLOPS_PLATFORM: "MLOps platform (MLflow / BentoML / Ray Serve)",
579
+ # JVM
580
+ ProjectType.JAVA_SPRING: "Java Spring Boot application",
581
+ ProjectType.JAVA_LIBRARY: "Java library / SDK",
582
+ # Cloud / Infrastructure
583
+ ProjectType.SERVERLESS: "Serverless / FaaS (Lambda / GCP Functions / Cloudflare Workers)",
584
+ ProjectType.KUBERNETES_OPERATOR: "Kubernetes operator / controller",
585
+ ProjectType.STREAMING_PIPELINE: "Streaming data pipeline (Kafka / Flink / Beam)",
586
+ ProjectType.DATA_WAREHOUSE: "Data warehouse (dbt / Snowflake / BigQuery)",
587
+ # Game development
588
+ ProjectType.GAME_UNITY: "Game (Unity)",
589
+ ProjectType.GAME_GODOT: "Game (Godot)",
590
+ # Web3
591
+ ProjectType.SMART_CONTRACT: "Smart contract (Solidity / EVM)",
592
+ # Desktop
593
+ ProjectType.DESKTOP_ELECTRON: "Desktop application (Electron)",
594
+ ProjectType.DESKTOP_TAURI: "Desktop application (Tauri — Rust + WebView)",
551
595
  }
552
596
 
553
597
  _SECTION_REFS: dict[str, str] = {
@@ -584,4 +628,26 @@ _SECTION_REFS: dict[str, str] = {
584
628
  ProjectType.EPISTEMIC_PIPELINE: "17.31",
585
629
  ProjectType.KNOWLEDGE_ENGINEERING: "17.32",
586
630
  ProjectType.AEE_RESEARCH: "17.33",
631
+ # AI / LLM / Agents
632
+ ProjectType.LLM_APP: "17.34",
633
+ ProjectType.AGENT_ORCHESTRATION: "17.35",
634
+ ProjectType.MCP_SERVER: "17.36",
635
+ ProjectType.RAG_PIPELINE: "17.37",
636
+ ProjectType.MLOPS_PLATFORM: "17.38",
637
+ # JVM
638
+ ProjectType.JAVA_SPRING: "17.39",
639
+ ProjectType.JAVA_LIBRARY: "17.40",
640
+ # Cloud / Infrastructure
641
+ ProjectType.SERVERLESS: "17.41",
642
+ ProjectType.KUBERNETES_OPERATOR: "17.42",
643
+ ProjectType.STREAMING_PIPELINE: "17.43",
644
+ ProjectType.DATA_WAREHOUSE: "17.44",
645
+ # Game development
646
+ ProjectType.GAME_UNITY: "17.45",
647
+ ProjectType.GAME_GODOT: "17.46",
648
+ # Web3
649
+ ProjectType.SMART_CONTRACT: "17.47",
650
+ # Desktop
651
+ ProjectType.DESKTOP_ELECTRON: "17.48",
652
+ ProjectType.DESKTOP_TAURI: "17.49",
587
653
  }
@@ -1142,15 +1142,81 @@ def _infer_type(result: DetectionResult) -> ProjectType:
1142
1142
  pkg = result.root / "package.json"
1143
1143
  if pkg.exists():
1144
1144
  content = pkg.read_text(encoding="utf-8")
1145
+ if "electron" in content:
1146
+ return ProjectType.DESKTOP_ELECTRON
1147
+ if "solidity" in content or "hardhat" in content or "ethers" in content:
1148
+ return ProjectType.SMART_CONTRACT
1149
+ if (result.root / "serverless.yml").exists() or (
1150
+ result.root / "wrangler.toml"
1151
+ ).exists():
1152
+ return ProjectType.SERVERLESS
1145
1153
  if "react" in content or "vue" in content or "angular" in content:
1146
1154
  # Check if there's also a server
1147
1155
  if (result.root / "server").exists() or "express" in content:
1148
1156
  return ProjectType.FULLSTACK_JS
1149
1157
  return ProjectType.WEB_FRONTEND
1158
+ # Tauri: has src-tauri/
1159
+ if (result.root / "src-tauri").is_dir():
1160
+ return ProjectType.DESKTOP_TAURI
1150
1161
  return ProjectType.FULLSTACK_JS
1151
1162
 
1163
+ # Data warehouse: dbt_project.yml is a strong signal
1164
+ if (result.root / "dbt_project.yml").exists():
1165
+ return ProjectType.DATA_WAREHOUSE
1166
+ # Kubernetes operator: Go + controllers/ dir
1167
+ if lang == "go" and (result.root / "controllers").is_dir():
1168
+ return ProjectType.KUBERNETES_OPERATOR
1169
+ # Serverless: serverless.yml or SAM template.yaml or wrangler.toml
1170
+ if (
1171
+ (result.root / "serverless.yml").exists()
1172
+ or (result.root / "serverless.yaml").exists()
1173
+ or (result.root / "wrangler.toml").exists()
1174
+ ):
1175
+ return ProjectType.SERVERLESS
1152
1176
  # Python types
1153
1177
  if lang == "python":
1178
+ # Detect AI / agent project types from dependencies before build-system checks
1179
+ _req_text = ""
1180
+ for _rf in (
1181
+ result.root / "requirements.txt",
1182
+ result.root / "pyproject.toml",
1183
+ ):
1184
+ if _rf.exists():
1185
+ _req_text += _rf.read_text(encoding="utf-8", errors="ignore").lower()
1186
+ _mcp_indicators = {"mcp", "model-context-protocol", "fastmcp", "modelcontextprotocol"}
1187
+ _agent_orch_indicators = {"autogen", "crewai", "langgraph", "swarm", "ag2", "pyautogen"}
1188
+ _llm_indicators = {
1189
+ "langchain",
1190
+ "llama-index",
1191
+ "llama_index",
1192
+ "haystack",
1193
+ "openai",
1194
+ "anthropic",
1195
+ "litellm",
1196
+ }
1197
+ _rag_indicators = {
1198
+ "chromadb",
1199
+ "faiss",
1200
+ "pinecone",
1201
+ "weaviate",
1202
+ "qdrant",
1203
+ "pgvector",
1204
+ "llama-index",
1205
+ }
1206
+ _mlops_indicators = {"mlflow", "bentoml", "ray", "kubeflow", "prefect", "airflow"}
1207
+ _streaming_indicators = {"kafka", "flink", "pyflink", "apache-beam", "pyspark"}
1208
+ if any(ind in _req_text for ind in _mcp_indicators):
1209
+ return ProjectType.MCP_SERVER
1210
+ if any(ind in _req_text for ind in _agent_orch_indicators):
1211
+ return ProjectType.AGENT_ORCHESTRATION
1212
+ if any(ind in _req_text for ind in _rag_indicators):
1213
+ return ProjectType.RAG_PIPELINE
1214
+ if any(ind in _req_text for ind in _mlops_indicators):
1215
+ return ProjectType.MLOPS_PLATFORM
1216
+ if any(ind in _req_text for ind in _streaming_indicators):
1217
+ return ProjectType.STREAMING_PIPELINE
1218
+ if any(ind in _req_text for ind in _llm_indicators):
1219
+ return ProjectType.LLM_APP
1154
1220
  if build in ("pyproject", "setuptools"):
1155
1221
  # Check for CLI entry point
1156
1222
  if any("cli.py" in e for e in result.entry_points):