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.
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/PKG-INFO +1 -1
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/pyproject.toml +1 -1
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/src/flowsh_cli/__init__.py +1 -1
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/src/flowsh_cli/cli.py +42 -0
- flowsh_cli-0.7.0/src/flowsh_cli/examples.py +100 -0
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/README.md +0 -0
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/src/flowsh_cli/__main__.py +0 -0
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/src/flowsh_cli/models.py +0 -0
- {flowsh_cli-0.6.0 → flowsh_cli-0.7.0}/src/flowsh_cli/render.py +0 -0
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|