keystone-cli 2.1.4 → 2.1.6

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 (49) hide show
  1. package/README.md +157 -33
  2. package/package.json +1 -1
  3. package/src/cli.ts +0 -1
  4. package/src/parser/schema.ts +0 -8
  5. package/src/runner/executors/dynamic-executor.ts +2 -8
  6. package/src/runner/executors/llm/tool-manager.ts +0 -1
  7. package/src/runner/executors/plan-executor.ts +0 -1
  8. package/src/runner/executors/request-executor.ts +2 -10
  9. package/src/runner/executors/script-executor.ts +0 -8
  10. package/src/runner/executors/shell-executor.ts +2 -65
  11. package/src/runner/executors/types.ts +0 -1
  12. package/src/runner/executors/verification_fixes.test.ts +9 -9
  13. package/src/runner/join-scheduling.test.ts +0 -2
  14. package/src/runner/mcp-client-audit.test.ts +7 -14
  15. package/src/runner/mcp-client.test.ts +9 -15
  16. package/src/runner/mcp-client.ts +2 -22
  17. package/src/runner/memoization-leak.test.ts +0 -1
  18. package/src/runner/memoization.test.ts +0 -1
  19. package/src/runner/optimization-runner.ts +0 -5
  20. package/src/runner/services/context-builder.ts +0 -4
  21. package/src/runner/shell-executor.test.ts +13 -17
  22. package/src/runner/standard-tools-integration.test.ts +15 -20
  23. package/src/runner/standard-tools.test.ts +1 -17
  24. package/src/runner/standard-tools.ts +3 -15
  25. package/src/runner/step-executor.test.ts +8 -11
  26. package/src/runner/workflow-runner.test.ts +0 -9
  27. package/src/runner/workflow-runner.ts +0 -3
  28. package/src/runner/workflow-subflows.test.ts +0 -1
  29. package/src/templates/basics/basic-inputs.yaml +0 -1
  30. package/src/templates/basics/basic-shell.yaml +0 -2
  31. package/src/templates/basics/full-feature-demo.yaml +1 -2
  32. package/src/templates/control-flow/fan-out-fan-in.yaml +0 -2
  33. package/src/templates/control-flow/idempotency-example.yaml +0 -1
  34. package/src/templates/control-flow/loop-parallel.yaml +1 -3
  35. package/src/templates/control-flow/retry-policy.yaml +0 -2
  36. package/src/templates/features/artifact-example.yaml +0 -2
  37. package/src/templates/features/llm-agent.yaml +62 -3
  38. package/src/templates/features/memory-service.yaml +0 -1
  39. package/src/templates/features/robust-automation.yaml +0 -2
  40. package/src/templates/features/script-example.yaml +0 -3
  41. package/src/templates/features/src/templates/features/downloaded/test-output/file1.txt +1 -0
  42. package/src/templates/features/src/templates/features/downloaded/test-output/file2.txt +1 -0
  43. package/src/templates/patterns/agent-handoff.yaml +0 -2
  44. package/src/templates/patterns/approval-process.yaml +1 -1
  45. package/src/templates/patterns/batch-processor.yaml +1 -2
  46. package/src/templates/patterns/composition-parent.yaml +0 -1
  47. package/src/templates/patterns/data-pipeline.yaml +0 -1
  48. package/src/templates/scaffolding/dev.yaml +0 -2
  49. package/src/templates/scaffolding/scaffold-feature.yaml +0 -1
@@ -16,7 +16,7 @@ steps:
16
16
  # Test shell execution
17
17
  - id: greet
18
18
  type: shell
19
- run: echo "${{ inputs.message }}"
19
+ run: echo "${{ escape(inputs.message) }}"
20
20
 
21
21
  # Test shell with transform
22
22
  - id: get_date
@@ -42,7 +42,6 @@ steps:
42
42
  - id: count_files
43
43
  type: shell
44
44
  needs: [write_file]
45
- allowInsecure: true
46
45
  run: ls ./tmp/keystone-*.txt | wc -l
47
46
  transform: parseInt(stdout.trim())
48
47
 
@@ -18,7 +18,6 @@ steps:
18
18
 
19
19
  - id: parallel_1
20
20
  type: shell
21
- allowInsecure: true
22
21
  run: sleep 2 && echo "Parallel 1 done"
23
22
  needs: [prepare]
24
23
  compensate:
@@ -28,7 +27,6 @@ steps:
28
27
 
29
28
  - id: parallel_2
30
29
  type: shell
31
- allowInsecure: true
32
30
  run: |
33
31
  echo "Parallel 2 failing intentionally..."
34
32
  exit 1
@@ -17,7 +17,6 @@ steps:
17
17
  idempotencyScope: global
18
18
  # Expire the record after 1 day
19
19
  idempotencyTtlSeconds: 86400
20
- allowInsecure: true
21
20
  run: |
