specsmith 0.12.0.dev493__tar.gz → 0.12.0.dev494__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.
- {specsmith-0.12.0.dev493/src/specsmith.egg-info → specsmith-0.12.0.dev494}/PKG-INFO +1 -1
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/pyproject.toml +1 -1
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/cli.py +100 -27
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/mcp_server.py +61 -11
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494/src/specsmith.egg-info}/PKG-INFO +1 -1
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_mcp_server.py +78 -3
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/LICENSE +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/README.md +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/setup.cfg +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/belief.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/certainty.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/failure_graph.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/py.typed +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/recovery.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/session.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/stress_tester.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/epistemic/trace.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/__main__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/broker.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/chat_runner.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/cleanup.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/context_seed.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/core.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/_status.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/dag.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/events.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/result.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/endpoints.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/events.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/execution_profiles.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/fallback.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/hf_leaderboard.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/hf_sync.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/indexer.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/llm_client.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/mcp.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/memory.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/model_intelligence.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/model_profiles.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/orchestrator.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/permissions.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/profiles.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/provider_registry.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/repl.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/router.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/rules.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/runner.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/safety.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/spawner.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/suggester.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/teams.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/tools.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/verifier.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/voice.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/architect.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/auditor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/auth.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/block_export.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/channel.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/ci_manager.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/commands/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/commands/intelligence.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/_compat.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/checker.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/evidence.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/regulations.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compliance/reporter.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/compressor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/config.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/console_utils.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/context_orchestrator.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/context_window.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/credit_analyzer.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/credits.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/base.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/citations.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/fpd.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/odp.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/patentsview.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/pfw.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/ppubs.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/datasources/ptab.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/differ.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/doctor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/drive.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/editor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/belief.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/certainty.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/failure_graph.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/recovery.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/epistemic/stress_tester.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/esdb/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/esdb/bridge.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/eval/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/eval/builtins.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/eval/runner.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/executor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/exporter.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/governance_logic.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/governance_store.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/governance_yaml.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/app.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/main_window.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/session_tab.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/theme.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/chat_view.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/input_bar.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/provider_bar.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/token_meter.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/tool_panel.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/widgets/update_checker.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/gui/worker.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/history_search.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/importer.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/instinct.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/agent_skill.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/aider.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/base.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/claude_code.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/codity.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/copilot.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/cursor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/gemini.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/integrations/windsurf.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/issue_reporter.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/languages.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/ledger.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/mcp_generator.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m002_agents_slim.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m003_compliance_init.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/m006_session_governance.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/migrations/runner.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/ollama_cmds.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/patent.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/paths.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/phase.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/plugins.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/profiles.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/rate_limits.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/releaser.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/requirements.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/requirements_parser.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/retrieval.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/safe_write.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/scaffolder.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/serve.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/session.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/session_init.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/session_store.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/cloud.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/corporate.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/cross_platform.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/devops.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/docs.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/embedded.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/governance.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/hardware.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/mobile.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/productivity.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/specsmith_skills.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills/ssh.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/skills_builder.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/sync.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/agents.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/contributing.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/license-MIT.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/community/security.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/editorconfig.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/gitattributes.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/gitignore.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/go/go.mod.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/go/main.go.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/roles.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/rules.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/governance/verification.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/js/package.json.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/ledger.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/python/cli.py.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/python/init.py.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/readme.md.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/rust/main.rs.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/tool_installer.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/toolrules.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/tools.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/trace.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/updater.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/upgrader.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/validator.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs/__init__.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs/base.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs/bitbucket.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs/github.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs/gitlab.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/vcs_commands.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/wireframes.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/workspace.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith.egg-info/SOURCES.txt +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith.egg-info/dependency_links.txt +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith.egg-info/entry_points.txt +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith.egg-info/requires.txt +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith.egg-info/top_level.txt +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_CMD_001.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_agent_profiles.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_agent_run_feedback.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_agent_runner_ready.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_ai_client.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_ai_intelligence.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_auditor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_channel.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_chat_diff_decision.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_chat_runner_openai_compat.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_chat_stdin_protocol.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_cli.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_cli_workflows_history_drive.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_compliance.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_compressor.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_dispatch.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_e2e_nexus.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_endpoints_cli.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_endpoints_store.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_epistemic.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_fallback_chain.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_importer.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_integrations.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_integrations_codity.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_intelligence.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_issue_reporter.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_mcp_client.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_new_modules.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_nexus.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_permissions.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_phase1_4_new.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_phase34_completion.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_rate_limits.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_req_248_262.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_req_358_359.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_scaffolder.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_skill_marketplace.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_skills_mcp.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_smoke.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_suggester.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_tools.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_validator.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_vcs.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/tests/test_warp_parity.py +0 -0
- {specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/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.
|
|
3
|
+
Version: 0.12.0.dev494
|
|
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.
|
|
7
|
+
version = "0.12.0.dev494"
|
|
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"
|
|
@@ -3207,32 +3207,61 @@ def checkpoint_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
3207
3207
|
|
|
3208
3208
|
# ── Human-readable anchor block ───────────────────────────────────────────
|
|
3209
3209
|
# Designed to be compact and survive context summarization.
|
|
3210
|
-
|
|
3210
|
+
_w = 57 # interior width — must match len(hbar)
|
|
3211
|
+
hbar = "\u2550" * _w # ═══…
|
|
3211
3212
|
vbar = "\u2551" # ║
|
|
3212
3213
|
health_icon = "\u2713" if health_ok else "\u2717"
|
|
3213
3214
|
esdb_icon = "\u2713" if esdb_ok else "\u2717"
|
|
3214
3215
|
wi_str = ", ".join(recent_wis) if recent_wis else "none seen"
|
|
3215
3216
|
|
|
3217
|
+
def _arow(rich: str, plain: str, wide: int = 0) -> str:
|
|
3218
|
+
"""Format one anchor box row: ║ <content padded to _w terminal cols> ║.
|
|
3219
|
+
|
|
3220
|
+
``plain`` is the markup-free string used for width calculation.
|
|
3221
|
+
``wide`` is the count of 2-wide (full-width/emoji) characters in ``plain``
|
|
3222
|
+
that add an extra terminal column beyond their Python ``len()``.
|
|
3223
|
+
"""
|
|
3224
|
+
pad = " " * max(0, _w - len(plain) - wide)
|
|
3225
|
+
return f"[bold cyan]{vbar}[/bold cyan]{rich}{pad}[bold cyan]{vbar}[/bold cyan]"
|
|
3226
|
+
|
|
3216
3227
|
console.print(f"[bold cyan]\u2554{hbar}\u2557[/bold cyan]")
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
console.print(
|
|
3220
|
-
|
|
3228
|
+
|
|
3229
|
+
r1 = f" GOVERNANCE ANCHOR {ts}"
|
|
3230
|
+
console.print(_arow(r1, r1))
|
|
3231
|
+
|
|
3232
|
+
r2_plain = f" Project : {project_name}"
|
|
3233
|
+
console.print(_arow(f" Project : [bold]{project_name}[/bold]", r2_plain))
|
|
3234
|
+
|
|
3235
|
+
r3_plain = f" Phase : {phase_emoji} {phase_label} ({phase_pct}%)"
|
|
3236
|
+
console.print(_arow(r3_plain, r3_plain, wide=1 if phase_emoji else 0))
|
|
3237
|
+
|
|
3238
|
+
r4_plain = (
|
|
3239
|
+
f" Health : {health_icon} clean"
|
|
3240
|
+
if health_ok
|
|
3241
|
+
else f" Health : {health_icon} {audit_failed} issues"
|
|
3221
3242
|
)
|
|
3222
|
-
|
|
3223
|
-
f"[green]{health_icon} clean[/green]"
|
|
3243
|
+
r4_rich = (
|
|
3244
|
+
f" Health : [green]{health_icon} clean[/green]"
|
|
3224
3245
|
if health_ok
|
|
3225
|
-
else f"[red]{health_icon} {audit_failed} issues[/red]"
|
|
3246
|
+
else f" Health : [red]{health_icon} {audit_failed} issues[/red]"
|
|
3226
3247
|
)
|
|
3227
|
-
console.print(
|
|
3228
|
-
|
|
3229
|
-
|
|
3248
|
+
console.print(_arow(r4_rich, r4_plain))
|
|
3249
|
+
|
|
3250
|
+
r5 = (
|
|
3251
|
+
f" REQs : {req_count} TESTs: {test_count}"
|
|
3230
3252
|
f" ESDB: {esdb_records} records ({esdb_icon} chain)"
|
|
3231
3253
|
)
|
|
3232
|
-
console.print(
|
|
3254
|
+
console.print(_arow(r5, r5))
|
|
3255
|
+
|
|
3256
|
+
r6 = f" WIs : {wi_str}"
|
|
3257
|
+
console.print(_arow(r6, r6))
|
|
3258
|
+
|
|
3233
3259
|
if last_preflight:
|
|
3234
|
-
|
|
3235
|
-
|
|
3260
|
+
_pf_max = _w - len(" Preflight: ") # 45 — was incorrectly 55
|
|
3261
|
+
pf_short = last_preflight[:_pf_max]
|
|
3262
|
+
r7 = f" Preflight: {pf_short}"
|
|
3263
|
+
console.print(_arow(r7, r7))
|
|
3264
|
+
|
|
3236
3265
|
console.print(f"[bold cyan]\u255a{hbar}\u255d[/bold cyan]")
|
|
3237
3266
|
console.print(
|
|
3238
3267
|
"[dim]Include this block verbatim in any context summary "
|
|
@@ -9021,13 +9050,23 @@ def mcp_list_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
9021
9050
|
|
|
9022
9051
|
@mcp_group.command(name="serve")
|
|
9023
9052
|
@click.option("--project-dir", type=click.Path(), default=".", show_default=True)
|
|
9024
|
-
|
|
9053
|
+
@click.option(
|
|
9054
|
+
"--project-dirs",
|
|
9055
|
+
default="",
|
|
9056
|
+
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."
|
|
9060
|
+
),
|
|
9061
|
+
)
|
|
9062
|
+
def mcp_serve_cmd(project_dir: str, project_dirs: str) -> None:
|
|
9025
9063
|
"""Start the native governance MCP stdio server (REQ-363).
|
|
9026
9064
|
|
|
9027
9065
|
Implements MCP 2024-11-05 over stdin/stdout (JSON-RPC 2.0).
|
|
9028
|
-
Exposes
|
|
9066
|
+
Exposes seven governance tools to any MCP client:
|
|
9029
9067
|
|
|
9030
9068
|
\b
|
|
9069
|
+
governance_project_list List all registered projects
|
|
9031
9070
|
governance_audit Run governance audit
|
|
9032
9071
|
governance_checkpoint Emit GOVERNANCE ANCHOR JSON
|
|
9033
9072
|
governance_preflight Preflight a change intent
|
|
@@ -9036,9 +9075,17 @@ def mcp_serve_cmd(project_dir: str) -> None:
|
|
|
9036
9075
|
governance_trace_seal Seal a milestone/decision
|
|
9037
9076
|
|
|
9038
9077
|
\b
|
|
9039
|
-
Warp config (Settings → Agents → MCP servers)::
|
|
9078
|
+
Single-project Warp config (Settings → Agents → MCP servers)::
|
|
9040
9079
|
|
|
9041
|
-
{"specsmith-governance": {"command": "specsmith",
|
|
9080
|
+
{"specsmith-governance": {"command": "specsmith",
|
|
9081
|
+
"args": ["mcp", "serve", "--project-dir", "/path/to/project"]}}
|
|
9082
|
+
|
|
9083
|
+
\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"]}}
|
|
9042
9089
|
|
|
9043
9090
|
\b
|
|
9044
9091
|
Or pass inline to oz (use ``specsmith mcp install-warp`` for the full snippet)::
|
|
@@ -9047,17 +9094,26 @@ def mcp_serve_cmd(project_dir: str) -> None:
|
|
|
9047
9094
|
"""
|
|
9048
9095
|
from specsmith.mcp_server import run_server
|
|
9049
9096
|
|
|
9050
|
-
|
|
9097
|
+
extra = [p.strip() for p in project_dirs.split(",") if p.strip()] if project_dirs else []
|
|
9098
|
+
run_server(project_dir=project_dir, extra_project_dirs=extra)
|
|
9051
9099
|
|
|
9052
9100
|
|
|
9053
9101
|
@mcp_group.command(name="install-warp")
|
|
9054
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
|
+
)
|
|
9055
9108
|
@click.option("--json", "as_json", is_flag=True, default=False, help="Emit JSON config only.")
|
|
9056
|
-
def mcp_install_warp_cmd(project_dir: str, as_json: bool) -> None:
|
|
9109
|
+
def mcp_install_warp_cmd(project_dir: str, project_dirs: str, as_json: bool) -> None:
|
|
9057
9110
|
"""Print the Warp MCP config snippet for the governance server (REQ-363).
|
|
9058
9111
|
|
|
9059
9112
|
Copy the output into Warp Settings → Agents → MCP servers, or pass it
|
|
9060
9113
|
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.
|
|
9061
9117
|
"""
|
|
9062
9118
|
import json as _json
|
|
9063
9119
|
import shutil
|
|
@@ -9068,10 +9124,17 @@ def mcp_install_warp_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
9068
9124
|
specsmith_exe = shutil.which("specsmith") or str(
|
|
9069
9125
|
Path(sys.executable).parent / ("specsmith.exe" if sys.platform == "win32" else "specsmith")
|
|
9070
9126
|
)
|
|
9127
|
+
default_dir = str(Path(project_dir).resolve())
|
|
9128
|
+
args: list[str] = ["mcp", "serve", "--project-dir", default_dir]
|
|
9129
|
+
|
|
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)]
|
|
9133
|
+
|
|
9071
9134
|
config = {
|
|
9072
9135
|
"specsmith-governance": {
|
|
9073
9136
|
"command": specsmith_exe,
|
|
9074
|
-
"args":
|
|
9137
|
+
"args": args,
|
|
9075
9138
|
}
|
|
9076
9139
|
}
|
|
9077
9140
|
|
|
@@ -9085,12 +9148,22 @@ def mcp_install_warp_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
9085
9148
|
"or pass inline to [bold]oz agent run --mcp '<json>'[/bold]:\n"
|
|
9086
9149
|
)
|
|
9087
9150
|
console.print(_json.dumps(config, indent=2))
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
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
|
+
)
|
|
9157
|
+
else:
|
|
9158
|
+
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]"
|
|
9166
|
+
)
|
|
9094
9167
|
|
|
9095
9168
|
|
|
9096
9169
|
main.add_command(mcp_group)
|
|
@@ -35,7 +35,6 @@ No external dependencies — stdlib only + existing specsmith modules.
|
|
|
35
35
|
|
|
36
36
|
from __future__ import annotations
|
|
37
37
|
|
|
38
|
-
import contextlib
|
|
39
38
|
import json
|
|
40
39
|
import sys
|
|
41
40
|
import time
|
|
@@ -50,7 +49,30 @@ MCP_PROTOCOL_VERSION = "2024-11-05"
|
|
|
50
49
|
SERVER_NAME = "specsmith-governance"
|
|
51
50
|
SERVER_VERSION = "0.12.0"
|
|
52
51
|
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
# Multi-project state — populated by run_server() at startup
|
|
54
|
+
# ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
# Default project dir used when a tool call omits ``project_dir``.
|
|
57
|
+
_DEFAULT_PROJECT_DIR: str = "."
|
|
58
|
+
|
|
59
|
+
# All registered project directories (absolute paths), default first.
|
|
60
|
+
_REGISTERED_PROJECTS: list[str] = []
|
|
61
|
+
|
|
53
62
|
_TOOLS: list[dict[str, Any]] = [
|
|
63
|
+
{
|
|
64
|
+
"name": "governance_project_list",
|
|
65
|
+
"description": (
|
|
66
|
+
"List all project directories registered in this MCP server instance. "
|
|
67
|
+
"Use the returned paths as the `project_dir` argument for other tools "
|
|
68
|
+
"when working with multiple simultaneous projects."
|
|
69
|
+
),
|
|
70
|
+
"inputSchema": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"properties": {},
|
|
73
|
+
"required": [],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
54
76
|
{
|
|
55
77
|
"name": "governance_audit",
|
|
56
78
|
"description": (
|
|
@@ -195,10 +217,25 @@ _TOOLS: list[dict[str, Any]] = [
|
|
|
195
217
|
|
|
196
218
|
|
|
197
219
|
def _resolve_root(args: dict[str, Any]) -> Path:
|
|
198
|
-
|
|
220
|
+
"""Resolve project_dir from args, falling back to the server default.
|
|
221
|
+
|
|
222
|
+
If ``project_dir`` is not in *args* (or is empty), we use
|
|
223
|
+
``_DEFAULT_PROJECT_DIR`` so callers don't have to repeat the path on
|
|
224
|
+
every tool call when only one project is active.
|
|
225
|
+
"""
|
|
226
|
+
raw = args.get("project_dir") or _DEFAULT_PROJECT_DIR
|
|
199
227
|
return Path(str(raw)).resolve()
|
|
200
228
|
|
|
201
229
|
|
|
230
|
+
def _handle_governance_project_list(args: dict[str, Any]) -> dict[str, Any]: # noqa: ARG001
|
|
231
|
+
"""Return the list of projects registered in this server instance."""
|
|
232
|
+
return {
|
|
233
|
+
"default_project": _DEFAULT_PROJECT_DIR,
|
|
234
|
+
"projects": _REGISTERED_PROJECTS,
|
|
235
|
+
"count": len(_REGISTERED_PROJECTS),
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
202
239
|
def _handle_governance_audit(args: dict[str, Any]) -> dict[str, Any]:
|
|
203
240
|
"""Run the governance audit and return structured results."""
|
|
204
241
|
root = _resolve_root(args)
|
|
@@ -487,6 +524,7 @@ def _handle_governance_trace_seal(args: dict[str, Any]) -> dict[str, Any]:
|
|
|
487
524
|
# ---------------------------------------------------------------------------
|
|
488
525
|
|
|
489
526
|
_HANDLERS = {
|
|
527
|
+
"governance_project_list": _handle_governance_project_list,
|
|
490
528
|
"governance_audit": _handle_governance_audit,
|
|
491
529
|
"governance_checkpoint": _handle_governance_checkpoint,
|
|
492
530
|
"governance_preflight": _handle_governance_preflight,
|
|
@@ -576,20 +614,32 @@ def _handle_request(msg: dict[str, Any]) -> dict[str, Any] | None:
|
|
|
576
614
|
return None
|
|
577
615
|
|
|
578
616
|
|
|
579
|
-
def run_server(
|
|
617
|
+
def run_server(
|
|
618
|
+
project_dir: str = ".",
|
|
619
|
+
extra_project_dirs: list[str] | None = None,
|
|
620
|
+
) -> None:
|
|
580
621
|
"""Start the MCP stdio server. Blocks until stdin closes.
|
|
581
622
|
|
|
582
623
|
Reads newline-delimited JSON-RPC 2.0 messages from stdin and
|
|
583
624
|
writes responses to stdout. Stderr is used for diagnostic messages.
|
|
584
|
-
The ``project_dir`` is injected into every tool call that doesn't
|
|
585
|
-
supply its own ``project_dir`` argument.
|
|
586
|
-
"""
|
|
587
|
-
import os
|
|
588
625
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
626
|
+
``project_dir`` becomes the default for tool calls that omit
|
|
627
|
+
``project_dir``. ``extra_project_dirs`` registers additional projects
|
|
628
|
+
accessible via ``governance_project_list`` and addressable by any tool
|
|
629
|
+
using their absolute path as ``project_dir``.
|
|
630
|
+
|
|
631
|
+
The server no longer calls ``os.chdir()``; all paths are resolved
|
|
632
|
+
absolutely, so the server can serve multiple projects from one process.
|
|
633
|
+
"""
|
|
634
|
+
global _DEFAULT_PROJECT_DIR, _REGISTERED_PROJECTS
|
|
635
|
+
|
|
636
|
+
# Register projects — always use absolute paths
|
|
637
|
+
_DEFAULT_PROJECT_DIR = str(Path(project_dir).resolve())
|
|
638
|
+
_REGISTERED_PROJECTS = [_DEFAULT_PROJECT_DIR]
|
|
639
|
+
for extra in extra_project_dirs or []:
|
|
640
|
+
abs_extra = str(Path(extra).resolve())
|
|
641
|
+
if abs_extra not in _REGISTERED_PROJECTS:
|
|
642
|
+
_REGISTERED_PROJECTS.append(abs_extra)
|
|
593
643
|
|
|
594
644
|
for raw_line in sys.stdin:
|
|
595
645
|
raw_line = raw_line.strip()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.12.0.
|
|
3
|
+
Version: 0.12.0.dev494
|
|
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
|
|
@@ -78,12 +78,13 @@ class TestMcpProtocol:
|
|
|
78
78
|
assert result["serverInfo"]["name"] == "specsmith-governance"
|
|
79
79
|
assert "tools" in result["capabilities"]
|
|
80
80
|
|
|
81
|
-
def
|
|
81
|
+
def test_tools_list_returns_seven_tools(self) -> None:
|
|
82
82
|
resp = _send_rpc(_make_rpc("tools/list", {}, req_id=2))
|
|
83
83
|
tools = resp["result"]["tools"]
|
|
84
|
-
assert len(tools) ==
|
|
84
|
+
assert len(tools) == 7
|
|
85
85
|
names = {t["name"] for t in tools}
|
|
86
86
|
assert names == {
|
|
87
|
+
"governance_project_list",
|
|
87
88
|
"governance_audit",
|
|
88
89
|
"governance_checkpoint",
|
|
89
90
|
"governance_preflight",
|
|
@@ -311,6 +312,80 @@ class TestGovernanceReqList:
|
|
|
311
312
|
assert resp["result"]["isError"] is False
|
|
312
313
|
|
|
313
314
|
|
|
315
|
+
class TestGovernanceProjectList:
|
|
316
|
+
def test_returns_default_project(self, tmp_path: Path) -> None:
|
|
317
|
+
from specsmith.mcp_server import _handle_governance_project_list, run_server
|
|
318
|
+
|
|
319
|
+
# Prime server state with a known directory
|
|
320
|
+
run_server.__func__ if hasattr(run_server, "__func__") else run_server # noqa: B018
|
|
321
|
+
import specsmith.mcp_server as _mod
|
|
322
|
+
|
|
323
|
+
_mod._DEFAULT_PROJECT_DIR = str(tmp_path)
|
|
324
|
+
_mod._REGISTERED_PROJECTS = [str(tmp_path)]
|
|
325
|
+
|
|
326
|
+
result = _handle_governance_project_list({})
|
|
327
|
+
assert result["default_project"] == str(tmp_path)
|
|
328
|
+
assert str(tmp_path) in result["projects"]
|
|
329
|
+
assert result["count"] >= 1
|
|
330
|
+
|
|
331
|
+
def test_via_tools_call(self, tmp_path: Path) -> None:
|
|
332
|
+
import specsmith.mcp_server as _mod
|
|
333
|
+
|
|
334
|
+
_mod._DEFAULT_PROJECT_DIR = str(tmp_path)
|
|
335
|
+
_mod._REGISTERED_PROJECTS = [str(tmp_path)]
|
|
336
|
+
|
|
337
|
+
resp = _send_rpc(
|
|
338
|
+
_make_rpc(
|
|
339
|
+
"tools/call",
|
|
340
|
+
{"name": "governance_project_list", "arguments": {}},
|
|
341
|
+
req_id=30,
|
|
342
|
+
)
|
|
343
|
+
)
|
|
344
|
+
assert resp["result"]["isError"] is False
|
|
345
|
+
content = json.loads(resp["result"]["content"][0]["text"])
|
|
346
|
+
assert "projects" in content
|
|
347
|
+
assert "count" in content
|
|
348
|
+
|
|
349
|
+
def test_extra_projects_registered(self, tmp_path: Path) -> None:
|
|
350
|
+
"""run_server registers extra_project_dirs and they appear in project_list."""
|
|
351
|
+
import io
|
|
352
|
+
|
|
353
|
+
import specsmith.mcp_server as _mod
|
|
354
|
+
from specsmith.mcp_server import run_server
|
|
355
|
+
|
|
356
|
+
extra = tmp_path / "extra"
|
|
357
|
+
extra.mkdir()
|
|
358
|
+
|
|
359
|
+
# Patch stdin to EOF immediately so run_server exits
|
|
360
|
+
old_stdin = sys.stdin
|
|
361
|
+
sys.stdin = io.StringIO("")
|
|
362
|
+
try:
|
|
363
|
+
run_server(project_dir=str(tmp_path), extra_project_dirs=[str(extra)])
|
|
364
|
+
finally:
|
|
365
|
+
sys.stdin = old_stdin
|
|
366
|
+
|
|
367
|
+
assert str(tmp_path.resolve()) == _mod._DEFAULT_PROJECT_DIR
|
|
368
|
+
assert str(extra.resolve()) in _mod._REGISTERED_PROJECTS
|
|
369
|
+
assert _mod._REGISTERED_PROJECTS[0] == str(tmp_path.resolve())
|
|
370
|
+
|
|
371
|
+
def test_no_chdir_called(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
372
|
+
"""run_server must NOT call os.chdir — paths are resolved absolutely."""
|
|
373
|
+
import io
|
|
374
|
+
|
|
375
|
+
from specsmith.mcp_server import run_server
|
|
376
|
+
|
|
377
|
+
chdir_calls: list[str] = []
|
|
378
|
+
monkeypatch.setattr("os.chdir", lambda p: chdir_calls.append(str(p)))
|
|
379
|
+
old_stdin = sys.stdin
|
|
380
|
+
sys.stdin = io.StringIO("")
|
|
381
|
+
try:
|
|
382
|
+
run_server(project_dir=str(tmp_path))
|
|
383
|
+
finally:
|
|
384
|
+
sys.stdin = old_stdin
|
|
385
|
+
|
|
386
|
+
assert chdir_calls == [], "run_server must not call os.chdir"
|
|
387
|
+
|
|
388
|
+
|
|
314
389
|
class TestGovernanceTraceSeal:
|
|
315
390
|
def test_missing_description_returns_error(self, tmp_path: Path) -> None:
|
|
316
391
|
from specsmith.mcp_server import _handle_governance_trace_seal
|
|
@@ -458,4 +533,4 @@ class TestMcpServeCli:
|
|
|
458
533
|
tools_resp = json.loads(lines[-1])
|
|
459
534
|
assert "result" in tools_resp
|
|
460
535
|
tools = tools_resp["result"]["tools"]
|
|
461
|
-
assert len(tools) ==
|
|
536
|
+
assert len(tools) == 7
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/dispatch/dispatcher.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/execution_profiles.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/model_intelligence.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specsmith-0.12.0.dev493 → specsmith-0.12.0.dev494}/src/specsmith/agent/provider_registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|