flowsh-cli 0.6.0__tar.gz → 0.7.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowsh-cli
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Generate Bash harness scripts from workflow YAML files.
5
5
  License-Expression: MIT
6
6
  Classifier: Programming Language :: Python :: 3.11
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "flowsh-cli"
7
- version = "0.6.0"
7
+ version = "0.7.0"
8
8
  description = "Generate Bash harness scripts from workflow YAML files."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -3,7 +3,7 @@
3
3
  from flowsh_cli.models import Workflow, WorkflowParseError, parse_workflows
4
4
  from flowsh_cli.render import harness_path, render_harness
5
5
 
6
- __version__ = "0.6.0"
6
+ __version__ = "0.7.0"
7
7
 
8
8
  __all__ = [
9
9
  "Workflow",
@@ -11,6 +11,7 @@ from typing import Annotated
11
11
  import typer
12
12
 
13
13
  from flowsh_cli import __version__
14
+ from flowsh_cli.examples import example_yaml, examples_index
14
15
  from flowsh_cli.models import Workflow, WorkflowParseError, parse_workflows, workflow_schema_yaml
15
16
  from flowsh_cli.render import harness_path, render_harness
16
17
 
@@ -71,11 +72,32 @@ def generate(
71
72
  is_eager=True,
72
73
  ),
73
74
  ] = False,
75
+ examples: Annotated[
76
+ bool,
77
+ typer.Option(
78
+ "--examples",
79
+ callback=lambda value: print_examples_index(value),
80
+ help="List available workflow examples and exit.",
81
+ is_eager=True,
82
+ ),
83
+ ] = False,
84
+ example: Annotated[
85
+ str | None,
86
+ typer.Option(
87
+ "--example",
88
+ metavar="NAME",
89
+ callback=lambda value: print_example(value),
90
+ help="Print a named example workflow YAML to stdout and exit.",
91
+ is_eager=True,
92
+ ),
93
+ ] = None,
74
94
  ) -> None:
75
95
  """Generate Bash harnesses from workflow YAML."""
76
96
 
77
97
  _ = version
78
98
  _ = schema
99
+ _ = examples
100
+ _ = example
79
101
 
80
102
  try:
81
103
  workflows = parse_workflows(workflow_yaml)
@@ -117,6 +139,26 @@ def print_schema(value: bool) -> None:
117
139
  raise typer.Exit
118
140
 
119
141
 
142
+ def print_examples_index(value: bool) -> None:
143
+ if not value:
144
+ return
145
+
146
+ print(examples_index())
147
+ raise typer.Exit
148
+
149
+
150
+ def print_example(value: str | None) -> None:
151
+ if value is None:
152
+ return
153
+
154
+ try:
155
+ print(example_yaml(value), end="")
156
+ except ValueError as error:
157
+ print(f"Error: {error}", file=sys.stderr)
158
+ raise typer.Exit(1) from error
159
+ raise typer.Exit
160
+
161
+
120
162
  def write_harnesses(workflows: list[Workflow], *, dry_run: bool, force: bool) -> None:
121
163
  output_paths = [(workflow, harness_path(workflow)) for workflow in workflows]
122
164
 
@@ -0,0 +1,100 @@
1
+ from __future__ import annotations
2
+
3
+ EXAMPLES: dict[str, tuple[str, str, str]] = {
4
+ # name -> (short_description, step_types, yaml)
5
+ "simple": (
6
+ "Vars + sequential bash steps",
7
+ "vars, bash",
8
+ """\
9
+ workflows:
10
+ - id: wf_simple
11
+ name: Simple example — vars and bash
12
+
13
+ steps:
14
+ - type: vars
15
+ name: Capture date
16
+ values:
17
+ TODAY: date -u +%F # shell command; stdout becomes the variable
18
+
19
+ - type: bash
20
+ name: Greet
21
+ run: echo "Hello, today is $TODAY"
22
+
23
+ - type: bash
24
+ name: Done
25
+ run: echo "Workflow complete"
26
+ """,
27
+ ),
28
+ "medium": (
29
+ "Params + vars + bash + agent with prompt expansion",
30
+ "vars, bash, agent",
31
+ """\
32
+ workflows:
33
+ - id: wf_medium
34
+ name: Medium example — params, vars, agent
35
+ params:
36
+ - name: TOPIC
37
+ description: Subject to summarise
38
+ required: true
39
+ steps:
40
+ - type: vars
41
+ values:
42
+ TODAY: date -u +%F
43
+ - type: bash
44
+ run: 'echo "Running on $TODAY for topic: $TOPIC"'
45
+ - type: agent
46
+ expandPrompt: true
47
+ prompt: |
48
+ Today is ${TODAY}. Write a one-paragraph summary about ${TOPIC}.
49
+ """,
50
+ ),
51
+ "sophisticated": (
52
+ "Params + vars + bash + agent + for + parallel + file handoff",
53
+ "vars, bash, agent, for, parallel",
54
+ """\
55
+ workflows:
56
+ - id: wf_sophisticated
57
+ name: Sophisticated example — for, parallel, file handoff
58
+ params:
59
+ - name: ITEMS
60
+ description: Newline-delimited list of items to process
61
+ required: true
62
+ steps:
63
+ - type: vars
64
+ values:
65
+ OUTFILE: mktemp
66
+ - type: parallel
67
+ steps:
68
+ - type: bash
69
+ run: echo "worker A started"
70
+ - type: bash
71
+ run: echo "worker B started"
72
+ - type: for
73
+ in: ITEMS
74
+ item: ITEM
75
+ steps:
76
+ - type: bash
77
+ run: echo "$ITEM" >> "$OUTFILE"
78
+ - type: agent
79
+ expandPrompt: true
80
+ prompt: |
81
+ The file ${OUTFILE} contains one processed item per line.
82
+ Summarise the results.
83
+ """,
84
+ ),
85
+ }
86
+
87
+
88
+ def examples_index() -> str:
89
+ lines = ["Available examples (use --example <name> to print runnable YAML):\n"]
90
+ for name, (desc, step_types, _) in EXAMPLES.items():
91
+ lines.append(f" {name:<14}{desc}")
92
+ lines.append(f" {'':14}Step types: {step_types}\n")
93
+ return "\n".join(lines)
94
+
95
+
96
+ def example_yaml(name: str) -> str:
97
+ if name not in EXAMPLES:
98
+ known = ", ".join(EXAMPLES)
99
+ raise ValueError(f"unknown example {name!r}. Available: {known}")
100
+ return EXAMPLES[name][2]
File without changes