specfact-cli 0.47.3__tar.gz → 0.47.6__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.
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/.gitignore +2 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/PKG-INFO +25 -17
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/README.md +22 -14
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/pyproject.toml +8 -4
- specfact_cli-0.47.6/src/__init__.py +6 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/__init__.py +3 -2
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/cli.py +87 -39
- specfact_cli-0.47.3/src/__init__.py +0 -6
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/LICENSE +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/bundled-module-registry/index.json +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/keys/README.md +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/keys/module-signing-public.pem +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/kanban.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/mixed.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/safe.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/scrum.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/ado.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/github.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/speckit.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/_bundle_shim.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/bundle_factory.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/logger_setup.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/persona_exporter.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/codebase_group.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/govern_group.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/member_group.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/project_group.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/spec_group.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/_bundle_import.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/module-package.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/commands.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/first_run_selection.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_io_shim.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/module-package.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/commands.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/alias_manager.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/bootstrap.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/crypto_validator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/custom_registries.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/dependency_resolver.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/extension_registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/marketplace_client.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_availability.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_discovery.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_grouping.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_installer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_lifecycle.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_packages.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_security.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/contract_predicates.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/icontract_helpers.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/project_artifact_write.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validation/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validation/command_audit.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/versioning/analyzer.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specfact-cli
|
|
3
|
-
Version: 0.47.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.47.6
|
|
4
|
+
Summary: AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery.
|
|
5
5
|
Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
|
|
7
7
|
Project-URL: Documentation, https://github.com/nold-ai/specfact-cli#readme
|
|
@@ -210,7 +210,7 @@ License: Apache License
|
|
|
210
210
|
See the License for the specific language governing permissions and
|
|
211
211
|
limitations under the License.
|
|
212
212
|
License-File: LICENSE
|
|
213
|
-
Keywords: agile,backlog,beartype,ceremonies,cli,contract-driven-development,contracts,crosshair,devops,existing-code,icontract,kanban,legacy,modernization,policy-as-code,property-based-testing,safe,scrum,specfact,specs,tdd,validation
|
|
213
|
+
Keywords: agile,ai-bloat,backlog,beartype,ceremonies,clean-code,cli,code-review,contract-driven-development,contracts,crosshair,devops,existing-code,icontract,kanban,legacy,modernization,policy-as-code,property-based-testing,safe,scrum,specfact,specs,tdd,technical-debt,validation
|
|
214
214
|
Classifier: Development Status :: 4 - Beta
|
|
215
215
|
Classifier: Intended Audience :: Developers
|
|
216
216
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -283,8 +283,8 @@ Description-Content-Type: text/markdown
|
|
|
283
283
|
|
|
284
284
|
# SpecFact CLI
|
|
285
285
|
|
|
286
|
-
>
|
|
287
|
-
>
|
|
286
|
+
> Defend AI-assisted Python code from bloat before it reaches PR.
|
|
287
|
+
> Run deterministic review, cleanup forecasts, and spec/contract evidence locally.
|
|
288
288
|
|
|
289
289
|
[](https://pypi.org/project/specfact-cli/)
|
|
290
290
|
[](https://pypi.org/project/specfact-cli/)
|
|
@@ -315,7 +315,7 @@ uvx specfact-cli code review run --path . --scope full
|
|
|
315
315
|
**Sample output:**
|
|
316
316
|
|
|
317
317
|
```text
|
|
318
|
-
SpecFact CLI - v0.
|
|
318
|
+
SpecFact CLI - v0.47.4
|
|
319
319
|
|
|
320
320
|
Running Ruff checks...
|
|
321
321
|
Running Radon complexity checks...
|
|
@@ -347,23 +347,30 @@ specfact code review run --path . --scope full
|
|
|
347
347
|
|
|
348
348
|
The sample output comes from a pinned capture against `nold-ai/specfact-demo-repo`. Reproduce it with `docs/_support/readme-first-contact/capture-readme-output.sh`; capture metadata lives alongside the raw logs in `docs/_support/readme-first-contact/sample-output/`.
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
## AI-bloat defense loop
|
|
351
|
+
|
|
352
|
+
SpecFact is the local AI-bloat defense CLI for Python-first teams using AI IDEs. The Code Review bundle reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies: redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, avoidable intermediate lists, and long low-branch functions.
|
|
353
|
+
|
|
354
|
+
For cleanup work, run a JSON review, inspect the cleanup forecast and AI-bloat index, hand remediation packets to your AI IDE, accept only safe changes, then re-run review for proof. The JSON report is the portable handoff artifact for Claude, Codex, Cursor, Copilot, or a headless agent.
|
|
355
|
+
|
|
356
|
+
These findings are bloat-shape detection and cleanup guidance, not AI-authorship detection. Exact simplify flags and report fields live in the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) and [Code Review run guide](https://modules.specfact.io/bundles/code-review/run/) on the modules docs site.
|
|
351
357
|
|
|
352
358
|
## What SpecFact does
|
|
353
359
|
|
|
354
|
-
- **
|
|
360
|
+
- **Defends against AI bloat deterministically** — forecast cleanup impact and route remediation packets to your AI IDE
|
|
361
|
+
- **Reviews AI-assisted changes against evidence** — compare code against contracts, clean-code rules, and policy gates
|
|
355
362
|
- **Extracts structure from existing code** — reverse-engineer brownfield repos before you change them
|
|
356
363
|
- **Blocks drift before merge** — use the same checks locally, in pre-commit, and in CI
|
|
357
|
-
- **
|
|
364
|
+
- **Consumes upstream planning inputs** — treat Spec Kit, OpenSpec, backlog, specs, tests, and contracts as validation evidence
|
|
358
365
|
- **Stays local-first** — no cloud account, no vendor lock-in, no built-in model dependency
|
|
359
366
|
|
|
360
367
|
## What is SpecFact?
|
|
361
368
|
|
|
362
|
-
SpecFact is a local CLI for
|
|
369
|
+
SpecFact is a local CLI for AI-bloat defense, deterministic code review, and backlog/spec/code drift control. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
|
|
363
370
|
|
|
364
371
|
It exists because delivery drifts in predictable ways:
|
|
365
372
|
|
|
366
|
-
- AI-assisted code lands faster than validation
|
|
373
|
+
- AI-assisted code lands faster than cleanup and validation catch up
|
|
367
374
|
- brownfield systems rarely have trustworthy up-to-date specs
|
|
368
375
|
- backlog intent gets reinterpreted before it reaches code
|
|
369
376
|
- teams need the same review rules across IDEs, CI, and pull requests
|
|
@@ -384,7 +391,7 @@ For a **single-hook** setup in downstream repos, keep using the stable id and sc
|
|
|
384
391
|
|
|
385
392
|
```yaml
|
|
386
393
|
- repo: https://github.com/nold-ai/specfact-cli
|
|
387
|
-
rev: v0.
|
|
394
|
+
rev: v0.47.4
|
|
388
395
|
hooks:
|
|
389
396
|
- id: specfact-smart-checks
|
|
390
397
|
```
|
|
@@ -412,17 +419,18 @@ SpecFact uses the same discipline it asks you to trust:
|
|
|
412
419
|
|
|
413
420
|
## For teams and organizations
|
|
414
421
|
|
|
415
|
-
SpecFact still scales beyond the solo-developer entry path
|
|
422
|
+
SpecFact still scales beyond the solo-developer entry path, but validation stays
|
|
423
|
+
the center:
|
|
416
424
|
|
|
417
|
-
- **
|
|
425
|
+
- **Upstream context adapters** for GitHub, Azure DevOps, Jira, Linear, OpenSpec, and Spec Kit inputs
|
|
418
426
|
- **DoR/DoD and policy enforcement** for teams that need repeatable gates
|
|
419
427
|
- **Evidence-backed PR review** with the same checks used locally
|
|
420
428
|
- **CI/CD adoption path** that keeps validation deterministic instead of model-driven
|
|
421
429
|
|
|
422
|
-
|
|
430
|
+
Optional module-deep paths include:
|
|
423
431
|
|
|
424
|
-
- `specfact
|
|
425
|
-
- `specfact
|
|
432
|
+
- `specfact project import ...`
|
|
433
|
+
- `specfact spec validate ...`
|
|
426
434
|
- `specfact backlog verify-readiness --bundle <bundle-name>`
|
|
427
435
|
- `specfact govern ...`
|
|
428
436
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# SpecFact CLI
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
3
|
+
> Defend AI-assisted Python code from bloat before it reaches PR.
|
|
4
|
+
> Run deterministic review, cleanup forecasts, and spec/contract evidence locally.
|
|
5
5
|
|
|
6
6
|
[](https://pypi.org/project/specfact-cli/)
|
|
7
7
|
[](https://pypi.org/project/specfact-cli/)
|
|
@@ -32,7 +32,7 @@ uvx specfact-cli code review run --path . --scope full
|
|
|
32
32
|
**Sample output:**
|
|
33
33
|
|
|
34
34
|
```text
|
|
35
|
-
SpecFact CLI - v0.
|
|
35
|
+
SpecFact CLI - v0.47.4
|
|
36
36
|
|
|
37
37
|
Running Ruff checks...
|
|
38
38
|
Running Radon complexity checks...
|
|
@@ -64,23 +64,30 @@ specfact code review run --path . --scope full
|
|
|
64
64
|
|
|
65
65
|
The sample output comes from a pinned capture against `nold-ai/specfact-demo-repo`. Reproduce it with `docs/_support/readme-first-contact/capture-readme-output.sh`; capture metadata lives alongside the raw logs in `docs/_support/readme-first-contact/sample-output/`.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
## AI-bloat defense loop
|
|
68
|
+
|
|
69
|
+
SpecFact is the local AI-bloat defense CLI for Python-first teams using AI IDEs. The Code Review bundle reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies: redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, avoidable intermediate lists, and long low-branch functions.
|
|
70
|
+
|
|
71
|
+
For cleanup work, run a JSON review, inspect the cleanup forecast and AI-bloat index, hand remediation packets to your AI IDE, accept only safe changes, then re-run review for proof. The JSON report is the portable handoff artifact for Claude, Codex, Cursor, Copilot, or a headless agent.
|
|
72
|
+
|
|
73
|
+
These findings are bloat-shape detection and cleanup guidance, not AI-authorship detection. Exact simplify flags and report fields live in the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) and [Code Review run guide](https://modules.specfact.io/bundles/code-review/run/) on the modules docs site.
|
|
68
74
|
|
|
69
75
|
## What SpecFact does
|
|
70
76
|
|
|
71
|
-
- **
|
|
77
|
+
- **Defends against AI bloat deterministically** — forecast cleanup impact and route remediation packets to your AI IDE
|
|
78
|
+
- **Reviews AI-assisted changes against evidence** — compare code against contracts, clean-code rules, and policy gates
|
|
72
79
|
- **Extracts structure from existing code** — reverse-engineer brownfield repos before you change them
|
|
73
80
|
- **Blocks drift before merge** — use the same checks locally, in pre-commit, and in CI
|
|
74
|
-
- **
|
|
81
|
+
- **Consumes upstream planning inputs** — treat Spec Kit, OpenSpec, backlog, specs, tests, and contracts as validation evidence
|
|
75
82
|
- **Stays local-first** — no cloud account, no vendor lock-in, no built-in model dependency
|
|
76
83
|
|
|
77
84
|
## What is SpecFact?
|
|
78
85
|
|
|
79
|
-
SpecFact is a local CLI for
|
|
86
|
+
SpecFact is a local CLI for AI-bloat defense, deterministic code review, and backlog/spec/code drift control. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
|
|
80
87
|
|
|
81
88
|
It exists because delivery drifts in predictable ways:
|
|
82
89
|
|
|
83
|
-
- AI-assisted code lands faster than validation
|
|
90
|
+
- AI-assisted code lands faster than cleanup and validation catch up
|
|
84
91
|
- brownfield systems rarely have trustworthy up-to-date specs
|
|
85
92
|
- backlog intent gets reinterpreted before it reaches code
|
|
86
93
|
- teams need the same review rules across IDEs, CI, and pull requests
|
|
@@ -101,7 +108,7 @@ For a **single-hook** setup in downstream repos, keep using the stable id and sc
|
|
|
101
108
|
|
|
102
109
|
```yaml
|
|
103
110
|
- repo: https://github.com/nold-ai/specfact-cli
|
|
104
|
-
rev: v0.
|
|
111
|
+
rev: v0.47.4
|
|
105
112
|
hooks:
|
|
106
113
|
- id: specfact-smart-checks
|
|
107
114
|
```
|
|
@@ -129,17 +136,18 @@ SpecFact uses the same discipline it asks you to trust:
|
|
|
129
136
|
|
|
130
137
|
## For teams and organizations
|
|
131
138
|
|
|
132
|
-
SpecFact still scales beyond the solo-developer entry path
|
|
139
|
+
SpecFact still scales beyond the solo-developer entry path, but validation stays
|
|
140
|
+
the center:
|
|
133
141
|
|
|
134
|
-
- **
|
|
142
|
+
- **Upstream context adapters** for GitHub, Azure DevOps, Jira, Linear, OpenSpec, and Spec Kit inputs
|
|
135
143
|
- **DoR/DoD and policy enforcement** for teams that need repeatable gates
|
|
136
144
|
- **Evidence-backed PR review** with the same checks used locally
|
|
137
145
|
- **CI/CD adoption path** that keeps validation deterministic instead of model-driven
|
|
138
146
|
|
|
139
|
-
|
|
147
|
+
Optional module-deep paths include:
|
|
140
148
|
|
|
141
|
-
- `specfact
|
|
142
|
-
- `specfact
|
|
149
|
+
- `specfact project import ...`
|
|
150
|
+
- `specfact spec validate ...`
|
|
143
151
|
- `specfact backlog verify-readiness --bundle <bundle-name>`
|
|
144
152
|
- `specfact govern ...`
|
|
145
153
|
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specfact-cli"
|
|
7
|
-
version = "0.47.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.47.6"
|
|
8
|
+
description = "AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
license = { file = "LICENSE" } # Apache License 2.0
|
|
@@ -14,8 +14,12 @@ authors = [
|
|
|
14
14
|
]
|
|
15
15
|
keywords = [
|
|
16
16
|
"agile",
|
|
17
|
+
"ai-bloat",
|
|
17
18
|
"devops",
|
|
18
19
|
"backlog",
|
|
20
|
+
"code-review",
|
|
21
|
+
"clean-code",
|
|
22
|
+
"technical-debt",
|
|
19
23
|
"scrum",
|
|
20
24
|
"kanban",
|
|
21
25
|
"safe",
|
|
@@ -220,9 +224,9 @@ security-audit = "python scripts/security_audit_gate.py"
|
|
|
220
224
|
# Development scripts
|
|
221
225
|
test = "pytest {args}"
|
|
222
226
|
test-cov = "pytest --cov=src --cov-report=term-missing {args}"
|
|
223
|
-
type-check = "basedpyright --pythonpath $(python -c 'import sys; print(sys.executable)') {args}"
|
|
227
|
+
type-check = "basedpyright --pythonpath \"$(python -c 'import sys; print(sys.executable)')\" {args}"
|
|
224
228
|
# basedpyright --level error: suppress warning noise in pre-commit (Block 1 runs `hatch run lint`).
|
|
225
|
-
lint = "ruff format . --check && basedpyright --level error --pythonpath $(python -c 'import sys; print(sys.executable)') && ruff check . && pylint src tests tools && python scripts/verify_safe_project_writes.py"
|
|
229
|
+
lint = "ruff format . --check && basedpyright --level error --pythonpath \"$(python -c 'import sys; print(sys.executable)')\" && ruff check . && pylint src tests tools && python scripts/verify_safe_project_writes.py"
|
|
226
230
|
lint-changed = "python scripts/run_changed_lint.py {args}"
|
|
227
231
|
governance = "pylint src tests tools --reports=y --output-format=parseable"
|
|
228
232
|
format = "ruff check . --fix && ruff format ."
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
|
-
SpecFact CLI -
|
|
2
|
+
SpecFact CLI - AI-bloat defense CLI for Python teams.
|
|
3
3
|
|
|
4
4
|
This package provides command-line tools for:
|
|
5
|
+
- Defending AI-assisted code against cleanup bloat
|
|
5
6
|
- Turning code into clear specs and plans
|
|
6
7
|
- Keeping backlog, specs, tests, and code in sync
|
|
7
8
|
- Enforcing validation and contract checks before production
|
|
@@ -75,6 +76,6 @@ def _install_progressive_disclosure() -> None:
|
|
|
75
76
|
# keeps missing-command and missing-parameter UX consistent outside the root CLI too.
|
|
76
77
|
_install_progressive_disclosure()
|
|
77
78
|
|
|
78
|
-
__version__ = "0.47.
|
|
79
|
+
__version__ = "0.47.6"
|
|
79
80
|
|
|
80
81
|
__all__ = ["__version__"]
|
|
@@ -87,19 +87,12 @@ KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES: frozenset[str] = frozenset(
|
|
|
87
87
|
"project",
|
|
88
88
|
"spec",
|
|
89
89
|
"govern",
|
|
90
|
-
"plan",
|
|
91
|
-
"validate",
|
|
92
90
|
"contract",
|
|
93
91
|
"sdd",
|
|
94
92
|
"generate",
|
|
95
93
|
"enforce",
|
|
96
94
|
"patch",
|
|
97
|
-
"migrate",
|
|
98
|
-
"repro",
|
|
99
|
-
"drift",
|
|
100
|
-
"analyze",
|
|
101
95
|
"policy",
|
|
102
|
-
"sync",
|
|
103
96
|
}
|
|
104
97
|
)
|
|
105
98
|
|
|
@@ -109,14 +102,7 @@ _INVOKED_TO_MARKETPLACE_MODULE: dict[str, str] = {
|
|
|
109
102
|
"backlog": "nold-ai/specfact-backlog",
|
|
110
103
|
"policy": "nold-ai/specfact-backlog",
|
|
111
104
|
"code": "nold-ai/specfact-codebase",
|
|
112
|
-
"analyze": "nold-ai/specfact-codebase",
|
|
113
|
-
"drift": "nold-ai/specfact-codebase",
|
|
114
|
-
"validate": "nold-ai/specfact-codebase",
|
|
115
|
-
"repro": "nold-ai/specfact-codebase",
|
|
116
105
|
"project": "nold-ai/specfact-project",
|
|
117
|
-
"plan": "nold-ai/specfact-project",
|
|
118
|
-
"sync": "nold-ai/specfact-project",
|
|
119
|
-
"migrate": "nold-ai/specfact-project",
|
|
120
106
|
"spec": "nold-ai/specfact-spec",
|
|
121
107
|
"contract": "nold-ai/specfact-spec",
|
|
122
108
|
"sdd": "nold-ai/specfact-spec",
|
|
@@ -126,6 +112,18 @@ _INVOKED_TO_MARKETPLACE_MODULE: dict[str, str] = {
|
|
|
126
112
|
"patch": "nold-ai/specfact-govern",
|
|
127
113
|
}
|
|
128
114
|
|
|
115
|
+
# Removed flat root aliases -> canonical grouped replacement (see docs/migration/migration-guide.md).
|
|
116
|
+
# These must never route through marketplace module availability diagnostics.
|
|
117
|
+
_REMOVED_FLAT_ALIAS_TO_CANONICAL: dict[str, str] = {
|
|
118
|
+
"plan": "specfact project",
|
|
119
|
+
"validate": "specfact code validate",
|
|
120
|
+
"analyze": "specfact code analyze",
|
|
121
|
+
"drift": "specfact code drift",
|
|
122
|
+
"repro": "specfact code repro",
|
|
123
|
+
"sync": "specfact project sync",
|
|
124
|
+
"migrate": "specfact project migrate",
|
|
125
|
+
}
|
|
126
|
+
|
|
129
127
|
|
|
130
128
|
def _print_missing_bundle_command_help(invoked: str) -> None:
|
|
131
129
|
"""Print install guidance when a bundle group or shim is not registered."""
|
|
@@ -168,34 +166,81 @@ def _print_missing_bundle_command_help(invoked: str) -> None:
|
|
|
168
166
|
)
|
|
169
167
|
|
|
170
168
|
|
|
169
|
+
def _print_removed_flat_alias_help(invoked: str) -> None:
|
|
170
|
+
"""Print canonical grouped-command guidance for a removed flat root alias."""
|
|
171
|
+
canonical = _REMOVED_FLAT_ALIAS_TO_CANONICAL[invoked]
|
|
172
|
+
console = get_configured_console()
|
|
173
|
+
console.print(
|
|
174
|
+
f"[bold red]No such command '{invoked}'.[/bold red]\n"
|
|
175
|
+
f"The flat [bold]specfact {invoked}[/bold] command was removed. "
|
|
176
|
+
f"Use [bold]{canonical} ...[/bold] instead."
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _print_unresolved_root_token_help(invoked: str) -> bool:
|
|
181
|
+
"""Render guidance for an unresolved root token; return True when guidance was printed."""
|
|
182
|
+
if invoked in _REMOVED_FLAT_ALIAS_TO_CANONICAL:
|
|
183
|
+
_print_removed_flat_alias_help(invoked)
|
|
184
|
+
return True
|
|
185
|
+
if invoked in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
|
|
186
|
+
_print_missing_bundle_command_help(invoked)
|
|
187
|
+
return True
|
|
188
|
+
return False
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _resolve_root_command_with_guidance(resolve: Callable[[Any, list[str]], Any], ctx: Any, args: list[str]) -> Any:
|
|
192
|
+
"""Resolve a root command, replacing unresolved known tokens with actionable guidance."""
|
|
193
|
+
if not args:
|
|
194
|
+
return resolve(ctx, args)
|
|
195
|
+
invoked = args[0]
|
|
196
|
+
try:
|
|
197
|
+
result = resolve(ctx, args)
|
|
198
|
+
except click.UsageError:
|
|
199
|
+
if _print_unresolved_root_token_help(invoked):
|
|
200
|
+
raise SystemExit(1) from None
|
|
201
|
+
raise
|
|
202
|
+
except ValueError as exc:
|
|
203
|
+
if _print_unresolved_root_token_help(invoked):
|
|
204
|
+
raise SystemExit(1) from exc
|
|
205
|
+
raise
|
|
206
|
+
_name, cmd, remaining = result
|
|
207
|
+
if cmd is not None or not remaining:
|
|
208
|
+
return result
|
|
209
|
+
unresolved = remaining[0]
|
|
210
|
+
if _print_unresolved_root_token_help(unresolved):
|
|
211
|
+
raise SystemExit(1)
|
|
212
|
+
return result
|
|
213
|
+
|
|
214
|
+
|
|
171
215
|
class _RootCLIGroup(ProgressiveDisclosureGroup):
|
|
172
216
|
"""Root group that shows actionable error when an unknown command is a known bundle group/shim."""
|
|
173
217
|
|
|
174
218
|
@ensure(lambda result: isinstance(result, tuple) and len(result) == 3, "result must be a 3-tuple")
|
|
175
219
|
def resolve_command(self, ctx: Any, args: list[str]) -> Any:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
raise
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
220
|
+
return _resolve_root_command_with_guidance(super().resolve_command, ctx, args)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _patch_missing_bundle_resolution(group: click.Group) -> click.Group:
|
|
224
|
+
"""Patch a generated Typer root group to preserve missing bundle diagnostics."""
|
|
225
|
+
if getattr(group, "_specfact_missing_bundle_resolution", False):
|
|
226
|
+
return group
|
|
227
|
+
|
|
228
|
+
original_get_command = group.get_command
|
|
229
|
+
original_resolve_command = group.resolve_command
|
|
230
|
+
|
|
231
|
+
def _get_command(ctx: click.Context, cmd_name: str) -> click.Command | None:
|
|
232
|
+
command = original_get_command(ctx, cmd_name)
|
|
233
|
+
if command is None and _print_unresolved_root_token_help(cmd_name):
|
|
234
|
+
raise SystemExit(1)
|
|
235
|
+
return command
|
|
236
|
+
|
|
237
|
+
def _resolve_command(ctx: click.Context, args: list[str]) -> Any:
|
|
238
|
+
return _resolve_root_command_with_guidance(original_resolve_command, ctx, args)
|
|
239
|
+
|
|
240
|
+
group.get_command = _get_command # type: ignore[method-assign]
|
|
241
|
+
group.resolve_command = _resolve_command # type: ignore[method-assign]
|
|
242
|
+
group._specfact_missing_bundle_resolution = True # type: ignore[attr-defined]
|
|
243
|
+
return group
|
|
199
244
|
|
|
200
245
|
|
|
201
246
|
# Map shell names for completion support
|
|
@@ -581,8 +626,7 @@ def _load_lazy_delegate_typer(cmd_name: str) -> typer.Typer:
|
|
|
581
626
|
try:
|
|
582
627
|
return CommandRegistry.get_typer(resolved_name)
|
|
583
628
|
except ValueError as exc:
|
|
584
|
-
if cmd_name
|
|
585
|
-
_print_missing_bundle_command_help(cmd_name)
|
|
629
|
+
if _print_unresolved_root_token_help(cmd_name):
|
|
586
630
|
raise SystemExit(1) from None
|
|
587
631
|
_raise_lazy_delegate_click_exception(exc)
|
|
588
632
|
raise AssertionError("unreachable") from None
|
|
@@ -866,6 +910,8 @@ def _get_command(typer_instance: typer.Typer) -> click.Command:
|
|
|
866
910
|
return _build_lazy_delegate_group(cmd_name, help_str)
|
|
867
911
|
assert _typer_get_command_original is not None
|
|
868
912
|
result = _typer_get_command_original(typer_instance)
|
|
913
|
+
if typer_instance is app and isinstance(result, click.Group):
|
|
914
|
+
result = _patch_missing_bundle_resolution(result)
|
|
869
915
|
flatten_name = getattr(typer_instance, "_specfact_flatten_same_name", None)
|
|
870
916
|
if isinstance(flatten_name, str) and isinstance(result, click.Group) and flatten_name in result.commands:
|
|
871
917
|
_flatten_specfact_nested_subgroup(result, flatten_name)
|
|
@@ -894,6 +940,8 @@ def _get_group_from_info_wrapper(
|
|
|
894
940
|
suggest_commands=suggest_commands,
|
|
895
941
|
rich_markup_mode=rich_markup_mode,
|
|
896
942
|
)
|
|
943
|
+
if typer_instance is app:
|
|
944
|
+
result = _patch_missing_bundle_resolution(result)
|
|
897
945
|
flatten_name = getattr(typer_instance, "_specfact_flatten_same_name", None) if typer_instance else None
|
|
898
946
|
if isinstance(flatten_name, str) and flatten_name in result.commands:
|
|
899
947
|
_flatten_specfact_nested_subgroup(result, flatten_name)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/contract_extractor.py
RENAMED
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/control_flow_analyzer.py
RENAMED
|
File without changes
|
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/relationship_mapper.py
RENAMED
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/requirement_extractor.py
RENAMED
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/test_pattern_extractor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/github_mapper.py
RENAMED
|
File without changes
|
{specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/template_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|