specfact-cli 0.6.8__tar.gz → 0.6.9__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.
Files changed (102) hide show
  1. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/PKG-INFO +1 -1
  2. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/pyproject.toml +1 -1
  3. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-compare.md +19 -0
  4. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-promote.md +27 -9
  5. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-select.md +115 -33
  6. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/__init__.py +1 -1
  7. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/__init__.py +1 -1
  8. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/code_analyzer.py +1 -0
  9. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/plan.py +386 -34
  10. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/generators/plan_generator.py +12 -1
  11. specfact_cli-0.6.9/src/specfact_cli/migrations/__init__.py +10 -0
  12. specfact_cli-0.6.9/src/specfact_cli/migrations/plan_migrator.py +208 -0
  13. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/models/__init__.py +2 -1
  14. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/models/plan.py +68 -0
  15. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/structure.py +131 -10
  16. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/.gitignore +0 -0
  17. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/LICENSE.md +0 -0
  18. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/README.md +0 -0
  19. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/mappings/node-async.yaml +0 -0
  20. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/mappings/python-async.yaml +0 -0
  21. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/mappings/speckit-default.yaml +0 -0
  22. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-enforce.md +0 -0
  23. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-import-from-code.md +0 -0
  24. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-add-feature.md +0 -0
  25. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-add-story.md +0 -0
  26. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-init.md +0 -0
  27. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-review.md +0 -0
  28. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-update-feature.md +0 -0
  29. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-plan-update-idea.md +0 -0
  30. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-repro.md +0 -0
  31. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/prompts/specfact-sync.md +0 -0
  32. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/schemas/deviation.schema.json +0 -0
  33. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/schemas/plan.schema.json +0 -0
  34. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/schemas/protocol.schema.json +0 -0
  35. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/templates/github-action.yml.j2 +0 -0
  36. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/templates/plan.bundle.yaml.j2 +0 -0
  37. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/templates/pr-template.md.j2 +0 -0
  38. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/templates/protocol.yaml.j2 +0 -0
  39. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/resources/templates/telemetry.yaml.example +0 -0
  40. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/__init__.py +0 -0
  41. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/analyze_agent.py +0 -0
  42. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/base.py +0 -0
  43. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/plan_agent.py +0 -0
  44. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/registry.py +0 -0
  45. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/agents/sync_agent.py +0 -0
  46. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/__init__.py +0 -0
  47. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  48. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  49. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  50. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  51. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  52. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  53. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/cli.py +0 -0
  54. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/__init__.py +0 -0
  55. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/constitution.py +0 -0
  56. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/enforce.py +0 -0
  57. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/import_cmd.py +0 -0
  58. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/init.py +0 -0
  59. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/repro.py +0 -0
  60. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/commands/sync.py +0 -0
  61. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/common/__init__.py +0 -0
  62. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/common/logger_setup.py +0 -0
  63. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/common/logging_utils.py +0 -0
  64. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/common/text_utils.py +0 -0
  65. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/common/utils.py +0 -0
  66. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/comparators/__init__.py +0 -0
  67. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  68. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  69. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  70. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/generators/__init__.py +0 -0
  71. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/generators/protocol_generator.py +0 -0
  72. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/generators/report_generator.py +0 -0
  73. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/generators/workflow_generator.py +0 -0
  74. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/importers/__init__.py +0 -0
  75. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/importers/speckit_converter.py +0 -0
  76. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  77. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/models/deviation.py +0 -0
  78. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/models/enforcement.py +0 -0
  79. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/models/protocol.py +0 -0
  80. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/modes/__init__.py +0 -0
  81. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/modes/detector.py +0 -0
  82. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/modes/router.py +0 -0
  83. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  84. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/sync/__init__.py +0 -0
  85. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/sync/repository_sync.py +0 -0
  86. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/sync/speckit_sync.py +0 -0
  87. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/sync/watcher.py +0 -0
  88. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/telemetry.py +0 -0
  89. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/__init__.py +0 -0
  90. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  91. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/console.py +0 -0
  92. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  93. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/feature_keys.py +0 -0
  94. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/git.py +0 -0
  95. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/github_annotations.py +0 -0
  96. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/ide_setup.py +0 -0
  97. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/prompts.py +0 -0
  98. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/utils/yaml_utils.py +0 -0
  99. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/validators/__init__.py +0 -0
  100. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/validators/fsm.py +0 -0
  101. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/validators/repro_checker.py +0 -0
  102. {specfact_cli-0.6.8 → specfact_cli-0.6.9}/src/specfact_cli/validators/schema.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specfact-cli
