specfact-cli 0.42.4__tar.gz → 0.42.5__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.42.4 → specfact_cli-0.42.5}/PKG-INFO +1 -1
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/pyproject.toml +1 -1
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/__init__.py +1 -1
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/cli.py +17 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/init/module-package.yaml +3 -3
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/init/src/commands.py +126 -37
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/ide_setup.py +418 -30
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/startup_checks.py +16 -2
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/.gitignore +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/LICENSE +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/README.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/keys/README.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/keys/module-signing-public.pem +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/shared/cli-enforcement.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.01-import.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.02-plan.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.03-review.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.04-sdd.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.05-enforce.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.06-sync.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.07-contracts.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.compare.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/prompts/specfact.validate.md +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/policies/kanban.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/policies/mixed.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/policies/safe.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/policies/scrum.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/ado.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/github.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/adapters/speckit.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/_bundle_shim.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/bundle_factory.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/logger_setup.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/persona_exporter.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/codebase_group.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/govern_group.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/member_group.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/project_group.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/groups/spec_group.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/_bundle_import.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/init/src/first_run_selection.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/module_io_shim.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/module_registry/module-package.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/module_registry/src/commands.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/alias_manager.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/bootstrap.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/crypto_validator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/custom_registries.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/dependency_resolver.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/extension_registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/marketplace_client.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_discovery.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_grouping.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_installer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_lifecycle.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_packages.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_security.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/contract_predicates.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/icontract_helpers.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validation/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validation/command_audit.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.42.4 → specfact_cli-0.42.5}/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.42.
|
|
3
|
+
Version: 0.42.5
|
|
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.42.
|
|
7
|
+
version = "0.42.5"
|
|
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"
|
|
@@ -653,6 +653,23 @@ for _name, _meta in _grouped_command_order(CommandRegistry.list_commands_for_hel
|
|
|
653
653
|
app.add_typer(_make_lazy_typer(_name, _meta.help), name=_name, help=_meta.help)
|
|
654
654
|
|
|
655
655
|
|
|
656
|
+
@beartype
|
|
657
|
+
@require(lambda: isinstance(app, typer.Typer), "Root CLI app must be initialized")
|
|
658
|
+
@ensure(lambda result: result is None, "Must return None")
|
|
659
|
+
def rebuild_root_app_from_registry() -> None:
|
|
660
|
+
"""Rebuild root Typer ``app`` from the current ``CommandRegistry``.
|
|
661
|
+
|
|
662
|
+
Call after ``register_builtin_commands()`` when tests clear and re-register the registry.
|
|
663
|
+
Otherwise ``get_command(app)`` still reflects lazy groups from ``cli`` import time while
|
|
664
|
+
``CommandRegistry`` lists only the newly registered commands (breaks CI core-only installs).
|
|
665
|
+
"""
|
|
666
|
+
app.registered_groups = []
|
|
667
|
+
if hasattr(app, "registered_commands"):
|
|
668
|
+
app.registered_commands = []
|
|
669
|
+
for _name, _meta in _grouped_command_order(CommandRegistry.list_commands_for_help()):
|
|
670
|
+
app.add_typer(_make_lazy_typer(_name, _meta.help), name=_name, help=_meta.help)
|
|
671
|
+
|
|
672
|
+
|
|
656
673
|
_CLI_SKIP_OUTPUT_ARGS: frozenset[str] = frozenset(
|
|
657
674
|
("--help", "-h", "--version", "-v", "--show-completion", "--install-completion")
|
|
658
675
|
)
|
{specfact_cli-0.42.4 → specfact_cli-0.42.5}/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.17
|
|
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:589ec7f24e7d0129cf61ad972e9f505c744ae14bd84db32cc241bc5013834163
|
|
21
|
+
signature: 9hiFgBYZZwCTMBRDBgly07v5JejhDHWXyX3/tTkTYOjjtkFT7xjZs2Pyea7l1mt2dhUZ/Tet4bdDRXyeSNcYCg==
|
|
@@ -29,11 +29,18 @@ from specfact_cli.utils.contract_predicates import repo_path_exists, repo_path_i
|
|
|
29
29
|
from specfact_cli.utils.env_manager import EnvManager, EnvManagerInfo, build_tool_command, detect_env_manager
|
|
30
30
|
from specfact_cli.utils.ide_setup import (
|
|
31
31
|
IDE_CONFIG,
|
|
32
|
+
PROMPT_SOURCE_CORE,
|
|
32
33
|
_copy_template_files_to_ide,
|
|
33
34
|
_discover_module_resource_dirs,
|
|
35
|
+
copy_prompts_by_source_to_ide,
|
|
36
|
+
count_outdated_ide_prompt_exports,
|
|
34
37
|
detect_ide,
|
|
38
|
+
discover_prompt_sources_catalog,
|
|
35
39
|
discover_prompt_template_files,
|
|
40
|
+
expected_ide_prompt_export_paths,
|
|
36
41
|
find_package_resources_path,
|
|
42
|
+
load_ide_prompt_export_source_ids,
|
|
43
|
+
write_ide_prompt_export_state,
|
|
37
44
|
)
|
|
38
45
|
|
|
39
46
|
|
|
@@ -65,8 +72,16 @@ is_first_run = first_run_selection.is_first_run
|
|
|
65
72
|
),
|
|
66
73
|
"Must return copied files and optional settings path",
|
|
67
74
|
)
|
|
68
|
-
def copy_templates_to_ide(
|
|
69
|
-
|
|
75
|
+
def copy_templates_to_ide(
|
|
76
|
+
repo_path: Path,
|
|
77
|
+
ide: str,
|
|
78
|
+
force: bool = False,
|
|
79
|
+
*,
|
|
80
|
+
prompts_by_source: dict[str, list[Path]] | None = None,
|
|
81
|
+
) -> tuple[list[Path], Path | None]:
|
|
82
|
+
"""Discover prompt templates and copy them; use ``prompts_by_source`` for namespaced multi-source export."""
|
|
83
|
+
if prompts_by_source is not None:
|
|
84
|
+
return copy_prompts_by_source_to_ide(repo_path, ide, prompts_by_source, force)
|
|
70
85
|
return _copy_template_files_to_ide(repo_path, ide, discover_prompt_template_files(repo_path), force)
|
|
71
86
|
|
|
72
87
|
|
|
@@ -307,36 +322,13 @@ def _resolve_templates_dir(repo_path: Path) -> Path | None:
|
|
|
307
322
|
return find_package_resources_path("specfact_cli", "resources/prompts")
|
|
308
323
|
|
|
309
324
|
|
|
310
|
-
def _expected_ide_prompt_basenames(repo_path: Path, format_type: str) -> list[str]:
|
|
311
|
-
prompt_files = discover_prompt_template_files(repo_path)
|
|
312
|
-
if format_type == "prompt.md":
|
|
313
|
-
return [f"{path.stem}.prompt.md" for path in prompt_files]
|
|
314
|
-
if format_type == "toml":
|
|
315
|
-
return [f"{path.stem}.toml" for path in prompt_files]
|
|
316
|
-
return [path.name for path in prompt_files]
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def _count_outdated_ide_prompts(ide_dir: Path, prompt_files: list[Path], format_type: str) -> int:
|
|
320
|
-
outdated = 0
|
|
321
|
-
for src in prompt_files:
|
|
322
|
-
if format_type == "prompt.md":
|
|
323
|
-
dest = ide_dir / f"{src.stem}.prompt.md"
|
|
324
|
-
elif format_type == "toml":
|
|
325
|
-
dest = ide_dir / f"{src.stem}.toml"
|
|
326
|
-
else:
|
|
327
|
-
dest = ide_dir / src.name
|
|
328
|
-
if src.exists() and dest.exists() and dest.stat().st_mtime < src.stat().st_mtime:
|
|
329
|
-
outdated += 1
|
|
330
|
-
return outdated
|
|
331
|
-
|
|
332
|
-
|
|
333
325
|
def _audit_prompt_installation(repo_path: Path) -> None:
|
|
334
326
|
"""Report prompt installation health and next steps without mutating files."""
|
|
335
327
|
detected_ide = detect_ide("auto")
|
|
336
328
|
config = IDE_CONFIG[detected_ide]
|
|
337
329
|
ide_dir = repo_path / str(config["folder"])
|
|
338
|
-
|
|
339
|
-
|
|
330
|
+
prompt_subset = load_ide_prompt_export_source_ids(repo_path, detected_ide)
|
|
331
|
+
expected_paths = expected_ide_prompt_export_paths(repo_path, detected_ide, prompt_source_ids=prompt_subset)
|
|
340
332
|
|
|
341
333
|
if not ide_dir.exists():
|
|
342
334
|
console.print(
|
|
@@ -345,9 +337,12 @@ def _audit_prompt_installation(repo_path: Path) -> None:
|
|
|
345
337
|
)
|
|
346
338
|
return
|
|
347
339
|
|
|
348
|
-
missing = [
|
|
349
|
-
|
|
350
|
-
|
|
340
|
+
missing = [p for p in expected_paths if not p.exists()]
|
|
341
|
+
outdated = (
|
|
342
|
+
count_outdated_ide_prompt_exports(repo_path, detected_ide, prompt_source_ids=prompt_subset)
|
|
343
|
+
if expected_paths
|
|
344
|
+
else 0
|
|
345
|
+
)
|
|
351
346
|
|
|
352
347
|
if not missing and outdated == 0:
|
|
353
348
|
console.print(f"[green]Prompt status:[/green] {detected_ide} prompts are present and up to date.")
|
|
@@ -359,6 +354,78 @@ def _audit_prompt_installation(repo_path: Path) -> None:
|
|
|
359
354
|
console.print(f"[dim]Run: specfact init ide --ide {detected_ide}{' --force' if outdated > 0 else ''}[/dim]")
|
|
360
355
|
|
|
361
356
|
|
|
357
|
+
def _raise_missing_prompt_source(token: str, catalog: dict[str, list[Path]]) -> None:
|
|
358
|
+
avail = ", ".join(sorted(catalog.keys()))
|
|
359
|
+
console.print(f"[red]Error:[/red] Prompt source [bold]{token}[/bold] is not available or has no prompt resources.")
|
|
360
|
+
console.print(f"[dim]Available sources: {avail}[/dim]")
|
|
361
|
+
console.print(
|
|
362
|
+
"[dim]Install modules with [bold]specfact module install --scope user|project[/bold] "
|
|
363
|
+
"or seed bundled artifacts with [bold]specfact module init --scope user|project[/bold].[/dim]"
|
|
364
|
+
)
|
|
365
|
+
raise typer.Exit(1)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
@beartype
|
|
369
|
+
def _parse_prompts_option_to_catalog(catalog: dict[str, list[Path]], prompts: str) -> dict[str, list[Path]]:
|
|
370
|
+
tokens = [t.strip() for t in prompts.split(",") if t.strip()]
|
|
371
|
+
if not tokens:
|
|
372
|
+
console.print("[red]Error:[/red] --prompts must list at least one source or `all`.")
|
|
373
|
+
raise typer.Exit(1)
|
|
374
|
+
if len(tokens) == 1 and tokens[0].lower() == "all":
|
|
375
|
+
return dict(catalog)
|
|
376
|
+
result: dict[str, list[Path]] = {}
|
|
377
|
+
for token in tokens:
|
|
378
|
+
key = PROMPT_SOURCE_CORE if token.lower() == "core" else token
|
|
379
|
+
if key not in catalog:
|
|
380
|
+
_raise_missing_prompt_source(token, catalog)
|
|
381
|
+
result[key] = catalog[key]
|
|
382
|
+
return result
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _select_prompt_sources_interactive(catalog: dict[str, list[Path]]) -> dict[str, list[Path]]:
|
|
386
|
+
keys = sorted(catalog.keys(), key=lambda k: (k != PROMPT_SOURCE_CORE, k))
|
|
387
|
+
if len(keys) <= 1:
|
|
388
|
+
return dict(catalog)
|
|
389
|
+
try:
|
|
390
|
+
import questionary # type: ignore[reportMissingImports]
|
|
391
|
+
except ImportError as e:
|
|
392
|
+
console.print(
|
|
393
|
+
"[red]Interactive prompt source selection requires 'questionary'. "
|
|
394
|
+
"Install with: pip install questionary[/red]"
|
|
395
|
+
)
|
|
396
|
+
raise typer.Exit(1) from e
|
|
397
|
+
|
|
398
|
+
console.print()
|
|
399
|
+
console.print(
|
|
400
|
+
Panel(
|
|
401
|
+
"[bold cyan]Prompt sources[/bold cyan]\n"
|
|
402
|
+
"Choose which prompt bundles to export (core and installed modules with prompt resources).",
|
|
403
|
+
border_style="cyan",
|
|
404
|
+
)
|
|
405
|
+
)
|
|
406
|
+
console.print("[dim]Controls: ↑↓ navigate • Space toggle • Enter confirm • Type to filter • Ctrl+C cancel[/dim]")
|
|
407
|
+
|
|
408
|
+
labels = [f"{k} ({len(catalog[k])} template(s))" for k in keys]
|
|
409
|
+
label_to_key = {labels[i]: keys[i] for i in range(len(keys))}
|
|
410
|
+
|
|
411
|
+
q = cast(Any, questionary)
|
|
412
|
+
choices_with_default = [q.Choice(title=lab, checked=True) for lab in labels]
|
|
413
|
+
selected = q.checkbox(
|
|
414
|
+
"Select prompt sources:",
|
|
415
|
+
choices=choices_with_default,
|
|
416
|
+
style=_questionary_style(),
|
|
417
|
+
).ask()
|
|
418
|
+
if not selected:
|
|
419
|
+
console.print("[red]Error:[/red] Select at least one prompt source.")
|
|
420
|
+
raise typer.Exit(1)
|
|
421
|
+
chosen: dict[str, list[Path]] = {}
|
|
422
|
+
for label in selected:
|
|
423
|
+
sid = label_to_key.get(label)
|
|
424
|
+
if sid is not None:
|
|
425
|
+
chosen[sid] = catalog[sid]
|
|
426
|
+
return chosen
|
|
427
|
+
|
|
428
|
+
|
|
362
429
|
def _select_ide_interactive(default_ide: str) -> str:
|
|
363
430
|
"""Select IDE interactively with up/down controls."""
|
|
364
431
|
try:
|
|
@@ -561,8 +628,16 @@ def init_ide(
|
|
|
561
628
|
"--ide",
|
|
562
629
|
help="IDE type (cursor, vscode, copilot, claude, gemini, qwen, opencode, windsurf, kilocode, auggie, roo, codebuddy, amp, q, auto)",
|
|
563
630
|
),
|
|
631
|
+
prompts: str | None = typer.Option(
|
|
632
|
+
None,
|
|
633
|
+
"--prompts",
|
|
634
|
+
help=(
|
|
635
|
+
"Comma-separated prompt sources: 'all', 'core', and/or module ids (e.g. nold-ai/specfact-backlog). "
|
|
636
|
+
"Default: all discovered sources. Omitted in interactive mode opens a multi-select."
|
|
637
|
+
),
|
|
638
|
+
),
|
|
564
639
|
) -> None:
|
|
565
|
-
"""Initialize IDE prompt templates and settings."""
|
|
640
|
+
"""Initialize IDE prompt templates and settings (exports core + installed module prompts; re-sync anytime)."""
|
|
566
641
|
repo_path = repo.resolve()
|
|
567
642
|
detected_default = detect_ide("auto")
|
|
568
643
|
if ide is not None:
|
|
@@ -595,14 +670,28 @@ def init_ide(
|
|
|
595
670
|
if install_deps:
|
|
596
671
|
_install_contract_enhancement_dependencies(repo_path, env_info)
|
|
597
672
|
|
|
598
|
-
|
|
599
|
-
if not
|
|
600
|
-
console.print("[red]Error:[/red]
|
|
673
|
+
catalog = discover_prompt_sources_catalog(repo_path)
|
|
674
|
+
if not catalog:
|
|
675
|
+
console.print("[red]Error:[/red] No prompt templates found.")
|
|
676
|
+
console.print(
|
|
677
|
+
"[dim]Seed or install modules first, e.g. [bold]specfact module init --scope project[/bold] "
|
|
678
|
+
"or [bold]specfact module install --scope user[/bold].[/dim]"
|
|
679
|
+
)
|
|
601
680
|
raise typer.Exit(1)
|
|
602
681
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
682
|
+
if prompts is not None:
|
|
683
|
+
selected_catalog = _parse_prompts_option_to_catalog(catalog, prompts)
|
|
684
|
+
elif is_non_interactive():
|
|
685
|
+
selected_catalog = dict(catalog)
|
|
686
|
+
else:
|
|
687
|
+
selected_catalog = _select_prompt_sources_interactive(catalog)
|
|
688
|
+
|
|
689
|
+
source_summary = ", ".join(sorted(selected_catalog.keys()))
|
|
690
|
+
console.print(f"[cyan]Prompt sources:[/cyan] {source_summary}")
|
|
691
|
+
copied_files, settings_path = copy_templates_to_ide(
|
|
692
|
+
repo_path, selected_ide, force, prompts_by_source=selected_catalog
|
|
693
|
+
)
|
|
694
|
+
write_ide_prompt_export_state(repo_path, selected_ide, sorted(selected_catalog.keys()))
|
|
606
695
|
_copy_backlog_field_mapping_templates(repo_path, force, console)
|
|
607
696
|
|
|
608
697
|
console.print()
|