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.
- package/README.md +157 -33
- package/package.json +1 -1
- package/src/cli.ts +0 -1
- package/src/parser/schema.ts +0 -8
- package/src/runner/executors/dynamic-executor.ts +2 -8
- package/src/runner/executors/llm/tool-manager.ts +0 -1
- package/src/runner/executors/plan-executor.ts +0 -1
- package/src/runner/executors/request-executor.ts +2 -10
- package/src/runner/executors/script-executor.ts +0 -8
- package/src/runner/executors/shell-executor.ts +2 -65
- package/src/runner/executors/types.ts +0 -1
- package/src/runner/executors/verification_fixes.test.ts +9 -9
- package/src/runner/join-scheduling.test.ts +0 -2
- package/src/runner/mcp-client-audit.test.ts +7 -14
- package/src/runner/mcp-client.test.ts +9 -15
- package/src/runner/mcp-client.ts +2 -22
- package/src/runner/memoization-leak.test.ts +0 -1
- package/src/runner/memoization.test.ts +0 -1
- package/src/runner/optimization-runner.ts +0 -5
- package/src/runner/services/context-builder.ts +0 -4
- package/src/runner/shell-executor.test.ts +13 -17
- package/src/runner/standard-tools-integration.test.ts +15 -20
- package/src/runner/standard-tools.test.ts +1 -17
- package/src/runner/standard-tools.ts +3 -15
- package/src/runner/step-executor.test.ts +8 -11
- package/src/runner/workflow-runner.test.ts +0 -9
- package/src/runner/workflow-runner.ts +0 -3
- package/src/runner/workflow-subflows.test.ts +0 -1
- package/src/templates/basics/basic-inputs.yaml +0 -1
- package/src/templates/basics/basic-shell.yaml +0 -2
- package/src/templates/basics/full-feature-demo.yaml +1 -2
- package/src/templates/control-flow/fan-out-fan-in.yaml +0 -2
- package/src/templates/control-flow/idempotency-example.yaml +0 -1
- package/src/templates/control-flow/loop-parallel.yaml +1 -3
- package/src/templates/control-flow/retry-policy.yaml +0 -2
- package/src/templates/features/artifact-example.yaml +0 -2
- package/src/templates/features/llm-agent.yaml +62 -3
- package/src/templates/features/memory-service.yaml +0 -1
- package/src/templates/features/robust-automation.yaml +0 -2
- package/src/templates/features/script-example.yaml +0 -3
- package/src/templates/features/src/templates/features/downloaded/test-output/file1.txt +1 -0
- package/src/templates/features/src/templates/features/downloaded/test-output/file2.txt +1 -0
- package/src/templates/patterns/agent-handoff.yaml +0 -2
- package/src/templates/patterns/approval-process.yaml +1 -1
- package/src/templates/patterns/batch-processor.yaml +1 -2
- package/src/templates/patterns/composition-parent.yaml +0 -1
- package/src/templates/patterns/data-pipeline.yaml +0 -1
- package/src/templates/scaffolding/dev.yaml +0 -2
- 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
|
|
@@ -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
|
-
|
|
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: "
|
|
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
|
-
|
|
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:
|
|
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' }}
|
|
@@ -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
|
|
@@ -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
|
-
|
|
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
|
|
|
@@ -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)' }}"
|