3
- Version: 0.6.8
3
+ Version: 0.6.9
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.6.8"
7
+ version = "0.6.9"
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"
@@ -72,6 +72,12 @@ Compare a manual plan bundle with an auto-derived plan bundle to detect deviatio
72
72
  - Parse the CLI table output to get plan names for the specified numbers
73
73
  - Extract the full plan file names from the table
74
74
 
75
+ - **For CI/CD/non-interactive use**: Use `--non-interactive` with filters:
76
+ ```
77
+ specfact plan select --non-interactive --current
78
+ specfact plan select --non-interactive --last 1
79
+ ```
80
+
75
81
  2. **Get full plan paths using CLI**:
76
82
 
77
83
  ```bash
@@ -81,6 +87,12 @@ Compare a manual plan bundle with an auto-derived plan bundle to detect deviatio
81
87
  - This will output the full plan name/path
82
88
  - Use this to construct the full path: `.specfact/plans/<plan_name>`
83
89
 
90
+ - **For CI/CD/non-interactive use**: Use `--non-interactive` with filters:
91
+ ```
92
+ specfact plan select --non-interactive --current
93
+ specfact plan select --non-interactive --last 1
94
+ ```
95
+
84
96
  **If user input contains plan names** (e.g., "main.bundle.yaml vs auto-derived.bundle.yaml"):
85
97
 
86
98
  - Use the plan names directly (may need to add `.bundle.yaml` suffix if missing)
@@ -169,6 +181,12 @@ specfact plan compare [--manual PATH] [--auto PATH] [--format {markdown|json|yam
169
181
  - Parse the CLI output to get the full plan name
170
182
  - Construct full path: `.specfact/plans/<plan_name>`
171
183
 
184
+ - **For CI/CD/non-interactive use**: Use `--non-interactive` with filters:
185
+ ```
186
+ specfact plan select --non-interactive --current
187
+ specfact plan select --non-interactive --last 1
188
+ ```
189
+
172
190
  - **If user input contains plan names** (e.g., "main.bundle.yaml vs auto-derived.bundle.yaml"):
173
191
  - Use plan names directly (may need to add `.bundle.yaml` suffix if missing)
174
192
  - Construct full path: `.specfact/plans/<plan_name>`
@@ -199,6 +217,7 @@ specfact plan compare [--manual PATH] [--auto PATH] [--format {markdown|json|yam
199
217
  ```
200
218
 
201
219
  - **Parse CLI output** to find latest auto-derived plan (by modification date)
220
+ - **For CI/CD/non-interactive**: Use `specfact plan select --non-interactive --last 1` to get most recent plan
202
221
  - **If found**: Ask user and **WAIT**:
203
222
 
204
223
  ```text
@@ -89,20 +89,32 @@ The `specfact plan promote` command helps move a plan bundle through its lifecyc
89
89
 
90
90
  **⚠️ CRITICAL: NEVER search the repository directly or read bundle files. Always use the CLI to get plan information.**
91
91
 
92
- **Execute `specfact plan select` (without arguments) to list all available plans**:
92
+ **Execute `specfact plan select` to list all available plans**:
93
93
 
94
94
  ```bash
95
+ # Interactive mode (may prompt for input)
95
96
  specfact plan select
