specsmith 0.10.1.dev292__tar.gz → 0.10.1.dev294__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 (234) hide show
  1. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/PKG-INFO +1 -1
  2. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/pyproject.toml +1 -1
  3. specsmith-0.10.1.dev294/src/specsmith/esdb/__init__.py +20 -0
  4. specsmith-0.10.1.dev294/src/specsmith/esdb/bridge.py +137 -0
  5. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/governance_logic.py +18 -0
  6. specsmith-0.10.1.dev294/src/specsmith/mcp_generator.py +210 -0
  7. specsmith-0.10.1.dev294/src/specsmith/skills_builder.py +193 -0
  8. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/PKG-INFO +1 -1
  9. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/SOURCES.txt +5 -0
  10. specsmith-0.10.1.dev294/tests/test_skills_mcp.py +109 -0
  11. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/LICENSE +0 -0
  12. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/README.md +0 -0
  13. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/setup.cfg +0 -0
  14. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/__init__.py +0 -0
  15. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/belief.py +0 -0
  16. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/certainty.py +0 -0
  17. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/failure_graph.py +0 -0
  18. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/py.typed +0 -0
  19. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/recovery.py +0 -0
  20. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/session.py +0 -0
  21. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/stress_tester.py +0 -0
  22. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/epistemic/trace.py +0 -0
  23. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/__init__.py +0 -0
  24. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/__main__.py +0 -0
  25. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/__init__.py +0 -0
  26. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/broker.py +0 -0
  27. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/chat_runner.py +0 -0
  28. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/cleanup.py +0 -0
  29. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/core.py +0 -0
  30. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/endpoints.py +0 -0
  31. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/events.py +0 -0
  32. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/execution_profiles.py +0 -0
  33. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/fallback.py +0 -0
  34. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/hf_sync.py +0 -0
  35. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/indexer.py +0 -0
  36. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/mcp.py +0 -0
  37. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/memory.py +0 -0
  38. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/model_intelligence.py +0 -0
  39. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/orchestrator.py +0 -0
  40. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/permissions.py +0 -0
  41. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/profiles.py +0 -0
  42. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/provider_registry.py +0 -0
  43. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/repl.py +0 -0
  44. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/router.py +0 -0
  45. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/rules.py +0 -0
  46. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/runner.py +0 -0
  47. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/safety.py +0 -0
  48. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/spawner.py +0 -0
  49. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/suggester.py +0 -0
  50. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/teams.py +0 -0
  51. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/tools.py +0 -0
  52. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/verifier.py +0 -0
  53. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/agent/voice.py +0 -0
  54. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/architect.py +0 -0
  55. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/auditor.py +0 -0
  56. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/auth.py +0 -0
  57. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/block_export.py +0 -0
  58. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/cli.py +0 -0
  59. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/commands/__init__.py +0 -0
  60. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/commands/intelligence.py +0 -0
  61. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/compliance.py +0 -0
  62. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/compressor.py +0 -0
  63. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/config.py +0 -0
  64. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/console_utils.py +0 -0
  65. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/context_window.py +0 -0
  66. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/credit_analyzer.py +0 -0
  67. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/credits.py +0 -0
  68. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/__init__.py +0 -0
  69. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/base.py +0 -0
  70. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/citations.py +0 -0
  71. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/fpd.py +0 -0
  72. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/odp.py +0 -0
  73. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/patentsview.py +0 -0
  74. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/pfw.py +0 -0
  75. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/ppubs.py +0 -0
  76. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/datasources/ptab.py +0 -0
  77. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/differ.py +0 -0
  78. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/doctor.py +0 -0
  79. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/drive.py +0 -0
  80. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/editor.py +0 -0
  81. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/__init__.py +0 -0
  82. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/belief.py +0 -0
  83. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/certainty.py +0 -0
  84. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/failure_graph.py +0 -0
  85. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/recovery.py +0 -0
  86. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/epistemic/stress_tester.py +0 -0
  87. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/eval/__init__.py +0 -0
  88. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/eval/builtins.py +0 -0
  89. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/eval/runner.py +0 -0
  90. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/executor.py +0 -0
  91. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/exporter.py +0 -0
  92. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/__init__.py +0 -0
  93. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/app.py +0 -0
  94. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/main_window.py +0 -0
  95. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/session_tab.py +0 -0
  96. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/theme.py +0 -0
  97. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/__init__.py +0 -0
  98. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/chat_view.py +0 -0
  99. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/input_bar.py +0 -0
  100. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  101. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/token_meter.py +0 -0
  102. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  103. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/widgets/update_checker.py +0 -0
  104. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/gui/worker.py +0 -0
  105. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/history_search.py +0 -0
  106. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/importer.py +0 -0
  107. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/instinct.py +0 -0
  108. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/__init__.py +0 -0
  109. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/agent_skill.py +0 -0
  110. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/aider.py +0 -0
  111. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/base.py +0 -0
  112. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/claude_code.py +0 -0
  113. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/copilot.py +0 -0
  114. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/cursor.py +0 -0
  115. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/gemini.py +0 -0
  116. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/integrations/windsurf.py +0 -0
  117. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/languages.py +0 -0
  118. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/ledger.py +0 -0
  119. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/patent.py +0 -0
  120. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/paths.py +0 -0
  121. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/phase.py +0 -0
  122. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/plugins.py +0 -0
  123. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/profiles.py +0 -0
  124. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/rate_limits.py +0 -0
  125. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/releaser.py +0 -0
  126. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/requirements.py +0 -0
  127. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/requirements_parser.py +0 -0
  128. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/retrieval.py +0 -0
  129. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/safe_write.py +0 -0
  130. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/scaffolder.py +0 -0
  131. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/serve.py +0 -0
  132. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/session.py +0 -0
  133. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/session_init.py +0 -0
  134. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/skills.py +0 -0
  135. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/sync.py +0 -0
  136. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/agents.md.j2 +0 -0
  137. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  138. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  139. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  140. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  141. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  142. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  143. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  144. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/community/security.md.j2 +0 -0
  145. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  146. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  147. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  148. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  149. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  150. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/editorconfig.j2 +0 -0
  151. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/gitattributes.j2 +0 -0
  152. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/gitignore.j2 +0 -0
  153. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/go/go.mod.j2 +0 -0
  154. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/go/main.go.j2 +0 -0
  155. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  156. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  157. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  158. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  159. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  160. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  161. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  162. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  163. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  164. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  165. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  166. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/js/package.json.j2 +0 -0
  167. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/ledger.md.j2 +0 -0
  168. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/python/cli.py.j2 +0 -0
  169. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/python/init.py.j2 +0 -0
  170. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  171. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/readme.md.j2 +0 -0
  172. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  173. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  174. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  175. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  176. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  177. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  178. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  179. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  180. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  181. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/tool_installer.py +0 -0
  182. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/toolrules.py +0 -0
  183. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/tools.py +0 -0
  184. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/trace.py +0 -0
  185. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/updater.py +0 -0
  186. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/upgrader.py +0 -0
  187. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/validator.py +0 -0
  188. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs/__init__.py +0 -0
  189. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs/base.py +0 -0
  190. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs/bitbucket.py +0 -0
  191. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs/github.py +0 -0
  192. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs/gitlab.py +0 -0
  193. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/vcs_commands.py +0 -0
  194. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/wireframes.py +0 -0
  195. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith/workspace.py +0 -0
  196. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/dependency_links.txt +0 -0
  197. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/entry_points.txt +0 -0
  198. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/requires.txt +0 -0
  199. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/src/specsmith.egg-info/top_level.txt +0 -0
  200. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_CMD_001.py +0 -0
  201. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_agent_profiles.py +0 -0
  202. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_agent_runner_ready.py +0 -0
  203. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_auditor.py +0 -0
  204. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_chat_diff_decision.py +0 -0
  205. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_chat_runner_openai_compat.py +0 -0
  206. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_chat_stdin_protocol.py +0 -0
  207. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_cli.py +0 -0
  208. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_cli_workflows_history_drive.py +0 -0
  209. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_compliance.py +0 -0
  210. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_compressor.py +0 -0
  211. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_e2e_nexus.py +0 -0
  212. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_endpoints_cli.py +0 -0
  213. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_endpoints_store.py +0 -0
  214. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_epistemic.py +0 -0
  215. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_fallback_chain.py +0 -0
  216. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_importer.py +0 -0
  217. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_integrations.py +0 -0
  218. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_intelligence.py +0 -0
  219. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_mcp_client.py +0 -0
  220. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_new_modules.py +0 -0
  221. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_nexus.py +0 -0
  222. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_permissions.py +0 -0
  223. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_phase1_4_new.py +0 -0
  224. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_phase34_completion.py +0 -0
  225. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_rate_limits.py +0 -0
  226. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_scaffolder.py +0 -0
  227. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_skill_marketplace.py +0 -0
  228. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_smoke.py +0 -0
  229. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_suggester.py +0 -0
  230. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_tools.py +0 -0
  231. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_validator.py +0 -0
  232. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_vcs.py +0 -0
  233. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/tests/test_warp_parity.py +0 -0
  234. {specsmith-0.10.1.dev292 → specsmith-0.10.1.dev294}/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.10.1.dev292
