specfact-cli 0.26.14__tar.gz → 0.26.16__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.26.14 → specfact_cli-0.26.16}/PKG-INFO +1 -1
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/pyproject.toml +8 -4
- specfact_cli-0.26.16/resources/prompts/specfact.backlog-daily.md +109 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.backlog-refine.md +26 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/__init__.py +1 -1
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/ado.py +5 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/github.py +30 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/base.py +31 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/cli.py +1 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/backlog_commands.py +1012 -40
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/logger_setup.py +11 -3
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/runtime.py +11 -3
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/.gitignore +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/LICENSE.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/README.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/shared/cli-enforcement.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.01-import.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.02-plan.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.03-review.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.04-sdd.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.05-enforce.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.06-sync.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.07-contracts.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.compare.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.sync-backlog.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/prompts/specfact.validate.md +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_agile.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_default.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_kanban.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_safe.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/field_mappings/ado_scrum.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/frameworks/safe/safe_feature_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/personas/developer/developer_task_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/backlog/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/adapters/speckit.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/adapters/local_yaml_adapter.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/ai_refiner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/format_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/markdown_format.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/formats/structured_format.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/backlog/template_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/auth.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/persona_exporter.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/bridge_templates.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.26.14 → specfact_cli-0.26.16}/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.26.
|
|
3
|
+
Version: 0.26.16
|
|
4
4
|
Summary: Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions.
|
|
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.26.
|
|
7
|
+
version = "0.26.16"
|
|
8
8
|
description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -272,9 +272,9 @@ TOKENIZERS_PARALLELISM = "false" # Good practice if using HuggingFace tokenizers
|
|
|
272
272
|
|
|
273
273
|
[tool.hatch.envs.hatch-test.scripts]
|
|
274
274
|
# Adapted from template, adjust JUnit path if necessary
|
|
275
|
-
run = "pytest --timeout=
|
|
276
|
-
run-cov = "coverage run -m pytest --timeout=
|
|
277
|
-
cov = "coverage run -m pytest --timeout=
|
|
275
|
+
run = "pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}" # 30s for code analysis/semgrep/graph tests under xdist
|
|
276
|
+
run-cov = "coverage run -m pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}"
|
|
277
|
+
cov = "coverage run -m pytest --timeout=30 --junitxml=logs/tests/junit/test-results.xml {args}"
|
|
278
278
|
cov-combine = "coverage combine --quiet"
|
|
279
279
|
xml = "coverage xml -o logs/tests/coverage/coverage.xml"
|
|
280
280
|
run-html = "coverage html --data-file=logs/tests/coverage/.coverage -d logs/tests/coverage/html"
|
|
@@ -334,6 +334,10 @@ output = "logs/tests/coverage/coverage.xml"
|
|
|
334
334
|
mode = "strict"
|
|
335
335
|
default_fixture_loop_scope = "function"
|
|
336
336
|
|
|
337
|
+
[tool.pytest-timeout]
|
|
338
|
+
timeout = 30
|
|
339
|
+
method = "thread"
|
|
340
|
+
|
|
337
341
|
[tool.hatch.build]
|
|
338
342
|
dev-mode-dirs = ["src","tools"]
|
|
339
343
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Daily standup and sprint review with story-by-story walkthrough"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# SpecFact Daily Standup Command
|
|
6
|
+
|
|
7
|
+
## User Input
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
$ARGUMENTS
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You **MUST** consider the user input before proceeding (if not empty).
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Run a daily standup view and optional interactive walkthrough of backlog items (GitHub Issues, Azure DevOps work items) with the DevOps team: list items in scope, review story-by-story, highlight current focus, surface issues or open questions, and allow adding discussion notes as annotation comments on the issue.
|
|
18
|
+
|
|
19
|
+
**When to use:** Daily standup, sprint review, quick status sync with the team.
|
|
20
|
+
|
|
21
|
+
**Quick:** `/specfact.daily` or `/specfact.backlog-daily` with optional adapter and filters. From a clone, org/repo or org/project are auto-detected from git remote.
|
|
22
|
+
|
|
23
|
+
## Parameters
|
|
24
|
+
|
|
25
|
+
### Required
|
|
26
|
+
|
|
27
|
+
- `ADAPTER` - Backlog adapter name (github, ado, etc.)
|
|
28
|
+
|
|
29
|
+
### Adapter Configuration (same as backlog-refine)
|
|
30
|
+
|
|
31
|
+
**GitHub:** `--repo-owner`, `--repo-name`, `--github-token` (optional).
|
|
32
|
+
**Azure DevOps:** `--ado-org`, `--ado-project`, `--ado-team` (optional), `--ado-base-url`, `--ado-token` (optional).
|
|
33
|
+
|
|
34
|
+
When run from a **clone**, org/repo or org/project are inferred from `git remote get-url origin`; no need to pass them unless overriding.
|
|
35
|
+
|
|
36
|
+
### Filters
|
|
37
|
+
|
|
38
|
+
- `--state STATE` - Filter by state (e.g. open, Active)
|
|
39
|
+
- `--assignee USERNAME` or `--assignee me` - Filter by assignee
|
|
40
|
+
- `--sprint SPRINT` / `--iteration PATH` - Filter by sprint/iteration (e.g. `current`)
|
|
41
|
+
- `--limit N` - Max items (default 20)
|
|
42
|
+
- `--blockers-first` - Sort items with blockers first
|
|
43
|
+
- `--show-unassigned` / `--unassigned-only` - Include or show only unassigned items
|
|
44
|
+
|
|
45
|
+
### Daily-Specific Options
|
|
46
|
+
|
|
47
|
+
- `--interactive` - Step-by-step review: select items with arrow keys, view full detail (refine-like) and **existing comments** on each issue
|
|
48
|
+
- `--copilot-export PATH` - Write summarized progress per story to a file for Copilot slash-command use
|
|
49
|
+
- `--summarize` - Output a prompt (instruction + filter context + standup data) to **stdout** for Copilot or slash command to generate a standup summary
|
|
50
|
+
- `--summarize-to PATH` - Write the same summarize prompt to a **file**
|
|
51
|
+
- `--suggest-next` - In interactive mode, show suggested next item by value score
|
|
52
|
+
- `--post` with `--yesterday`, `--today`, `--blockers` - Post a standup comment to the first item's issue (when adapter supports comments)
|
|
53
|
+
|
|
54
|
+
## Workflow
|
|
55
|
+
|
|
56
|
+
### Step 1: Run Daily Standup
|
|
57
|
+
|
|
58
|
+
Execute the CLI with adapter and optional filters:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
specfact backlog daily $ADAPTER [--state open] [--sprint current] [--assignee me] [--limit 20]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Or use the slash command with arguments: `/specfact.backlog-daily --adapter ado --sprint current`
|
|
65
|
+
|
|
66
|
+
**What you see:** A standup table (assigned items) and a "Pending / open for commitment" table (unassigned items in scope). Each row shows ID, title, status, last updated, and optional yesterday/today/blockers from the item body.
|
|
67
|
+
|
|
68
|
+
### Step 2: Interactive Story-by-Story Review (with DevOps team)
|
|
69
|
+
|
|
70
|
+
When the user runs **`--interactive`** (or the slash command drives an interactive flow):
|
|
71
|
+
|
|
72
|
+
1. **For each story** (one at a time):
|
|
73
|
+
- **Present** the item: ID, title, status, assignees, last updated, description, acceptance criteria, standup fields (yesterday/today/blockers), and **existing comments** annotated to that issue (when the adapter supports fetching comments).
|
|
74
|
+
- **Highlight current focus**: What is the team member working on? What is the next intended step?
|
|
75
|
+
- **Surface issues or open questions**: Blockers, ambiguities, dependencies, or decisions needed.
|
|
76
|
+
- **Allow discussion notes**: If the team agrees, suggest or add a **comment** on the issue (e.g. "Standup YYYY-MM-DD: …" or "Discussion: …") so the discussion is captured as an annotation. Only add comments when the user explicitly approves (e.g. "add that as a comment").
|
|
77
|
+
- **Move to next** only when the team is done with this story (e.g. "next", "done").
|
|
78
|
+
|
|
79
|
+
2. **Rules**:
|
|
80
|
+
- Do not update the backlog item body or title unless the user asks for a refinement (use `specfact backlog refine` for that).
|
|
81
|
+
- Comments are for **discussion notes** and standup updates; keep them short and actionable.
|
|
82
|
+
- If the adapter does not support comments, report that clearly and skip adding comments.
|
|
83
|
+
|
|
84
|
+
3. **Navigation**: After each story, offer "Next story", "Previous story", "Back to list", "Exit" (or equivalent) so the team can move through the list without re-running the command.
|
|
85
|
+
|
|
86
|
+
### Step 3: Generate Standup Summary (optional)
|
|
87
|
+
|
|
88
|
+
When the user has run `specfact backlog daily ... --summarize` or `--summarize-to PATH`, the output is a **prompt** containing:
|
|
89
|
+
|
|
90
|
+
- A short instruction: generate a concise daily standup summary from the following data.
|
|
91
|
+
- Filter context (adapter, state, sprint, assignee, limit).
|
|
92
|
+
- Per-item data (same as `--copilot-export`: ID, title, status, assignees, last updated, progress, blockers).
|
|
93
|
+
|
|
94
|
+
**Use this output** by pasting it into Copilot or invoking the slash command `specfact.daily` with this context, so the AI can produce a short narrative summary (e.g. "Today's standup: 3 in progress, 1 blocked, 2 pending commitment …").
|
|
95
|
+
|
|
96
|
+
## Comments on Issues
|
|
97
|
+
|
|
98
|
+
- **Interactive detail view** shows **existing comments** on each issue (GitHub issue comments, ADO work item discussion) when the adapter supports it. Use them to understand prior discussion and avoid repeating questions.
|
|
99
|
+
- **Adding comments**: When the team agrees to record a discussion note or standup update, add it as a comment on the issue (via `--post` for standup lines, or by guiding the user to run the CLI/post manually). Do not invent comments; only suggest or add when the user approves.
|
|
100
|
+
|
|
101
|
+
## CLI Enforcement
|
|
102
|
+
|
|
103
|
+
- Execute `specfact backlog daily` (or equivalent) first; use its output as context.
|
|
104
|
+
- Use `--interactive` for story-by-story walkthrough; use `--summarize` or `--summarize-to` when a standup summary prompt is needed.
|
|
105
|
+
- Use `--copilot-export` when you need a file of item summaries for reference during standup.
|
|
106
|
+
|
|
107
|
+
## Context
|
|
108
|
+
|
|
109
|
+
{ARGS}
|
|
@@ -69,6 +69,8 @@ Refine backlog items from DevOps tools (GitHub Issues, Azure DevOps, etc.) into
|
|
|
69
69
|
- Ambiguous name-only matches will prompt for explicit iteration path
|
|
70
70
|
- `--release RELEASE` - Filter by release identifier (case-insensitive)
|
|
71
71
|
- `--limit N` - Maximum number of items to process in this refinement session (caps batch size)
|
|
72
|
+
- `--ignore-refined` / `--no-ignore-refined` - When set (default), exclude already-refined items so `--limit` applies to items that need refinement. Use `--no-ignore-refined` to process the first N items in order.
|
|
73
|
+
- `--id ISSUE_ID` - Refine only this backlog item (issue or work item ID). Other items are ignored.
|
|
72
74
|
- `--persona PERSONA` - Filter templates by persona (product-owner, architect, developer)
|
|
73
75
|
- `--framework FRAMEWORK` - Filter templates by framework (agile, scrum, safe, kanban)
|
|
74
76
|
|
|
@@ -162,6 +164,30 @@ specfact backlog refine $ADAPTER \
|
|
|
162
164
|
- Use `:quit` or `:abort` to cancel the entire session gracefully
|
|
163
165
|
- Session cancellation shows summary and exits without error
|
|
164
166
|
|
|
167
|
+
### Interactive refinement (Copilot mode)
|
|
168
|
+
|
|
169
|
+
When refining backlog items in Copilot mode (e.g. after export to tmp or during a refinement session), follow this **per-story loop** so the PO and stakeholders can review and approve before any update:
|
|
170
|
+
|
|
171
|
+
1. **For each story** (one at a time):
|
|
172
|
+
- **Present** the refined story in a clear, readable format:
|
|
173
|
+
- Use headings for Title, Body, Acceptance Criteria, Metrics.
|
|
174
|
+
- Use tables or panels for structured data so it is easy to scan.
|
|
175
|
+
- **Assess specification level** so the DevOps team knows if the story is ready, under-specified, or over-specified:
|
|
176
|
+
- **Under-specified**: Missing acceptance criteria, vague scope, unclear "so that" or user value. List evidence (e.g. "No AC", "Scope could mean X or Y"). Suggest what to add.
|
|
177
|
+
- **Over-specified**: Too much implementation detail, too many sub-steps for one story, or solution prescribed instead of outcome. List evidence and suggest what to trim or split.
|
|
178
|
+
- **Fit for scope and intent**: Clear persona, capability, benefit, and testable AC; appropriate size. State briefly why it is ready (and, if DoR is in use, that DoR is satisfied).
|
|
179
|
+
- **List ambiguities** or open questions (e.g. unclear scope, missing acceptance criteria, conflicting assumptions).
|
|
180
|
+
- **Ask** the PO and other stakeholders for clarification: "Please review the refined story above. Do you want any changes? Any ambiguities to resolve? Should this story be split?"
|
|
181
|
+
- **If the user provides feedback**: Re-refine the story incorporating the feedback, then repeat from "Present" for this story.
|
|
182
|
+
- **Only when the user explicitly approves** (e.g. "looks good", "approved", "no changes"): Mark this story as done and move to the **next** story.
|
|
183
|
+
- **Do not update** the backlog item (or write to the refined file as final) until the user has approved this story.
|
|
184
|
+
|
|
185
|
+
2. **Formatting**:
|
|
186
|
+
- Use clear headings, bullet lists, and optional tables/panels so refinement sessions are easy to follow and enjoyable.
|
|
187
|
+
- Keep each story’s block self-contained so stakeholders can focus on one item at a time.
|
|
188
|
+
|
|
189
|
+
3. **Rule**: The backlog item (or exported block) must only be updated/finalized **after** the user has approved the refined content for that story. Then proceed to the next story with the same process.
|
|
190
|
+
|
|
165
191
|
### Step 3: Present Results
|
|
166
192
|
|
|
167
193
|
Display refinement results:
|
|
@@ -3107,6 +3107,11 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
3107
3107
|
|
|
3108
3108
|
return filtered_items
|
|
3109
3109
|
|
|
3110
|
+
@beartype
|
|
3111
|
+
def supports_add_comment(self) -> bool:
|
|
3112
|
+
"""Whether this adapter can add comments (requires token, org, project)."""
|
|
3113
|
+
return bool(self.api_token and self.org and self.project)
|
|
3114
|
+
|
|
3110
3115
|
@beartype
|
|
3111
3116
|
def add_comment(self, item: BacklogItem, comment: str) -> bool:
|
|
3112
3117
|
"""
|
|
@@ -2644,6 +2644,11 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2644
2644
|
lambda result, item: result.id == item.id and result.provider == item.provider,
|
|
2645
2645
|
"Updated item must preserve id and provider",
|
|
2646
2646
|
)
|
|
2647
|
+
@beartype
|
|
2648
|
+
def supports_add_comment(self) -> bool:
|
|
2649
|
+
"""Whether this adapter can add comments (requires token and repo)."""
|
|
2650
|
+
return bool(self.api_token and self.repo_owner and self.repo_name)
|
|
2651
|
+
|
|
2647
2652
|
@beartype
|
|
2648
2653
|
def add_comment(self, item: BacklogItem, comment: str) -> bool:
|
|
2649
2654
|
"""
|
|
@@ -2681,6 +2686,31 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2681
2686
|
except Exception:
|
|
2682
2687
|
return False
|
|
2683
2688
|
|
|
2689
|
+
@beartype
|
|
2690
|
+
def get_comments(self, item: BacklogItem) -> list[str]:
|
|
2691
|
+
"""
|
|
2692
|
+
Fetch comments for a GitHub issue.
|
|
2693
|
+
|
|
2694
|
+
Args:
|
|
2695
|
+
item: BacklogItem to fetch comments for
|
|
2696
|
+
|
|
2697
|
+
Returns:
|
|
2698
|
+
List of comment body strings, or empty list on error
|
|
2699
|
+
"""
|
|
2700
|
+
if not self.repo_owner or not self.repo_name:
|
|
2701
|
+
return []
|
|
2702
|
+
issue_number: int | None = None
|
|
2703
|
+
if item.id.isdigit():
|
|
2704
|
+
issue_number = int(item.id)
|
|
2705
|
+
elif item.url:
|
|
2706
|
+
match = re.search(r"/issues/(\d+)", item.url)
|
|
2707
|
+
if match:
|
|
2708
|
+
issue_number = int(match.group(1))
|
|
2709
|
+
if not issue_number:
|
|
2710
|
+
return []
|
|
2711
|
+
raw = self._get_issue_comments(self.repo_owner, self.repo_name, issue_number)
|
|
2712
|
+
return [str(c.get("body", "")).strip() for c in raw if isinstance(c, dict)]
|
|
2713
|
+
|
|
2684
2714
|
def update_backlog_item(self, item: BacklogItem, update_fields: list[str] | None = None) -> BacklogItem:
|
|
2685
2715
|
"""
|
|
2686
2716
|
Update a GitHub issue.
|
|
@@ -147,6 +147,20 @@ class BacklogAdapter(ABC):
|
|
|
147
147
|
"""
|
|
148
148
|
return None
|
|
149
149
|
|
|
150
|
+
@beartype
|
|
151
|
+
@ensure(lambda result: isinstance(result, bool), "Must return boolean")
|
|
152
|
+
def supports_add_comment(self) -> bool:
|
|
153
|
+
"""
|
|
154
|
+
Whether this adapter supports adding comments to backlog items.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
True if add_comment will attempt to post, False otherwise
|
|
158
|
+
|
|
159
|
+
Note:
|
|
160
|
+
Default is False. Override in adapters that support issue comments.
|
|
161
|
+
"""
|
|
162
|
+
return False
|
|
163
|
+
|
|
150
164
|
@beartype
|
|
151
165
|
def add_comment(self, item: BacklogItem, comment: str) -> bool:
|
|
152
166
|
"""
|
|
@@ -164,3 +178,20 @@ class BacklogAdapter(ABC):
|
|
|
164
178
|
can use the default False implementation.
|
|
165
179
|
"""
|
|
166
180
|
return False
|
|
181
|
+
|
|
182
|
+
@beartype
|
|
183
|
+
def get_comments(self, item: BacklogItem) -> list[str]:
|
|
184
|
+
"""
|
|
185
|
+
Fetch comments for a backlog item (optional).
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
item: BacklogItem to fetch comments for
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
List of comment body strings, or empty list if not supported or on error
|
|
192
|
+
|
|
193
|
+
Note:
|
|
194
|
+
This is an optional method. Adapters that don't support fetching comments
|
|
195
|
+
can use the default empty list implementation.
|
|
196
|
+
"""
|
|
197
|
+
return []
|
|
@@ -454,6 +454,7 @@ def cli_main() -> None:
|
|
|
454
454
|
console.print() # Empty line after banner
|
|
455
455
|
elif not is_help_or_version and not is_test_mode:
|
|
456
456
|
# Show simple version line like other CLIs (skip for help/version commands and in test mode)
|
|
457
|
+
# Printed before startup checks so users see output immediately (important with slow checks e.g. xagt)
|
|
457
458
|
print_version_line()
|
|
458
459
|
|
|
459
460
|
# Run startup checks (template validation and version check)
|