97
+
98
+ # Non-interactive mode (for CI/CD - no prompts)
99
+ specfact plan select --non-interactive --current
100
+ specfact plan select --non-interactive --last 1
101
+
102
+ # Filter options
103
+ specfact plan select --current # Show only active plan
104
+ specfact plan select --stages draft,review # Filter by stages
105
+ specfact plan select --last 5 # Show last 5 plans
96
106
  ```
97
107
 
98
- **⚠️ Note on Interactive Prompt**: This command will display a table and then wait for user input. The copilot should:
108
+ **⚠️ Note on Interactive Prompt**:
99
109
 
100
- 1. **Capture the table output** that appears before the prompt
101
- 2. **Parse the table** to extract plan information including **current stage** (already included in the table)
102
- 3. **Handle the interactive prompt** by either:
103
- - Using a timeout to cancel after parsing (e.g., `timeout 5 specfact plan select` or similar)
104
- - Sending an interrupt signal after capturing the output
105
- - Or in a copilot environment, the output may be available before the prompt blocks
110
+ - **For CI/CD/non-interactive use**: Use `--non-interactive` flag with `--current` or `--last 1` to avoid prompts
111
+ - **For interactive use**: This command will display a table and then wait for user input. The copilot should:
112
+ 1. **Capture the table output** that appears before the prompt
113
+ 2. **Parse the table** to extract plan information including **current stage** (already included in the table)
114
+ 3. **Handle the interactive prompt** by either:
115
+ - Using a timeout to cancel after parsing (e.g., `timeout 5 specfact plan select` or similar)
116
+ - Sending an interrupt signal after capturing the output
117
+ - Or in a copilot environment, the output may be available before the prompt blocks
106
118
 
107
119
  **This command will**:
108
120
 
@@ -229,8 +241,14 @@ If still unclear, ask:
229
241
  If the current stage is not clear from the table output, use the CLI to get it:
230
242
 
231
243
  ```bash
232
- # Get plan details including current stage
244
+ # Get plan details including current stage (interactive)
233
245
  specfact plan select <plan_number>
