specsmith 0.10.1.dev277__tar.gz → 0.10.1.dev281__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.10.1.dev277/src/specsmith.egg-info → specsmith-0.10.1.dev281}/PKG-INFO +1 -1
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/pyproject.toml +1 -1
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/cleanup.py +2 -1
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/cli.py +1 -1
- specsmith-0.10.1.dev281/src/specsmith/context_window.py +274 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281/src/specsmith.egg-info}/PKG-INFO +1 -1
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith.egg-info/SOURCES.txt +2 -0
- specsmith-0.10.1.dev281/tests/test_compliance.py +527 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/LICENSE +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/README.md +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/setup.cfg +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/belief.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/certainty.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/failure_graph.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/py.typed +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/recovery.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/session.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/stress_tester.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/epistemic/trace.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/__main__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/broker.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/chat_runner.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/core.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/endpoints.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/events.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/execution_profiles.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/fallback.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/indexer.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/mcp.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/memory.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/model_intelligence.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/orchestrator.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/permissions.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/profiles.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/provider_registry.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/repl.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/router.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/rules.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/runner.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/safety.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/suggester.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/tools.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/verifier.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/agent/voice.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/architect.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/auditor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/auth.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/block_export.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/commands/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/commands/intelligence.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/compressor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/config.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/console_utils.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/credit_analyzer.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/credits.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/base.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/citations.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/fpd.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/odp.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/patentsview.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/pfw.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/ppubs.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/datasources/ptab.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/differ.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/doctor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/drive.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/editor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/belief.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/certainty.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/failure_graph.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/recovery.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/epistemic/stress_tester.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/executor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/exporter.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/governance_logic.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/app.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/main_window.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/session_tab.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/theme.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/chat_view.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/input_bar.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/provider_bar.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/token_meter.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/tool_panel.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/widgets/update_checker.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/gui/worker.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/history_search.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/importer.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/instinct.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/agent_skill.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/aider.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/base.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/claude_code.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/copilot.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/cursor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/gemini.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/integrations/windsurf.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/languages.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/ledger.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/patent.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/paths.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/phase.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/plugins.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/profiles.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/rate_limits.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/releaser.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/requirements.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/requirements_parser.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/retrieval.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/safe_write.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/scaffolder.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/serve.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/session.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/skills.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/sync.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/agents.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/contributing.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/license-MIT.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/community/security.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/editorconfig.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/gitattributes.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/gitignore.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/go/go.mod.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/go/main.go.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/roles.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/rules.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/governance/verification.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/js/package.json.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/ledger.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/python/cli.py.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/python/init.py.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/readme.md.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/rust/main.rs.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/tool_installer.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/toolrules.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/tools.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/trace.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/updater.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/upgrader.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/validator.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs/__init__.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs/base.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs/bitbucket.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs/github.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs/gitlab.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/vcs_commands.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/wireframes.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith/workspace.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith.egg-info/dependency_links.txt +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith.egg-info/entry_points.txt +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith.egg-info/requires.txt +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/src/specsmith.egg-info/top_level.txt +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_CMD_001.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_agent_profiles.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_agent_runner_ready.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_auditor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_chat_diff_decision.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_chat_runner_openai_compat.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_chat_stdin_protocol.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_cli.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_cli_workflows_history_drive.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_compressor.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_e2e_nexus.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_endpoints_cli.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_endpoints_store.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_epistemic.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_fallback_chain.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_importer.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_integrations.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_mcp_client.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_nexus.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_permissions.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_phase1_4_new.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_phase34_completion.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_rate_limits.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_scaffolder.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_skill_marketplace.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_smoke.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_suggester.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_tools.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_validator.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_vcs.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_warp_parity.py +0 -0
- {specsmith-0.10.1.dev277 → specsmith-0.10.1.dev281}/tests/test_warp_parity_followup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.10.1.
|
|
3
|
+
Version: 0.10.1.dev281
|
|
4
4
|
Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
|
|
5
5
|
Author: BitConcepts
|
|
6
6
|
License-Expression: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specsmith"
|
|
7
|
-
version = "0.10.1.
|
|
7
|
+
version = "0.10.1.dev281"
|
|
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"
|
|
@@ -7917,7 +7917,7 @@ def rules_list_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
7917
7917
|
project / ".specsmith" / "rules",
|
|
7918
7918
|
project / "docs" / "governance",
|
|
7919
7919
|
]
|
|
7920
|
-
workspace_dirs = [project / ".warp" / "rules"]
|
|
7920
|
+
workspace_dirs = [project / ".kairos" / "rules", project / ".warp" / "rules"]
|
|
7921
7921
|
personal_dirs = [home / "rules"]
|
|
7922
7922
|
for d in project_dirs:
|
|
7923
7923
|
if d.is_dir():
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2026 BitConcepts, LLC. All rights reserved.
|
|
3
|
+
"""Context Window Management (REQ-228..REQ-231).
|
|
4
|
+
|
|
5
|
+
Provides:
|
|
6
|
+
- GPU VRAM detection (NVIDIA via nvidia-smi, AMD via rocm-smi) — REQ-228
|
|
7
|
+
- Context window size recommendation for Ollama based on VRAM — REQ-228
|
|
8
|
+
- ContextFillTracker: per-turn token accounting + JSONL event emission — REQ-229
|
|
9
|
+
- ContextFullError: hard-ceiling enforcement — REQ-231
|
|
10
|
+
|
|
11
|
+
The hard reservation ensures at least 15 % of the context window (or 2048 tokens
|
|
12
|
+
minimum) is always free, so auto-compression always has room to run — REQ-231.
|
|
13
|
+
|
|
14
|
+
JSONL event schema (emitted by ContextFillTracker.record):
|
|
15
|
+
{"type": "context_fill", "used": <int>, "limit": <int>, "pct": <float>}
|
|
16
|
+
|
|
17
|
+
When pct >= hard_ceiling_pct, attempting to record more tokens raises
|
|
18
|
+
ContextFullError and the caller MUST trigger emergency compression before
|
|
19
|
+
accepting any further user input.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import subprocess
|
|
25
|
+
from dataclasses import dataclass, field
|
|
26
|
+
from typing import Any
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Constants
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
#: Hard ceiling as a percentage of the context window. The caller must trigger
|
|
33
|
+
#: emergency compression when fill reaches or exceeds this value (REQ-231).
|
|
34
|
+
HARD_CEILING_PCT: float = 85.0
|
|
35
|
+
|
|
36
|
+
#: Minimum number of tokens that must remain free regardless of HARD_CEILING_PCT.
|
|
37
|
+
MIN_FREE_TOKENS: int = 2048
|
|
38
|
+
|
|
39
|
+
#: VRAM → num_ctx recommendation tiers (Ollama / llama.cpp).
|
|
40
|
+
_VRAM_TIERS: list[tuple[float, int]] = [
|
|
41
|
+
(20.0, 32768),
|
|
42
|
+
(12.0, 16384),
|
|
43
|
+
(6.0, 8192),
|
|
44
|
+
(0.0, 4096), # CPU-only or very low VRAM
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
# Custom exceptions
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ContextFullError(RuntimeError):
|
|
54
|
+
"""Raised when the context window has reached the hard ceiling.
|
|
55
|
+
|
|
56
|
+
Callers must trigger emergency compression before accepting any further
|
|
57
|
+
user input (REQ-231).
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, used: int, limit: int, pct: float) -> None:
|
|
61
|
+
self.used = used
|
|
62
|
+
self.limit = limit
|
|
63
|
+
self.pct = pct
|
|
64
|
+
super().__init__(
|
|
65
|
+
f"Context window hard ceiling reached: {pct:.1f}% full "
|
|
66
|
+
f"({used}/{limit} tokens). Emergency compression required (REQ-231)."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
# GPU VRAM detection
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _run_silent(cmd: list[str]) -> str:
|
|
76
|
+
"""Run *cmd* and return stdout; return '' on any error."""
|
|
77
|
+
try:
|
|
78
|
+
result = subprocess.run(
|
|
79
|
+
cmd,
|
|
80
|
+
capture_output=True,
|
|
81
|
+
text=True,
|
|
82
|
+
timeout=5,
|
|
83
|
+
)
|
|
84
|
+
return result.stdout if result.returncode == 0 else ""
|
|
85
|
+
except Exception: # noqa: BLE001
|
|
86
|
+
return ""
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _detect_nvidia_vram() -> float:
|
|
90
|
+
"""Return total NVIDIA VRAM in GB, or 0.0 if nvidia-smi is unavailable."""
|
|
91
|
+
output = _run_silent(
|
|
92
|
+
["nvidia-smi", "--query-gpu=memory.total", "--format=csv,noheader,nounits"]
|
|
93
|
+
)
|
|
94
|
+
total_mib = 0
|
|
95
|
+
for line in output.splitlines():
|
|
96
|
+
line = line.strip()
|
|
97
|
+
if line.isdigit():
|
|
98
|
+
total_mib += int(line)
|
|
99
|
+
return total_mib / 1024.0 if total_mib else 0.0
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _detect_amd_vram() -> float:
|
|
103
|
+
"""Return total AMD VRAM in GB via rocm-smi, or 0.0 if unavailable."""
|
|
104
|
+
output = _run_silent(["rocm-smi", "--showmeminfo", "vram"])
|
|
105
|
+
total_bytes = 0
|
|
106
|
+
for line in output.splitlines():
|
|
107
|
+
# rocm-smi outputs lines like: "GPU[0] : VRAM Total Memory (B): 17163091968"
|
|
108
|
+
if "Total Memory (B)" in line and ":" in line:
|
|
109
|
+
try:
|
|
110
|
+
value = int(line.split(":")[-1].strip())
|
|
111
|
+
total_bytes += value
|
|
112
|
+
except ValueError:
|
|
113
|
+
continue
|
|
114
|
+
return total_bytes / (1024**3) if total_bytes else 0.0
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def detect_gpu_vram() -> float:
|
|
118
|
+
"""Detect total GPU VRAM in GB across NVIDIA and AMD devices.
|
|
119
|
+
|
|
120
|
+
Returns 0.0 when no GPU is detected or when the relevant CLI tools
|
|
121
|
+
(``nvidia-smi`` / ``rocm-smi``) are not installed. This function
|
|
122
|
+
never raises — safe to call on any platform.
|
|
123
|
+
|
|
124
|
+
Satisfies REQ-228.
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
vram = _detect_nvidia_vram()
|
|
128
|
+
if vram > 0.0:
|
|
129
|
+
return vram
|
|
130
|
+
return _detect_amd_vram()
|
|
131
|
+
except Exception: # noqa: BLE001
|
|
132
|
+
return 0.0
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# ---------------------------------------------------------------------------
|
|
136
|
+
# Context window sizing
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def suggest_context_window(vram_gb: float) -> int:
|
|
141
|
+
"""Recommend an Ollama ``num_ctx`` value based on available VRAM.
|
|
142
|
+
|
|
143
|
+
Uses a simple tier table so that users with less VRAM don't
|
|
144
|
+
accidentally OOM their machine. Cloud providers use their own
|
|
145
|
+
published context limits and are not affected by this function.
|
|
146
|
+
|
|
147
|
+
Tiers:
|
|
148
|
+
- ≥ 20 GB → 32 768 tokens
|
|
149
|
+
- ≥ 12 GB → 16 384 tokens
|
|
150
|
+
- ≥ 6 GB → 8 192 tokens
|
|
151
|
+
- < 6 GB / CPU-only → 4 096 tokens
|
|
152
|
+
|
|
153
|
+
Satisfies REQ-228.
|
|
154
|
+
"""
|
|
155
|
+
for threshold, num_ctx in _VRAM_TIERS:
|
|
156
|
+
if vram_gb >= threshold:
|
|
157
|
+
return num_ctx
|
|
158
|
+
return 4096 # unreachable but safe fallback
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# ---------------------------------------------------------------------------
|
|
162
|
+
# Context fill tracker
|
|
163
|
+
# ---------------------------------------------------------------------------
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@dataclass
|
|
167
|
+
class ContextFillEvent:
|
|
168
|
+
"""Structured context fill event (emitted as JSONL by ContextFillTracker)."""
|
|
169
|
+
|
|
170
|
+
type: str = "context_fill"
|
|
171
|
+
used: int = 0
|
|
172
|
+
limit: int = 0
|
|
173
|
+
pct: float = 0.0
|
|
174
|
+
|
|
175
|
+
def to_dict(self) -> dict[str, Any]:
|
|
176
|
+
return {"type": self.type, "used": self.used, "limit": self.limit, "pct": self.pct}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@dataclass
|
|
180
|
+
class ContextFillTracker:
|
|
181
|
+
"""Track token usage across turns and emit fill events.
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
limit:
|
|
186
|
+
Total context window size in tokens.
|
|
187
|
+
hard_ceiling_pct:
|
|
188
|
+
When fill reaches this percentage, :exc:`ContextFullError` is raised
|
|
189
|
+
regardless of the auto-compress toggle. Defaults to
|
|
190
|
+
:data:`HARD_CEILING_PCT` (85 %).
|
|
191
|
+
min_free_tokens:
|
|
192
|
+
Minimum tokens that must remain free. If ``hard_ceiling_pct`` would
|
|
193
|
+
allow fewer free tokens than this value, the effective ceiling is
|
|
194
|
+
tightened. Defaults to :data:`MIN_FREE_TOKENS` (2048).
|
|
195
|
+
|
|
196
|
+
Satisfies REQ-229 (fill tracking + JSONL events) and REQ-231 (hard ceiling).
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
limit: int
|
|
200
|
+
hard_ceiling_pct: float = HARD_CEILING_PCT
|
|
201
|
+
min_free_tokens: int = MIN_FREE_TOKENS
|
|
202
|
+
_used: int = field(default=0, init=False, repr=False)
|
|
203
|
+
_events: list[ContextFillEvent] = field(default_factory=list, init=False, repr=False)
|
|
204
|
+
|
|
205
|
+
# ------------------------------------------------------------------
|
|
206
|
+
# Properties
|
|
207
|
+
# ------------------------------------------------------------------
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def used(self) -> int:
|
|
211
|
+
"""Current token usage."""
|
|
212
|
+
return self._used
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def fill_pct(self) -> float:
|
|
216
|
+
"""Current fill as a percentage of *limit*."""
|
|
217
|
+
if self.limit <= 0:
|
|
218
|
+
return 0.0
|
|
219
|
+
return min(self._used / self.limit * 100.0, 100.0)
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def effective_ceiling_pct(self) -> float:
|
|
223
|
+
"""Effective ceiling accounting for :attr:`min_free_tokens`."""
|
|
224
|
+
min_free_ceiling = max(0.0, (1.0 - self.min_free_tokens / max(self.limit, 1)) * 100.0)
|
|
225
|
+
return min(self.hard_ceiling_pct, min_free_ceiling)
|
|
226
|
+
|
|
227
|
+
# ------------------------------------------------------------------
|
|
228
|
+
# Public API
|
|
229
|
+
# ------------------------------------------------------------------
|
|
230
|
+
|
|
231
|
+
def record(self, used: int, limit: int | None = None) -> ContextFillEvent:
|
|
232
|
+
"""Record the current token usage and return a fill event.
|
|
233
|
+
|
|
234
|
+
Parameters
|
|
235
|
+
----------
|
|
236
|
+
used:
|
|
237
|
+
Total tokens used so far (prompt + completion).
|
|
238
|
+
limit:
|
|
239
|
+
Override the tracker's limit for this specific turn. Pass
|
|
240
|
+
``None`` (default) to use the tracker's configured limit.
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
ContextFillEvent
|
|
245
|
+
The fill event for this turn.
|
|
246
|
+
|
|
247
|
+
Raises
|
|
248
|
+
------
|
|
249
|
+
ContextFullError
|
|
250
|
+
When :attr:`fill_pct` reaches or exceeds
|
|
251
|
+
:attr:`effective_ceiling_pct`.
|
|
252
|
+
"""
|
|
253
|
+
effective_limit = limit if limit is not None else self.limit
|
|
254
|
+
self._used = used
|
|
255
|
+
if effective_limit != self.limit and effective_limit > 0:
|
|
256
|
+
self.limit = effective_limit
|
|
257
|
+
|
|
258
|
+
pct = min(used / max(self.limit, 1) * 100.0, 100.0)
|
|
259
|
+
event = ContextFillEvent(used=used, limit=self.limit, pct=round(pct, 2))
|
|
260
|
+
self._events.append(event)
|
|
261
|
+
|
|
262
|
+
if pct >= self.effective_ceiling_pct:
|
|
263
|
+
raise ContextFullError(used=used, limit=self.limit, pct=pct)
|
|
264
|
+
|
|
265
|
+
return event
|
|
266
|
+
|
|
267
|
+
def reset(self) -> None:
|
|
268
|
+
"""Reset usage to zero (e.g. after successful compression)."""
|
|
269
|
+
self._used = 0
|
|
270
|
+
self._events.clear()
|
|
271
|
+
|
|
272
|
+
def all_events(self) -> list[ContextFillEvent]:
|
|
273
|
+
"""Return all recorded fill events in order."""
|
|
274
|
+
return list(self._events)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.10.1.
|
|
3
|
+
Version: 0.10.1.dev281
|
|
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
|
|
@@ -20,6 +20,7 @@ src/specsmith/cli.py
|
|
|
20
20
|
src/specsmith/compressor.py
|
|
21
21
|
src/specsmith/config.py
|
|
22
22
|
src/specsmith/console_utils.py
|
|
23
|
+
src/specsmith/context_window.py
|
|
23
24
|
src/specsmith/credit_analyzer.py
|
|
24
25
|
src/specsmith/credits.py
|
|
25
26
|
src/specsmith/differ.py
|
|
@@ -190,6 +191,7 @@ tests/test_chat_runner_openai_compat.py
|
|
|
190
191
|
tests/test_chat_stdin_protocol.py
|
|
191
192
|
tests/test_cli.py
|
|
192
193
|
tests/test_cli_workflows_history_drive.py
|
|
194
|
+
tests/test_compliance.py
|
|
193
195
|
tests/test_compressor.py
|
|
194
196
|
tests/test_e2e_nexus.py
|
|
195
197
|
tests/test_endpoints_cli.py
|