flowsh-cli 0.9.0__tar.gz → 0.10.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.9.0
3
+ Version: 0.10.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.9.0"
7
+ version = "0.10.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.9.0"
6
+ __version__ = "0.10.0"
7
7
 
8
8
  __all__ = [
9
9
  "Workflow",
@@ -19,6 +19,12 @@ from pydantic import (
19
19
 
20
20
  MAX_WORKFLOW_YAML_BYTES = 1_048_576
21
21
 
22
+ # Execution model: `when:` conditions are evaluated directly in the parent harness
23
+ # process, so any exported variable is visible there immediately. Step bodies for
24
+ # `bash`, `vars`, `for`, and `while` each execute in their own subprocess
25
+ # (`bash -euo pipefail <<'EOF' ... EOF`), so only exported variables (e.g. `vars`
26
+ # step values or a `capture`d agent output) are visible inside them.
27
+
22
28
 
23
29
  class WorkflowParseError(ValueError):
24
30
  """Raised when the input YAML cannot be parsed or validated."""
@@ -96,7 +102,13 @@ class AgentStep(BaseStep):
96
102
  command: str | None = None
97
103
  capture: str | None = Field(
98
104
  default=None,
99
- description="Name of a shell variable that receives the full agent output for later steps.",
105
+ description=(
106
+ "Name of a shell variable that receives the full agent output. "
107
+ "The value is exported, so it is visible in this step's siblings' `when:` "
108
+ "conditions (evaluated in-process) and in later steps' bodies — including "
109
+ "inside `bash`, `vars`, `for`, and `while` steps, each of which runs its own "
110
+ "body in a separate subprocess."
111
+ ),
100
112
  )
101
113
  dangerouslySkipPermissions: bool = Field(
102
114
  default=False,
@@ -216,6 +228,14 @@ class ForStep(BaseStep):
216
228
  raise ValueError("must match ^[A-Z_][A-Z0-9_]*$")
217
229
  return value
218
230
 
231
+ @field_validator("steps")
232
+ @classmethod
233
+ def reject_nested_for_steps(cls, value: list[Step]) -> list[Step]:
234
+ for step in value:
235
+ if isinstance(step, ForStep):
236
+ raise ValueError("nested for steps are not supported")
237
+ return value
238
+
219
239
 
220
240
  class WhileStep(BaseStep):
221
241
  type: Literal["while"]
@@ -222,6 +222,7 @@ def render_harness(workflow: Workflow) -> str:
222
222
  " status=$?",
223
223
  " printf '%s\\n' \"$output\"",
224
224
  ' printf -v "$capture" \'%s\' "$output"',
225
+ ' export "$capture"',
225
226
  ' return "$status"',
226
227
  " else",
227
228
  ' "${cmd[@]}" -- "$prompt"',
@@ -537,6 +538,11 @@ def _render_arg_block(params: list[WorkflowParam]) -> list[str]:
537
538
 
538
539
  lines: list[str] = [
539
540
  "DRY_RUN=false",
541
+ ]
542
+ for param in params:
543
+ lines.append(f'{param.name}="${{{param.name}:-}}"')
544
+ lines.append(f"export {param.name}")
545
+ lines += [
540
546
  "POSITIONAL_ARGS=()",
541
547
  "",
542
548
  "while [[ $# -gt 0 ]]; do",
File without changes