22
21
  echo "Processing order ${{ inputs.order_id }}..."
23
22
  # Simulate a side effect
@@ -11,7 +11,6 @@ steps:
11
11
  # Generate test data
12
12
  - id: generate_items
13
13
  type: shell
14
- allowInsecure: true
15
14
  run: "echo 'item1\nitem2\nitem3\nitem4\nitem5'"
16
15
  transform: "stdout.split('\\n').filter(Boolean)"
17
16
 
@@ -21,8 +20,7 @@ steps:
21
20
  needs: [generate_items]
22
21
  foreach: ${{ steps.generate_items.output }}
23
22
  concurrency: 3
24
- allowInsecure: true
25
- run: "echo 'Processing: ${{ item }}' && sleep 0.1"
23
+ run: "echo 'Processing: ${{ escape(item) }}' && sleep 0.1"
26
24
  transform: "stdout.trim()"
27
25
 
28
26
  # Test conditional using .every() (tests aggregation fix)
@@ -6,7 +6,6 @@ steps:
6
6
  # Test retry with a command that fails first few times
7
7
  - id: flaky_command
8
8
  type: shell
9
- allowInsecure: true
10
9
  run: |
11
10
  if [ ! -f /tmp/keystone-retry-test ]; then
12
11
  echo "1" > /tmp/keystone-retry-test
@@ -27,7 +26,6 @@ steps:
27
26
  # Test timeout (should complete before timeout)
28
27
  - id: quick_task
29
28
  type: shell
30
- allowInsecure: true
31
29
  run: sleep 0.1 && echo "Completed"
32
30
  timeout: 5000
33
31
  needs: [flaky_command]
@@ -5,7 +5,6 @@ description: "Demonstrate artifact upload and download between steps"
5
5
  steps:
6
6
  - id: create_content
7
7
  type: shell
8
- allowInsecure: true
9
8
  run: |
10
9
  mkdir -p src/templates/features/test-output
11
10
  echo "Hello from step 1" > src/templates/features/test-output/file1.txt
@@ -33,7 +32,6 @@ steps:
33
32
  - id: verify
34
33
  type: shell
35
34
  needs: [download_files]
36
- allowInsecure: true
37
35
  run: |
38
36
  ls -R src/templates/features/downloaded
39
37
  cat src/templates/features/downloaded/file1.txt
@@ -1,9 +1,68 @@
1
1
  $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
2
  name: llm-agent
3
- description: "Test LLM step"
3
+ description: "Interactive LLM workflow with human-in-the-loop collaboration"
4
+
5
+ inputs:
6
+ topic:
7
+ type: string
8
+ default: "workflow automation"
4
9
 
5
10
  steps:
6
- - id: ask_llm
11
+ # LLM generates initial suggestions
12
+ - id: generate_ideas
13
+ type: llm
14
+ agent: summarizer
15
+ prompt: |
16
+ Generate 3 creative ideas related to "${{ inputs.topic }}".
17
+ Format your response as a numbered list.
18
+
19
+ # Human reviews and selects an idea
20
+ - id: review_ideas
21
+ type: human
22
+ message: |
23
+ The LLM generated these ideas:
24
+
25
+ ${{ steps.generate_ideas.output }}
26
+
27
+ Press Enter to continue with the first idea, or provide your own selection.
28
+ inputType: text
29
+
30
+ # LLM elaborates on the selected idea
31
+ - id: elaborate
7
32
  type: llm
8
33
  agent: summarizer
9
- prompt: "Hello, who are you?"
34
+ prompt: |
35
+ The user selected this idea: "${{ steps.review_ideas.output || 'Use the first idea from the list' }}"
36
+
37
+ Please provide a detailed explanation of how to implement this idea,
38
+ including key considerations and potential challenges.
39
+
40
+ # Final human confirmation
41
+ - id: confirm
42
+ type: human
43
+ message: |
44
+ Here's the detailed plan:
45
+
46
+ ${{ steps.elaborate.output }}
47
+
48
+ Press Enter to confirm and save this plan.
49
+ inputType: confirm
50
+
51
+ # Save the plan to a file
52
+ - id: save_plan
53
+ type: file
54
+ if: ${{ steps.confirm.output }}
55
+ op: write
56
+ path: ./plan.md
57
+ content: |
58
+ # Plan for ${{ inputs.topic }}
59
+
60
+ ## Selected Idea
61
+ ${{ steps.review_ideas.output || 'First idea from generated list' }}
62
+
63
+ ## Detailed Plan
64
+ ${{ steps.elaborate.output }}
65
+
66
+ outputs:
67
+ plan: ${{ steps.elaborate.output }}
68
+ saved: ${{ steps.save_plan.outputs.path || 'not saved' }}
@@ -49,7 +49,6 @@ steps:
49
49
  - id: summary
50
50
  type: shell
51
51
  needs: [confirm_memory]
