specfact-cli 0.43.3__tar.gz → 0.45.1__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.43.3 → specfact_cli-0.45.1}/PKG-INFO +38 -27
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/README.md +31 -19
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/pyproject.toml +29 -18
- specfact_cli-0.45.1/resources/templates/github-action.yml.j2 +200 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/pr-template.md.j2 +9 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/__init__.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/speckit.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/analyze_agent.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/ambiguity_scanner.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/code_analyzer.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/contract_extractor.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/graph_analyzer.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/relationship_mapper.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/cli.py +200 -74
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/logger_setup.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/enrichers/constitution_enricher.py +5 -5
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/persona_exporter.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/plan_generator.py +4 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/workflow_generator.py +7 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/_bundle_import.py +7 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/module-package.yaml +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/commands.py +15 -50
- specfact_cli-0.45.1/src/specfact_cli/modules/init/src/first_run_selection.py +354 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_io_shim.py +0 -4
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/module-package.yaml +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/commands.py +505 -105
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/bootstrap.py +13 -3
- specfact_cli-0.45.1/src/specfact_cli/registry/dependency_resolver.py +186 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_installer.py +40 -8
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_packages.py +147 -201
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync.py +4 -4
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/spec_to_code.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/context_detection.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/progress.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/progressive_disclosure.py +0 -16
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/source_scanner.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/structure.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/dependency_installer.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/orchestrator.py +1 -1
- specfact_cli-0.43.3/resources/templates/github-action.yml.j2 +0 -172
- specfact_cli-0.43.3/src/specfact_cli/modules/init/src/first_run_selection.py +0 -198
- specfact_cli-0.43.3/src/specfact_cli/registry/dependency_resolver.py +0 -109
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/.gitignore +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/LICENSE +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/keys/README.md +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/keys/module-signing-public.pem +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/kanban.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/mixed.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/safe.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/policies/scrum.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/ado.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/github.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/_bundle_shim.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/bundle_factory.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/codebase_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/govern_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/member_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/project_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/groups/spec_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/alias_manager.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/crypto_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/custom_registries.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/extension_registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/marketplace_client.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_discovery.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_grouping.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_lifecycle.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_security.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/contract_predicates.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/icontract_helpers.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validation/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validation/command_audit.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/versioning/analyzer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specfact-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.45.1
|
|
4
4
|
Summary: The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases.
|
|
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
|
|
@@ -224,30 +224,28 @@ Classifier: Topic :: Software Development :: Testing
|
|
|
224
224
|
Requires-Python: >=3.11
|
|
225
225
|
Requires-Dist: azure-identity>=1.17.1
|
|
226
226
|
Requires-Dist: beartype>=0.22.4
|
|
227
|
-
Requires-Dist: cffi>=1.17.1
|
|
228
|
-
Requires-Dist: crosshair-tool>=0.0.97
|
|
229
227
|
Requires-Dist: cryptography>=43.0.0
|
|
230
228
|
Requires-Dist: gitpython>=3.1.45
|
|
231
229
|
Requires-Dist: graphviz>=0.20.1
|
|
232
|
-
Requires-Dist: hypothesis>=6.142.4
|
|
233
230
|
Requires-Dist: icontract>=2.7.1
|
|
234
231
|
Requires-Dist: jinja2>=3.1.6
|
|
235
232
|
Requires-Dist: jsonschema>=4.23.0
|
|
236
233
|
Requires-Dist: networkx>=3.4.2
|
|
237
234
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27.0
|
|
238
235
|
Requires-Dist: opentelemetry-sdk>=1.27.0
|
|
236
|
+
Requires-Dist: packaging>=24.0
|
|
239
237
|
Requires-Dist: pydantic>=2.12.3
|
|
240
|
-
Requires-Dist: python-dotenv>=1.2.1
|
|
241
238
|
Requires-Dist: pyyaml>=6.0.3
|
|
242
239
|
Requires-Dist: questionary>=2.0.1
|
|
243
|
-
Requires-Dist: radon>=6.0.1
|
|
244
240
|
Requires-Dist: requests>=2.32.3
|
|
245
241
|
Requires-Dist: rich<13.6.0,>=13.5.2
|
|
246
242
|
Requires-Dist: ruamel-yaml>=0.18.16
|
|
247
|
-
Requires-Dist:
|
|
248
|
-
Requires-Dist: typer>=0.20.0
|
|
243
|
+
Requires-Dist: typer<0.24,>=0.20.0
|
|
249
244
|
Requires-Dist: typing-extensions>=4.15.0
|
|
250
245
|
Requires-Dist: watchdog>=6.0.0
|
|
246
|
+
Provides-Extra: contracts
|
|
247
|
+
Requires-Dist: crosshair-tool>=0.0.97; extra == 'contracts'
|
|
248
|
+
Requires-Dist: hypothesis>=6.142.4; extra == 'contracts'
|
|
251
249
|
Provides-Extra: dev
|
|
252
250
|
Requires-Dist: basedpyright>=1.32.1; extra == 'dev'
|
|
253
251
|
Requires-Dist: bearer>=3.1.0; extra == 'dev'
|
|
@@ -268,6 +266,7 @@ Requires-Dist: pytest>=8.4.2; extra == 'dev'
|
|
|
268
266
|
Requires-Dist: radon>=6.0.1; extra == 'dev'
|
|
269
267
|
Requires-Dist: ruff>=0.14.2; extra == 'dev'
|
|
270
268
|
Requires-Dist: semgrep>=1.144.0; extra == 'dev'
|
|
269
|
+
Requires-Dist: setuptools>=69.0.0; extra == 'dev'
|
|
271
270
|
Requires-Dist: tomlkit>=0.13.3; extra == 'dev'
|
|
272
271
|
Requires-Dist: types-pyyaml>=6.0.12.20250516; extra == 'dev'
|
|
273
272
|
Provides-Extra: enhanced-analysis
|
|
@@ -352,26 +351,40 @@ With SpecFact, you get:
|
|
|
352
351
|
|
|
353
352
|
## How do I get started?
|
|
354
353
|
|
|
355
|
-
### Start Here (
|
|
354
|
+
### Start Here (about 2 minutes): scored code review — no `pip install`
|
|
356
355
|
|
|
357
|
-
|
|
356
|
+
**Point SpecFact at your code.** From a **git repository** (any branch), run two commands:
|
|
358
357
|
|
|
359
358
|
```bash
|
|
360
|
-
|
|
361
|
-
uvx specfact-cli
|
|
362
|
-
|
|
363
|
-
# Or install globally
|
|
364
|
-
pip install -U specfact-cli
|
|
359
|
+
uvx specfact-cli init --profile solo-developer
|
|
360
|
+
uvx specfact-cli code review run --path . --scope full
|
|
365
361
|
```
|
|
366
362
|
|
|
367
|
-
|
|
363
|
+
You should see a **Verdict** (PASS/FAIL), a **Score**, and categorized **findings** — the fastest way to see SpecFact on real code before you dive into backlog, specs, or CI.
|
|
364
|
+
|
|
365
|
+
- **Command 1** installs the `solo-developer` bundles (including `specfact-codebase` and `specfact-code-review`) into your user module store so `code review` and related commands are available on the next invocation.
|
|
366
|
+
- **Command 2** runs the clean-code review on the repo at `.`. Use **`--scope full`** on the first run so review does not depend on having local git changes.
|
|
367
|
+
|
|
368
|
+
**Already installed the CLI?** Use the same flow with `specfact` instead of `uvx specfact-cli`:
|
|
368
369
|
|
|
369
370
|
```bash
|
|
370
|
-
# Recommended first run
|
|
371
371
|
specfact init --profile solo-developer
|
|
372
|
+
specfact code review run --path . --scope full
|
|
372
373
|
```
|
|
373
374
|
|
|
374
|
-
|
|
375
|
+
**Read the canonical walkthrough:** **[Documentation — Quickstart](https://docs.specfact.io/getting-started/quickstart/)** · **[Installation](https://docs.specfact.io/getting-started/installation/)** (uvx-first, then persistent install).
|
|
376
|
+
|
|
377
|
+
### Install (persistent CLI for daily use)
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
pip install -U specfact-cli
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
You can still use **`uvx specfact-cli@latest ...`** anytime without installing; it always fetches the latest published CLI.
|
|
384
|
+
|
|
385
|
+
### After the wow path: deeper workflows
|
|
386
|
+
|
|
387
|
+
When you want analysis, snapshots, or sidecar validation on top of the review layer:
|
|
375
388
|
|
|
376
389
|
```bash
|
|
377
390
|
# Analyze a codebase you care about
|
|
@@ -385,10 +398,7 @@ specfact code validate sidecar init my-project /path/to/repo
|
|
|
385
398
|
specfact code validate sidecar run my-project /path/to/repo
|
|
386
399
|
```
|
|
387
400
|
|
|
388
|
-
|
|
389
|
-
validated starting point instead of jumping straight into blind change work.
|
|
390
|
-
|
|
391
|
-
### AI IDE Setup
|
|
401
|
+
### AI IDE setup
|
|
392
402
|
|
|
393
403
|
```bash
|
|
394
404
|
specfact init ide
|
|
@@ -406,7 +416,7 @@ your IDE. If module prompt payloads are not installed yet, the CLI uses packaged
|
|
|
406
416
|
Use SpecFact as the validation layer around fast-moving implementation work.
|
|
407
417
|
|
|
408
418
|
Start with:
|
|
409
|
-
- `specfact init --profile solo-developer`
|
|
419
|
+
- `uvx specfact-cli init --profile solo-developer` then `uvx specfact-cli code review run --path . --scope full` (see **Start Here** above)
|
|
410
420
|
- `specfact code validate sidecar init <bundle> /path/to/repo`
|
|
411
421
|
- `specfact code validate sidecar run <bundle> /path/to/repo`
|
|
412
422
|
|
|
@@ -584,10 +594,11 @@ Use `https://modules.specfact.io/` for the in-depth backlog, project, spec, gove
|
|
|
584
594
|
|
|
585
595
|
## How It Works (High Level)
|
|
586
596
|
|
|
587
|
-
1. **Bootstrap**:
|
|
588
|
-
2. **
|
|
589
|
-
3. **
|
|
590
|
-
4. **
|
|
597
|
+
1. **Bootstrap**: use **uvx** or **pip**, then `init --profile` to install the bundles you need (for example `solo-developer` for a scored **code review** first).
|
|
598
|
+
2. **Review or analyze**: run **`code review run`** on a repo, or import code and snapshot state for deeper workflows.
|
|
599
|
+
3. **Sync**: connect backlog systems or sync external artifacts into project bundles when you are ready.
|
|
600
|
+
4. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
|
|
601
|
+
5. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
|
|
591
602
|
|
|
592
603
|
## Where SpecFact Fits
|
|
593
604
|
|
|
@@ -71,26 +71,40 @@ With SpecFact, you get:
|
|
|
71
71
|
|
|
72
72
|
## How do I get started?
|
|
73
73
|
|
|
74
|
-
### Start Here (
|
|
74
|
+
### Start Here (about 2 minutes): scored code review — no `pip install`
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
**Point SpecFact at your code.** From a **git repository** (any branch), run two commands:
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
|
|
80
|
-
uvx specfact-cli
|
|
81
|
-
|
|
82
|
-
# Or install globally
|
|
83
|
-
pip install -U specfact-cli
|
|
79
|
+
uvx specfact-cli init --profile solo-developer
|
|
80
|
+
uvx specfact-cli code review run --path . --scope full
|
|
84
81
|
```
|
|
85
82
|
|
|
86
|
-
|
|
83
|
+
You should see a **Verdict** (PASS/FAIL), a **Score**, and categorized **findings** — the fastest way to see SpecFact on real code before you dive into backlog, specs, or CI.
|
|
84
|
+
|
|
85
|
+
- **Command 1** installs the `solo-developer` bundles (including `specfact-codebase` and `specfact-code-review`) into your user module store so `code review` and related commands are available on the next invocation.
|
|
86
|
+
- **Command 2** runs the clean-code review on the repo at `.`. Use **`--scope full`** on the first run so review does not depend on having local git changes.
|
|
87
|
+
|
|
88
|
+
**Already installed the CLI?** Use the same flow with `specfact` instead of `uvx specfact-cli`:
|
|
87
89
|
|
|
88
90
|
```bash
|
|
89
|
-
# Recommended first run
|
|
90
91
|
specfact init --profile solo-developer
|
|
92
|
+
specfact code review run --path . --scope full
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
**Read the canonical walkthrough:** **[Documentation — Quickstart](https://docs.specfact.io/getting-started/quickstart/)** · **[Installation](https://docs.specfact.io/getting-started/installation/)** (uvx-first, then persistent install).
|
|
96
|
+
|
|
97
|
+
### Install (persistent CLI for daily use)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install -U specfact-cli
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
You can still use **`uvx specfact-cli@latest ...`** anytime without installing; it always fetches the latest published CLI.
|
|
104
|
+
|
|
105
|
+
### After the wow path: deeper workflows
|
|
106
|
+
|
|
107
|
+
When you want analysis, snapshots, or sidecar validation on top of the review layer:
|
|
94
108
|
|
|
95
109
|
```bash
|
|
96
110
|
# Analyze a codebase you care about
|
|
@@ -104,10 +118,7 @@ specfact code validate sidecar init my-project /path/to/repo
|
|
|
104
118
|
specfact code validate sidecar run my-project /path/to/repo
|
|
105
119
|
```
|
|
106
120
|
|
|
107
|
-
|
|
108
|
-
validated starting point instead of jumping straight into blind change work.
|
|
109
|
-
|
|
110
|
-
### AI IDE Setup
|
|
121
|
+
### AI IDE setup
|
|
111
122
|
|
|
112
123
|
```bash
|
|
113
124
|
specfact init ide
|
|
@@ -125,7 +136,7 @@ your IDE. If module prompt payloads are not installed yet, the CLI uses packaged
|
|
|
125
136
|
Use SpecFact as the validation layer around fast-moving implementation work.
|
|
126
137
|
|
|
127
138
|
Start with:
|
|
128
|
-
- `specfact init --profile solo-developer`
|
|
139
|
+
- `uvx specfact-cli init --profile solo-developer` then `uvx specfact-cli code review run --path . --scope full` (see **Start Here** above)
|
|
129
140
|
- `specfact code validate sidecar init <bundle> /path/to/repo`
|
|
130
141
|
- `specfact code validate sidecar run <bundle> /path/to/repo`
|
|
131
142
|
|
|
@@ -303,10 +314,11 @@ Use `https://modules.specfact.io/` for the in-depth backlog, project, spec, gove
|
|
|
303
314
|
|
|
304
315
|
## How It Works (High Level)
|
|
305
316
|
|
|
306
|
-
1. **Bootstrap**:
|
|
307
|
-
2. **
|
|
308
|
-
3. **
|
|
309
|
-
4. **
|
|
317
|
+
1. **Bootstrap**: use **uvx** or **pip**, then `init --profile` to install the bundles you need (for example `solo-developer` for a scored **code review** first).
|
|
318
|
+
2. **Review or analyze**: run **`code review run`** on a repo, or import code and snapshot state for deeper workflows.
|
|
319
|
+
3. **Sync**: connect backlog systems or sync external artifacts into project bundles when you are ready.
|
|
320
|
+
4. **Validate**: run spec, governance, and sidecar validation flows before implementation or release.
|
|
321
|
+
5. **Iterate safely**: use module-provided workflows while the core runtime keeps command mounting, trust, and lifecycle consistent.
|
|
310
322
|
|
|
311
323
|
## Where SpecFact Fits
|
|
312
324
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specfact-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.45.1"
|
|
8
8
|
description = "The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -36,6 +36,10 @@ keywords = [
|
|
|
36
36
|
"cli",
|
|
37
37
|
"specfact",
|
|
38
38
|
]
|
|
39
|
+
# Install profiles (PEP 621 extras):
|
|
40
|
+
# - `pip install specfact-cli` — minimal runtime (CLI, registry, contracts via icontract/beartype, no CrossHair/Hypothesis wheels).
|
|
41
|
+
# - `pip install specfact-cli[contracts]` — add CrossHair + Hypothesis for contract exploration / property tooling.
|
|
42
|
+
# - `pip install specfact-cli[dev]` — contributors: pytest, linters, and same contract tools as [contracts] (see dev list).
|
|
39
43
|
classifiers = [
|
|
40
44
|
"Development Status :: 4 - Beta",
|
|
41
45
|
"Intended Audience :: Developers",
|
|
@@ -51,16 +55,17 @@ classifiers = [
|
|
|
51
55
|
dependencies = [
|
|
52
56
|
# Core dependencies
|
|
53
57
|
"pydantic>=2.12.3",
|
|
54
|
-
"python-dotenv>=1.2.1",
|
|
55
58
|
"typing-extensions>=4.15.0",
|
|
56
59
|
"PyYAML>=6.0.3",
|
|
57
60
|
"requests>=2.32.3",
|
|
58
61
|
"azure-identity>=1.17.1",
|
|
59
62
|
"cryptography>=43.0.0",
|
|
60
|
-
"
|
|
61
|
-
|
|
63
|
+
"packaging>=24.0",
|
|
64
|
+
# PEP 440 / markers for module installer and registry (do not rely on transitive pins only)
|
|
65
|
+
|
|
62
66
|
# CLI framework
|
|
63
|
-
|
|
67
|
+
# Typer 0.24+ requires click>=8.2.1 (generic Choice[...]); dev semgrep pins click~=8.1.8 — cap Typer.
|
|
68
|
+
"typer>=0.20.0,<0.24",
|
|
64
69
|
"rich>=13.5.2,<13.6.0", # Compatible with semgrep (requires rich~=13.5.2)
|
|
65
70
|
"questionary>=2.0.1", # Interactive prompts with arrow key navigation
|
|
66
71
|
|
|
@@ -80,16 +85,10 @@ dependencies = [
|
|
|
80
85
|
# Schema validation
|
|
81
86
|
"jsonschema>=4.23.0",
|
|
82
87
|
|
|
83
|
-
# Contract-First
|
|
88
|
+
# Contract-First (runtime decorators; exploration tools are optional extra `contracts`)
|
|
84
89
|
"icontract>=2.7.1", # Design-by-contract decorators
|
|
85
90
|
"beartype>=0.22.4", # Runtime type checking
|
|
86
|
-
|
|
87
|
-
"hypothesis>=6.142.4", # Property-based testing
|
|
88
|
-
|
|
89
|
-
# Code analysis
|
|
90
|
-
"ruff>=0.14.2",
|
|
91
|
-
"radon>=6.0.1",
|
|
92
|
-
|
|
91
|
+
|
|
93
92
|
# File system watching
|
|
94
93
|
"watchdog>=6.0.0",
|
|
95
94
|
|
|
@@ -99,7 +98,13 @@ dependencies = [
|
|
|
99
98
|
]
|
|
100
99
|
|
|
101
100
|
[project.optional-dependencies]
|
|
101
|
+
contracts = [
|
|
102
|
+
"crosshair-tool>=0.0.97",
|
|
103
|
+
"hypothesis>=6.142.4",
|
|
104
|
+
]
|
|
105
|
+
|
|
102
106
|
dev = [
|
|
107
|
+
"setuptools>=69.0.0",
|
|
103
108
|
"pytest>=8.4.2",
|
|
104
109
|
"pytest-cov>=7.0.0",
|
|
105
110
|
"pytest-mock>=3.15.1",
|
|
@@ -114,12 +119,14 @@ dev = [
|
|
|
114
119
|
"types-PyYAML>=6.0.12.20250516",
|
|
115
120
|
"pip-tools>=7.5.1",
|
|
116
121
|
"semgrep>=1.144.0", # Latest version compatible with rich~=13.5.2
|
|
117
|
-
|
|
118
|
-
#
|
|
119
|
-
"icontract>=2.7.1",
|
|
120
|
-
"beartype>=0.22.4",
|
|
122
|
+
|
|
123
|
+
# Same contract exploration stack as [contracts] (extras cannot self-reference)
|
|
121
124
|
"crosshair-tool>=0.0.97",
|
|
122
125
|
"hypothesis>=6.142.4",
|
|
126
|
+
|
|
127
|
+
# Contract-First Development Dependencies (dev)
|
|
128
|
+
"icontract>=2.7.1",
|
|
129
|
+
"beartype>=0.22.4",
|
|
123
130
|
|
|
124
131
|
# Enhanced Analysis Tools (for local development)
|
|
125
132
|
# Note: syft excluded from dev/test due to rich version conflict with semgrep
|
|
@@ -165,12 +172,13 @@ specfact-cli = "specfact_cli.cli:cli_main" # Alias for uvx compatibility
|
|
|
165
172
|
[tool.hatch.envs.default]
|
|
166
173
|
python = "3.12"
|
|
167
174
|
dependencies = [
|
|
175
|
+
# Semgrep pulls opentelemetry; some versions import pkg_resources (setuptools)
|
|
176
|
+
"setuptools>=69.0.0",
|
|
168
177
|
"pip-tools",
|
|
169
178
|
"pytest",
|
|
170
179
|
"pytest-cov",
|
|
171
180
|
"pytest-mock",
|
|
172
181
|
"pytest-xdist",
|
|
173
|
-
"python-dotenv",
|
|
174
182
|
"pre-commit",
|
|
175
183
|
# Ensure format/lint tools are available in the hatch env
|
|
176
184
|
"isort>=7.0.0",
|
|
@@ -204,6 +212,9 @@ governance = "pylint src tests tools --reports=y --output-format=parseable"
|
|
|
204
212
|
format = "ruff check . --fix && ruff format ."
|
|
205
213
|
|
|
206
214
|
# Code scanning (Semgrep)
|
|
215
|
+
# Semgrep 1.38+ deprecated implicit .semgrep.yml discovery; always pass --config explicitly.
|
|
216
|
+
# Script must not be named `semgrep` (Hatch treats that as circular expansion with the semgrep CLI).
|
|
217
|
+
semgrep-full = "semgrep --config tools/semgrep {args}"
|
|
207
218
|
scan = "semgrep --config tools/semgrep/async.yml {args}"
|
|
208
219
|
scan-all = "semgrep --config tools/semgrep/async.yml ."
|
|
209
220
|
scan-json = "semgrep --config tools/semgrep/async.yml --json . > logs/semgrep-results.json"
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
|
2
|
+
# yamllint disable rule:line-length rule:truthy
|
|
3
|
+
# Generated workflow — aligns with current SpecFact CLI: non-interactive CI must run
|
|
4
|
+
# `specfact init --profile …` (or `specfact module install …`) before `specfact code …` commands.
|
|
5
|
+
name: SpecFact CLI Validation
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main, dev]
|
|
10
|
+
paths-ignore:
|
|
11
|
+
- "docs/**"
|
|
12
|
+
- "**.md"
|
|
13
|
+
- "**.mdc"
|
|
14
|
+
push:
|
|
15
|
+
branches: [main, dev]
|
|
16
|
+
paths-ignore:
|
|
17
|
+
- "docs/**"
|
|
18
|
+
- "**.md"
|
|
19
|
+
- "**.mdc"
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
budget:
|
|
23
|
+
description: "Time budget in seconds for code repro"
|
|
24
|
+
required: false
|
|
25
|
+
default: "{{ budget }}"
|
|
26
|
+
type: string
|
|
27
|
+
mode:
|
|
28
|
+
description: "Enforcement mode (block, warn, log)"
|
|
29
|
+
required: false
|
|
30
|
+
default: "block"
|
|
31
|
+
type: choice
|
|
32
|
+
options:
|
|
33
|
+
- block
|
|
34
|
+
- warn
|
|
35
|
+
- log
|
|
36
|
+
version_check_mode:
|
|
37
|
+
description: "Project bundle version check (info, warn, block; skipped if no .specfact/projects)"
|
|
38
|
+
required: false
|
|
39
|
+
default: "info"
|
|
40
|
+
type: choice
|
|
41
|
+
options:
|
|
42
|
+
- info
|
|
43
|
+
- warn
|
|
44
|
+
- block
|
|
45
|
+
bundle_name:
|
|
46
|
+
description: "Project bundle name for `specfact project version check` (under .specfact/projects/)"
|
|
47
|
+
required: false
|
|
48
|
+
default: "{{ bundle_name }}"
|
|
49
|
+
type: string
|
|
50
|
+
|
|
51
|
+
jobs:
|
|
52
|
+
specfact-validation:
|
|
53
|
+
name: Contract Validation
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
permissions:
|
|
56
|
+
contents: read
|
|
57
|
+
pull-requests: write
|
|
58
|
+
checks: write
|
|
59
|
+
steps:
|
|
60
|
+
- name: Checkout
|
|
61
|
+
uses: actions/checkout@v4
|
|
62
|
+
|
|
63
|
+
- name: Set up Python
|
|
64
|
+
uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: "{{ python_version }}"
|
|
67
|
+
cache: "pip"
|
|
68
|
+
|
|
69
|
+
- name: Install SpecFact CLI
|
|
70
|
+
run: |
|
|
71
|
+
python -m pip install --upgrade pip
|
|
72
|
+
echo "📦 Installing SpecFact CLI..."
|
|
73
|
+
pip install specfact-cli
|
|
74
|
+
|
|
75
|
+
- name: Bootstrap SpecFact (CI — required for workflow commands)
|
|
76
|
+
run: |
|
|
77
|
+
# Non-interactive CI must pass --profile or --install (see `specfact init --help`).
|
|
78
|
+
specfact init --profile solo-developer --repo .
|
|
79
|
+
|
|
80
|
+
- name: Set validation parameters
|
|
81
|
+
id: validation
|
|
82
|
+
run: |
|
|
83
|
+
BUDGET="{% raw %}${{ github.event.inputs.budget || '{% endraw %}{{ budget }}{% raw %}' }}{% endraw %}"
|
|
84
|
+
MODE="{% raw %}${{ github.event.inputs.mode || 'block' }}{% endraw %}"
|
|
85
|
+
VERSION_CHECK_MODE="{% raw %}${{ github.event.inputs.version_check_mode || 'info' }}{% endraw %}"
|
|
86
|
+
BUNDLE_NAME="{% raw %}${{ github.event.inputs.bundle_name || '{% endraw %}{{ bundle_name }}{% raw %}' }}{% endraw %}"
|
|
87
|
+
echo "budget=$BUDGET" >> "$GITHUB_OUTPUT"
|
|
88
|
+
echo "mode=$MODE" >> "$GITHUB_OUTPUT"
|
|
89
|
+
echo "version_check_mode=$VERSION_CHECK_MODE" >> "$GITHUB_OUTPUT"
|
|
90
|
+
echo "bundle_name=$BUNDLE_NAME" >> "$GITHUB_OUTPUT"
|
|
91
|
+
echo "SPECFACT_BUDGET=$BUDGET" >> "$GITHUB_ENV"
|
|
92
|
+
echo "SPECFACT_MODE=$MODE" >> "$GITHUB_ENV"
|
|
93
|
+
echo "SPECFACT_VERSION_CHECK_MODE=$VERSION_CHECK_MODE" >> "$GITHUB_ENV"
|
|
94
|
+
echo "BUNDLE_NAME=$BUNDLE_NAME" >> "$GITHUB_ENV"
|
|
95
|
+
|
|
96
|
+
- name: Optional — CrossHair / repro tooling setup
|
|
97
|
+
continue-on-error: true
|
|
98
|
+
run: specfact code repro setup
|
|
99
|
+
|
|
100
|
+
- name: Run contract validation (code repro)
|
|
101
|
+
id: repro
|
|
102
|
+
continue-on-error: true
|
|
103
|
+
run: |
|
|
104
|
+
set +e
|
|
105
|
+
specfact code repro --verbose --budget "{% raw %}${{ steps.validation.outputs.budget }}{% endraw %}"
|
|
106
|
+
ec=$?
|
|
107
|
+
set -e
|
|
108
|
+
echo "exit_code=$ec" >> "$GITHUB_OUTPUT"
|
|
109
|
+
|
|
110
|
+
- name: Project bundle version check (optional)
|
|
111
|
+
id: version_check
|
|
112
|
+
continue-on-error: true
|
|
113
|
+
run: |
|
|
114
|
+
VERSION_CHECK_MODE="{% raw %}${{ steps.validation.outputs.version_check_mode }}{% endraw %}"
|
|
115
|
+
BUNDLE_NAME="{% raw %}${{ steps.validation.outputs.bundle_name }}{% endraw %}"
|
|
116
|
+
echo "📌 Bundle version check (mode: $VERSION_CHECK_MODE, bundle: $BUNDLE_NAME)..."
|
|
117
|
+
if [ ! -d .specfact/projects ]; then
|
|
118
|
+
echo "No .specfact/projects — skipping project version check."
|
|
119
|
+
echo "version_check_passed=skipped" >> "$GITHUB_OUTPUT"
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
if ! find .specfact/projects -mindepth 1 -maxdepth 1 -type d 2>/dev/null | grep -q .; then
|
|
123
|
+
echo "No project bundles under .specfact/projects — skipping."
|
|
124
|
+
echo "version_check_passed=skipped" >> "$GITHUB_OUTPUT"
|
|
125
|
+
exit 0
|
|
126
|
+
fi
|
|
127
|
+
if specfact project version check --repo . --bundle "$BUNDLE_NAME"; then
|
|
128
|
+
echo "version_check_passed=true" >> "$GITHUB_OUTPUT"
|
|
129
|
+
else
|
|
130
|
+
echo "version_check_passed=false" >> "$GITHUB_OUTPUT"
|
|
131
|
+
if [ "$VERSION_CHECK_MODE" = "warn" ]; then
|
|
132
|
+
echo "⚠️ Version check did not pass (warn mode — continuing)"
|
|
133
|
+
elif [ "$VERSION_CHECK_MODE" = "block" ]; then
|
|
134
|
+
echo "❌ Version check failed (block mode)"
|
|
135
|
+
exit 1
|
|
136
|
+
else
|
|
137
|
+
echo "ℹ️ Version check finished (info mode — continuing)"
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
- name: Find latest repro report
|
|
142
|
+
id: report
|
|
143
|
+
if: always()
|
|
144
|
+
run: |
|
|
145
|
+
REPORT_DIR=".specfact/reports/enforcement"
|
|
146
|
+
if [ -d "$REPORT_DIR" ]; then
|
|
147
|
+
LATEST_REPORT=$(find "$REPORT_DIR" -name "report-*.yaml" -type f -printf "%T@ %p\n" | sort -n | tail -1 | cut -d' ' -f2-)
|
|
148
|
+
if [ -n "$LATEST_REPORT" ]; then
|
|
149
|
+
echo "path=$LATEST_REPORT" >> "$GITHUB_OUTPUT"
|
|
150
|
+
echo "SPECFACT_REPORT_PATH=$LATEST_REPORT" >> "$GITHUB_ENV"
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
- name: Create GitHub annotations
|
|
155
|
+
id: annotations
|
|
156
|
+
if: {% raw %}${{ always() && steps.report.outputs.path != '' }}{% endraw %}
|
|
157
|
+
run: |
|
|
158
|
+
python -m specfact_cli.utils.github_annotations || true
|
|
159
|
+
|
|
160
|
+
- name: Generate PR comment
|
|
161
|
+
id: pr-comment
|
|
162
|
+
if: {% raw %}${{ always() && github.event_name == 'pull_request' && steps.report.outputs.path != '' }}{% endraw %}
|
|
163
|
+
run: |
|
|
164
|
+
python -m specfact_cli.utils.github_annotations
|
|
165
|
+
if [ -f ".specfact/pr-comment.md" ]; then
|
|
166
|
+
echo "comment_path=.specfact/pr-comment.md" >> "$GITHUB_OUTPUT"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
- name: Post PR comment
|
|
170
|
+
if: {% raw %}${{ always() && github.event_name == 'pull_request' && steps.pr-comment.outputs.comment_path != '' }}{% endraw %}
|
|
171
|
+
uses: actions/github-script@v7
|
|
172
|
+
with:
|
|
173
|
+
script: |
|
|
174
|
+
const fs = require('fs');
|
|
175
|
+
const commentPath = '{% raw %}${{ steps.pr-comment.outputs.comment_path }}{% endraw %}';
|
|
176
|
+
if (fs.existsSync(commentPath)) {
|
|
177
|
+
const comment = fs.readFileSync(commentPath, 'utf8');
|
|
178
|
+
github.rest.issues.createComment({
|
|
179
|
+
issue_number: context.issue.number,
|
|
180
|
+
owner: context.repo.owner,
|
|
181
|
+
repo: context.repo.repo,
|
|
182
|
+
body: comment
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
- name: Upload validation report
|
|
187
|
+
if: always()
|
|
188
|
+
uses: actions/upload-artifact@v4
|
|
189
|
+
with:
|
|
190
|
+
name: specfact-report
|
|
191
|
+
path: |
|
|
192
|
+
.specfact/reports/enforcement/*.yaml
|
|
193
|
+
.specfact/pr-comment.md
|
|
194
|
+
if-no-files-found: ignore
|
|
195
|
+
|
|
196
|
+
- name: Fail workflow if validation failed
|
|
197
|
+
if: {% raw %}${{ steps.repro.outputs.exit_code != '0' && steps.validation.outputs.mode == 'block' }}{% endraw %}
|
|
198
|
+
run: |
|
|
199
|
+
echo "❌ Validation failed. Exiting with error code."
|
|
200
|
+
exit 1
|
|
@@ -14,6 +14,15 @@
|
|
|
14
14
|
|
|
15
15
|
## ✅ Validation
|
|
16
16
|
|
|
17
|
+
**CI / local prerequisites (SpecFact v0.40+):**
|
|
18
|
+
|
|
19
|
+
- Install: `pip install specfact-cli` (or `uvx specfact-cli@latest` for one-off runs).
|
|
20
|
+
- **Non-interactive / CI** must bootstrap workflow bundles before `specfact code …` or `specfact project …`:
|
|
21
|
+
- `specfact init --profile solo-developer --repo .` (or another profile / `specfact init --install …`), **or**
|
|
22
|
+
- `specfact module install nold-ai/specfact-codebase` (and other bundles as needed).
|
|
23
|
+
- Contract repro in CI uses **`specfact code repro`** (not `specfact repro`). Optional: `specfact code repro setup` for CrossHair config.
|
|
24
|
+
- Optional `specfact project version check` needs a project under `.specfact/projects/<bundle>/` and `--bundle <name>`.
|
|
25
|
+
|
|
17
26
|
**SpecFact CLI Validation Results:**
|
|
18
27
|
|
|
19
28
|
{% if validation_passed %}
|
|
@@ -426,7 +426,7 @@ class SpecKitAdapter(BridgeAdapter):
|
|
|
426
426
|
)
|
|
427
427
|
if title_match:
|
|
428
428
|
feature_title = title_match.group(1).strip()
|
|
429
|
-
except
|
|
429
|
+
except (OSError, UnicodeDecodeError):
|
|
430
430
|
pass
|
|
431
431
|
if not feature_title or feature_title.strip() == "":
|
|
432
432
|
return "Unknown Feature"
|
|
@@ -262,7 +262,7 @@ Focus on semantic understanding, not just structural parsing. Generate the plan
|
|
|
262
262
|
try:
|
|
263
263
|
content = dep_file.read_text(encoding="utf-8")[:500]
|
|
264
264
|
dependencies.append(f"{dep_file.name}: {content[:100]}...")
|
|
265
|
-
except
|
|
265
|
+
except (OSError, UnicodeDecodeError):
|
|
266
266
|
pass
|
|
267
267
|
return dependencies
|
|
268
268
|
|
|
@@ -772,7 +772,7 @@ class AmbiguityScanner:
|
|
|
772
772
|
continue
|
|
773
773
|
if user_clean and len(user_clean) > 2 and user_lower not in excluded and len(user_clean.split()) <= 3:
|
|
774
774
|
result.add(user_clean.title())
|
|
775
|
-
except
|
|
775
|
+
except (OSError, UnicodeDecodeError, re.error):
|
|
776
776
|
pass
|
|
777
777
|
return result
|
|
778
778
|
|
|
@@ -898,9 +898,9 @@ class AmbiguityScanner:
|
|
|
898
898
|
continue
|
|
899
899
|
try:
|
|
900
900
|
self._personas_from_py_file(py_file, result, excluded)
|
|
901
|
-
except
|
|
901
|
+
except (OSError, UnicodeDecodeError, re.error):
|
|
902
902
|
continue
|
|
903
|
-
except
|
|
903
|
+
except (OSError, UnicodeDecodeError, re.error):
|
|
904
904
|
pass
|
|
905
905
|
return result
|
|
906
906
|
|
|
@@ -1794,14 +1794,14 @@ class CodeAnalyzer:
|
|
|
1794
1794
|
for commit in commits:
|
|
1795
1795
|
try:
|
|
1796
1796
|
self._process_commit_for_feature_bounds(commit)
|
|
1797
|
-
except
|
|
1797
|
+
except (OSError, ValueError):
|
|
1798
1798
|
# Skip individual commits that fail (corrupted, etc.)
|
|
1799
1799
|
continue
|
|
1800
1800
|
|
|
1801
1801
|
except ImportError:
|
|
1802
1802
|
# GitPython not available, skip
|
|
1803
1803
|
pass
|
|
1804
|
-
except
|
|
1804
|
+
except OSError:
|
|
1805
1805
|
# Git operations failed, skip gracefully
|
|
1806
1806
|
pass
|
|
1807
1807
|
|
{specfact_cli-0.43.3 → specfact_cli-0.45.1}/src/specfact_cli/analyzers/contract_extractor.py
RENAMED
|
@@ -240,7 +240,7 @@ class ContractExtractor:
|
|
|
240
240
|
if hasattr(ast, "unparse"):
|
|
241
241
|
try:
|
|
242
242
|
return ast.unparse(node)
|
|
243
|
-
except
|
|
243
|
+
except (ValueError, TypeError):
|
|
244
244
|
pass
|
|
245
245
|
|
|
246
246
|
# Fallback: manual conversion
|
|
@@ -282,7 +282,7 @@ class ContractExtractor:
|
|
|
282
282
|
if hasattr(ast, "unparse"):
|
|
283
283
|
try:
|
|
284
284
|
return ast.unparse(node)
|
|
285
|
-
except
|
|
285
|
+
except (ValueError, TypeError):
|
|
286
286
|
pass
|
|
287
287
|
|
|
288
288
|
return "..."
|
|
@@ -295,7 +295,7 @@ class ContractExtractor:
|
|
|
295
295
|
if hasattr(ast, "unparse"):
|
|
296
296
|
try:
|
|
297
297
|
return ast.unparse(node)
|
|
298
|
-
except
|
|
298
|
+
except (ValueError, TypeError):
|
|
299
299
|
pass
|
|
300
300
|
|
|
301
301
|
# Fallback: basic conversion
|