Skip to content

Commit fa9f84e

Browse files
refactor(examples): CLI interface improvements
changes: - file: auto_loop.py area: cli modified: [auto_loop] - file: commands.py area: cli added: [generate_strategy_cli] - file: 02_mcp_integration.py area: core added: [simulate_planfile_apply, run_mcp_tool, simulate_planfile_review, simulate_planfile_generate, create_mcp_tool_definitions, example_mcp_session] - file: 03_proxy_routing.py area: core added: [__init__, example_budget_tracking, get_usage_stats, ProxyClient, get_routing_decision, example_strategy_generation_with_proxy, +2 more] - file: 04_llx_integration.py area: core added: [__init__, select_model, _calculate_complexity_score, analyze_project, example_metric_driven_planning, ProjectMetrics, +5 more] - file: test_interactive_mode.py area: test added: [run_interactive_planfile, main] new_tests: 2 - file: llx_validator.py area: core added: [__init__, _is_llx_available, validate_strategy, _parse_llx_analysis, create_validation_script, analyze_generated_code, +2 more] - file: summary.py area: core added: [create_summary] - file: test_all_examples.py area: test added: [__init__, _validate_strategy_with_llm, _test_shell_example, ExampleTester, main, _validate_yaml, +7 more] new_tests: 1 - file: github.py area: core modified: [GitHubBackend, __init__] - file: gitlab.py area: core modified: [__init__, GitLabBackend] - file: jira.py area: core modified: [__init__, JiraBackend] - file: client.py area: cli added: [call_llm] - file: generator.py area: core added: [_parse_strategy_response, generate_strategy, _auto_select_model, _basic_metrics, _collect_metrics] - file: prompts.py area: core added: [build_strategy_prompt] testing: new_tests: 3 scenarios: - interactive_mode - expect_script - all_examples dependencies: flow: "commands→auto_loop" - commands.py -> auto_loop.py stats: lines: "+4589/-54 (net +4535)" files: 32 complexity: "Large structural change (normalized)"
1 parent 601ac9d commit fa9f84e

36 files changed

+4612
-57
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.1.12] - 2026-03-26
11+
12+
### Docs
13+
- Update docs/CLI.md
14+
- Update docs/README.md
15+
- Update planfile/examples/README.md
16+
17+
### Other
18+
- Update planfile/cli/auto_loop.py
19+
- Update planfile/cli/commands.py
20+
- Update planfile/examples/bash-generation/test_planfile_generation.sh
21+
- Update planfile/examples/bash-generation/verify_planfile.sh
22+
- Update planfile/examples/ecosystem/01_full_workflow.sh
23+
- Update planfile/examples/ecosystem/02_mcp_integration.py
24+
- Update planfile/examples/ecosystem/03_proxy_routing.py
25+
- Update planfile/examples/ecosystem/04_llx_integration.py
26+
- Update planfile/examples/interactive-tests/test_interactive_expect.sh
27+
- Update planfile/examples/interactive-tests/test_interactive_mode.py
28+
- ... and 19 more files
29+
1030
## [0.1.11] - 2026-03-26
1131

1232
### Docs

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.11
1+
0.1.12

