specsmith 0.21.0.dev787__tar.gz → 0.22.0__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.21.0.dev787/src/specsmith.egg-info → specsmith-0.22.0}/PKG-INFO +48 -13
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/README.md +47 -12
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/pyproject.toml +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/__init__.py +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/advanced_code_analysis.py +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/cleanup.py +2 -2
- specsmith-0.22.0/src/specsmith/chat_handoff.py +107 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/cli.py +145 -7
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/commands/zoo_code.py +19 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/config.py +7 -4
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/context_orchestrator.py +5 -4
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/importer.py +3 -1
- specsmith-0.22.0/src/specsmith/improvement_tracker.py +186 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/warp.py +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/__init__.py +4 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m006_session_governance.py +1 -1
- specsmith-0.22.0/src/specsmith/migrations/m011_windows_skill_shell.py +64 -0
- specsmith-0.22.0/src/specsmith/migrations/m012_normalize_skill_shell.py +56 -0
- specsmith-0.22.0/src/specsmith/model_optimizer.py +182 -0
- specsmith-0.22.0/src/specsmith/model_registry.py +970 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/quality_report.py +5 -2
- specsmith-0.22.0/src/specsmith/release_guard.py +36 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/session_store.py +82 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/__init__.py +55 -59
- specsmith-0.22.0/src/specsmith/skills/governance.py +523 -0
- specsmith-0.22.0/src/specsmith/skills/specsmith_core_commands.py +355 -0
- specsmith-0.22.0/src/specsmith/skills/specsmith_operations.py +67 -0
- specsmith-0.22.0/src/specsmith/skills/specsmith_skills.py +110 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/sync.py +34 -11
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/agents.md.j2 +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/contributing.md.j2 +16 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/gitignore.j2 +5 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/updater.py +24 -2
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs_commands.py +33 -14
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/wi_store.py +9 -2
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/workspace.py +1 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0/src/specsmith.egg-info}/PKG-INFO +48 -13
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith.egg-info/SOURCES.txt +20 -1
- specsmith-0.22.0/tests/test_branch_workflow.py +88 -0
- specsmith-0.22.0/tests/test_chat_handoff.py +80 -0
- specsmith-0.22.0/tests/test_docs_artifacts.py +19 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_enforcement.py +101 -2
- specsmith-0.22.0/tests/test_improvement_tracker.py +242 -0
- specsmith-0.22.0/tests/test_migrations_skill_shell.py +58 -0
- specsmith-0.22.0/tests/test_model_registry.py +260 -0
- specsmith-0.22.0/tests/test_release_guard.py +41 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_scaffolder.py +3 -1
- specsmith-0.22.0/tests/test_session_events.py +53 -0
- specsmith-0.22.0/tests/test_updater.py +16 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_warp_parity_followup.py +25 -1
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_wi_lifecycle.py +14 -0
- specsmith-0.22.0/tests/test_windows_launcher.py +40 -0
- specsmith-0.21.0.dev787/src/specsmith/skills/governance.py +0 -1370
- specsmith-0.21.0.dev787/src/specsmith/skills/specsmith_skills.py +0 -29
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/LICENSE +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/setup.cfg +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/belief.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/certainty.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/failure_graph.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/py.typed +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/recovery.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/session.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/stress_tester.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/epistemic/trace.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/__main__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/broker.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/chat_runner.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/context_seed.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/core.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/_status.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/dag.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/events.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/dispatch/result.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/endpoints.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/events.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/execution_profiles.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/fallback.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/hf_leaderboard.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/hf_sync.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/indexer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/llm_client.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/mcp.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/memory.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/model_intelligence.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/model_profiles.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/model_router.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/orchestrator.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/permissions.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/profiles.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/provider_registry.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/repl.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/router.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/rules.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/runner.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/safety.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/spawner.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/suggester.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/teams.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/terminal_env.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/token_pricing.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/tools.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/verifier.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/agent/voice.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/approvals.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/architect.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/auditor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/auth.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/block_export.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/channel.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/ci_manager.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/code_analysis.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/commands/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/commands/intelligence.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/commands/issues_policy.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/commands/reporting.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/_compat.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/checker.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/evidence.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/regulations.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compliance/reporter.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/compressor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/console_utils.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/context_window.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/credit_analyzer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/credits.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/dashboard.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/base.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/citations.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/fpd.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/odp.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/patentsview.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/pfw.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/ppubs.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/datasources/ptab.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/differ.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/doctor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/drive.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/editor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/efficiency.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/belief.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/certainty.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/failure_graph.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/recovery.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/epistemic/stress_tester.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb/_license.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb/bridge.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb/sqlite_store.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb_sweep.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/esdb_writer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/eval/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/eval/builtins.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/eval/runner.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/executor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/exporter.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/governance_logic.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/governance_store.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/governance_yaml.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/governed_pr.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/app.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/main_window.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/session_tab.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/theme.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/chat_view.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/input_bar.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/provider_bar.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/token_meter.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/tool_panel.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/widgets/update_checker.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/gui/worker.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/history_search.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/instinct.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/agent_skill.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/aider.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/base.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/claude_code.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/codity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/copilot.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/cursor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/gemini.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/integrations/windsurf.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/issue_reporter.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/languages.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/ledger.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/local_model.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/mcp_generator.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/mcp_server.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m002_agents_slim.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m003_compliance_init.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m007_yaml_first.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m008_esdb_full_coverage.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m009_esdb_first.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/m010_post_esdb_cleanup.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/migrations/runner.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/ollama_cmds.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/patent.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/paths.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/phase.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/plugins.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/policy.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/profiles.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/project_metrics.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/rate_limits.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/recover.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/releaser.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/requirements.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/requirements_parser.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/retrieval.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/risk.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/safe_write.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/scaffolder.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/serve.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/session.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/session_init.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/ai_agents.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/cloud.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/corporate.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/cross_platform.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/data_engineering.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/devops.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/docs.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/embedded.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/hardware.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/mobile.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/platform_engineering.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/productivity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/software_engineering.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/ssh.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills/web_backend.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/skills_builder.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/license-MIT.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/community/security.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/editorconfig.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/gitattributes.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/go/go.mod.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/go/main.go.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/roles.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/rules.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/governance/verification.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/js/package.json.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/ledger.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/python/cli.py.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/python/init.py.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/readme.md.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/rust/main.rs.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/tool_installer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/toolrules.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/tools.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/trace.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/transcripts.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/upgrader.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/validator.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs/__init__.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs/base.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs/bitbucket.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs/github.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/vcs/gitlab.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith/wireframes.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith.egg-info/dependency_links.txt +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith.egg-info/entry_points.txt +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith.egg-info/requires.txt +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/src/specsmith.egg-info/top_level.txt +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_CMD_001.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_agent_profiles.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_agent_run_feedback.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_agent_runner_ready.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_ai_client.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_ai_intelligence.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_architect_interview.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_architect_v2.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_architecture.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_audit_governance.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_auditor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_benchmark_harness.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_broker_scope.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_channel.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_chat_diff_decision.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_chat_runner_openai_compat.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_chat_stdin_protocol.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_cleanup_cmd.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_cli.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_cli_regressions.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_cli_workflows_history_drive.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_compliance.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_compliance_governance.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_compressor.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_deprecation_registry.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_dispatch.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_dual_write.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_e2e_nexus.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_efficiency.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_endpoints_cli.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_endpoints_store.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_epistemic.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_backend_switch.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_integration.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_license.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_sqlite.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_status_integrity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_status_output.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_sweep.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_verify_chain_cli.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_esdb_writer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_fallback_chain.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_golden_path.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_importer.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_init_modes.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_integrations.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_integrations_codity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_integrations_warp.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_intelligence.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_issue_policy_features.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_issue_reporter.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_issues_263_264.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_local_model.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_markdown_deprecation.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_mcp_client.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_mcp_server.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_metrics_flush.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_migration_direction.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_model_router.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_new_modules.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_nexus.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_parallel_agents.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_permissions.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_phase1_4_new.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_phase34_completion.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_project_metrics.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_quality_report.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_rate_limits.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_releaser.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_repl.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_repl_extended.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_reporting_commands.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_req_248_262.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_req_358_359.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_resume_command.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_schema_migrations.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_skill_marketplace.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_skills_mcp.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_smoke.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_sqlite_parity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_suggester.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_sync_reconcile.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_terminal_env.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_token_cost.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_tools.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_trace_vault_esdb.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_typing_guardrails.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_validator.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_vcs.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_warp_parity.py +0 -0
- {specsmith-0.21.0.dev787 → specsmith-0.22.0}/tests/test_wi_lifecycle_extended.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.0
|
|
4
4
|
Summary: AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider.
|
|
5
5
|
Author: Layer1Labs Silicon, Inc.
|
|
6
6
|
License-Expression: MIT
|
|
@@ -102,6 +102,8 @@ AI Agents / IDE Clients
|
|
|
102
102
|
## When to use / when not to use
|
|
103
103
|
|
|
104
104
|
- Use when you need governed AI development, auditable decision trails, and requirement-to-test linkage.
|
|
105
|
+
- Use especially for larger projects where governance reduces token costs by 2-6x compared to ungoverned approaches (as demonstrated in our efficiency benchmarks)
|
|
106
|
+
- Use with local LLMs like LMStudio, vLLM, or llama.cpp for maximum cost control and privacy
|
|
105
107
|
- Avoid when rapid local prototyping is the only goal and formal governance is unnecessary.
|
|
106
108
|
|
|
107
109
|
## Comparison summary
|
|
@@ -124,8 +126,34 @@ We ran a [multi-condition benchmark](https://specsmith.readthedocs.io/en/stable/
|
|
|
124
126
|
|
|
125
127
|
**Key findings:** specsmith FULL is the only condition to achieve 100% pass rate on the feature-addition task (T1). It uses 2.6× fewer tokens than ungoverned and produces a cost-of-pass 3.2× lower than the next-best alternative. With gpt-5.5, governance reduces cost-of-pass by **6.3×** ($0.028 vs $0.179).
|
|
126
128
|
|
|
129
|
+
## Current Stats
|
|
130
|
+
|
|
131
|
+
- **52+ model profiles** in registry (including Qwen3.6-35B-A3B)
|
|
132
|
+
- **127 canonical skills** available across all domains
|
|
133
|
+
- **10 governance skills** (including improvement-reporter, agent-flow-controller, model-runtime-optimizer)
|
|
134
|
+
- **Development mode** with improvement tracking and session analysis
|
|
135
|
+
|
|
136
|
+
See the [full benchmark report](https://specsmith.readthedocs.io/en/stable/efficiency-benchmark/) and [model comparison (gpt-4o-mini vs gpt-5.5)](https://specsmith.readthedocs.io/en/stable/model-comparison/).
|
|
137
|
+
|
|
138
|
+
### Development Mode Features
|
|
139
|
+
|
|
140
|
+
When enabled in project configuration, development mode provides:
|
|
141
|
+
|
|
142
|
+
- **Enhanced logging** for all agent interactions and decision-making processes
|
|
143
|
+
- **Session analysis** that tracks what worked, what didn't, and improvement suggestions
|
|
144
|
+
- **Cost-per-correct-solution metrics** to measure efficiency
|
|
145
|
+
- **Automated improvement tracking** to identify patterns and areas for optimization
|
|
146
|
+
- **Session reports** that can be generated for review and analysis
|
|
147
|
+
|
|
148
|
+
To enable development mode, set `enable_development_mode: true` in your project's `.specsmith/config.yml` file.
|
|
149
|
+
|
|
127
150
|
See the [full benchmark report](https://specsmith.readthedocs.io/en/stable/efficiency-benchmark/) and [model comparison (gpt-4o-mini vs gpt-5.5)](https://specsmith.readthedocs.io/en/stable/model-comparison/).
|
|
128
151
|
|
|
152
|
+
**v0.22.0** - Epistemic chat handoffs preserve source provenance for Zoo-Code and
|
|
153
|
+
other agents, while a mergeable JSONL session-event log keeps collaboration state
|
|
154
|
+
reviewable. This release also adds CPU-safe local-model fallback (REQ-445) and
|
|
155
|
+
stable-release validation before PyPI publishing.
|
|
156
|
+
|
|
129
157
|
**v0.20.0** — Native Warp integration: `specsmith integrate warp` scaffolds `.warp/` MCP + launch configs and a Warp-aware `specsmith run` banner (REQ-444). Plus VRAM-aware local model recommendations: `specsmith local-model recommend` prints a per-role lineup (default / fast / harder pass / general) with a `fits`/`tight`/`spills` fit assessment (REQ-445).
|
|
130
158
|
|
|
131
159
|
**v0.19.x** — `specsmith wi link-test`, the governance-YAML content auditor and sync markdown-reconcile warnings, and a HuggingFace provider + 15-model multi-provider benchmark matrix for GovernanceBench.
|
|
@@ -148,6 +176,7 @@ specsmith ollama gpu # detect GPU VRAM, recommend context
|
|
|
148
176
|
specsmith local-model recommend # VRAM-aware model lineup (fits/tight/spills)
|
|
149
177
|
specsmith integrate warp # scaffold Warp-native governance (MCP + launch config)
|
|
150
178
|
specsmith export # generate full compliance report
|
|
179
|
+
specsmith endpoints add lmstudio # add LMStudio endpoint for BYOE support
|
|
151
180
|
|
|
152
181
|
# Update channels
|
|
153
182
|
specsmith channel set stable # pin to stable releases
|
|
@@ -215,17 +244,6 @@ specsmith phase list # list all phases
|
|
|
215
244
|
The current phase is persisted in `scaffold.yml` as `aee_phase`. Each phase has a checklist
|
|
216
245
|
of file/command criteria, recommended commands, and a readiness percentage.
|
|
217
246
|
|
|
218
|
-
## 1.0 release criteria status
|
|
219
|
-
|
|
220
|
-
| Criterion | Status | Source |
|
|
221
|
-
|---|---|---|
|
|
222
|
-
| Stable CLI core contract documented | In progress | `docs/stability.md` |
|
|
223
|
-
| Stable generated file schemas documented | In progress | `docs/stability.md` |
|
|
224
|
-
| Stable MCP tool schemas documented | In progress | `docs/stability.md` |
|
|
225
|
-
| Migration tests linked (#218) | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
226
|
-
| Security threat model documented | In progress | `docs/security-threat-model.md` |
|
|
227
|
-
| Docs/tutorial/glossary baseline complete | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
228
|
-
| Upgrade path and changelog criteria defined | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
229
247
|
|
|
230
248
|
---
|
|
231
249
|
|
|
@@ -353,6 +371,14 @@ specsmith phase # current phase + readiness %
|
|
|
353
371
|
specsmith audit # full governance health check
|
|
354
372
|
```
|
|
355
373
|
|
|
374
|
+
> **Session Bootstrap**: For a more streamlined session start, you can also use:
|
|
375
|
+
> ```bash
|
|
376
|
+
> specsmith load # run migrate, audit, sync, and checkpoint in sequence
|
|
377
|
+
> ```
|
|
378
|
+
> This command combines the essential bootstrap steps for a clean session start.
|
|
379
|
+
>
|
|
380
|
+
> **Note**: The `specsmith load` command is particularly useful for quickly setting up a new session with all governance checks in place.
|
|
381
|
+
|
|
356
382
|
> **Agentic REPL:** run `specsmith run` to start the Nexus governance-gated LLM REPL.
|
|
357
383
|
> Every utterance is preflighted automatically. Use `/why` to see the governance trace.
|
|
358
384
|
> For the multi-agent DAG dispatcher, see `specsmith dispatch run "<task>"`.
|
|
@@ -1130,6 +1156,16 @@ specsmith skill install specsmith-audit
|
|
|
1130
1156
|
|
|
1131
1157
|
Skills are installed as `.agents/skills/<slug>/SKILL.md` and are auto-discovered by any AI tool that scans `.agents/skills/`.
|
|
1132
1158
|
|
|
1159
|
+
### Skill Policy
|
|
1160
|
+
|
|
1161
|
+
If a skill is reusable across projects, it belongs in `src/specsmith/skills/<domain>.py`.
|
|
1162
|
+
|
|
1163
|
+
If a skill is project-specific, generated by the user, or experimental, it belongs in `.specsmith/skills/<skill-id>/`.
|
|
1164
|
+
|
|
1165
|
+
If a skill needs to be read by Claude Code, Warp, Cursor, Aider, etc., it is exported/materialized into `.agents/skills/<slug>/SKILL.md`.
|
|
1166
|
+
|
|
1167
|
+
Do not hand-edit `.agents/skills/` as a canonical source.
|
|
1168
|
+
|
|
1133
1169
|
### Skill domains
|
|
1134
1170
|
|
|
1135
1171
|
| Domain | Count | Coverage |
|
|
@@ -1388,7 +1424,6 @@ command reference, project types, tool registry, governance model, ESDB, skills
|
|
|
1388
1424
|
- [PyPI](https://pypi.org/project/specsmith/)
|
|
1389
1425
|
- [Documentation](https://specsmith.readthedocs.io)
|
|
1390
1426
|
- [Stability Contract](https://github.com/layer1labs/specsmith/blob/develop/docs/stability.md)
|
|
1391
|
-
- [1.0 Release Criteria](https://github.com/layer1labs/specsmith/blob/develop/docs/roadmap/1.0-criteria.md)
|
|
1392
1427
|
- [Editions Matrix](https://github.com/layer1labs/specsmith/blob/develop/docs/editions.md)
|
|
1393
1428
|
- [Changelog](https://github.com/layer1labs/specsmith/blob/develop/CHANGELOG.md)
|
|
1394
1429
|
- [Contributing](https://github.com/layer1labs/specsmith/blob/develop/CONTRIBUTING.md)
|
|
@@ -24,6 +24,8 @@ AI Agents / IDE Clients
|
|
|
24
24
|
## When to use / when not to use
|
|
25
25
|
|
|
26
26
|
- Use when you need governed AI development, auditable decision trails, and requirement-to-test linkage.
|
|
27
|
+
- Use especially for larger projects where governance reduces token costs by 2-6x compared to ungoverned approaches (as demonstrated in our efficiency benchmarks)
|
|
28
|
+
- Use with local LLMs like LMStudio, vLLM, or llama.cpp for maximum cost control and privacy
|
|
27
29
|
- Avoid when rapid local prototyping is the only goal and formal governance is unnecessary.
|
|
28
30
|
|
|
29
31
|
## Comparison summary
|
|
@@ -46,8 +48,34 @@ We ran a [multi-condition benchmark](https://specsmith.readthedocs.io/en/stable/
|
|
|
46
48
|
|
|
47
49
|
**Key findings:** specsmith FULL is the only condition to achieve 100% pass rate on the feature-addition task (T1). It uses 2.6× fewer tokens than ungoverned and produces a cost-of-pass 3.2× lower than the next-best alternative. With gpt-5.5, governance reduces cost-of-pass by **6.3×** ($0.028 vs $0.179).
|
|
48
50
|
|
|
51
|
+
## Current Stats
|
|
52
|
+
|
|
53
|
+
- **52+ model profiles** in registry (including Qwen3.6-35B-A3B)
|
|
54
|
+
- **127 canonical skills** available across all domains
|
|
55
|
+
- **10 governance skills** (including improvement-reporter, agent-flow-controller, model-runtime-optimizer)
|
|
56
|
+
- **Development mode** with improvement tracking and session analysis
|
|
57
|
+
|
|
58
|
+
See the [full benchmark report](https://specsmith.readthedocs.io/en/stable/efficiency-benchmark/) and [model comparison (gpt-4o-mini vs gpt-5.5)](https://specsmith.readthedocs.io/en/stable/model-comparison/).
|
|
59
|
+
|
|
60
|
+
### Development Mode Features
|
|
61
|
+
|
|
62
|
+
When enabled in project configuration, development mode provides:
|
|
63
|
+
|
|
64
|
+
- **Enhanced logging** for all agent interactions and decision-making processes
|
|
65
|
+
- **Session analysis** that tracks what worked, what didn't, and improvement suggestions
|
|
66
|
+
- **Cost-per-correct-solution metrics** to measure efficiency
|
|
67
|
+
- **Automated improvement tracking** to identify patterns and areas for optimization
|
|
68
|
+
- **Session reports** that can be generated for review and analysis
|
|
69
|
+
|
|
70
|
+
To enable development mode, set `enable_development_mode: true` in your project's `.specsmith/config.yml` file.
|
|
71
|
+
|
|
49
72
|
See the [full benchmark report](https://specsmith.readthedocs.io/en/stable/efficiency-benchmark/) and [model comparison (gpt-4o-mini vs gpt-5.5)](https://specsmith.readthedocs.io/en/stable/model-comparison/).
|
|
50
73
|
|
|
74
|
+
**v0.22.0** - Epistemic chat handoffs preserve source provenance for Zoo-Code and
|
|
75
|
+
other agents, while a mergeable JSONL session-event log keeps collaboration state
|
|
76
|
+
reviewable. This release also adds CPU-safe local-model fallback (REQ-445) and
|
|
77
|
+
stable-release validation before PyPI publishing.
|
|
78
|
+
|
|
51
79
|
**v0.20.0** — Native Warp integration: `specsmith integrate warp` scaffolds `.warp/` MCP + launch configs and a Warp-aware `specsmith run` banner (REQ-444). Plus VRAM-aware local model recommendations: `specsmith local-model recommend` prints a per-role lineup (default / fast / harder pass / general) with a `fits`/`tight`/`spills` fit assessment (REQ-445).
|
|
52
80
|
|
|
53
81
|
**v0.19.x** — `specsmith wi link-test`, the governance-YAML content auditor and sync markdown-reconcile warnings, and a HuggingFace provider + 15-model multi-provider benchmark matrix for GovernanceBench.
|
|
@@ -70,6 +98,7 @@ specsmith ollama gpu # detect GPU VRAM, recommend context
|
|
|
70
98
|
specsmith local-model recommend # VRAM-aware model lineup (fits/tight/spills)
|
|
71
99
|
specsmith integrate warp # scaffold Warp-native governance (MCP + launch config)
|
|
72
100
|
specsmith export # generate full compliance report
|
|
101
|
+
specsmith endpoints add lmstudio # add LMStudio endpoint for BYOE support
|
|
73
102
|
|
|
74
103
|
# Update channels
|
|
75
104
|
specsmith channel set stable # pin to stable releases
|
|
@@ -137,17 +166,6 @@ specsmith phase list # list all phases
|
|
|
137
166
|
The current phase is persisted in `scaffold.yml` as `aee_phase`. Each phase has a checklist
|
|
138
167
|
of file/command criteria, recommended commands, and a readiness percentage.
|
|
139
168
|
|
|
140
|
-
## 1.0 release criteria status
|
|
141
|
-
|
|
142
|
-
| Criterion | Status | Source |
|
|
143
|
-
|---|---|---|
|
|
144
|
-
| Stable CLI core contract documented | In progress | `docs/stability.md` |
|
|
145
|
-
| Stable generated file schemas documented | In progress | `docs/stability.md` |
|
|
146
|
-
| Stable MCP tool schemas documented | In progress | `docs/stability.md` |
|
|
147
|
-
| Migration tests linked (#218) | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
148
|
-
| Security threat model documented | In progress | `docs/security-threat-model.md` |
|
|
149
|
-
| Docs/tutorial/glossary baseline complete | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
150
|
-
| Upgrade path and changelog criteria defined | In progress | `docs/roadmap/1.0-criteria.md` |
|
|
151
169
|
|
|
152
170
|
---
|
|
153
171
|
|
|
@@ -275,6 +293,14 @@ specsmith phase # current phase + readiness %
|
|
|
275
293
|
specsmith audit # full governance health check
|
|
276
294
|
```
|
|
277
295
|
|
|
296
|
+
> **Session Bootstrap**: For a more streamlined session start, you can also use:
|
|
297
|
+
> ```bash
|
|
298
|
+
> specsmith load # run migrate, audit, sync, and checkpoint in sequence
|
|
299
|
+
> ```
|
|
300
|
+
> This command combines the essential bootstrap steps for a clean session start.
|
|
301
|
+
>
|
|
302
|
+
> **Note**: The `specsmith load` command is particularly useful for quickly setting up a new session with all governance checks in place.
|
|
303
|
+
|
|
278
304
|
> **Agentic REPL:** run `specsmith run` to start the Nexus governance-gated LLM REPL.
|
|
279
305
|
> Every utterance is preflighted automatically. Use `/why` to see the governance trace.
|
|
280
306
|
> For the multi-agent DAG dispatcher, see `specsmith dispatch run "<task>"`.
|
|
@@ -1052,6 +1078,16 @@ specsmith skill install specsmith-audit
|
|
|
1052
1078
|
|
|
1053
1079
|
Skills are installed as `.agents/skills/<slug>/SKILL.md` and are auto-discovered by any AI tool that scans `.agents/skills/`.
|
|
1054
1080
|
|
|
1081
|
+
### Skill Policy
|
|
1082
|
+
|
|
1083
|
+
If a skill is reusable across projects, it belongs in `src/specsmith/skills/<domain>.py`.
|
|
1084
|
+
|
|
1085
|
+
If a skill is project-specific, generated by the user, or experimental, it belongs in `.specsmith/skills/<skill-id>/`.
|
|
1086
|
+
|
|
1087
|
+
If a skill needs to be read by Claude Code, Warp, Cursor, Aider, etc., it is exported/materialized into `.agents/skills/<slug>/SKILL.md`.
|
|
1088
|
+
|
|
1089
|
+
Do not hand-edit `.agents/skills/` as a canonical source.
|
|
1090
|
+
|
|
1055
1091
|
### Skill domains
|
|
1056
1092
|
|
|
1057
1093
|
| Domain | Count | Coverage |
|
|
@@ -1310,7 +1346,6 @@ command reference, project types, tool registry, governance model, ESDB, skills
|
|
|
1310
1346
|
- [PyPI](https://pypi.org/project/specsmith/)
|
|
1311
1347
|
- [Documentation](https://specsmith.readthedocs.io)
|
|
1312
1348
|
- [Stability Contract](https://github.com/layer1labs/specsmith/blob/develop/docs/stability.md)
|
|
1313
|
-
- [1.0 Release Criteria](https://github.com/layer1labs/specsmith/blob/develop/docs/roadmap/1.0-criteria.md)
|
|
1314
1349
|
- [Editions Matrix](https://github.com/layer1labs/specsmith/blob/develop/docs/editions.md)
|
|
1315
1350
|
- [Changelog](https://github.com/layer1labs/specsmith/blob/develop/CHANGELOG.md)
|
|
1316
1351
|
- [Contributing](https://github.com/layer1labs/specsmith/blob/develop/CONTRIBUTING.md)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specsmith"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.22.0"
|
|
8
8
|
description = "AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -8,4 +8,4 @@ from importlib.metadata import version as _pkg_version
|
|
|
8
8
|
try:
|
|
9
9
|
__version__: str = _pkg_version("specsmith")
|
|
10
10
|
except PackageNotFoundError: # running from source without install
|
|
11
|
-
__version__ = "0.
|
|
11
|
+
__version__ = "0.22.0" # fallback: keep in sync with pyproject.toml
|
|
@@ -249,7 +249,7 @@ def _consolidate_governance_files(root: Path) -> list[str]:
|
|
|
249
249
|
reqs_yaml_dir = root / "docs" / "requirements"
|
|
250
250
|
reqs_yaml_dir.mkdir(parents=True, exist_ok=True)
|
|
251
251
|
consolidated.append("Consolidated requirements to YAML structure")
|
|
252
|
-
except Exception:
|
|
252
|
+
except Exception: # noqa: BLE001 # intentional: fire-and-forget cleanup; log is written above
|
|
253
253
|
pass
|
|
254
254
|
|
|
255
255
|
if tests_dir.exists() and tests_dir.is_dir():
|
|
@@ -258,7 +258,7 @@ def _consolidate_governance_files(root: Path) -> list[str]:
|
|
|
258
258
|
tests_yaml_dir = root / "docs" / "tests"
|
|
259
259
|
tests_yaml_dir.mkdir(parents=True, exist_ok=True)
|
|
260
260
|
consolidated.append("Consolidated tests to YAML structure")
|
|
261
|
-
except Exception:
|
|
261
|
+
except Exception: # noqa: BLE001 # intentional: fire-and-forget cleanup; log is written above
|
|
262
262
|
pass
|
|
263
263
|
|
|
264
264
|
return consolidated
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2026 Layer1Labs Silicon, Inc. All rights reserved.
|
|
3
|
+
"""Evidence-preserving chat compaction and portable agent handoffs (REQ-446)."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import hashlib
|
|
8
|
+
import json
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
SCHEMA_VERSION = 1
|
|
13
|
+
_MAX_EXCERPT = 280
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_handoff(
|
|
17
|
+
history: list[dict[str, Any]],
|
|
18
|
+
*,
|
|
19
|
+
work_item_ids: list[str] | None = None,
|
|
20
|
+
) -> dict[str, Any]:
|
|
21
|
+
"""Build an extractive, provenance-preserving envelope from chat turns.
|
|
22
|
+
|
|
23
|
+
This deliberately does not ask an LLM to invent a prose summary. Each
|
|
24
|
+
compacted claim remains a bounded excerpt linked to a deterministic turn ID,
|
|
25
|
+
allowing another agent to inspect the original history before relying on it.
|
|
26
|
+
"""
|
|
27
|
+
turns: list[dict[str, str]] = []
|
|
28
|
+
for index, turn in enumerate(history):
|
|
29
|
+
role = turn.get("role")
|
|
30
|
+
content = turn.get("content")
|
|
31
|
+
if not isinstance(role, str) or not isinstance(content, str) or not content.strip():
|
|
32
|
+
continue
|
|
33
|
+
canonical = json.dumps(
|
|
34
|
+
{"role": role, "content": content}, sort_keys=True, ensure_ascii=False
|
|
35
|
+
)
|
|
36
|
+
source_id = f"turn:{hashlib.sha256(canonical.encode('utf-8')).hexdigest()[:16]}"
|
|
37
|
+
turns.append(
|
|
38
|
+
{
|
|
39
|
+
"source_id": source_id,
|
|
40
|
+
"role": role,
|
|
41
|
+
"excerpt": content.strip()[:_MAX_EXCERPT],
|
|
42
|
+
"position": str(index),
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
payload = {
|
|
47
|
+
"schema_version": SCHEMA_VERSION,
|
|
48
|
+
"kind": "epistemic_chat_handoff",
|
|
49
|
+
"created_at": datetime.now(timezone.utc).isoformat(),
|
|
50
|
+
"confidence": 1.0,
|
|
51
|
+
"uncertainty": "Extractive envelope; excerpts are not inferred claims.",
|
|
52
|
+
"work_item_ids": sorted(set(work_item_ids or [])),
|
|
53
|
+
"turns": turns,
|
|
54
|
+
}
|
|
55
|
+
fingerprint = json.dumps(payload, sort_keys=True, ensure_ascii=False)
|
|
56
|
+
digest = hashlib.sha256(fingerprint.encode("utf-8")).hexdigest()[:16].upper()
|
|
57
|
+
payload["id"] = f"HANDOFF-{digest}"
|
|
58
|
+
validate_handoff(payload)
|
|
59
|
+
return payload
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def validate_handoff(payload: dict[str, Any]) -> None:
|
|
63
|
+
"""Reject malformed or unsupported handoff claims before persistence/import."""
|
|
64
|
+
if (
|
|
65
|
+
payload.get("schema_version") != SCHEMA_VERSION
|
|
66
|
+
or payload.get("kind") != "epistemic_chat_handoff"
|
|
67
|
+
):
|
|
68
|
+
raise ValueError("unsupported handoff schema")
|
|
69
|
+
if not isinstance(payload.get("id"), str) or not payload["id"].startswith("HANDOFF-"):
|
|
70
|
+
raise ValueError("handoff must have a stable ID")
|
|
71
|
+
if payload.get("confidence") != 1.0:
|
|
72
|
+
raise ValueError("extractive handoffs must retain confidence 1.0")
|
|
73
|
+
for turn in payload.get("turns", []):
|
|
74
|
+
if not isinstance(turn, dict) or not isinstance(turn.get("source_id"), str):
|
|
75
|
+
raise ValueError("handoff turn is missing provenance")
|
|
76
|
+
if not isinstance(turn.get("excerpt"), str) or len(turn["excerpt"]) > _MAX_EXCERPT:
|
|
77
|
+
raise ValueError("handoff excerpt is invalid")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def render_handoff_context(payload: dict[str, Any]) -> str:
|
|
81
|
+
"""Render a bounded context entry that tells agents how to verify it."""
|
|
82
|
+
validate_handoff(payload)
|
|
83
|
+
excerpts = "\n".join(
|
|
84
|
+
f"- [{turn['source_id']}] {turn['role']}: {turn['excerpt']}" for turn in payload["turns"]
|
|
85
|
+
)
|
|
86
|
+
return (
|
|
87
|
+
f"[Epistemic handoff {payload['id']} | {len(payload['turns'])} extractive turns | "
|
|
88
|
+
"verify source IDs before treating excerpts as decisions]\n"
|
|
89
|
+
f"{excerpts}"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def store_handoff(root: Any, payload: dict[str, Any]) -> None:
|
|
94
|
+
"""Persist a validated handoff in the active ESDB backend."""
|
|
95
|
+
validate_handoff(payload)
|
|
96
|
+
from specsmith.esdb import SqliteRecord, open_default_store
|
|
97
|
+
|
|
98
|
+
with open_default_store(root) as store:
|
|
99
|
+
store.upsert(
|
|
100
|
+
SqliteRecord(
|
|
101
|
+
id=payload["id"],
|
|
102
|
+
kind="chat_handoff",
|
|
103
|
+
label="Epistemic chat handoff",
|
|
104
|
+
confidence=1.0,
|
|
105
|
+
data=payload,
|
|
106
|
+
),
|
|
107
|
+
)
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
7
|
import contextlib
|
|
8
|
+
import sys
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import Any
|
|
10
11
|
|
|
@@ -189,13 +190,17 @@ def _maybe_prompt_project_update() -> None:
|
|
|
189
190
|
|
|
190
191
|
if installed < project:
|
|
191
192
|
# Backward migration (downgrade) — hard error, REQ-370.
|
|
193
|
+
from specsmith.updater import version_mismatch_remediation
|
|
194
|
+
|
|
195
|
+
remedy = version_mismatch_remediation(project_ver)
|
|
192
196
|
click.echo(
|
|
193
197
|
f"\nERROR: specsmith downgrade detected.\n"
|
|
194
198
|
f" Project spec_version : {project_ver}\n"
|
|
195
199
|
f" Installed specsmith : {__version__} (older)\n"
|
|
196
200
|
"\n"
|
|
197
201
|
" Backward migration is not supported.\n"
|
|
198
|
-
"
|
|
202
|
+
f" Install the required version: {remedy}\n"
|
|
203
|
+
" Stable projects can instead use: pipx upgrade specsmith\n"
|
|
199
204
|
" Then re-run this command.",
|
|
200
205
|
err=True,
|
|
201
206
|
)
|
|
@@ -595,8 +600,19 @@ def _load_config_with_inheritance(config_path: str) -> dict[str, object]:
|
|
|
595
600
|
VCS_PLATFORM_CHOICES = {"1": "github", "2": "gitlab", "3": "bitbucket", "4": ""}
|
|
596
601
|
VCS_PLATFORM_LABELS = {"1": "GitHub", "2": "GitLab", "3": "Bitbucket", "4": "None"}
|
|
597
602
|
|
|
598
|
-
BRANCH_STRATEGY_CHOICES = {
|
|
599
|
-
|
|
603
|
+
BRANCH_STRATEGY_CHOICES = {
|
|
604
|
+
"1": "single-branch",
|
|
605
|
+
"2": "gitflow",
|
|
606
|
+
"3": "trunk-based",
|
|
607
|
+
"4": "github-flow",
|
|
608
|
+
}
|
|
609
|
+
BRANCH_STRATEGY_LABELS = {
|
|
610
|
+
"1": "Single branch (direct governed work on main)",
|
|
611
|
+
"2": "Gitflow",
|
|
612
|
+
"3": "Trunk-based",
|
|
613
|
+
"4": "GitHub Flow",
|
|
614
|
+
}
|
|
615
|
+
_BRANCH_WORKFLOWS = tuple(BRANCH_STRATEGY_CHOICES.values())
|
|
600
616
|
|
|
601
617
|
|
|
602
618
|
def _interactive_config(no_git: bool) -> ProjectConfig:
|
|
@@ -631,7 +647,7 @@ def _interactive_config(no_git: bool) -> ProjectConfig:
|
|
|
631
647
|
for k, v in BRANCH_STRATEGY_LABELS.items():
|
|
632
648
|
console.print(f" {k}. {v}")
|
|
633
649
|
branch_choice = click.prompt("Select strategy", default="1")
|
|
634
|
-
branching_strategy = BRANCH_STRATEGY_CHOICES.get(branch_choice, "
|
|
650
|
+
branching_strategy = BRANCH_STRATEGY_CHOICES.get(branch_choice, "single-branch")
|
|
635
651
|
|
|
636
652
|
return ProjectConfig(
|
|
637
653
|
name=name,
|
|
@@ -1881,6 +1897,17 @@ def doctor(project_dir: str, onboarding: bool, as_json: bool) -> None:
|
|
|
1881
1897
|
ok, detail = _tool_version(tool)
|
|
1882
1898
|
_add(tool, ok, detail)
|
|
1883
1899
|
|
|
1900
|
+
if _is_windows_platform():
|
|
1901
|
+
from specsmith.updater import find_windows_launchers
|
|
1902
|
+
|
|
1903
|
+
launchers = find_windows_launchers(__import__("os").environ.get("PATH", ""))
|
|
1904
|
+
_add(
|
|
1905
|
+
"specsmith launchers",
|
|
1906
|
+
len(launchers) <= 1,
|
|
1907
|
+
str(launchers[0]) if len(launchers) == 1 else f"{len(launchers)} found; use pipx only",
|
|
1908
|
+
warn=len(launchers) > 1,
|
|
1909
|
+
)
|
|
1910
|
+
|
|
1884
1911
|
overall = "pass" if all(c["status"] != "fail" for c in checks) else "fail"
|
|
1885
1912
|
|
|
1886
1913
|
if as_json:
|
|
@@ -1899,6 +1926,11 @@ def doctor(project_dir: str, onboarding: bool, as_json: bool) -> None:
|
|
|
1899
1926
|
console.print("One or more checks failed.")
|
|
1900
1927
|
|
|
1901
1928
|
|
|
1929
|
+
def _is_windows_platform() -> bool:
|
|
1930
|
+
"""Return whether the CLI is running on Windows."""
|
|
1931
|
+
return sys.platform == "win32"
|
|
1932
|
+
|
|
1933
|
+
|
|
1902
1934
|
@main.command()
|
|
1903
1935
|
@click.option(
|
|
1904
1936
|
"--project-dir",
|
|
@@ -3634,12 +3666,12 @@ def branch_create(name: str, project_dir: str) -> None:
|
|
|
3634
3666
|
"""Create a branch following the branching strategy."""
|
|
3635
3667
|
root = Path(project_dir).resolve()
|
|
3636
3668
|
scaffold_path = root / "scaffold.yml"
|
|
3637
|
-
strategy = "
|
|
3669
|
+
strategy = "single-branch"
|
|
3638
3670
|
main_branch = "main"
|
|
3639
3671
|
if scaffold_path.exists():
|
|
3640
3672
|
with open(scaffold_path) as f:
|
|
3641
3673
|
raw = yaml.safe_load(f) or {}
|
|
3642
|
-
strategy = raw.get("branching_strategy", "
|
|
3674
|
+
strategy = raw.get("branching_strategy", "single-branch")
|
|
3643
3675
|
main_branch = raw.get("default_branch", "main")
|
|
3644
3676
|
|
|
3645
3677
|
from specsmith.vcs_commands import create_branch
|
|
@@ -3648,7 +3680,34 @@ def branch_create(name: str, project_dir: str) -> None:
|
|
|
3648
3680
|
if result.success:
|
|
3649
3681
|
console.print(f"[green]\u2713[/green] {result.message}")
|
|
3650
3682
|
else:
|
|
3651
|
-
|
|
3683
|
+
raise click.ClickException(result.message)
|
|
3684
|
+
|
|
3685
|
+
|
|
3686
|
+
@branch_group.command(name="workflow")
|
|
3687
|
+
@click.argument("strategy", required=False, type=click.Choice(_BRANCH_WORKFLOWS))
|
|
3688
|
+
@click.option("--project-dir", type=click.Path(exists=True), default=".")
|
|
3689
|
+
def branch_workflow(strategy: str | None, project_dir: str) -> None:
|
|
3690
|
+
"""Show or explicitly select the governed branching workflow."""
|
|
3691
|
+
root = Path(project_dir).resolve()
|
|
3692
|
+
scaffold_path = root / "scaffold.yml"
|
|
3693
|
+
if not scaffold_path.exists():
|
|
3694
|
+
raise click.ClickException(
|
|
3695
|
+
"No scaffold.yml found; run specsmith init before selecting a workflow."
|
|
3696
|
+
)
|
|
3697
|
+
|
|
3698
|
+
with scaffold_path.open(encoding="utf-8") as handle:
|
|
3699
|
+
raw = yaml.safe_load(handle) or {}
|
|
3700
|
+
current = str(raw.get("branching_strategy", "single-branch"))
|
|
3701
|
+
if strategy is None:
|
|
3702
|
+
console.print(f"Branch workflow: {current}")
|
|
3703
|
+
return
|
|
3704
|
+
|
|
3705
|
+
raw["branching_strategy"] = strategy
|
|
3706
|
+
scaffold_path.write_text(
|
|
3707
|
+
yaml.safe_dump(raw, default_flow_style=False, sort_keys=False),
|
|
3708
|
+
encoding="utf-8",
|
|
3709
|
+
)
|
|
3710
|
+
console.print(f"[green]\u2713[/green] Branch workflow set to {strategy}")
|
|
3652
3711
|
|
|
3653
3712
|
|
|
3654
3713
|
@branch_group.command(name="list")
|
|
@@ -3789,6 +3848,13 @@ def channel_set_cmd(channel: str) -> None:
|
|
|
3789
3848
|
immediately for all subsequent ``specsmith self-update`` / ``update`` calls.
|
|
3790
3849
|
"""
|
|
3791
3850
|
from specsmith.channel import set_persisted_channel
|
|
3851
|
+
from specsmith.updater import is_prerelease_version, version_mismatch_remediation
|
|
3852
|
+
|
|
3853
|
+
if channel == "stable" and is_prerelease_version(__version__):
|
|
3854
|
+
raise click.UsageError(
|
|
3855
|
+
"Cannot select stable while a prerelease is installed. "
|
|
3856
|
+
f"Install a stable build first: {version_mismatch_remediation('0.22.0')}"
|
|
3857
|
+
)
|
|
3792
3858
|
|
|
3793
3859
|
set_persisted_channel(channel)
|
|
3794
3860
|
channel_color = "cyan" if channel == "dev" else "green"
|
|
@@ -14446,5 +14512,77 @@ def ai_analyze_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
14446
14512
|
raise SystemExit(1) from e
|
|
14447
14513
|
|
|
14448
14514
|
|
|
14515
|
+
# Development mode and improvement tracking commands
|
|
14516
|
+
@main.group(name="dev", invoke_without_command=True)
|
|
14517
|
+
def dev_group() -> None:
|
|
14518
|
+
"""Development mode and improvement tracking commands."""
|
|
14519
|
+
pass
|
|
14520
|
+
|
|
14521
|
+
|
|
14522
|
+
@dev_group.command(name="session-report")
|
|
14523
|
+
@click.option(
|
|
14524
|
+
"--session-id",
|
|
14525
|
+
type=str,
|
|
14526
|
+
default=None,
|
|
14527
|
+
help="Session ID to report on (default: latest session).",
|
|
14528
|
+
)
|
|
14529
|
+
@click.option(
|
|
14530
|
+
"--project-dir",
|
|
14531
|
+
type=click.Path(exists=True),
|
|
14532
|
+
default=".",
|
|
14533
|
+
help="Project root directory.",
|
|
14534
|
+
)
|
|
14535
|
+
@click.option(
|
|
14536
|
+
"--json",
|
|
14537
|
+
"as_json",
|
|
14538
|
+
is_flag=True,
|
|
14539
|
+
default=False,
|
|
14540
|
+
help="Emit results as JSON.",
|
|
14541
|
+
)
|
|
14542
|
+
def dev_session_report_cmd(session_id: str | None, project_dir: str, as_json: bool) -> None:
|
|
14543
|
+
"""Generate a session report with improvement analysis."""
|
|
14544
|
+
from pathlib import Path
|
|
14545
|
+
|
|
14546
|
+
from specsmith.improvement_tracker import ImprovementTracker
|
|
14547
|
+
|
|
14548
|
+
root = Path(project_dir).resolve()
|
|
14549
|
+
tracker = ImprovementTracker(root)
|
|
14550
|
+
|
|
14551
|
+
if as_json:
|
|
14552
|
+
# Return JSON output
|
|
14553
|
+
import json as _json
|
|
14554
|
+
|
|
14555
|
+
if session_id:
|
|
14556
|
+
analysis = tracker.get_session_analysis(session_id)
|
|
14557
|
+
if analysis:
|
|
14558
|
+
click.echo(_json.dumps(analysis.model_dump(), indent=2))
|
|
14559
|
+
else:
|
|
14560
|
+
click.echo(_json.dumps({"error": "Session not found"}, indent=2))
|
|
14561
|
+
else:
|
|
14562
|
+
# Get latest session
|
|
14563
|
+
# For simplicity, we'll just list recent sessions
|
|
14564
|
+
improvements = tracker.get_recent_improvements(10)
|
|
14565
|
+
result = {"recent_improvements": [imp.model_dump() for imp in improvements]}
|
|
14566
|
+
click.echo(_json.dumps(result, indent=2))
|
|
14567
|
+
else:
|
|
14568
|
+
# Return human-readable output
|
|
14569
|
+
if session_id:
|
|
14570
|
+
analysis = tracker.get_session_analysis(session_id)
|
|
14571
|
+
if analysis:
|
|
14572
|
+
report = tracker.generate_session_report(session_id)
|
|
14573
|
+
click.echo(report)
|
|
14574
|
+
else:
|
|
14575
|
+
click.echo(f"Session {session_id} not found.")
|
|
14576
|
+
else:
|
|
14577
|
+
# Show recent improvements
|
|
14578
|
+
improvements = tracker.get_recent_improvements(10)
|
|
14579
|
+
if improvements:
|
|
14580
|
+
click.echo("Recent Improvements:")
|
|
14581
|
+
for imp in improvements:
|
|
14582
|
+
click.echo(f" - {imp.description} ({imp.severity})")
|
|
14583
|
+
else:
|
|
14584
|
+
click.echo("No recent improvements recorded.")
|
|
14585
|
+
|
|
14586
|
+
|
|
14449
14587
|
if __name__ == "__main__":
|
|
14450
14588
|
main()
|
|
@@ -22,6 +22,25 @@ def zoo_code_group() -> None:
|
|
|
22
22
|
"""Manage Zoo-Code integration and benchmarking for Specsmith."""
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
@zoo_code_group.command("export-handoff")
|
|
26
|
+
@click.option("--project-dir", default=".", help="Governed project containing session state")
|
|
27
|
+
@click.option("--output", type=click.Path(), required=True, help="Portable handoff JSON path")
|
|
28
|
+
def zoo_code_export_handoff(project_dir: str, output: str) -> None:
|
|
29
|
+
"""Export the latest session as a validated portable agent handoff."""
|
|
30
|
+
from specsmith.chat_handoff import build_handoff
|
|
31
|
+
from specsmith.session_store import load_session
|
|
32
|
+
|
|
33
|
+
root = Path(project_dir)
|
|
34
|
+
context, history = load_session(root)
|
|
35
|
+
handoff = build_handoff(history, work_item_ids=list((context or {}).get("work_item_ids", [])))
|
|
36
|
+
output_path = Path(output)
|
|
37
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
output_path.write_text(
|
|
39
|
+
json.dumps(handoff, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"
|
|
40
|
+
)
|
|
41
|
+
click.echo(f"Exported epistemic handoff {handoff['id']} to {output_path}")
|
|
42
|
+
|
|
43
|
+
|
|
25
44
|
@zoo_code_group.command("init")
|
|
26
45
|
@click.option("--output-dir", default=".", help="Directory to create Zoo-Code config files")
|
|
27
46
|
def zoo_code_init(output_dir: str) -> None:
|