246
+
247
+ # Get current plan stage (non-interactive)
248
+ specfact plan select --non-interactive --current
249
+
250
+ # Get most recent plan stage (non-interactive)
251
+ specfact plan select --non-interactive --last 1
234
252
  ```
235
253
 
236
254
  The CLI output will show:
@@ -10,22 +10,23 @@ description: Select active plan from available plan bundles
10
10
 
11
11
  ### Quick Summary
12
12
 
13
- - ✅ **DO**: Execute `specfact plan select` CLI command (it already exists)
13
+ - ✅ **DO**: Execute `specfact plan select --non-interactive` CLI command (it already exists) - **ALWAYS use --non-interactive flag**
14
14
  - ✅ **DO**: Parse and format CLI output for the user
15
15
  - ✅ **DO**: Read plan bundle YAML files for display purposes (when user requests details)
16
16
  - ❌ **DON'T**: Write code to implement this command
17
17
  - ❌ **DON'T**: Modify `.specfact/plans/config.yaml` directly (the CLI handles this)
18
18
  - ❌ **DON'T**: Implement plan loading, selection, or config writing logic
19
19
  - ❌ **DON'T**: Create new Python functions or classes for plan selection
20
+ - ❌ **DON'T**: Execute commands without `--non-interactive` flag (causes timeouts in Copilot)
20
21
 
21
22
  **The `specfact plan select` command already exists and handles all the logic. Your job is to execute it and present its output to the user.**
22
23
 
23
24
  ### What You Should Do
24
25
 
25
- 1. **Execute the CLI**: Run `specfact plan select` (or `specfact plan select <plan>` if user provides a plan)
26
+ 1. **Execute the CLI**: Run `specfact plan select --non-interactive` (or `specfact plan select --non-interactive <plan>` if user provides a plan) - **ALWAYS use --non-interactive flag**
26
27
  2. **Format output**: Parse the CLI's Rich table output and convert it to a Markdown table for Copilot readability
27
28
  3. **Handle user input**: If user wants details, read the plan bundle YAML file (read-only) to display information
28
- 4. **Execute selection**: When user selects a plan, execute `specfact plan select <number>` or `specfact plan select <plan_name>`
29
+ 4. **Execute selection**: When user selects a plan, execute `specfact plan select --non-interactive <number>` or `specfact plan select --non-interactive <plan_name>` - **ALWAYS use --non-interactive flag**
29
30
  5. **Present results**: Show the CLI's output to confirm the selection
30
31
 
31
32
  ### What You Should NOT Do
@@ -43,6 +44,13 @@ $ARGUMENTS
43
44
 
44
45
  You **MUST** consider the user input before proceeding (if not empty).
45
46
 
47
+ **Important**: If the user hasn't specified how many plans to show, ask them before executing the command:
48
+
49
+ - Ask: "How many plans would you like to see? (Enter a number, or 'all' to show all plans)"
50
+ - If user provides a number (e.g., "5", "10"): Use `--last N` filter
51
+ - If user says "all" or doesn't specify: Don't use `--last` filter (show all plans)
52
+ - **WAIT FOR USER RESPONSE** before proceeding with the CLI command
53
+
46
54
  ## ⚠️ CRITICAL: CLI Usage Enforcement
47
55
 
48
56
  **YOU MUST ALWAYS EXECUTE THE SPECFACT CLI COMMAND**. Never create artifacts directly or implement functionality.
@@ -92,23 +100,76 @@ You **MUST** consider the user input before proceeding (if not empty).
92
100
 
93
101
  ## Execution Steps
94
102
 
95
- ### 1. Execute CLI Command (REQUIRED - The Command Already Exists)
103
+ ### 1. Ask User How Many Plans to Show (REQUIRED FIRST STEP)
104
+
105
+ **Before executing the CLI command, ask the user how many plans they want to see:**
106
+
107
+ ```markdown
108
+ How many plans would you like to see?
109
+ - Enter a **number** (e.g., "5", "10", "20") to show the last N plans
110
+ - Enter **"all"** to show all available plans
111
+ - Press **Enter** (or say nothing) to show all plans (default)
112
+
113
+ [WAIT FOR USER RESPONSE - DO NOT CONTINUE]
114
+ ```
115
+
116
+ **After user responds:**
117
+
118
+ - **If user provides a number** (e.g., "5", "10"): Use `--last N` filter when executing the CLI command
119
+ - **If user says "all"** or provides no input: Don't use `--last` filter (show all plans)
120
+ - **If user cancels** (e.g., "q", "quit"): Exit without executing CLI command
121
+
122
+ **Note**: This step is skipped if:
123
+
124
+ - User explicitly provided a plan number or name in their input (e.g., "select plan 5")
125
+ - User explicitly requested a filter (e.g., "--current", "--stages draft")
126
+ - User is in non-interactive mode (CI/CD automation)
127
+
128
+ ### 2. Execute CLI Command (REQUIRED - The Command Already Exists)
129
+
130
+ **⚠️ CRITICAL: Always use `--non-interactive` flag** to avoid interactive prompts that can cause timeouts or hang in Copilot environments.
96
131
 
97
132
  **The `specfact plan select` command already exists. Execute it to list and select plans:**
98
133
 
99
134
  ```bash
100
- # Interactive mode (no arguments)
101
- specfact plan select
135
+ # ALWAYS use --non-interactive to avoid prompts (shows all plans)
136
+ specfact plan select --non-interactive
102
137
 
103
- # Select by number
104
- specfact plan select <number>
138
+ # Show last N plans (based on user's preference from step 1) - ALWAYS with --non-interactive
139
+ specfact plan select --non-interactive --last 5 # Show last 5 plans
140
+ specfact plan select --non-interactive --last 10 # Show last 10 plans
105
141
 