docs/CLI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Options:
4747
Examples:
4848
```bash
4949
# Basic auto-loop
50-
planfile auto loop --strategy strategy.yaml
50+
planfile auto loop --strategy planfile.yaml
5151

5252
# With multiple backends
5353
planfile auto loop --strategy strategy.yaml --backend github --backend jira

docs/README.md

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- code2docs:start --># planfile
1+
<!-- code2docs:start --># strategy
22

33
![version](https://img.shields.io/badge/version-0.1.0-blue) ![python](https://img.shields.io/badge/python-%3E%3D3.10-blue) ![coverage](https://img.shields.io/badge/coverage-unknown-lightgrey) ![functions](https://img.shields.io/badge/functions-90-green)
44
> **90** functions | **19** classes | **22** files | CC̄ = 5.4
@@ -7,32 +7,32 @@
77
88
**Author:** Tom Sapletta
99
**License:** Apache-2.0[(LICENSE)](./LICENSE)
10-
**Repository:** [https://github.com/semcod/planfile](https://github.com/semcod/planfile)
10+
**Repository:** [https://github.com/semcod/strategy](https://github.com/semcod/strategy)
1111

1212
## Installation
1313

1414
### From PyPI
1515

1616
```bash
17-
pip install planfile
17+
pip install strategy
1818
```
1919

2020
### From Source
2121

2222
```bash
23-
git clone https://github.com/semcod/planfile
24-
cd planfile
23+
git clone https://github.com/semcod/strategy
24+
cd strategy
2525
pip install -e .
2626
```
2727

2828
### Optional Extras
2929

3030
```bash
31-
pip install planfile[github] # github features
32-
pip install planfile[jira] # jira features
33-
pip install planfile[gitlab] # gitlab features
34-
pip install planfile[all] # all optional features
35-
pip install planfile[dev] # development tools
31+
pip install strategy[github] # github features
32+
pip install strategy[jira] # jira features
33+
pip install strategy[gitlab] # gitlab features
34+
pip install strategy[all] # all optional features
35+
pip install strategy[dev] # development tools
3636
```
3737

3838
## Quick Start
@@ -41,25 +41,25 @@ pip install planfile[dev] # development tools
4141

4242
```bash
4343
# Generate full documentation for your project
44-
planfile ./my-project
44+
strategy ./my-project
4545

4646
# Only regenerate README
47-
planfile ./my-project --readme-only
47+
strategy ./my-project --readme-only
4848

4949
# Preview what would be generated (no file writes)
50-
planfile ./my-project --dry-run
50+
strategy ./my-project --dry-run
5151

5252
# Check documentation health
53-
planfile check ./my-project
53+
strategy check ./my-project
5454

5555
# Sync — regenerate only changed modules
56-
planfile sync ./my-project
56+
strategy sync ./my-project
5757
```
5858

5959
### Python API
6060

6161
```python
62-
from planfile import generate_readme, generate_docs, Code2DocsConfig
62+
from strategy import generate_readme, generate_docs, Code2DocsConfig
6363

6464
# Quick: generate README
6565
generate_readme("./my-project")
@@ -71,7 +71,7 @@ docs = generate_docs("./my-project", config=config)
7171

7272
## Generated Output
7373

74-
When you run `planfile`, the following files are produced:
74+
When you run `strategy`, the following files are produced:
7575

7676
```
7777
<project>/
@@ -94,7 +94,7 @@ When you run `planfile`, the following files are produced:
9494

9595
## Configuration
9696

97-
Create `planfile.yaml` in your project root (or run `planfile init`):
97+
Create `strategy.yaml` in your project root (or run `strategy init`):
9898

9999
```yaml
100100
project:
@@ -126,7 +126,7 @@ examples:
126126
from_entry_points: true
127127

128128
sync:
129-
planfile: markers # markers | full | git-diff
129+
strategy: markers # markers | full | git-diff
130130
watch: false
131131
ignore:
132132
- "tests/"
@@ -135,22 +135,22 @@ sync:
135135
136136
## Sync Markers
137137
138-
planfile can update only specific sections of an existing README using HTML comment markers:
138+
strategy can update only specific sections of an existing README using HTML comment markers:
139139
140140
```markdown
141-
<!-- planfile:start -->
141+
<!-- strategy:start -->
142142
# Project Title
143143
... auto-generated content ...
144-
<!-- planfile:end -->
144+
<!-- strategy:end -->
145145
```
146146

147147
Content outside the markers is preserved when regenerating. Enable this with `sync_markers: true` in your configuration.
148148

149149
## Architecture
150150