3
+ Version: 0.10.1.dev294
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.10.1.dev292"
7
+ version = "0.10.1.dev294"
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"
@@ -0,0 +1,20 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs / BitConcepts, LLC.
3
+ """ChronoMemory ESDB Python bridge.
4
+
5
+ Provides a pure-Python adapter for the Rust ESDB engine.
6
+ Until PyO3 bindings are compiled, this module exposes the ESDB
7
+ data model as Python dataclasses that mirror the Rust types.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ __all__ = ["EsdbBridge", "is_esdb_available"]
13
+
14
+
15
+ def is_esdb_available(project_dir: str = ".") -> bool:
16
+ """Check if an ESDB exists for the given project."""
17
+ from pathlib import Path
18
+
19
+ esdb_dir = Path(project_dir).resolve() / ".chronomemory"
20
+ return (esdb_dir / "events.wal").is_file()
@@ -0,0 +1,137 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs / BitConcepts, LLC.
3
+ """ESDB bridge — adapter between .specsmith/ JSON and ESDB concepts.
4
+
5
+ This module provides read-only access to the current .specsmith/ flat JSON
6
+ state through ESDB-compatible query interfaces. It allows specsmith's
7
+ governance logic to work with either backend transparently.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ from dataclasses import dataclass, field
14
+ from pathlib import Path
15
+ from typing import Any
16
+
17
+
18
+ @dataclass
19
+ class EsdbRecord:
20
+ """Python mirror of the Rust Record type."""
21
+
22
+ id: str
23
+ kind: str
24
+ status: str = "active"
25
+ confidence: float = 0.7
26
+ label: str = ""
27
+ data: dict[str, Any] = field(default_factory=dict)
28
+ source_ids: list[str] = field(default_factory=list)
29
+
30
+
31
+ @dataclass
32
+ class EsdbStatus:
33
+ """ESDB health status for the REST API."""
34
+
35
+ available: bool
36
+ backend: str # "esdb" or "json-fallback"
37
+ record_count: int = 0
38
+ wal_seq: int = 0
39
+ epoch: int = 0
40
+ chain_valid: bool = True
41
+
42
+ def to_dict(self) -> dict[str, Any]:
43
+ return {
44
+ "available": self.available,
45
+ "backend": self.backend,
46
+ "record_count": self.record_count,
47
+ "wal_seq": self.wal_seq,
48
+ "epoch": self.epoch,
49
+ "chain_valid": self.chain_valid,
50
+ }
51
+
52
+
53
+ class EsdbBridge:
54
+ """Read-only bridge to .specsmith/ JSON files using ESDB semantics.
55
+
56
+ When the Rust ESDB engine is available (via PyO3 bindings), this
57
+ class delegates to it. Otherwise, it reads the flat JSON files
58
+ directly and presents them through an ESDB-compatible interface.
59
+ """
60
+
61
+ def __init__(self, project_dir: str = ".") -> None:
62
+ self.root = Path(project_dir).resolve()
63
+ self._requirements: list[EsdbRecord] | None = None
64
+ self._testcases: list[EsdbRecord] | None = None
65
+
66
+ def status(self) -> EsdbStatus:
67
+ """Return ESDB status."""
68
+ reqs = self._load_requirements()
69
+ tests = self._load_testcases()
70
+ return EsdbStatus(
71
+ available=True,
72
+ backend="json-fallback",
73
+ record_count=len(reqs) + len(tests),
74
+ )
75
+
76
+ def requirements(self) -> list[EsdbRecord]:
77
+ """Load requirements as ESDB records."""
78
+ return self._load_requirements()
79
+
80
+ def testcases(self) -> list[EsdbRecord]:
81
+ """Load test cases as ESDB records."""
82
+ return self._load_testcases()
83
+
84
+ def record_counts(self) -> dict[str, int]:
85
+ """Record counts by kind (for dashboard)."""
86
+ return {
87
+ "requirements": len(self._load_requirements()),
88
+ "testcases": len(self._load_testcases()),
89
+ }
90
+
91
+ def _load_requirements(self) -> list[EsdbRecord]:
92
+ if self._requirements is not None:
93
+ return self._requirements
94
+ path = self.root / ".specsmith" / "requirements.json"
95
+ if not path.is_file():
96
+ self._requirements = []
97
+ return []
98
+ try:
99
+ raw = json.loads(path.read_text(encoding="utf-8"))
100
+ self._requirements = [
101
+ EsdbRecord(
102
+ id=r.get("id", ""),
103
+ kind="requirement",
104
+ label=r.get("title", ""),
105
+ confidence=float(r.get("confidence", 0.7)),
106
+ data=r,
107
+ )
108
+ for r in raw
109
+ if isinstance(r, dict)
110
+ ]
111
+ except (OSError, ValueError):
112
+ self._requirements = []
113
+ return self._requirements
114
+
115
+ def _load_testcases(self) -> list[EsdbRecord]:
116
+ if self._testcases is not None:
117
+ return self._testcases
118
+ path = self.root / ".specsmith" / "testcases.json"
119
+ if not path.is_file():
120
+ self._testcases = []
121
+ return []
122
+ try:
123
+ raw = json.loads(path.read_text(encoding="utf-8"))
124
+ self._testcases = [
125
+ EsdbRecord(
126
+ id=r.get("id", ""),
127
+ kind="testcase",
128
+ label=r.get("title", ""),
129
+ confidence=float(r.get("confidence", 1.0)),
130
+ data=r,
131
+ )
132
+ for r in raw
133
+ if isinstance(r, dict)
134
+ ]
135
+ except (OSError, ValueError):
136
+ self._testcases = []
137
+ return self._testcases
@@ -614,6 +614,24 @@ class GovernanceHTTPServer:
614
614
  except Exception as exc: # noqa: BLE001