106
- # Select by plan name
107
- specfact plan select <plan_name>
142
+ # Select by number - ALWAYS with --non-interactive
143
+ specfact plan select --non-interactive <number>
144
+
145
+ # Select by plan name - ALWAYS with --non-interactive
146
+ specfact plan select --non-interactive <plan_name>
147
+
148
+ # Filter options - ALWAYS with --non-interactive
149
+ specfact plan select --non-interactive --current # Show only active plan
150
+ specfact plan select --non-interactive --stages draft,review # Filter by stages
151
+ specfact plan select --non-interactive --last 5 # Show last 5 plans by modification time
108
152
  ```
109
153
 
154
+ **Important**:
155
+
156
+ 1. **ALWAYS use `--non-interactive` flag** when executing the CLI command to avoid interactive prompts
157
+ 2. Use the `--last N` filter based on the user's response from step 1:
158
+ - If user said "5": Execute `specfact plan select --non-interactive --last 5`
159
+ - If user said "10": Execute `specfact plan select --non-interactive --last 10`
160
+ - If user said "all" or nothing: Execute `specfact plan select --non-interactive` (no `--last` filter)
161
+
162
+ **Note**: The `--non-interactive` flag prevents the CLI from waiting for user input, which is essential in Copilot environments where interactive prompts can cause timeouts.
163
+
110
164
  **Note**: Mode is auto-detected by the CLI. No need to specify `--mode` flag.
111
165
 
166
+ **Filter Options**:
167
+
168
+ - `--non-interactive`: Disable interactive prompts (for CI/CD). If multiple plans match filters, command will error. Use with `--current` or `--last 1` for single plan selection.
169
+ - `--current`: Show only the currently active plan
170
+ - `--stages STAGES`: Filter by stages (comma-separated: draft,review,approved,released)
171
+ - `--last N`: Show last N plans by modification time (most recent first)
172
+
112
173
  **The CLI command (which already exists) performs**:
113
174
 
114
175
  - Scans `.specfact/plans/` for all `*.bundle.yaml` files
@@ -118,11 +179,19 @@ specfact plan select <plan_name>
118
179
 
119
180
  **You don't need to implement any of this - just execute the CLI command.**
120
181
 
121
- **Important**: The plan is a **positional argument**, not a `--plan` option. Use:
182
+ **Important**:
122
183
 
123
- - `specfact plan select 20` (select by number)
124
- - `specfact plan select main.bundle.yaml` (select by name)
184
+ 1. The plan is a **positional argument**, not a `--plan` option
185
+ 2. **ALWAYS use `--non-interactive` flag** to avoid interactive prompts
186
+
187
+ Use:
188
+
189
+ - `specfact plan select --non-interactive 20` (select by number - ALWAYS with --non-interactive)
190
+ - `specfact plan select --non-interactive main.bundle.yaml` (select by name - ALWAYS with --non-interactive)
191
+ - `specfact plan select --non-interactive --current` (get active plan)
192
+ - `specfact plan select --non-interactive --last 1` (get most recent plan)
125
193
  - NOT `specfact plan select --plan 20` (this will fail)
194
+ - NOT `specfact plan select 20` (missing --non-interactive, may cause timeout)
126
195
 
127
196
  **Capture CLI output**:
128
197
 
@@ -136,7 +205,7 @@ specfact plan select <plan_name>
136
205
  - Do not attempt to update config manually
137
206
  - Suggest fixes based on error message
138
207
 
139
- ### 2. Format and Present Plans (Copilot-Friendly Format)
208
+ ### 3. Format and Present Plans (Copilot-Friendly Format)
140
209
 
141
210
  **⚠️ CRITICAL**: In Copilot mode, you MUST format the plan list as a **Markdown table** for better readability. The CLI's Rich table output is not copilot-friendly.
142
211
 
@@ -164,7 +233,7 @@ specfact plan select <plan_name>
164
233
  [WAIT FOR USER RESPONSE - DO NOT CONTINUE]
165
234
  ```
166
235
 
167
- ### 3. Handle Plan Details Request (If User Requests Details)
236
+ ### 4. Handle Plan Details Request (If User Requests Details)
168
237
 
169
238
  **If user requests details** (e.g., "1 details" or "show 1"):
170
239
 