151151
```
152-
planfile/
153-
├── planfile/ ├── runner ├── yaml_loader ├── loaders/ ├── cli_loader ├── auto_loop ├── cli/ ├── __main__ ├── priorities ├── utils/ ├── metrics ├── commands ├── integrations/ ├── gitlab ├── jira ├── github ├── generic├── docker-entrypoint├── project ├── ci_runner ├── models ├── base```
152+
strategy/
153+
├── planfile/ ├── yaml_loader ├── cli_loader ├── loaders/ ├── runner ├── auto_loop ├── cli/ ├── __main__ ├── priorities ├── utils/ ├── commands ├── metrics ├── integrations/ ├── gitlab ├── jira ├── github ├── generic├── docker-entrypoint├── project ├── ci_runner ├── models ├── base```
154154
155155
## API Overview
156156
@@ -178,8 +178,6 @@ planfile/
178178
179179
### Functions
180180
181-
- `apply_strategy(strategy, project_path, backends, backend_name)` — Apply a strategy to create/update tickets.
182-
- `review_strategy(strategy, project_path, backends, backend_name)` — Review strategy execution by checking ticket statuses.
183181
- `load_yaml(file_path)` — Load YAML file and return as dictionary.
184182
- `save_yaml(data, file_path)` — Save dictionary to YAML file.
185183
- `load_strategy_yaml(file_path)` — Load strategy from YAML file.
@@ -192,19 +190,21 @@ planfile/
192190
- `load_strategy_from_json(file_path)` — Load strategy from JSON file.
193191
- `save_strategy_to_json(strategy, file_path)` — Save strategy to JSON file.
194192
- `export_results_to_markdown(results, file_path)` — Export strategy results to Markdown file.
193+
- `apply_strategy(strategy, project_path, backends, backend_name)` — Apply a strategy to create/update tickets.
194+
- `review_strategy(strategy, project_path, backends, backend_name)` — Review strategy execution by checking ticket statuses.
195195
- `get_backend(backend_type)` — Get backend instance by type.
196196
- `auto_loop(strategy, project_path, backend, max_iterations)` — Run automated CI/CD loop: test → ticket → fix → retest.
197197
- `ci_status(project_path)` — Check current CI status without running tests.
198198
- `calculate_task_priority(base_priority, task_type, sprint_id, weight_factors)` — Calculate task priority based on type, sprint, and base priority.
199199
- `map_priority_to_system(priority, system)` — Map generic priority to system-specific priority.
200200
- `get_priority_color(priority)` — Get color code for priority (for UI display).
201-
- `analyze_project_metrics(project_path)` — Analyze project metrics for strategy review.
202-
- `calculate_strategy_health(strategy_results)` — Calculate health metrics for a strategy execution.
203201
- `get_backend(backend_type, config)` — Get backend instance by type and config.
204202
- `apply_strategy_cli(strategy_path, project_path, backend, config_file)` — Apply a strategy to create tickets.
205203
- `review_strategy_cli(strategy_path, project_path, backend, config_file)` — Review strategy execution and progress.
206204
- `validate_strategy_cli(strategy_path, verbose)` — Validate a strategy YAML file.
207205
- `main()` — Main CLI entry point.
206+
- `analyze_project_metrics(project_path)` — Analyze project metrics for strategy review.
207+
- `calculate_strategy_health(strategy_results)` — Calculate health metrics for a strategy execution.
208208
- `check_env()` — —
209209
- `validate_config()` — —
210210
- `setup_workspace()` — —

planfile/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- CLI and API for applying and reviewing strategies
88
"""
99

10-
__version__ = "0.1.11"
10+
__version__ = "0.1.12"
1111
__author__ = "Tom Sapletta"
1212
__email__ = "tom@sapletta.com"
1313

planfile/cli/auto_loop.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
import typer
55
from pathlib import Path
6-
from typing import Optional, List
6+
from typing import Optional, List, Any
77
from rich.console import Console
88
from rich.progress import Progress, SpinnerColumn, TextColumn
99
from rich.table import Table
@@ -15,6 +15,7 @@
1515
import os
1616

1717
console = Console()
18+
app = typer.Typer(help="Automated CI/CD commands")
1819

1920

2021
def get_backend(backend_type: str) -> Any:
@@ -77,7 +78,7 @@ def auto_loop(
7778
console.print()
7879

7980
# Validate strategy exists
80-
if not planfile.exists():
81+
if not strategy.exists():
8182
console.print(f"[red]✗ Strategy file not found: {strategy}[/red]")
8283
raise typer.Exit(1)
8384

@@ -150,7 +151,7 @@ def auto_loop(
150151
# Final status
151152
if results["success"]:
152153
console.print("\n[green]✅ Loop completed successfully![/green]")
153-
console.print(f"Strategy '{runner.planfile.name}' is complete!")
154+
console.print(f"Strategy '{strategy.name}' is complete!")
154155
else:
155156
console.print(f"\n[red]❌ Loop failed: {results['final_status']}[/red]")
156157
console.print(f"Total iterations: {results['total_iterations']}")
@@ -212,6 +213,4 @@ def ci_status(
212213
console.print(f" • {f}")
213214

214215

215-
# Add to main CLI
216-
from .commands import app
217-
app.add_typer(typer.Typer(name="auto", help="Automated CI/CD commands"), name="auto")
216+
# Note: This module is imported by commands.py to add the auto subcommand

planfile/cli/commands.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
from ..integrations.jira import JiraBackend
1717
from ..integrations.gitlab import GitLabBackend
1818
from ..integrations.generic import GenericBackend
19+
from . import auto_loop
1920

2021
app = typer.Typer(help="Strategy CLI - Manage strategies and sprints")
2122
console = Console()
2223
logger = logging.getLogger(__name__)
2324

25+
# Add auto subcommand
26+
app.add_typer(auto_loop.app, name="auto", help="Automated CI/CD commands")
27+
2428

2529
def get_backend(backend_type: str, config: dict):
2630
"""Get backend instance by type and config."""
@@ -323,6 +327,47 @@ def validate_strategy_cli(
323327
raise typer.Exit(1)
324328

325329

330+
@app.command("generate")
331+
def generate_strategy_cli(
332+
project_path: str = typer.Argument(".", help="Project path to analyze"),
333+
output: str = typer.Option("strategy.yaml", help="Output file path"),
334+
model: Optional[str] = typer.Option(None, help="LiteLLM model ID"),
335+
sprints: int = typer.Option(3, help="Number of sprints to generate"),
336+
focus: Optional[str] = typer.Option(None, help="Focus area: complexity, duplication, tests, docs"),
337+
toon_dir: Optional[str] = typer.Option(None, help="Pre-existing .toon analysis directory"),
338+
dry_run: bool = typer.Option(False, help="Show prompt but don't call LLM"),
339+
):
340+
"""Generate strategy.yaml from project analysis + LLM."""
341+
from ..llm.generator import generate_strategy
342+
from ..loaders.yaml_loader import save_strategy_yaml
343+
344+
try:
345+
console.print(f"[bold]Analyzing project:[/bold] {project_path}")
346+
347+
strategy = generate_strategy(
348+
project_path,
349+
model=model,
350+
sprints=sprints,
351+
focus=focus,
352+
toon_dir=toon_dir,
353+
dry_run=dry_run,
354+
)
355+
356+
if not dry_run:
357+
save_strategy_yaml(strategy, output)
358+
console.print(f"[green]✓[/green] Strategy saved to: {output}")
359+
console.print(f" Sprints: {len(strategy.sprints)}")
360+
total_tasks = sum(len(s.task_patterns) for s in strategy.sprints)
361+
console.print(f" Tasks: {total_tasks}")
362+
363+
if strategy.quality_gates:
364+
console.print(f" Quality Gates: {len(strategy.quality_gates)}")
365+
366+
except Exception as e:
367+
console.print(f"[red]✗[/red] Generation failed: {e}")
368+
raise typer.Exit(1)
369+
370+
326371
def main():
327372
"""Main CLI entry point."""
328373
app()

0 commit comments

Comments
 (0)