specfact-cli 0.43.3__tar.gz → 0.44.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/PKG-INFO +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/pyproject.toml +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/speckit.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/analyze_agent.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/ambiguity_scanner.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/code_analyzer.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/contract_extractor.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/graph_analyzer.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/relationship_mapper.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/logger_setup.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/enrichers/constitution_enricher.py +5 -5
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/persona_exporter.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/_bundle_import.py +7 -3
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/module-package.yaml +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/src/commands.py +0 -50
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/module_io_shim.py +0 -4
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/bootstrap.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_packages.py +0 -19
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync.py +4 -4
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/spec_to_code.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/context_detection.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/progress.py +3 -3
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/progressive_disclosure.py +0 -16
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/source_scanner.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/structure.py +2 -2
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/dependency_installer.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/orchestrator.py +1 -1
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/.gitignore +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/LICENSE +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/README.md +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/keys/README.md +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/keys/module-signing-public.pem +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/policies/kanban.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/policies/mixed.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/policies/safe.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/policies/scrum.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/ado.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/github.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/cli.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/_bundle_shim.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/bundle_factory.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/codebase_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/govern_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/member_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/project_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/groups/spec_group.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/src/first_run_selection.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/module_registry/module-package.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/module_registry/src/commands.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/alias_manager.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/crypto_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/custom_registries.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/dependency_resolver.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/extension_registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/marketplace_client.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_discovery.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_grouping.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_installer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_lifecycle.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_security.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/contract_predicates.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/icontract_helpers.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validation/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validation/command_audit.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.43.3 → specfact_cli-0.44.0}/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.44.0
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specfact-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.44.0"
|
|
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"
|
|
@@ -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.44.0}/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
|
|
@@ -178,7 +178,7 @@ class GraphAnalyzer:
|
|
|
178
178
|
edges = future.result()
|
|
179
179
|
for module_name, matching_module in edges:
|
|
180
180
|
graph.add_edge(module_name, matching_module)
|
|
181
|
-
except
|
|
181
|
+
except (OSError, RuntimeError):
|
|
182
182
|
pass
|
|
183
183
|
completed += 1
|
|
184
184
|
if progress_callback:
|
|
@@ -211,7 +211,7 @@ class GraphAnalyzer:
|
|
|
211
211
|
callee_module = self._resolve_module_from_function(callee, python_files)
|
|
212
212
|
if callee_module and callee_module in graph:
|
|
213
213
|
graph.add_edge(module_name, callee_module)
|
|
214
|
-
except
|
|
214
|
+
except (OSError, RuntimeError):
|
|
215
215
|
pass
|
|
216
216
|
completed += 1
|
|
217
217
|
if progress_callback:
|
{specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/analyzers/relationship_mapper.py
RENAMED
|
@@ -306,7 +306,7 @@ class RelationshipMapper:
|
|
|
306
306
|
if file_hash:
|
|
307
307
|
self.analysis_cache[file_hash] = empty_result
|
|
308
308
|
return (file_key, empty_result)
|
|
309
|
-
except
|
|
309
|
+
except (OSError, PermissionError):
|
|
310
310
|
pass
|
|
311
311
|
|
|
312
312
|
try:
|
|
@@ -354,7 +354,7 @@ class RelationshipMapper:
|
|
|
354
354
|
if not f.done():
|
|
355
355
|
f.cancel()
|
|
356
356
|
raise
|
|
357
|
-
except
|
|
357
|
+
except (OSError, ValueError):
|
|
358
358
|
pass
|
|
359
359
|
completed_count += 1
|
|
360
360
|
if progress_callback:
|
|
@@ -426,11 +426,11 @@ class LoggerSetup:
|
|
|
426
426
|
log_file_path = os.path.join(logs_dir, log_file)
|
|
427
427
|
|
|
428
428
|
log_file_dir = os.path.dirname(log_file_path)
|
|
429
|
-
os.makedirs(log_file_dir, mode=
|
|
429
|
+
os.makedirs(log_file_dir, mode=0o755, exist_ok=True)
|
|
430
430
|
try:
|
|
431
431
|
with open(log_file_path, "a", encoding="utf-8"):
|
|
432
432
|
pass
|
|
433
|
-
except
|
|
433
|
+
except OSError:
|
|
434
434
|
pass
|
|
435
435
|
|
|
436
436
|
try:
|
{specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/enrichers/constitution_enricher.py
RENAMED
|
@@ -145,7 +145,7 @@ class ConstitutionEnricher:
|
|
|
145
145
|
# Simple dependency name without version constraints
|
|
146
146
|
result["technology_stack"].append(dep)
|
|
147
147
|
|
|
148
|
-
except
|
|
148
|
+
except (OSError, UnicodeDecodeError, ValueError):
|
|
149
149
|
pass # If parsing fails, return empty result
|
|
150
150
|
|
|
151
151
|
return result
|
|
@@ -190,7 +190,7 @@ class ConstitutionEnricher:
|
|
|
190
190
|
else:
|
|
191
191
|
result["technology_stack"].append(dep)
|
|
192
192
|
|
|
193
|
-
except
|
|
193
|
+
except (OSError, UnicodeDecodeError, ValueError):
|
|
194
194
|
pass
|
|
195
195
|
|
|
196
196
|
return result
|
|
@@ -235,7 +235,7 @@ class ConstitutionEnricher:
|
|
|
235
235
|
users = [u.strip() for u in re.split(r"[,;]", users_text)]
|
|
236
236
|
result["target_users"] = users[:5]
|
|
237
237
|
|
|
238
|
-
except
|
|
238
|
+
except (OSError, UnicodeDecodeError, ValueError):
|
|
239
239
|
pass
|
|
240
240
|
|
|
241
241
|
return result
|
|
@@ -265,7 +265,7 @@ class ConstitutionEnricher:
|
|
|
265
265
|
# Extract principles from headings and key sections
|
|
266
266
|
extracted = self._extract_principles_from_markdown(content, rule_file)
|
|
267
267
|
principles.extend(extracted)
|
|
268
|
-
except
|
|
268
|
+
except (OSError, UnicodeDecodeError, ValueError):
|
|
269
269
|
pass
|
|
270
270
|
|
|
271
271
|
return principles
|
|
@@ -293,7 +293,7 @@ class ConstitutionEnricher:
|
|
|
293
293
|
# Extract quality standards
|
|
294
294
|
extracted = self._extract_quality_standards(content)
|
|
295
295
|
standards.extend(extracted)
|
|
296
|
-
except
|
|
296
|
+
except (OSError, UnicodeDecodeError, ValueError):
|
|
297
297
|
pass
|
|
298
298
|
|
|
299
299
|
return standards
|
|
@@ -242,7 +242,7 @@ class PersonaExporter:
|
|
|
242
242
|
protocol_data = load_structured_file(protocol_file)
|
|
243
243
|
protocol_name = protocol_file.stem.replace(".protocol", "")
|
|
244
244
|
protocols[protocol_name] = protocol_data
|
|
245
|
-
except
|
|
245
|
+
except (OSError, ValueError):
|
|
246
246
|
pass
|
|
247
247
|
return protocols
|
|
248
248
|
|
|
@@ -267,7 +267,7 @@ class PersonaExporter:
|
|
|
267
267
|
contract_data = load_structured_file(contract_file)
|
|
268
268
|
contract_name = contract_file.stem.replace(".openapi", "").replace(".asyncapi", "")
|
|
269
269
|
contracts[contract_name] = contract_data
|
|
270
|
-
except
|
|
270
|
+
except (OSError, ValueError):
|
|
271
271
|
pass
|
|
272
272
|
return contracts
|
|
273
273
|
|
|
@@ -19,9 +19,13 @@ def bootstrap_local_bundle_sources(anchor_file: str) -> None:
|
|
|
19
19
|
anchor = Path(anchor_file).resolve()
|
|
20
20
|
candidates: list[Path] = []
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
for env_name in ("SPECFACT_CLI_MODULES_REPO", "SPECFACT_MODULES_REPO"):
|
|
23
|
+
env_repo = os.environ.get(env_name)
|
|
24
|
+
if not env_repo:
|
|
25
|
+
continue
|
|
26
|
+
candidate = Path(env_repo).expanduser().resolve()
|
|
27
|
+
if candidate not in candidates:
|
|
28
|
+
candidates.append(candidate)
|
|
25
29
|
|
|
26
30
|
for parent in anchor.parents:
|
|
27
31
|
# Primary dev layout: .../nold-ai/specfact-cli-worktrees/... and sibling specfact-cli-modules
|
{specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/modules/init/module-package.yaml
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: init
|
|
2
|
-
version: 0.1.
|
|
2
|
+
version: 0.1.21
|
|
3
3
|
commands:
|
|
4
4
|
- init
|
|
5
5
|
category: core
|
|
@@ -17,5 +17,5 @@ publisher:
|
|
|
17
17
|
description: Initialize SpecFact workspace and bootstrap local configuration.
|
|
18
18
|
license: Apache-2.0
|
|
19
19
|
integrity:
|
|
20
|
-
checksum: sha256:
|
|
21
|
-
signature:
|
|
20
|
+
checksum: sha256:925fd303b581441618597b5fa5d7f308cbc31405455ae7811243c072616974bf
|
|
21
|
+
signature: uMDekXAxcKEDb8V1rqEeL8X806bP4otT5rT5ShXFlUNjcJ06c90s7xg1KqTNYj/eVsuh07xKSGnWKo1BG6juAw==
|
|
@@ -13,7 +13,6 @@ from icontract import ensure, require
|
|
|
13
13
|
from rich.console import Console
|
|
14
14
|
from rich.panel import Panel
|
|
15
15
|
from rich.rule import Rule
|
|
16
|
-
from rich.table import Table
|
|
17
16
|
|
|
18
17
|
from specfact_cli import __version__
|
|
19
18
|
from specfact_cli.contracts.module_interface import ModuleIOContract
|
|
@@ -222,21 +221,6 @@ def _questionary_style() -> Any:
|
|
|
222
221
|
)
|
|
223
222
|
|
|
224
223
|
|
|
225
|
-
def _render_modules_table(modules_list: list[dict[str, Any]]) -> None:
|
|
226
|
-
"""Render discovered modules with effective enabled/disabled state."""
|
|
227
|
-
table = Table(title="Installed Modules")
|
|
228
|
-
table.add_column("Module", style="cyan")
|
|
229
|
-
table.add_column("Version", style="magenta")
|
|
230
|
-
table.add_column("State", style="green")
|
|
231
|
-
for module in modules_list:
|
|
232
|
-
module_id = str(module.get("id", ""))
|
|
233
|
-
version = str(module.get("version", ""))
|
|
234
|
-
enabled = bool(module.get("enabled", True))
|
|
235
|
-
state = "enabled" if enabled else "disabled"
|
|
236
|
-
table.add_row(module_id, version, state)
|
|
237
|
-
console.print(table)
|
|
238
|
-
|
|
239
|
-
|
|
240
224
|
def _module_checkbox_rows(candidates: list[dict[str, Any]]) -> tuple[dict[str, str], list[str]]:
|
|
241
225
|
display_to_id: dict[str, str] = {}
|
|
242
226
|
choices: list[str] = []
|
|
@@ -274,40 +258,6 @@ def _run_module_checkbox_prompt(
|
|
|
274
258
|
return [display_to_id[s] for s in selected if s in display_to_id]
|
|
275
259
|
|
|
276
260
|
|
|
277
|
-
def _select_module_ids_interactive(action: str, modules_list: list[dict[str, Any]]) -> list[str]:
|
|
278
|
-
"""Select one or more module IDs interactively via arrow-key checkbox menu."""
|
|
279
|
-
try:
|
|
280
|
-
import questionary # type: ignore[reportMissingImports]
|
|
281
|
-
except ImportError as e:
|
|
282
|
-
console.print(
|
|
283
|
-
"[red]Interactive module selection requires 'questionary'. Install with: pip install questionary[/red]"
|
|
284
|
-
)
|
|
285
|
-
raise typer.Exit(1) from e
|
|
286
|
-
|
|
287
|
-
target_enabled = action == "disable"
|
|
288
|
-
candidates = [m for m in modules_list if bool(m.get("enabled", True)) is target_enabled]
|
|
289
|
-
if not candidates:
|
|
290
|
-
console.print(f"[yellow]No modules available to {action}.[/yellow]")
|
|
291
|
-
return []
|
|
292
|
-
|
|
293
|
-
action_title = "Enable" if action == "enable" else "Disable"
|
|
294
|
-
current_state = "disabled" if action == "enable" else "enabled"
|
|
295
|
-
console.print()
|
|
296
|
-
console.print(
|
|
297
|
-
Panel(
|
|
298
|
-
f"[bold cyan]{action_title} Modules[/bold cyan]\n"
|
|
299
|
-
f"Choose one or more currently [bold]{current_state}[/bold] modules.",
|
|
300
|
-
border_style="cyan",
|
|
301
|
-
)
|
|
302
|
-
)
|
|
303
|
-
console.print(
|
|
304
|
-
"[dim]Controls: ↑↓ navigate • Space toggle • Enter confirm • Type to search/filter • Ctrl+C cancel[/dim]"
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
display_to_id, choices = _module_checkbox_rows(candidates)
|
|
308
|
-
return _run_module_checkbox_prompt(action, display_to_id, choices, questionary)
|
|
309
|
-
|
|
310
|
-
|
|
311
261
|
def _resolve_templates_dir(repo_path: Path) -> Path | None:
|
|
312
262
|
"""Resolve a representative templates directory from installed modules or a dev repo checkout."""
|
|
313
263
|
prompt_files = discover_prompt_template_files(repo_path, include_package_fallback=True)
|
|
@@ -17,10 +17,6 @@ def _import_source_exists(source: Path) -> bool:
|
|
|
17
17
|
return source.exists()
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def _export_target_exists(target: Path) -> bool:
|
|
21
|
-
return target.exists()
|
|
22
|
-
|
|
23
|
-
|
|
24
20
|
def _external_source_nonempty(external_source: str) -> bool:
|
|
25
21
|
return len(external_source.strip()) > 0
|
|
26
22
|
|
|
@@ -742,25 +742,6 @@ def _check_protocol_compliance(module_class: Any) -> list[str]:
|
|
|
742
742
|
return operations
|
|
743
743
|
|
|
744
744
|
|
|
745
|
-
@beartype
|
|
746
|
-
@require(lambda package_name: cast(str, package_name).strip() != "", "Package name must not be empty")
|
|
747
|
-
@ensure(lambda result: result is not None, "Protocol inspection target must be resolved")
|
|
748
|
-
def _resolve_protocol_target(module_obj: Any, package_name: str) -> Any:
|
|
749
|
-
"""Resolve runtime interface used for protocol inspection."""
|
|
750
|
-
runtime_interface = getattr(module_obj, "runtime_interface", None)
|
|
751
|
-
if runtime_interface is not None:
|
|
752
|
-
return runtime_interface
|
|
753
|
-
commands_interface = getattr(module_obj, "commands", None)
|
|
754
|
-
if commands_interface is not None:
|
|
755
|
-
return commands_interface
|
|
756
|
-
# Module app entrypoints often only expose `app`; load module-local commands for protocol detection.
|
|
757
|
-
try:
|
|
758
|
-
return importlib.import_module(f"specfact_cli.modules.{package_name}.src.commands")
|
|
759
|
-
except Exception:
|
|
760
|
-
pass
|
|
761
|
-
return module_obj
|
|
762
|
-
|
|
763
|
-
|
|
764
745
|
def _resolve_protocol_source_paths(
|
|
765
746
|
package_dir: Path,
|
|
766
747
|
package_name: str,
|
|
@@ -67,7 +67,7 @@ def _code_repo_from_cwd(repo_name: str) -> Path | None:
|
|
|
67
67
|
)
|
|
68
68
|
if result.returncode == 0 and repo_name in result.stdout:
|
|
69
69
|
return cwd
|
|
70
|
-
except
|
|
70
|
+
except (OSError, ValueError):
|
|
71
71
|
pass
|
|
72
72
|
return None
|
|
73
73
|
|
|
@@ -79,7 +79,7 @@ def _code_repo_from_parent(repo_name: str) -> Path | None:
|
|
|
79
79
|
repo_path = cwd.parent / repo_name
|
|
80
80
|
if repo_path.exists() and (repo_path / ".git").exists():
|
|
81
81
|
return repo_path
|
|
82
|
-
except
|
|
82
|
+
except (OSError, ValueError):
|
|
83
83
|
pass
|
|
84
84
|
return None
|
|
85
85
|
|
|
@@ -94,7 +94,7 @@ def _code_repo_from_grandparent_siblings(repo_name: str) -> Path | None:
|
|
|
94
94
|
for sibling in grandparent.iterdir():
|
|
95
95
|
if sibling.is_dir() and sibling.name == repo_name and (sibling / ".git").exists():
|
|
96
96
|
return sibling
|
|
97
|
-
except
|
|
97
|
+
except (OSError, ValueError):
|
|
98
98
|
pass
|
|
99
99
|
return None
|
|
100
100
|
|
|
@@ -1498,7 +1498,7 @@ class BridgeSync:
|
|
|
1498
1498
|
parsed_hostname: str | None = cast(str | None, parsed.hostname)
|
|
1499
1499
|
if parsed_hostname and parsed_hostname.lower() == "dev.azure.com":
|
|
1500
1500
|
pass
|
|
1501
|
-
except
|
|
1501
|
+
except ValueError:
|
|
1502
1502
|
pass
|
|
1503
1503
|
|
|
1504
1504
|
def _collect_source_tracking_entries_from_proposal_text(self, proposal_content: str) -> list[dict[str, Any]]:
|
|
@@ -220,7 +220,7 @@ class SpecToCodeSync:
|
|
|
220
220
|
data = cast(dict[str, Any], _tomli.load(f))
|
|
221
221
|
if "project" in data and "dependencies" in data["project"]:
|
|
222
222
|
dependencies.extend(data["project"]["dependencies"])
|
|
223
|
-
except
|
|
223
|
+
except (ImportError, OSError, ValueError):
|
|
224
224
|
pass # Ignore parsing errors
|
|
225
225
|
|
|
226
226
|
return dependencies
|
|
@@ -208,7 +208,7 @@ def _detect_python_framework(repo_path: Path, context: ProjectContext) -> None:
|
|
|
208
208
|
context.framework = "flask"
|
|
209
209
|
elif "fastapi" in content:
|
|
210
210
|
context.framework = "fastapi"
|
|
211
|
-
except
|
|
211
|
+
except (OSError, UnicodeDecodeError):
|
|
212
212
|
pass
|
|
213
213
|
|
|
214
214
|
|
|
@@ -225,7 +225,7 @@ def _detect_js_framework(repo_path: Path, context: ProjectContext) -> None:
|
|
|
225
225
|
context.framework = "react"
|
|
226
226
|
elif "vue" in deps:
|
|
227
227
|
context.framework = "vue"
|
|
228
|
-
except
|
|
228
|
+
except (OSError, json.JSONDecodeError):
|
|
229
229
|
pass
|
|
230
230
|
|
|
231
231
|
|
|
@@ -45,7 +45,7 @@ def _safe_progress_display(display_console: Console) -> bool:
|
|
|
45
45
|
# Rich stores active Live displays in Console._live
|
|
46
46
|
if hasattr(display_console, "_live") and display_console._live is not None:
|
|
47
47
|
return False
|
|
48
|
-
except
|
|
48
|
+
except AttributeError:
|
|
49
49
|
pass
|
|
50
50
|
|
|
51
51
|
return True
|
|
@@ -149,7 +149,7 @@ def load_bundle_with_progress(
|
|
|
149
149
|
# Brief pause to show completion
|
|
150
150
|
time.sleep(0.1)
|
|
151
151
|
return bundle
|
|
152
|
-
except
|
|
152
|
+
except (RuntimeError, OSError):
|
|
153
153
|
# If Progress creation fails (e.g., LiveError), fall back to direct load
|
|
154
154
|
pass
|
|
155
155
|
|
|
@@ -222,7 +222,7 @@ def save_bundle_with_progress(
|
|
|
222
222
|
# Brief pause to show completion
|
|
223
223
|
time.sleep(0.1)
|
|
224
224
|
return
|
|
225
|
-
except
|
|
225
|
+
except (RuntimeError, OSError):
|
|
226
226
|
# If Progress creation fails (e.g., LiveError), fall back to direct save
|
|
227
227
|
pass
|
|
228
228
|
|
{specfact_cli-0.43.3 → specfact_cli-0.44.0}/src/specfact_cli/utils/progressive_disclosure.py
RENAMED
|
@@ -82,22 +82,6 @@ def intercept_help_advanced() -> None:
|
|
|
82
82
|
sys.argv[:] = normalized_args
|
|
83
83
|
|
|
84
84
|
|
|
85
|
-
@beartype
|
|
86
|
-
def _is_help_context(ctx: ClickContext | None) -> bool:
|
|
87
|
-
"""Check if this context is for showing help."""
|
|
88
|
-
if ctx is None:
|
|
89
|
-
return False
|
|
90
|
-
# Check if help was requested by looking at params or info_name
|
|
91
|
-
if hasattr(ctx, "params") and ctx.params:
|
|
92
|
-
# Check if any help option is in params
|
|
93
|
-
for param in ctx.params.values() if isinstance(ctx.params, dict) else []:
|
|
94
|
-
param_name = getattr(param, "name", None)
|
|
95
|
-
if param_name and param_name in ("--help", "-h", "--help-advanced", "-ha"):
|
|
96
|
-
return True
|
|
97
|
-
# Check info_name for help indicators
|
|
98
|
-
return bool(hasattr(ctx, "info_name") and ctx.info_name and "help" in str(ctx.info_name).lower())
|
|
99
|
-
|
|
100
|
-
|
|
101
85
|
@beartype
|
|
102
86
|
def _is_advanced_help_context(ctx: ClickContext | None) -> bool:
|
|
103
87
|
"""Check if this context is for showing advanced help."""
|
|
@@ -512,7 +512,7 @@ class SourceArtifactScanner:
|
|
|
512
512
|
source_tracking = SourceTracking()
|
|
513
513
|
source_tracking.update_hash(file_path)
|
|
514
514
|
file_hashes_cache[rel_path] = source_tracking.file_hashes.get(rel_path, "")
|
|
515
|
-
except
|
|
515
|
+
except (OSError, ValueError):
|
|
516
516
|
pass
|
|
517
517
|
|
|
518
518
|
def _index_test_file_for_link_cache(
|
|
@@ -552,7 +552,7 @@ class SourceArtifactScanner:
|
|
|
552
552
|
source_tracking = SourceTracking()
|
|
553
553
|
source_tracking.update_hash(file_path)
|
|
554
554
|
file_hashes_cache[rel_path] = source_tracking.file_hashes.get(rel_path, "")
|
|
555
|
-
except
|
|
555
|
+
except (OSError, ValueError):
|
|
556
556
|
pass
|
|
557
557
|
|
|
558
558
|
def _run_parallel_feature_linking(
|
|
@@ -252,7 +252,7 @@ class SpecFactStructure:
|
|
|
252
252
|
bundle_dir = base_path / cls.PROJECTS / active_bundle
|
|
253
253
|
if bundle_dir.exists() and (bundle_dir / "bundle.manifest.yaml").exists():
|
|
254
254
|
return bundle_dir
|
|
255
|
-
except
|
|
255
|
+
except (OSError, ValueError):
|
|
256
256
|
# Fallback if config read fails
|
|
257
257
|
pass
|
|
258
258
|
|
|
@@ -302,7 +302,7 @@ class SpecFactStructure:
|
|
|
302
302
|
active_bundle = config.get(cls.ACTIVE_BUNDLE_CONFIG_KEY)
|
|
303
303
|
if active_bundle:
|
|
304
304
|
return active_bundle
|
|
305
|
-
except
|
|
305
|
+
except (OSError, ValueError):
|
|
306
306
|
# Fallback if config read fails
|
|
307
307
|
pass
|
|
308
308
|
|
|
@@ -55,7 +55,7 @@ def create_sidecar_venv(venv_path: Path, repo_path: Path) -> bool:
|
|
|
55
55
|
if result.returncode == 0:
|
|
56
56
|
# Venv exists and works, skip recreation
|
|
57
57
|
return True
|
|
58
|
-
except
|
|
58
|
+
except (OSError, subprocess.SubprocessError):
|
|
59
59
|
# Venv exists but Python can't run (e.g., libpython issue)
|
|
60
60
|
# Delete and recreate
|
|
61
61
|
pass
|
|
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
|