@@ -209,10 +278,10 @@ specfact plan select <plan_name>
209
278
  ```
210
279
 
211
280
  1. **After showing details**, ask if user wants to select the plan:
212
- - If **yes**: Execute `specfact plan select <number>` or `specfact plan select <plan_name>` (use positional argument, NOT `--plan` option)
281
+ - If **yes**: Execute `specfact plan select --non-interactive <number>` or `specfact plan select --non-interactive <plan_name>` (use positional argument with --non-interactive, NOT `--plan` option)
213
282
  - If **no**: Return to the plan list and ask for selection again
214
283
 
215
- ### 4. Handle User Selection
284
+ ### 5. Handle User Selection
216
285
 
217
286
  **After user provides selection** (number or plan name), execute CLI with the selected plan:
218
287
 
@@ -221,15 +290,15 @@ specfact plan select <plan_name>
221
290
  **If user provided a number** (e.g., "20"):
222
291
 
223
292
  ```bash
224
- # Use the number directly as positional argument
225
- specfact plan select 20
293
+ # Use the number directly as positional argument - ALWAYS with --non-interactive
294
+ specfact plan select --non-interactive 20
226
295
  ```
227
296
 
228
297
  **If user provided a plan name** (e.g., "main.bundle.yaml"):
229
298
 
230
299
  ```bash