52
- allowInsecure: true
53
52
  run: |
54
53
  echo "Memory Service Demo Complete"
55
54
  echo "Recalled: ${{ steps.recall_preference.output[0].content }}"
@@ -7,7 +7,6 @@ steps:
7
7
  # This step attempts to run a broken command, but the agent should fix it
8
8
  - id: auto_heal_demo
9
9
  type: shell
10
- allowInsecure: true
11
10
  run: |
12
11
  # This command has a typo and should fail
13
12
  ech "Hello World"
@@ -40,7 +39,6 @@ steps:
40
39
  - id: summary
41
40
  type: shell
42
41
  needs: [reflexion_demo]
43
- allowInsecure: true
44
42
  run: |
45
43
  echo "Robust automation demo complete."
46
44
  echo "Healed Command Output: ${{ steps.auto_heal_demo.output.stdout }}"
@@ -5,12 +5,10 @@ description: "Demonstrate sandboxed JavaScript execution"
5
5
  steps:
6
6
  - id: generate_data
7
7
  type: shell
8
- allowInsecure: true
9
8
  run: echo '{"values":[1,2,3,4,5]}'
10
9
 
11
10
  - id: process_data
12
11
  type: script
13
- allowInsecure: true
14
12
  needs: [generate_data]
15
13
  run: |
16
14
  const data = JSON.parse(steps.generate_data.output.stdout);
@@ -22,7 +20,6 @@ steps:
22
20
  - id: print_result
23
21
  type: shell
24
22
  needs: [process_data]
25
- allowInsecure: true
26
23
  run: |
27
24
  echo "Sum: ${{ steps.process_data.output.sum }}"
28
25
  echo "Average: ${{ steps.process_data.output.avg }}"
@@ -0,0 +1 @@
1
+ Hello from step 1 (second file)
@@ -33,7 +33,6 @@ steps:
33
33
  execution:
34
34
  id: remember_context
35
35
  type: script
36
- allowInsecure: true
37
36
  run: |
38
37
  (function() {
39
38
  return {
@@ -48,6 +47,5 @@ steps:
48
47
  - id: show_context
49
48
  type: shell
50
49
  needs: [route]
51
- allowInsecure: true
52
50
  run: |
53
51
  echo "Memory: ${{ memory.user }} on ${{ memory.topic }} (env=${{ env.CURRENT_TOPIC }})"
@@ -33,5 +33,5 @@ steps:
33
33
  - id: finalize_rejection
34
34
  type: shell
35
35
  if: ${{ steps.request_approval.output == false }}
36
- run: echo "Rejection reason - ${{ steps.get_rejection_reason.output }}"
36
+ run: echo "Rejection reason - ${{ escape(steps.get_rejection_reason.output) }}"
37
37
  needs: [get_rejection_reason]
@@ -15,8 +15,7 @@ steps:
15
15
  # 1. Dynamic Input Generation
16
16
  - id: list_files
17
17
  type: shell
18
- allowInsecure: true
19
- run: "ls ${{ inputs.target_dir }}/*.txt"
18
+ run: "ls ${{ escape(inputs.target_dir) }}/*.txt"
20
19
  # Extract stdout lines into an array
21
20
  transform: "stdout.split('\\n').filter(Boolean)"
22
21
 
@@ -14,5 +14,4 @@ steps:
14
14
  - id: print_result
15
15
  type: shell
16
16
  needs: [run_child]
17
- allowInsecure: true
18
17
  run: echo "Child workflow result - ${{ escape(steps.run_child.outputs.result) }}"
@@ -21,7 +21,6 @@ steps:
21
21
 
22
22
  - id: process_data
23
23
  type: shell
24
- allowInsecure: true
25
24
  run: |
26
25
  echo "${{ steps.read_data.output }}" | tr '[:lower:]' '[:upper:]'
27
26
  transform: "stdout.trim()"
@@ -77,7 +77,6 @@ steps:
77
77
  agent: software-engineer
78
78
  needs: [approve_plan]
79
79
  useStandardTools: true
80
- allowInsecure: true
81
80
  prompt: |
82
81
  Implement the following plan for the task:
83
82
  ${{ inputs.task }}
@@ -101,7 +100,6 @@ steps:
101
100
  agent: tester
102
101
  needs: [implement]
103
102
  useStandardTools: true
104
- allowInsecure: true
105
103
  prompt: |
106
104
  Verify the changes made for the task:
107
105
  ${{ inputs.task }}
@@ -48,7 +48,6 @@ steps:
48
48
  - id: summary
49
49
  type: shell
50
50
  needs: [write_files]
51
- allowInsecure: true
52
51
  run: |
53
52
  echo "Scaffolding complete. Files created:"
54
53
  echo "${{ steps.generate.outputs && steps.generate.outputs.files ? steps.generate.outputs.files.map(f => f.path).join('\n') : '(dry run: no files generated)' }}"