615
615
  self._json_err(str(exc), code=500)
616
616
 
617
+ # ── ESDB ──────────────────────────────────────────────
618
+ elif self.path == "/api/esdb/status":
619
+ try:
620
+ from specsmith.esdb.bridge import EsdbBridge
621
+
622
+ bridge = EsdbBridge(project_dir)
623
+ self._json_ok(bridge.status().to_dict())
624
+ except Exception as exc: # noqa: BLE001
625
+ self._json_err(str(exc), code=500)
626
+ elif self.path == "/api/esdb/counts":
627
+ try:
628
+ from specsmith.esdb.bridge import EsdbBridge
629
+
630
+ bridge = EsdbBridge(project_dir)
631
+ self._json_ok(bridge.record_counts())
632
+ except Exception as exc: # noqa: BLE001
633
+ self._json_err(str(exc), code=500)
634
+
617
635
  # ── Datasources ────────────────────────────────────────
618
636
  elif self.path == "/api/datasources":
619
637
  try:
@@ -0,0 +1,210 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs / BitConcepts, LLC.
3
+ """MCP Server Generator — auto-scaffold Model Context Protocol servers.
4
+
5
+ Generates Python MCP servers from natural-language tool descriptions using
6
+ the FastMCP pattern. Each generated server includes a `server.py`,
7
+ `tool_schema.json`, and `README.md`.
8
+
9
+ Usage:
10
+ from specsmith.mcp_generator import generate_mcp_server, list_mcp_servers
11
+ server = generate_mcp_server("Search USPTO patents by keyword")
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import re
18
+ import uuid
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+
24
+ @dataclass
25
+ class MCPServerSpec:
26
+ """Specification for a generated MCP server."""
27
+
28
+ id: str
29
+ name: str
30
+ description: str
31
+ tools: list[MCPToolSpec] = field(default_factory=list)
32
+ transport: str = "stdio" # "stdio" or "http"
33
+ port: int = 8100
34
+
35
+ def to_dict(self) -> dict[str, Any]:
36
+ return {
37
+ "id": self.id,
38
+ "name": self.name,
39
+ "description": self.description,
40
+ "tools": [t.to_dict() for t in self.tools],
41
+ "transport": self.transport,
42
+ "port": self.port,
43
+ }
44
+
45
+
46
+ @dataclass
47
+ class MCPToolSpec:
48
+ """Specification for a single MCP tool."""
49
+
50
+ name: str
51
+ description: str
52
+ input_params: dict[str, str] = field(default_factory=dict)
53
+ output_type: str = "text"
54
+
55
+ def to_dict(self) -> dict[str, Any]:
56
+ return {
57
+ "name": self.name,
58
+ "description": self.description,
59
+ "input_params": self.input_params,
60
+ "output_type": self.output_type,
61
+ }
62
+
63
+
64
+ def _generate_server_id(name: str) -> str:
65
+ slug = re.sub(r"[^a-z0-9]+", "-", name.lower().strip())[:30]
66
+ return f"mcp-{slug}-{uuid.uuid4().hex[:6]}"
67
+
68
+
69
+ def _generate_server_py(spec: MCPServerSpec) -> str:
70
+ """Generate a Python MCP server file."""
71
+ tool_funcs = []
72
+ for tool in spec.tools:
73
+ params = ", ".join(f"{k}: str" for k in tool.input_params)
74
+ func = f'''
75
+ @mcp.tool()
76
+ def {tool.name}({params}) -> dict:
77
+ """{tool.description}"""
78
+ # TODO: implement actual logic
79
+ return {{"result": "stub response", "tool": "{tool.name}"}}
80
+ '''
81
+ tool_funcs.append(func)
82
+
83
+ transport_line = (
84
+ f' mcp.run(transport="streamable-http", host="127.0.0.1", port={spec.port})'
85
+ if spec.transport == "http"
86
+ else ' mcp.run(transport="stdio")'
87
+ )
88
+
89
+ return f'''#!/usr/bin/env python3
90
+ # Auto-generated MCP server: {spec.name}
91
+ # Generated by specsmith mcp generate
92
+
93
+ from mcp.server.fastmcp import FastMCP
94
+
95
+ mcp = FastMCP("{spec.name}")
96
+ {"".join(tool_funcs)}
97
+
98
+ if __name__ == "__main__":
99
+ {transport_line}
100
+ '''
101
+
102
+
103
+ def _generate_readme(spec: MCPServerSpec) -> str:
104
+ """Generate README.md for the MCP server."""
105
+ tool_list = "\n".join(f"- **{t.name}**: {t.description}" for t in spec.tools)
106
+ return f"""# {spec.name}
107
+
108
+ {spec.description}
109
+
110
+ ## Tools
111
+
112
+ {tool_list}
113
+
114
+ ## Usage
115
+
116
+ ```bash
117
+ # stdio mode
118
+ python server.py
119
+
120
+ # HTTP mode (if configured)
121
+ python server.py
122
+ ```
123
+
124
+ ## Configuration
125
+
126
+ Add to your MCP client config:
127
+
128
+ ```json
129
+ {{
130
+ "mcpServers": {{
131
+ "{spec.id}": {{
132
+ "command": "python",
133
+ "args": ["server.py"]
134
+ }}
135
+ }}
136
+ }}
137
+ ```
138
+ """
139
+
140
+
141
+ def generate_mcp_server(
142
+ tool_description: str,
143
+ project_dir: str = ".",
144
+ transport: str = "stdio",
145
+ port: int = 8100,
146
+ ) -> MCPServerSpec:
147
+ """Generate an MCP server from a natural-language tool description.
148
+
149
+ Creates a server directory with `server.py`, `tool_schema.json`, and `README.md`.
150
+ """
151
+ # Parse description into server + tool spec
152
+ name = tool_description.strip()[:50]
153
+ server_id = _generate_server_id(name)
154
+ tool_name = re.sub(r"[^a-z0-9_]+", "_", name.lower().strip())[:40]
155
+
156
+ tool = MCPToolSpec(
157
+ name=tool_name,
158
+ description=tool_description.strip(),
159
+ input_params={"query": "Search query or input"},
160
+ )
161
+
162
+ spec = MCPServerSpec(
163
+ id=server_id,
164
+ name=name,
165
+ description=tool_description.strip(),
166
+ tools=[tool],
167
+ transport=transport,
168
+ port=port,
169
+ )
170
+
171
+ # Create server directory
172
+ server_dir = Path(project_dir).resolve() / ".specsmith" / "mcp-servers" / server_id
173
+ server_dir.mkdir(parents=True, exist_ok=True)
174
+
175
+ # Write files
176
+ (server_dir / "server.py").write_text(_generate_server_py(spec), encoding="utf-8")
177
+ (server_dir / "tool_schema.json").write_text(
178
+ json.dumps(spec.to_dict(), indent=2, ensure_ascii=False), encoding="utf-8"
179
+ )
180
+ (server_dir / "README.md").write_text(_generate_readme(spec), encoding="utf-8")
181
+
182
+ return spec
183
+
184
+
185
+ def list_mcp_servers(project_dir: str = ".") -> list[MCPServerSpec]:
186
+ """List all generated MCP servers."""
187
+ servers_dir = Path(project_dir).resolve() / ".specsmith" / "mcp-servers"
188
+ if not servers_dir.is_dir():
189
+ return []
190
+ servers: list[MCPServerSpec] = []
191
+ for server_dir in sorted(servers_dir.iterdir()):
192
+ schema_path = server_dir / "tool_schema.json"
193
+ if schema_path.is_file():
194
+ try:
195
+ raw = json.loads(schema_path.read_text(encoding="utf-8"))
196
+ servers.append(
197
+ MCPServerSpec(
198
+ id=raw.get("id", ""),
199
+ name=raw.get("name", ""),
200
+ description=raw.get("description", ""),
201
+ transport=raw.get("transport", "stdio"),
202
+ port=raw.get("port", 8100),
203
+ )
204
+ )
205
+ except (OSError, ValueError):
206
+ continue
207
+ return servers
208
+
209
+
210
+ __all__ = ["MCPServerSpec", "MCPToolSpec", "generate_mcp_server", "list_mcp_servers"]
@@ -0,0 +1,193 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs / BitConcepts, LLC.
3
+ """AI-powered Skills Builder — generate agent skills from natural-language descriptions.
4
+
5
+ Skills follow the SkillNet-style ontology: each skill is a folder containing
6
+ a SKILL.md file with structured metadata (name, purpose, activation rules,
7
+ input/output schema, epistemic contract, tools used, tests required).
8
+
9
+ Usage:
10
+ from specsmith.skills_builder import build_skill, list_skills
11
+ skill = build_skill("Summarize a Python file into bullet points")
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import re
18
+ import uuid
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+
24
+ @dataclass
25
+ class SkillSpec:
26
+ """Structured specification for an agent skill."""
27
+
28
+ id: str
29
+ name: str
30
+ purpose: str
31
+ activation_rules: list[str] = field(default_factory=list)
32
+ input_schema: dict[str, str] = field(default_factory=dict)
33
+ output_schema: dict[str, str] = field(default_factory=dict)
34
+ epistemic_contract: str = ""
35
+ tools_used: list[str] = field(default_factory=list)
36
+ tests_required: list[str] = field(default_factory=list)
37
+ stop_conditions: list[str] = field(default_factory=list)
38
+ tags: list[str] = field(default_factory=list)
39
+ active: bool = False
40
+
41
+ def to_dict(self) -> dict[str, Any]:
42
+ return {
43
+ "id": self.id,
44
+ "name": self.name,
45
+ "purpose": self.purpose,
46
+ "activation_rules": self.activation_rules,
47
+ "input_schema": self.input_schema,
48
+ "output_schema": self.output_schema,
49
+ "epistemic_contract": self.epistemic_contract,
50
+ "tools_used": self.tools_used,
51
+ "tests_required": self.tests_required,
52
+ "stop_conditions": self.stop_conditions,
53
+ "tags": self.tags,
54
+ "active": self.active,
55
+ }
56
+
57
+ def to_markdown(self) -> str:
58
+ """Generate SKILL.md content."""
59
+ lines = [
60
+ f"# {self.name}",
61
+ "",
62
+ f"**ID:** {self.id}",
63
+ f"**Purpose:** {self.purpose}",
64
+ "",
65
+ "## Activation Rules",
66
+ "",
67
+ ]
68
+ for rule in self.activation_rules:
69
+ lines.append(f"- {rule}")
70
+ lines.extend(
71
+ [
72
+ "",
73
+ "## Input Schema",
74
+ "",
75
+ "```json",
76
+ json.dumps(self.input_schema, indent=2),
77
+ "```",
78
+ "",
79
+ "## Output Schema",
80
+ "",
81
+ "```json",
82
+ json.dumps(self.output_schema, indent=2),
83
+ "```",
84
+ "",
85
+ "## Epistemic Contract",
86
+ "",
87
+ self.epistemic_contract or "No epistemic contract defined.",
88
+ "",
89
+ "## Tools Used",
90
+ "",
91
+ ]
92
+ )
93
+ for tool in self.tools_used:
94
+ lines.append(f"- {tool}")
95
+ lines.extend(["", "## Tests Required", ""])
96
+ for test in self.tests_required:
97
+ lines.append(f"- {test}")
98
+ lines.extend(["", "## Stop Conditions", ""])
99
+ for cond in self.stop_conditions:
100
+ lines.append(f"- {cond}")
101
+ return "\n".join(lines)
102
+
103
+
104
+ def _generate_skill_id(name: str) -> str:
105
+ slug = re.sub(r"[^a-z0-9]+", "-", name.lower().strip())[:30]
106
+ return f"skill-{slug}-{uuid.uuid4().hex[:6]}"
107
+
108
+
109
+ def build_skill(
110
+ description: str,
111
+ project_dir: str = ".",
112
+ tags: list[str] | None = None,
113
+ ) -> SkillSpec:
114
+ """Build a skill from a natural-language description.
115
+
116
+ Currently generates a deterministic skill spec from the description.
117
+ When an AI provider is configured, this will use the LLM to generate
118
+ richer skill content.
119
+ """
120
+ # Deterministic generation (no LLM required)
121
+ name = description.strip()[:60]
122
+ skill_id = _generate_skill_id(name)
123
+
124
+ spec = SkillSpec(
125
+ id=skill_id,
126
+ name=name,
127
+ purpose=description.strip(),
128
+ activation_rules=[f"User requests: {description[:80]}"],
129
+ input_schema={"task": "string", "context": "string (optional)"},
130
+ output_schema={"result": "string", "confidence": "number"},
131
+ epistemic_contract="Output must be verifiable against the input task.",
132
+ tools_used=["read_file", "run_shell"],
133
+ tests_required=[f"Verify {name} produces correct output"],
134
+ stop_conditions=["Confidence below 0.3", "Timeout exceeded"],
135
+ tags=tags or [],
136
+ )
137
+
138
+ # Save to disk
139
+ skill_dir = Path(project_dir).resolve() / ".specsmith" / "skills" / skill_id
140
+ skill_dir.mkdir(parents=True, exist_ok=True)
141
+ (skill_dir / "SKILL.md").write_text(spec.to_markdown(), encoding="utf-8")
142
+
143
+ # Save JSON metadata
144
+ (skill_dir / "skill.json").write_text(
145
+ json.dumps(spec.to_dict(), indent=2, ensure_ascii=False),
146
+ encoding="utf-8",
147
+ )
148
+
149
+ return spec
150
+
151
+
152
+ def list_skills(project_dir: str = ".") -> list[SkillSpec]:
153
+ """List all available skills in the project."""
154
+ skills_dir = Path(project_dir).resolve() / ".specsmith" / "skills"
155
+ if not skills_dir.is_dir():
156
+ return []
157
+ skills: list[SkillSpec] = []
158
+ for skill_dir in sorted(skills_dir.iterdir()):
159
+ meta_path = skill_dir / "skill.json"
160
+ if meta_path.is_file():
161
+ try:
162
+ raw = json.loads(meta_path.read_text(encoding="utf-8"))
163
+ skills.append(
164
+ SkillSpec(
165
+ id=raw.get("id", ""),
166
+ name=raw.get("name", ""),
167
+ purpose=raw.get("purpose", ""),
168
+ activation_rules=raw.get("activation_rules", []),
169
+ tools_used=raw.get("tools_used", []),
170
+ tags=raw.get("tags", []),
171
+ active=raw.get("active", False),
172
+ )
173
+ )
174
+ except (OSError, ValueError):
175
+ continue
176
+ return skills
177
+
178
+
179
+ def activate_skill(skill_id: str, project_dir: str = ".") -> bool:
180
+ """Activate a skill by ID."""
181
+ meta_path = Path(project_dir).resolve() / ".specsmith" / "skills" / skill_id / "skill.json"
182
+ if not meta_path.is_file():
183
+ return False
184
+ try:
185
+ raw = json.loads(meta_path.read_text(encoding="utf-8"))
186
+ raw["active"] = True
187
+ meta_path.write_text(json.dumps(raw, indent=2, ensure_ascii=False), encoding="utf-8")
188
+ return True
189
+ except (OSError, ValueError):
190
+ return False
191
+
192
+
193
+ __all__ = ["SkillSpec", "activate_skill", "build_skill", "list_skills"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.10.1.dev292
3
+ Version: 0.10.1.dev294
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
@@ -36,6 +36,7 @@ src/specsmith/importer.py
36
36
  src/specsmith/instinct.py
37
37
  src/specsmith/languages.py
38
38
  src/specsmith/ledger.py
39
+ src/specsmith/mcp_generator.py
39
40
  src/specsmith/patent.py
40
41
  src/specsmith/paths.py
41
42
  src/specsmith/phase.py
@@ -52,6 +53,7 @@ src/specsmith/serve.py
52
53
  src/specsmith/session.py
53
54
  src/specsmith/session_init.py
54
55
  src/specsmith/skills.py
56
+ src/specsmith/skills_builder.py
55
57
  src/specsmith/sync.py
56
58
  src/specsmith/tool_installer.py
57
59
  src/specsmith/toolrules.py
@@ -115,6 +117,8 @@ src/specsmith/epistemic/certainty.py
115
117
  src/specsmith/epistemic/failure_graph.py
116
118
  src/specsmith/epistemic/recovery.py
117
119
  src/specsmith/epistemic/stress_tester.py
120
+ src/specsmith/esdb/__init__.py
121
+ src/specsmith/esdb/bridge.py
118
122
  src/specsmith/eval/__init__.py
119
123
  src/specsmith/eval/builtins.py
120
124
  src/specsmith/eval/runner.py
@@ -218,6 +222,7 @@ tests/test_phase34_completion.py
218
222
  tests/test_rate_limits.py
219
223
  tests/test_scaffolder.py
220
224
  tests/test_skill_marketplace.py
225
+ tests/test_skills_mcp.py
221
226
  tests/test_smoke.py
222
227
  tests/test_suggester.py
223
228
  tests/test_tools.py