231
- # Use the plan name directly as positional argument
232
- specfact plan select main.bundle.yaml
300
+ # Use the plan name directly as positional argument - ALWAYS with --non-interactive
301
+ specfact plan select --non-interactive main.bundle.yaml
233
302
  ```
234
303
 
235
304
  **If you need to resolve a number to a plan name first** (for logging/display purposes):
@@ -242,7 +311,7 @@ specfact plan select main.bundle.yaml
242
311
 
243
312
  **Note**: The CLI accepts both numbers and plan names as positional arguments. You can use either format directly.
244
313
 
245
- ### 5. Present Results
314
+ ### 6. Present Results
246
315
 
247
316
  **Present the CLI selection results** to the user:
248
317
 
@@ -307,7 +376,7 @@ specfact plan select main.bundle.yaml
307
376
  **If user provides a number** (e.g., "1"):
308
377
 
309
378
  - Validate the number is within range
310
- - Execute: `specfact plan select <number>` (use number as positional argument)
379
+ - Execute: `specfact plan select --non-interactive <number>` (use number as positional argument, ALWAYS with --non-interactive)
311
380
  - Confirm the selection
312
381
 
313
382
  **If user provides a number with "details"** (e.g., "1 details", "show 1"):
@@ -316,13 +385,13 @@ specfact plan select main.bundle.yaml
316
385
  - Load the plan bundle YAML file
317
386
  - Extract and display detailed information (see "Handle Plan Details Request" section)
318
387
  - Ask if user wants to select this plan
319
- - If yes: Execute `specfact plan select <number>` (use number as positional argument, NOT `--plan` option)
388
+ - If yes: Execute `specfact plan select --non-interactive <number>` (use number as positional argument with --non-interactive, NOT `--plan` option)
320
389
  - If no: Return to plan list and ask for selection again
321
390
 
322
391
  **If user provides a plan name directly** (e.g., "main.bundle.yaml"):
323
392
 
324
393
  - Validate the plan exists in the plans list
325
- - Execute: `specfact plan select <plan_name>` (use plan name as positional argument, NOT `--plan` option)
394
+ - Execute: `specfact plan select --non-interactive <plan_name>` (use plan name as positional argument with --non-interactive, NOT `--plan` option)
326
395
  - Confirm the selection
327
396
 
328
397
  **If user provides 'q' or 'quit'**:
@@ -369,30 +438,43 @@ Create a plan with:
369
438
 
370
439
  **Step 1**: Check if a plan argument is provided in user input.
371
440
 
372
- - **If provided**: Execute `specfact plan select <plan>` directly (the CLI handles setting it as active)
373
- - **If missing**: Execute `specfact plan select` (interactive mode - the CLI displays the list)
441
+ - **If provided**: Execute `specfact plan select --non-interactive <plan>` directly (ALWAYS with --non-interactive, the CLI handles setting it as active)
442
+ - **If missing**: Proceed to Step 2
443
+
444
+ **Step 2**: Ask user how many plans to show.
445
+
446
+ - Ask: "How many plans would you like to see? (Enter a number, or 'all' to show all plans)"
447
+ - **WAIT FOR USER RESPONSE** before proceeding
448
+ - If user provides a number: Note it for use with `--last N` filter
449
+ - If user says "all" or nothing: No `--last` filter will be used
450
+
451
+ **Step 3**: Execute CLI command with appropriate filter.
452
+
453
+ - **ALWAYS use `--non-interactive` flag** to avoid interactive prompts
454
+ - If user provided a number N: Execute `specfact plan select --non-interactive --last N`
455
+ - If user said "all" or nothing: Execute `specfact plan select --non-interactive` (no filter)
456
+ - If user explicitly requested other filters (e.g., `--current`, `--stages`): Use those filters with `--non-interactive` (e.g., `specfact plan select --non-interactive --current`)
374
457
 
375
- **Step 2**: Format the CLI output as a **Markdown table** (copilot-friendly):
458
+ **Step 4**: Format the CLI output as a **Markdown table** (copilot-friendly):
376
459
 
377
- - Execute `specfact plan select` (if no plan argument provided)
378
460
  - Parse the CLI's output (Rich table format)
379
461
  - Convert to Markdown table with columns: #, Status, Plan Name, Features, Stories, Stage, Modified
380
462
  - Include selection instructions with examples
381
463
 
382
- **Step 3**: Wait for user input:
464
+ **Step 5**: Wait for user input:
383
465
 
384
466
  - Number selection (e.g., "1", "2", "3") - Select plan directly
385
467
  - Number with "details" (e.g., "1 details", "show 1") - Show plan details first
386
468
  - Plan name (e.g., "main.bundle.yaml") - Select by name
387
469
  - Quit command (e.g., "q", "quit") - Cancel
388
470
 
389
- **Step 4**: Handle user input:
471
+ **Step 6**: Handle user input:
390
472
 
391
473
  - **If details requested**: Read plan bundle YAML file (for display only), show detailed information, ask for confirmation
392
- - **If selection provided**: Execute `specfact plan select <number>` or `specfact plan select <plan_name>` (positional argument, NOT `--plan` option) - the CLI handles the selection
474
+ - **If selection provided**: Execute `specfact plan select --non-interactive <number>` or `specfact plan select --non-interactive <plan_name>` (positional argument with --non-interactive, NOT `--plan` option) - the CLI handles the selection
393
475
  - **If quit**: Exit without executing any CLI commands
394
476
 
395
- **Step 5**: Present results and confirm selection.
477
+ **Step 7**: Present results and confirm selection.
396
478
 
397
479
  ## Context
398
480
 
@@ -3,4 +3,4 @@ SpecFact CLI - Spec→Contract→Sentinel tool for contract-driven development.
3
3
  """
4
4
 
5
5
  # Define the package version (kept in sync with pyproject.toml and setup.py)
6
- __version__ = "0.6.8"
6
+ __version__ = "0.6.9"
@@ -9,6 +9,6 @@ This package provides command-line tools for:
9
9
  - Validating reproducibility
10
10
  """
11
11
 
12
- __version__ = "0.6.8"
12
+ __version__ = "0.6.9"
13
13
 
14
14
  __all__ = ["__version__"]
@@ -216,6 +216,7 @@ class CodeAnalyzer:
216
216
  analysis_scope="partial" if self.entry_point else "full",
217
217
  entry_point=str(self.entry_point.relative_to(self.repo_path)) if self.entry_point else None,
218
218
  external_dependencies=sorted(self.external_dependencies),
219
+ summary=None,
219
220
  )
220
221
 
221
222
  return PlanBundle(