cc24d8c8ac
Completely removed all legacy plan commands from the CLI:
- Removed tell, build, new, current, cd, continue CLI commands
- Removed programmatic wrapper functions (tell_command, build_command, etc.)
- Removed legacy deprecation message
- Updated help text to indicate V3 Plan Lifecycle exclusively
- Removed stale references to tell/build in help output and command validation
Removes the legacy 'tell' and 'build' CLI shortcuts from main.py:
- Removed echo lines advertising tell/build commands
- Removed tell/build from valid_cmds list
- Removed tell/build from _LIGHTWEIGHT_COMMANDS frozenset
- These dead entries were preventing helpful error messages
Test infrastructure improvements:
- Event bus exception test: Patch the module-level logger during emit() so that
structlog.testing.capture_logs() can capture the logs. Without patching, the
module-level logger created at import time is not captured by the context manager.
- Session create/list commands: Suppress cleveragents.mcp logger to CRITICAL level
during JSON/YAML output formatting to prevent health check warnings with ANSI codes
from being written to stdout before JSON output, which breaks JSON parsing.
- Extended plan_cli_coverage_boost with scenarios for estimation_result,
invariants, execution_environment, validation_summary, and checkpoint
coverage in _plan_spec_dict
Documentation:
- Created docs/Legacy_to_V3_Guide.md with comprehensive migration instructions
- Updated CONTRIBUTING.md to document removal of legacy workflow
- Updated CHANGELOG.md to reference issue #4181 instead of PR #10800
ISSUES CLOSED: #4181
199 lines
9.2 KiB
Gherkin
199 lines
9.2 KiB
Gherkin
Feature: Plan CLI coverage boost
|
|
As a developer
|
|
I want to exercise uncovered branches in plan.py
|
|
So that code coverage is improved for the plan CLI module
|
|
|
|
# ---- _plan_spec_dict helper ----
|
|
|
|
Scenario: _plan_spec_dict returns error_message when truthy
|
|
Given a v3 Plan with error_message set to "Strategy failed"
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "error_message" with value "Strategy failed"
|
|
|
|
Scenario: _plan_spec_dict falls back to legacy format for non-Plan objects
|
|
Given a non-Plan object with string value "legacy plan data"
|
|
When I call _plan_spec_dict on the object
|
|
Then the spec dict should equal {"plan": "legacy plan data"}
|
|
|
|
Scenario: _plan_spec_dict omits error_message when it is None
|
|
Given a v3 Plan with error_message set to None
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should not contain key "error_message"
|
|
|
|
Scenario: _plan_spec_dict includes estimation_result when set
|
|
Given a v3 Plan with estimation_result set
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "estimation"
|
|
|
|
Scenario: _plan_spec_dict includes invariants when populated
|
|
Given a v3 Plan with invariants populated
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "invariants"
|
|
|
|
Scenario: _plan_spec_dict includes execution_environment when set
|
|
Given a v3 Plan with execution_environment set
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "execution_environment"
|
|
And the spec dict should contain key "execution_env_priority"
|
|
|
|
Scenario: _plan_spec_dict includes dod_evaluation when validation_summary set
|
|
Given a v3 Plan with validation_summary populated
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "dod_evaluation"
|
|
|
|
Scenario: _plan_spec_dict includes last_completed_step and last_checkpoint_id
|
|
Given a v3 Plan with last_completed_step and last_checkpoint_id
|
|
When I call _plan_spec_dict on the plan
|
|
Then the spec dict should contain key "last_completed_step"
|
|
And the spec dict should contain key "last_checkpoint_id"
|
|
|
|
# ---- _print_lifecycle_plan helper ----
|
|
|
|
Scenario: _print_lifecycle_plan prints all optional timestamps
|
|
Given a v3 Plan with all timestamps populated
|
|
When I call _print_lifecycle_plan on the plan
|
|
Then the printed output should contain "Strategize Started"
|
|
And the printed output should contain "Strategize Completed"
|
|
And the printed output should contain "Execute Started"
|
|
And the printed output should contain "Execute Completed"
|
|
And the printed output should contain "Applied At"
|
|
|
|
Scenario: _print_lifecycle_plan prints estimation_actor when set
|
|
Given a v3 Plan with estimation_actor set to "local/cost-estimator"
|
|
When I call _print_lifecycle_plan on the plan
|
|
Then the printed output should contain "Estimation Actor"
|
|
And the printed output should contain "local/cost-estimator"
|
|
|
|
Scenario: _print_lifecycle_plan prints invariant_actor when set
|
|
Given a v3 Plan with invariant_actor set to "local/invariant-checker"
|
|
When I call _print_lifecycle_plan on the plan
|
|
Then the printed output should contain "Invariant Actor"
|
|
And the printed output should contain "local/invariant-checker"
|
|
|
|
Scenario: _print_lifecycle_plan falls back for non-Plan objects
|
|
Given a non-Plan object with string value "legacy-plan-object"
|
|
When I call _print_lifecycle_plan on the object
|
|
Then the printed output should contain "legacy-plan-object"
|
|
|
|
# ---- execute_plan non-rich format ----
|
|
|
|
Scenario: execute_plan outputs JSON when format is json
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has a complete strategize plan for execute
|
|
When I invoke execute with "--format" "json" and plan id
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "plan_id"
|
|
And the plan coverage output should contain "sandbox"
|
|
And the plan coverage output should contain "worker"
|
|
And the plan coverage output should contain "progress"
|
|
And the plan coverage output should contain "strategy_summary"
|
|
And the plan coverage output should contain "command"
|
|
And the plan coverage output should contain "exit_code"
|
|
|
|
@tdd_issue @tdd_issue_4251 @tdd_expected_fail
|
|
Scenario: execute_plan JSON output has spec-required envelope structure
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has a complete strategize plan for execute
|
|
When I invoke execute with "--format" "json" and plan id
|
|
Then the plan coverage command should succeed
|
|
And the execute JSON output has the spec-required envelope fields
|
|
And the execute JSON output data has sandbox with strategy field
|
|
And the execute JSON output data has progress list with label and status
|
|
|
|
# ---- apply_plan non-rich format ----
|
|
|
|
Scenario: apply_plan outputs JSON when format is json
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has a complete execute plan for apply
|
|
When I invoke apply with "--format" "json" and plan id
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "plan_id"
|
|
|
|
# ---- list_plans regex and state/processing_state filtering ----
|
|
|
|
Scenario: list_plans filters by regex pattern
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has multiple plans for lifecycle list
|
|
When I invoke list with regex "alpha"
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "alpha"
|
|
And the plan coverage output should not contain "beta"
|
|
|
|
Scenario: list_plans filters by state
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has plans in different processing states
|
|
When I invoke list with "--state" "processing"
|
|
Then the plan coverage command should succeed
|
|
|
|
Scenario: list_plans filters by processing_state alias
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has plans in different processing states
|
|
When I invoke list with "--processing-state" "complete"
|
|
Then the plan coverage command should succeed
|
|
|
|
Scenario: list_plans rejects invalid regex
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has multiple plans for lifecycle list
|
|
When I invoke list with regex "[invalid"
|
|
Then the plan coverage command should abort
|
|
And the plan coverage output should contain "Invalid regex"
|
|
|
|
Scenario: list_plans filters by action name
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has multiple plans for lifecycle list
|
|
When I invoke list with "--action" "local/test-action"
|
|
Then the plan coverage command should succeed
|
|
|
|
Scenario: list_plans outputs JSON when format is json
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service has multiple plans for lifecycle list
|
|
When I invoke list with "--format" "json"
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "plan_id"
|
|
|
|
# ---- cancel_plan ----
|
|
|
|
Scenario: cancel_plan in non-rich format without reason
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service can cancel a plan
|
|
When I invoke cancel with "--format" "json" and no reason
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "plan_id"
|
|
And the plan coverage output should not contain "cancel_reason"
|
|
|
|
Scenario: cancel_plan in non-rich format with reason
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service can cancel a plan
|
|
When I invoke cancel with "--format" "json" and reason "not needed"
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "cancel_reason"
|
|
And the plan coverage output should contain "not needed"
|
|
|
|
Scenario: cancel_plan in rich format with reason
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service can cancel a plan
|
|
When I invoke cancel in rich format with reason "obsolete"
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "Plan cancelled"
|
|
And the plan coverage output should contain "Reason: obsolete"
|
|
|
|
Scenario: cancel_plan in rich format without reason
|
|
Given a plan lifecycle CLI runner for coverage
|
|
And a mocked lifecycle service for plan coverage commands
|
|
And the service can cancel a plan
|
|
When I invoke cancel in rich format without reason
|
|
Then the plan coverage command should succeed
|
|
And the plan coverage output should contain "Plan cancelled"
|