specfact-cli 0.30.1__tar.gz → 0.30.2__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.30.1 → specfact_cli-0.30.2}/PKG-INFO +1 -1
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/pyproject.toml +1 -1
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.backlog-daily.md +13 -3
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.backlog-refine.md +12 -1
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/ado.py +56 -6
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/github.py +34 -29
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/ai_refiner.py +19 -1
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/commands.py +839 -77
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/.gitignore +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/LICENSE.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/README.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/shared/cli-enforcement.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.01-import.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.02-plan.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.03-review.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.04-sdd.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.05-enforce.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.06-sync.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.07-contracts.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.compare.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.sync-backlog.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/prompts/specfact.validate.md +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/field_mappings/ado_agile.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/field_mappings/ado_default.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/field_mappings/ado_kanban.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/field_mappings/ado_safe.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/field_mappings/ado_scrum.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/frameworks/safe/safe_feature_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/personas/developer/developer_task_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/backlog/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/persona/architect.md.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/persona/developer.md.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/persona/product-owner.md.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/__main__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/backlog_base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/openspec.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/openspec_parser.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/registry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/adapters/speckit.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/adapters/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/adapters/local_yaml_adapter.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/converter.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/filters.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/format_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/formats/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/formats/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/formats/markdown_format.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/formats/structured_format.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/mappers/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/backlog/template_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/cli.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/auth.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/backlog_commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/contract_cmd.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/plan.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/project_cmd.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/update.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/commands/validate.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/common/logger_setup.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/contracts/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/contracts/crosshair_props.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/contracts/module_interface.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/persona_exporter.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/merge/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/merge/resolver.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/backlog_item.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/capabilities.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/change.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/contract.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/dor_config.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/module_package.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/persona_template.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/models/validation.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/analyze/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/analyze/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/analyze/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/analyze/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/auth/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/auth/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/auth/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/auth/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/ado.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/github.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/jira.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/adapters/linear.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/backlog/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/contract/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/contract/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/contract/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/contract/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/drift/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/drift/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/drift/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/drift/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/enforce/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/enforce/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/enforce/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/enforce/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/generate/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/generate/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/generate/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/generate/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/import_cmd/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/import_cmd/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/import_cmd/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/import_cmd/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/init/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/init/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/init/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/init/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/migrate/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/migrate/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/migrate/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/migrate/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/module_io_shim.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/plan/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/plan/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/plan/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/plan/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/project/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/project/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/project/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/project/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/repro/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/repro/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/repro/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/repro/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sdd/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sdd/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sdd/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sdd/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/spec/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/spec/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/spec/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/spec/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sync/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sync/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sync/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/sync/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/validate/module-package.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/validate/src/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/validate/src/app.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/modules/validate/src/commands.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/parsers/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/parsers/persona_importer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/bootstrap.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/bridge_registry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/help_cache.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/metadata.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/module_packages.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/module_state.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/registry/registry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/bridge_templates.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/registry.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/auth_tokens.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/bundle_converters.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/code_change_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/content_sanitizer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/env_manager.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/metadata.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/persona_ownership.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/startup_checks.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/terminal.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/agile_validation.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/schema.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/models.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/src/specfact_cli/versioning/__init__.py +0 -0
- {specfact_cli-0.30.1 → specfact_cli-0.30.2}/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.30.
|
|
3
|
+
Version: 0.30.2
|
|
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.30.
|
|
7
|
+
version = "0.30.2"
|
|
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"
|
|
@@ -37,8 +37,12 @@ When run from a **clone**, org/repo or org/project are inferred from `git remote
|
|
|
37
37
|
|
|
38
38
|
- `--state STATE` - Filter by state (e.g. open, Active)
|
|
39
39
|
- `--assignee USERNAME` or `--assignee me` - Filter by assignee
|
|
40
|
+
- `--search QUERY` - Provider-specific search query
|
|
41
|
+
- `--release RELEASE` - Filter by release identifier
|
|
42
|
+
- `--id ISSUE_ID` - Filter to one exact backlog item ID
|
|
40
43
|
- `--sprint SPRINT` / `--iteration PATH` - Filter by sprint/iteration (e.g. `current`)
|
|
41
44
|
- `--limit N` - Max items (default 20)
|
|
45
|
+
- `--first-issues N` / `--last-issues N` - Optional issue window (oldest/newest by numeric ID, mutually exclusive)
|
|
42
46
|
- `--blockers-first` - Sort items with blockers first
|
|
43
47
|
- `--show-unassigned` / `--unassigned-only` - Include or show only unassigned items
|
|
44
48
|
|
|
@@ -48,8 +52,11 @@ When run from a **clone**, org/repo or org/project are inferred from `git remote
|
|
|
48
52
|
- `--copilot-export PATH` - Write summarized progress per story to a file for Copilot slash-command use
|
|
49
53
|
- `--summarize` - Output a prompt (instruction + filter context + standup data) to **stdout** for Copilot or slash command to generate a standup summary
|
|
50
54
|
- `--summarize-to PATH` - Write the same summarize prompt to a **file**
|
|
55
|
+
- `--comments` / `--annotations` - Include descriptions and comments in `--copilot-export` and summarize output
|
|
56
|
+
- `--first-comments N` / `--last-comments N` - Optional comment window for export/summarize outputs (`--comments`); default includes all comments
|
|
51
57
|
- `--suggest-next` - In interactive mode, show suggested next item by value score
|
|
52
58
|
- `--post` with `--yesterday`, `--today`, `--blockers` - Post a standup comment to the first item's issue (when adapter supports comments)
|
|
59
|
+
- Interactive navigation action `Post standup update` - Post yesterday/today/blockers to the currently selected story during `--interactive` walkthrough
|
|
53
60
|
|
|
54
61
|
## Workflow
|
|
55
62
|
|
|
@@ -70,10 +77,12 @@ Or use the slash command with arguments: `/specfact.backlog-daily --adapter ado
|
|
|
70
77
|
When the user runs **`--interactive`** (or the slash command drives an interactive flow):
|
|
71
78
|
|
|
72
79
|
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
|
|
80
|
+
- **Present** the item: ID, title, status, assignees, last updated, description, acceptance criteria, standup fields (yesterday/today/blockers), and the **latest existing comment** (when the adapter supports fetching comments).
|
|
81
|
+
- **Interactive comment scope**: If older comments exist, explicitly mention the count of hidden comments and guide users to export options for full context.
|
|
74
82
|
- **Highlight current focus**: What is the team member working on? What is the next intended step?
|
|
75
83
|
- **Surface issues or open questions**: Blockers, ambiguities, dependencies, or decisions needed.
|
|
76
84
|
- **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").
|
|
85
|
+
- If in CLI interactive navigation, use **Post standup update** to write the note to the selected story directly.
|
|
77
86
|
- **Move to next** only when the team is done with this story (e.g. "next", "done").
|
|
78
87
|
|
|
79
88
|
2. **Rules**:
|
|
@@ -95,8 +104,9 @@ When the user has run `specfact backlog daily ... --summarize` or `--summarize-t
|
|
|
95
104
|
|
|
96
105
|
## Comments on Issues
|
|
97
106
|
|
|
98
|
-
- **Interactive detail view** shows **
|
|
99
|
-
- **
|
|
107
|
+
- **Interactive detail view** shows only the **latest comment** plus a hint when additional comments exist, to keep standup readable.
|
|
108
|
+
- **Full comment context**: use `--copilot-export <path> --comments` or `--summarize --comments` (optional `--first-comments N` / `--last-comments N`) to include full or scoped comment history.
|
|
109
|
+
- **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 first-item standup lines or interactive **Post standup update** for selected stories). Do not invent comments; only suggest or add when the user approves.
|
|
100
110
|
|
|
101
111
|
## CLI Enforcement
|
|
102
112
|
|
|
@@ -69,6 +69,7 @@ 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
|
+
- `--first-issues N` / `--last-issues N` - Process only the first or last N items after filters/refinement checks (mutually exclusive; sorted by numeric issue/work-item ID, lower=older, higher=newer)
|
|
72
73
|
- `--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
74
|
- `--id ISSUE_ID` - Refine only this backlog item (issue or work item ID). Other items are ignored.
|
|
74
75
|
- `--persona PERSONA` - Filter templates by persona (product-owner, architect, developer)
|
|
@@ -91,13 +92,23 @@ Refine backlog items from DevOps tools (GitHub Issues, Azure DevOps, etc.) into
|
|
|
91
92
|
- `--export-to-tmp` - Export backlog items to temporary file for copilot processing (default: `/tmp/specfact-backlog-refine-<timestamp>.md`)
|
|
92
93
|
- `--import-from-tmp` - Import refined content from temporary file after copilot processing (default: `/tmp/specfact-backlog-refine-<timestamp>-refined.md`)
|
|
93
94
|
- `--tmp-file PATH` - Custom temporary file path (overrides default)
|
|
95
|
+
- `--first-comments N` / `--last-comments N` - Optional comment window for preview and write-mode prompt context (default preview shows last 2; write prompts include full comments by default)
|
|
94
96
|
|
|
95
97
|
**Export/Import Workflow**:
|
|
96
98
|
|
|
97
99
|
1. Export items: `specfact backlog refine --adapter github --export-to-tmp --repo-owner OWNER --repo-name NAME`
|
|
98
|
-
2. Process with copilot: Open exported file
|
|
100
|
+
2. Process with copilot: Open exported file and follow the embedded `## Copilot Instructions` and per-item template guidance (`Target Template`, `Required Sections`, `Optional Sections`). Save as `-refined.md`
|
|
99
101
|
3. Import refined: `specfact backlog refine --adapter github --import-from-tmp --repo-owner OWNER --repo-name NAME --write`
|
|
100
102
|
|
|
103
|
+
When refining from an exported file, treat the embedded instructions in that file as the source of truth for required structure and formatting.
|
|
104
|
+
|
|
105
|
+
**Comment context in export**:
|
|
106
|
+
|
|
107
|
+
- Export includes item comments when adapter supports comment retrieval (GitHub + ADO).
|
|
108
|
+
- Export always includes full comment history (no truncation).
|
|
109
|
+
- Use `--first-comments N` or `--last-comments N` only to adjust preview output density.
|
|
110
|
+
- For refined import readiness, the `-refined.md` artifact should omit the instruction header and keep only item sections.
|
|
111
|
+
|
|
101
112
|
### Definition of Ready (DoR)
|
|
102
113
|
|
|
103
114
|
- `--check-dor` - Check Definition of Ready (DoR) rules before refinement (loads from `.specfact/dor.yaml`)
|
|
@@ -2356,18 +2356,39 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2356
2356
|
if not self.api_token:
|
|
2357
2357
|
return []
|
|
2358
2358
|
|
|
2359
|
-
url = f"{self.base_url}/{org}/{project}/_apis/wit/
|
|
2359
|
+
url = f"{self.base_url}/{org}/{project}/_apis/wit/workItems/{work_item_id}/comments"
|
|
2360
2360
|
headers = {
|
|
2361
2361
|
"Accept": "application/json",
|
|
2362
2362
|
**self._auth_headers(),
|
|
2363
2363
|
}
|
|
2364
2364
|
|
|
2365
2365
|
try:
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2366
|
+
comments: list[dict[str, Any]] = []
|
|
2367
|
+
continuation_token: str | None = None
|
|
2368
|
+
seen_tokens: set[str] = set()
|
|
2369
|
+
|
|
2370
|
+
while True:
|
|
2371
|
+
params: dict[str, Any] = {"api-version": "7.1-preview.4", "$top": 200, "order": "asc"}
|
|
2372
|
+
if continuation_token:
|
|
2373
|
+
params["continuationToken"] = continuation_token
|
|
2374
|
+
|
|
2375
|
+
response = requests.get(url, headers=headers, params=params, timeout=30)
|
|
2376
|
+
response.raise_for_status()
|
|
2377
|
+
response_data = response.json()
|
|
2378
|
+
|
|
2379
|
+
raw_comments = response_data.get("comments", [])
|
|
2380
|
+
if isinstance(raw_comments, list):
|
|
2381
|
+
comments.extend([c for c in raw_comments if isinstance(c, dict)])
|
|
2382
|
+
|
|
2383
|
+
next_token = response.headers.get("x-ms-continuationtoken") or response_data.get("continuationToken")
|
|
2384
|
+
if not next_token or not isinstance(next_token, str):
|
|
2385
|
+
break
|
|
2386
|
+
if next_token in seen_tokens:
|
|
2387
|
+
break
|
|
2388
|
+
seen_tokens.add(next_token)
|
|
2389
|
+
continuation_token = next_token
|
|
2390
|
+
|
|
2391
|
+
return comments
|
|
2371
2392
|
except requests.RequestException:
|
|
2372
2393
|
# Return empty list on error - comments are optional
|
|
2373
2394
|
return []
|
|
@@ -3145,6 +3166,35 @@ class AdoAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
3145
3166
|
except Exception:
|
|
3146
3167
|
return False
|
|
3147
3168
|
|
|
3169
|
+
@beartype
|
|
3170
|
+
def get_comments(self, item: BacklogItem) -> list[str]:
|
|
3171
|
+
"""
|
|
3172
|
+
Fetch comments for an Azure DevOps work item.
|
|
3173
|
+
|
|
3174
|
+
Args:
|
|
3175
|
+
item: BacklogItem to fetch comments for
|
|
3176
|
+
|
|
3177
|
+
Returns:
|
|
3178
|
+
List of comment body strings, or empty list on error
|
|
3179
|
+
"""
|
|
3180
|
+
if not self.org or not self.project:
|
|
3181
|
+
return []
|
|
3182
|
+
|
|
3183
|
+
if not item.id.isdigit():
|
|
3184
|
+
return []
|
|
3185
|
+
|
|
3186
|
+
raw = self._get_work_item_comments(self.org, self.project, int(item.id))
|
|
3187
|
+
comment_texts: list[str] = []
|
|
3188
|
+
for comment in raw:
|
|
3189
|
+
if not isinstance(comment, dict):
|
|
3190
|
+
continue
|
|
3191
|
+
text = comment.get("text") or comment.get("body")
|
|
3192
|
+
if isinstance(text, str):
|
|
3193
|
+
stripped = text.strip()
|
|
3194
|
+
if stripped:
|
|
3195
|
+
comment_texts.append(stripped)
|
|
3196
|
+
return comment_texts
|
|
3197
|
+
|
|
3148
3198
|
@beartype
|
|
3149
3199
|
@require(lambda item: isinstance(item, BacklogItem), "Item must be BacklogItem")
|
|
3150
3200
|
@require(
|
|
@@ -2526,7 +2526,11 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2526
2526
|
if filters.assignee:
|
|
2527
2527
|
# Strip leading @ if present for GitHub search
|
|
2528
2528
|
assignee_value = filters.assignee.lstrip("@")
|
|
2529
|
-
|
|
2529
|
+
normalized_assignee_value = BacklogFilters.normalize_filter_value(assignee_value)
|
|
2530
|
+
if normalized_assignee_value == "me":
|
|
2531
|
+
query_parts.append("assignee:@me")
|
|
2532
|
+
else:
|
|
2533
|
+
query_parts.append(f"assignee:{assignee_value}")
|
|
2530
2534
|
|
|
2531
2535
|
if filters.labels:
|
|
2532
2536
|
for label in filters.labels:
|
|
@@ -2585,24 +2589,25 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2585
2589
|
# Normalize assignee filter (strip @, lowercase)
|
|
2586
2590
|
assignee_filter = filters.assignee.lstrip("@")
|
|
2587
2591
|
normalized_assignee = BacklogFilters.normalize_filter_value(assignee_filter)
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2592
|
+
# `me` is provider-relative identity and should rely on GitHub query semantics.
|
|
2593
|
+
if normalized_assignee != "me":
|
|
2594
|
+
filtered_items = [
|
|
2595
|
+
item
|
|
2596
|
+
for item in filtered_items
|
|
2597
|
+
if any(
|
|
2598
|
+
# Match against login (case-insensitive)
|
|
2599
|
+
BacklogFilters.normalize_filter_value(assignee) == normalized_assignee
|
|
2600
|
+
# Or match against display name if available (case-insensitive)
|
|
2601
|
+
or (
|
|
2602
|
+
hasattr(item, "provider_fields")
|
|
2603
|
+
and isinstance(item.provider_fields, dict)
|
|
2604
|
+
and item.provider_fields.get("assignee_login")
|
|
2605
|
+
and BacklogFilters.normalize_filter_value(item.provider_fields["assignee_login"])
|
|
2606
|
+
== normalized_assignee
|
|
2607
|
+
)
|
|
2608
|
+
for assignee in item.assignees
|
|
2602
2609
|
)
|
|
2603
|
-
|
|
2604
|
-
)
|
|
2605
|
-
]
|
|
2610
|
+
]
|
|
2606
2611
|
|
|
2607
2612
|
if filters.iteration:
|
|
2608
2613
|
filtered_items = [item for item in filtered_items if item.iteration and item.iteration == filters.iteration]
|
|
@@ -2633,17 +2638,6 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2633
2638
|
|
|
2634
2639
|
return filtered_items
|
|
2635
2640
|
|
|
2636
|
-
@beartype
|
|
2637
|
-
@require(lambda item: isinstance(item, BacklogItem), "Item must be BacklogItem")
|
|
2638
|
-
@require(
|
|
2639
|
-
lambda item, update_fields: update_fields is None or isinstance(update_fields, list),
|
|
2640
|
-
"Update fields must be None or list",
|
|
2641
|
-
)
|
|
2642
|
-
@ensure(lambda result: isinstance(result, BacklogItem), "Must return BacklogItem")
|
|
2643
|
-
@ensure(
|
|
2644
|
-
lambda result, item: result.id == item.id and result.provider == item.provider,
|
|
2645
|
-
"Updated item must preserve id and provider",
|
|
2646
|
-
)
|
|
2647
2641
|
@beartype
|
|
2648
2642
|
def supports_add_comment(self) -> bool:
|
|
2649
2643
|
"""Whether this adapter can add comments (requires token and repo)."""
|
|
@@ -2711,6 +2705,17 @@ class GitHubAdapter(BridgeAdapter, BacklogAdapterMixin, BacklogAdapter):
|
|
|
2711
2705
|
raw = self._get_issue_comments(self.repo_owner, self.repo_name, issue_number)
|
|
2712
2706
|
return [str(c.get("body", "")).strip() for c in raw if isinstance(c, dict)]
|
|
2713
2707
|
|
|
2708
|
+
@beartype
|
|
2709
|
+
@require(lambda item: isinstance(item, BacklogItem), "Item must be BacklogItem")
|
|
2710
|
+
@require(
|
|
2711
|
+
lambda item, update_fields: update_fields is None or isinstance(update_fields, list),
|
|
2712
|
+
"Update fields must be None or list",
|
|
2713
|
+
)
|
|
2714
|
+
@ensure(lambda result: isinstance(result, BacklogItem), "Must return BacklogItem")
|
|
2715
|
+
@ensure(
|
|
2716
|
+
lambda result, item: result.id == item.id and result.provider == item.provider,
|
|
2717
|
+
"Updated item must preserve id and provider",
|
|
2718
|
+
)
|
|
2714
2719
|
def update_backlog_item(self, item: BacklogItem, update_fields: list[str] | None = None) -> BacklogItem:
|
|
2715
2720
|
"""
|
|
2716
2721
|
Update a GitHub issue.
|
|
@@ -73,8 +73,14 @@ class BacklogAIRefiner:
|
|
|
73
73
|
@beartype
|
|
74
74
|
@require(lambda self, item: isinstance(item, BacklogItem), "Item must be BacklogItem")
|
|
75
75
|
@require(lambda self, template: isinstance(template, BacklogTemplate), "Template must be BacklogTemplate")
|
|
76
|
+
@require(
|
|
77
|
+
lambda self, comments=None: comments is None or isinstance(comments, list),
|
|
78
|
+
"Comments must be a list of strings or None",
|
|
79
|
+
)
|
|
76
80
|
@ensure(lambda result: isinstance(result, str) and len(result) > 0, "Must return non-empty prompt string")
|
|
77
|
-
def generate_refinement_prompt(
|
|
81
|
+
def generate_refinement_prompt(
|
|
82
|
+
self, item: BacklogItem, template: BacklogTemplate, comments: list[str] | None = None
|
|
83
|
+
) -> str:
|
|
78
84
|
"""
|
|
79
85
|
Generate prompt for IDE AI copilot to refine backlog item.
|
|
80
86
|
|
|
@@ -122,6 +128,16 @@ The adapter will map these back to separate ADO fields during writeback."""
|
|
|
122
128
|
if item.work_item_type:
|
|
123
129
|
metrics_info += f"\nWork Item Type: {item.work_item_type}"
|
|
124
130
|
|
|
131
|
+
comment_lines: list[str] = []
|
|
132
|
+
if comments:
|
|
133
|
+
comment_lines.append("Comments (latest discussion context):")
|
|
134
|
+
for index, comment in enumerate(comments, 1):
|
|
135
|
+
comment_lines.append(f"{index}. {comment}")
|
|
136
|
+
else:
|
|
137
|
+
comment_lines.append("Comments (latest discussion context):")
|
|
138
|
+
comment_lines.append("- No comments found")
|
|
139
|
+
comments_info = "\n".join(comment_lines)
|
|
140
|
+
|
|
125
141
|
prompt = f"""Transform the following backlog item into the {template.name} template format.
|
|
126
142
|
|
|
127
143
|
Original Backlog Item:
|
|
@@ -132,6 +148,8 @@ Provider: {item.provider}
|
|
|
132
148
|
Body:
|
|
133
149
|
{item.body_markdown}
|
|
134
150
|
|
|
151
|
+
{comments_info}
|
|
152
|
+
|
|
135
153
|
Target Template: {template.name}
|
|
136
154
|
Description: {template.description}
|
|
137
155
|
|