keystone-cli 1.0.3 → 1.1.0

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 (153) hide show
  1. package/README.md +276 -32
  2. package/package.json +8 -4
  3. package/src/cli.ts +350 -416
  4. package/src/commands/doc.ts +31 -0
  5. package/src/commands/event.ts +29 -0
  6. package/src/commands/graph.ts +37 -0
  7. package/src/commands/index.ts +14 -0
  8. package/src/commands/init.ts +185 -0
  9. package/src/commands/run.ts +124 -0
  10. package/src/commands/schema.ts +40 -0
  11. package/src/commands/utils.ts +78 -0
  12. package/src/commands/validate.ts +111 -0
  13. package/src/db/workflow-db.test.ts +314 -0
  14. package/src/db/workflow-db.ts +810 -210
  15. package/src/expression/evaluator-audit.test.ts +4 -2
  16. package/src/expression/evaluator.test.ts +14 -1
  17. package/src/expression/evaluator.ts +166 -19
  18. package/src/parser/config-schema.ts +18 -0
  19. package/src/parser/schema.ts +153 -22
  20. package/src/parser/test-schema.ts +6 -6
  21. package/src/parser/workflow-parser.test.ts +24 -0
  22. package/src/parser/workflow-parser.ts +65 -3
  23. package/src/runner/auto-heal.test.ts +5 -6
  24. package/src/runner/blueprint-executor.test.ts +2 -2
  25. package/src/runner/debug-repl.test.ts +5 -8
  26. package/src/runner/debug-repl.ts +59 -16
  27. package/src/runner/durable-timers.test.ts +11 -2
  28. package/src/runner/engine-executor.test.ts +1 -1
  29. package/src/runner/events.ts +57 -0
  30. package/src/runner/executors/artifact-executor.ts +166 -0
  31. package/src/runner/{blueprint-executor.ts → executors/blueprint-executor.ts} +15 -7
  32. package/src/runner/{engine-executor.ts → executors/engine-executor.ts} +55 -7
  33. package/src/runner/executors/file-executor.test.ts +48 -0
  34. package/src/runner/executors/file-executor.ts +324 -0
  35. package/src/runner/{foreach-executor.ts → executors/foreach-executor.ts} +168 -80
  36. package/src/runner/executors/human-executor.ts +144 -0
  37. package/src/runner/executors/join-executor.ts +75 -0
  38. package/src/runner/executors/llm-executor.ts +1266 -0
  39. package/src/runner/executors/memory-executor.ts +71 -0
  40. package/src/runner/executors/plan-executor.ts +104 -0
  41. package/src/runner/executors/request-executor.ts +265 -0
  42. package/src/runner/executors/script-executor.ts +43 -0
  43. package/src/runner/executors/shell-executor.ts +403 -0
  44. package/src/runner/executors/subworkflow-executor.ts +114 -0
  45. package/src/runner/executors/types.ts +69 -0
  46. package/src/runner/executors/wait-executor.ts +59 -0
  47. package/src/runner/join-scheduling.test.ts +197 -0
  48. package/src/runner/llm-adapter-runtime.test.ts +209 -0
  49. package/src/runner/llm-adapter.test.ts +419 -24
  50. package/src/runner/llm-adapter.ts +130 -26
  51. package/src/runner/llm-clarification.test.ts +2 -1
  52. package/src/runner/llm-executor.test.ts +532 -17
  53. package/src/runner/mcp-client-audit.test.ts +1 -2
  54. package/src/runner/mcp-client.ts +136 -46
  55. package/src/runner/mcp-manager.test.ts +4 -0
  56. package/src/runner/mcp-server.test.ts +58 -0
  57. package/src/runner/mcp-server.ts +26 -0
  58. package/src/runner/memoization.test.ts +190 -0
  59. package/src/runner/optimization-runner.ts +4 -9
  60. package/src/runner/quality-gate.test.ts +69 -0
  61. package/src/runner/reflexion.test.ts +6 -17
  62. package/src/runner/resource-pool.ts +102 -14
  63. package/src/runner/services/context-builder.ts +144 -0
  64. package/src/runner/services/secret-manager.ts +105 -0
  65. package/src/runner/services/workflow-validator.ts +131 -0
  66. package/src/runner/shell-executor.test.ts +28 -4
  67. package/src/runner/standard-tools-ast.test.ts +196 -0
  68. package/src/runner/standard-tools-execution.test.ts +27 -0
  69. package/src/runner/standard-tools-integration.test.ts +6 -10
  70. package/src/runner/standard-tools.ts +339 -102
  71. package/src/runner/step-executor.test.ts +216 -4
  72. package/src/runner/step-executor.ts +69 -941
  73. package/src/runner/stream-utils.ts +7 -3
  74. package/src/runner/test-harness.ts +20 -1
  75. package/src/runner/timeout.test.ts +10 -0
  76. package/src/runner/timeout.ts +11 -2
  77. package/src/runner/tool-integration.test.ts +1 -1
  78. package/src/runner/wait-step.test.ts +102 -0
  79. package/src/runner/workflow-runner.test.ts +208 -15
  80. package/src/runner/workflow-runner.ts +890 -818
  81. package/src/runner/workflow-scheduler.ts +75 -0
  82. package/src/runner/workflow-state.ts +269 -0
  83. package/src/runner/workflow-subflows.test.ts +13 -12
  84. package/src/scripts/generate-schemas.ts +16 -0
  85. package/src/templates/agents/explore.md +1 -0
  86. package/src/templates/agents/general.md +1 -0
  87. package/src/templates/agents/handoff-router.md +14 -0
  88. package/src/templates/agents/handoff-specialist.md +15 -0
  89. package/src/templates/agents/keystone-architect.md +13 -44
  90. package/src/templates/agents/my-agent.md +1 -0
  91. package/src/templates/agents/software-engineer.md +1 -0
  92. package/src/templates/agents/summarizer.md +1 -0
  93. package/src/templates/agents/test-agent.md +1 -0
  94. package/src/templates/agents/tester.md +1 -0
  95. package/src/templates/{basic-inputs.yaml → basics/basic-inputs.yaml} +2 -0
  96. package/src/templates/{basic-shell.yaml → basics/basic-shell.yaml} +2 -1
  97. package/src/templates/{full-feature-demo.yaml → basics/full-feature-demo.yaml} +2 -0
  98. package/src/templates/{stop-watch.yaml → basics/stop-watch.yaml} +1 -0
  99. package/src/templates/{child-rollback.yaml → control-flow/child-rollback.yaml} +1 -0
  100. package/src/templates/{cleanup-finally.yaml → control-flow/cleanup-finally.yaml} +1 -0
  101. package/src/templates/{fan-out-fan-in.yaml → control-flow/fan-out-fan-in.yaml} +3 -0
  102. package/src/templates/control-flow/idempotency-example.yaml +30 -0
  103. package/src/templates/{loop-parallel.yaml → control-flow/loop-parallel.yaml} +3 -0
  104. package/src/templates/{parent-rollback.yaml → control-flow/parent-rollback.yaml} +1 -0
  105. package/src/templates/{retry-policy.yaml → control-flow/retry-policy.yaml} +3 -0
  106. package/src/templates/features/artifact-example.yaml +39 -0
  107. package/src/templates/{engine-example.yaml → features/engine-example.yaml} +1 -0
  108. package/src/templates/{human-interaction.yaml → features/human-interaction.yaml} +1 -0
  109. package/src/templates/{llm-agent.yaml → features/llm-agent.yaml} +1 -0
  110. package/src/templates/{memory-service.yaml → features/memory-service.yaml} +2 -0
  111. package/src/templates/{robust-automation.yaml → features/robust-automation.yaml} +3 -0
  112. package/src/templates/features/script-example.yaml +27 -0
  113. package/src/templates/patterns/agent-handoff.yaml +53 -0
  114. package/src/templates/{approval-process.yaml → patterns/approval-process.yaml} +1 -0
  115. package/src/templates/{batch-processor.yaml → patterns/batch-processor.yaml} +2 -0
  116. package/src/templates/{composition-child.yaml → patterns/composition-child.yaml} +1 -0
  117. package/src/templates/{composition-parent.yaml → patterns/composition-parent.yaml} +1 -0
  118. package/src/templates/{data-pipeline.yaml → patterns/data-pipeline.yaml} +2 -0
  119. package/src/templates/{decompose-implement.yaml → scaffolding/decompose-implement.yaml} +1 -0
  120. package/src/templates/{decompose-problem.yaml → scaffolding/decompose-problem.yaml} +1 -0
  121. package/src/templates/{decompose-research.yaml → scaffolding/decompose-research.yaml} +1 -0
  122. package/src/templates/{decompose-review.yaml → scaffolding/decompose-review.yaml} +1 -0
  123. package/src/templates/{dev.yaml → scaffolding/dev.yaml} +1 -0
  124. package/src/templates/scaffolding/review-loop.yaml +97 -0
  125. package/src/templates/{scaffold-feature.yaml → scaffolding/scaffold-feature.yaml} +2 -0
  126. package/src/templates/{scaffold-generate.yaml → scaffolding/scaffold-generate.yaml} +1 -0
  127. package/src/templates/{scaffold-plan.yaml → scaffolding/scaffold-plan.yaml} +1 -0
  128. package/src/templates/testing/invalid.yaml +6 -0
  129. package/src/ui/dashboard.tsx +191 -33
  130. package/src/utils/auth-manager.test.ts +337 -0
  131. package/src/utils/auth-manager.ts +157 -61
  132. package/src/utils/blueprint-utils.ts +4 -6
  133. package/src/utils/config-loader.test.ts +2 -0
  134. package/src/utils/config-loader.ts +12 -3
  135. package/src/utils/constants.ts +76 -0
  136. package/src/utils/container.ts +63 -0
  137. package/src/utils/context-injector.test.ts +200 -0
  138. package/src/utils/context-injector.ts +244 -0
  139. package/src/utils/doc-generator.ts +85 -0
  140. package/src/utils/env-filter.ts +45 -0
  141. package/src/utils/json-parser.test.ts +12 -0
  142. package/src/utils/json-parser.ts +30 -5
  143. package/src/utils/logger.ts +12 -1
  144. package/src/utils/mermaid.ts +4 -0
  145. package/src/utils/paths.ts +52 -1
  146. package/src/utils/process-sandbox-worker.test.ts +46 -0
  147. package/src/utils/process-sandbox.ts +227 -14
  148. package/src/utils/redactor.test.ts +11 -6
  149. package/src/utils/redactor.ts +25 -9
  150. package/src/utils/sandbox.ts +3 -0
  151. package/src/runner/llm-executor.ts +0 -638
  152. package/src/runner/shell-executor.ts +0 -366
  153. package/src/templates/invalid.yaml +0 -5
@@ -0,0 +1,30 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: idempotency-example
3
+ description: "Demonstrate safely retrying side-effecting steps"
4
+
5
+ inputs:
6
+ order_id:
7
+ type: string
8
+ default: "order-123"
9
+
10
+ steps:
11
+ - id: risky_operation
12
+ type: shell
13
+ # This key ensures that for a given order_id, this step runs only once
14
+ # even if the workflow is retried or resumed.
15
+ idempotencyKey: '"process-order-" + inputs.order_id'
16
+ # Scope can be global (across all runs) or run (just this run)
17
+ idempotencyScope: global
18
+ # Expire the record after 1 day
19
+ idempotencyTtlSeconds: 86400
20
+ allowInsecure: true
21
+ run: |
22
+ echo "Processing order ${{ inputs.order_id }}..."
23
+ # Simulate a side effect
24
+ sleep 1
25
+ echo "Charged payment for ${{ inputs.order_id }}"
26
+
27
+ - id: next_step
28
+ type: shell
29
+ needs: [risky_operation]
30
+ run: echo "Order processed."
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: loop-parallel
2
3
  description: "Test the foreach race condition fix and .every() support"
3
4
 
@@ -10,6 +11,7 @@ steps:
10
11
  # Generate test data
11
12
  - id: generate_items
12
13
  type: shell
14
+ allowInsecure: true
13
15
  run: "echo 'item1\nitem2\nitem3\nitem4\nitem5'"
14
16
  transform: "stdout.split('\\n').filter(Boolean)"
15
17
 
@@ -19,6 +21,7 @@ steps:
19
21
  needs: [generate_items]
20
22
  foreach: ${{ steps.generate_items.output }}
21
23
  concurrency: 3
24
+ allowInsecure: true
22
25
  run: "echo 'Processing: ${{ item }}' && sleep 0.1"
23
26
  transform: "stdout.trim()"
24
27
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: nested-rollback-parent
2
3
  description: Parent workflow that triggers a child and then fails
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: retry-policy
2
3
  description: "Test retry and timeout features"
3
4
 
@@ -5,6 +6,7 @@ steps:
5
6
  # Test retry with a command that fails first few times
6
7
  - id: flaky_command
7
8
  type: shell
9
+ allowInsecure: true
8
10
  run: |
9
11
  if [ ! -f /tmp/keystone-retry-test ]; then
10
12
  echo "1" > /tmp/keystone-retry-test
@@ -25,6 +27,7 @@ steps:
25
27
  # Test timeout (should complete before timeout)
26
28
  - id: quick_task
27
29
  type: shell
30
+ allowInsecure: true
28
31
  run: sleep 0.1 && echo "Completed"
29
32
  timeout: 5000
30
33
  needs: [flaky_command]
@@ -0,0 +1,39 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: artifact-example
3
+ description: "Demonstrate artifact upload and download between steps"
4
+
5
+ steps:
6
+ - id: create_content
7
+ type: shell
8
+ allowInsecure: true
9
+ run: |
10
+ mkdir -p ./output
11
+ echo "Hello from step 1" > ./output/file1.txt
12
+ echo "Hello from step 1 (second file)" > ./output/file2.txt
13
+
14
+ - id: upload_files
15
+ type: artifact
16
+ op: upload
17
+ name: build-outputs
18
+ paths: ["./output/*.txt"]
19
+ needs: [create_content]
20
+
21
+ - id: clean_local
22
+ type: shell
23
+ needs: [upload_files]
24
+ run: rm -rf ./output
25
+
26
+ - id: download_files
27
+ type: artifact
28
+ op: download
29
+ name: build-outputs
30
+ path: ./downloaded
31
+ needs: [clean_local]
32
+
33
+ - id: verify
34
+ type: shell
35
+ needs: [download_files]
36
+ allowInsecure: true
37
+ run: |
38
+ ls -R ./downloaded
39
+ cat ./downloaded/file1.txt
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: engine-example
2
3
  description: "Run an allowlisted external CLI and capture a structured summary"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: human-interaction
2
3
  description: A workflow that prompts the user for input and uses it in another step.
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: llm-agent
2
3
  description: "Test LLM step"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: memory-service
2
3
  description: "Demonstrate long-term memory capabilities"
3
4
 
@@ -48,6 +49,7 @@ steps:
48
49
  - id: summary
49
50
  type: shell
50
51
  needs: [confirm_memory]
52
+ allowInsecure: true
51
53
  run: |
52
54
  echo "Memory Service Demo Complete"
53
55
  echo "Recalled: ${{ steps.recall_preference.output[0].content }}"
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: robust-automation
2
3
  description: "Demonstrate auto-healing and reflexion features"
3
4
 
@@ -6,6 +7,7 @@ steps:
6
7
  # This step attempts to run a broken command, but the agent should fix it
7
8
  - id: auto_heal_demo
8
9
  type: shell
10
+ allowInsecure: true
9
11
  run: |
10
12
  # This command has a typo and should fail
11
13
  ech "Hello World"
@@ -38,6 +40,7 @@ steps:
38
40
  - id: summary
39
41
  type: shell
40
42
  needs: [reflexion_demo]
43
+ allowInsecure: true
41
44
  run: |
42
45
  echo "Robust automation demo complete."
43
46
  echo "Healed Command Output: ${{ steps.auto_heal_demo.output.stdout }}"
@@ -0,0 +1,27 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: script-example
3
+ description: "Demonstrate sandboxed JavaScript execution"
4
+
5
+ steps:
6
+ - id: generate_data
7
+ type: shell
8
+ run: echo '{"values":[1,2,3,4,5]}'
9
+
10
+ - id: process_data
11
+ type: script
12
+ allowInsecure: true
13
+ needs: [generate_data]
14
+ run: |
15
+ const data = JSON.parse(steps.generate_data.output.stdout);
16
+ // Calculate sum and average
17
+ const sum = data.values.reduce((a, b) => a + b, 0);
18
+ const avg = sum / data.values.length;
19
+ return { sum, avg, count: data.values.length };
20
+
21
+ - id: print_result
22
+ type: shell
23
+ needs: [process_data]
24
+ allowInsecure: true
25
+ run: |
26
+ echo "Sum: ${{ steps.process_data.output.sum }}"
27
+ echo "Average: ${{ steps.process_data.output.avg }}"
@@ -0,0 +1,53 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: agent-handoff
3
+ description: "Demo of agent handoffs and tool-driven context updates."
4
+
5
+ inputs:
6
+ topic:
7
+ type: string
8
+ default: "billing"
9
+ user:
10
+ type: string
11
+ default: "Ada"
12
+
13
+ steps:
14
+ - id: route
15
+ type: llm
16
+ agent: handoff-router
17
+ prompt: |
18
+ We need help on "${{ inputs.topic }}" for "${{ inputs.user }}".
19
+ First, call remember_context with the topic and user.
20
+ If a specialist is needed, transfer to handoff-specialist.
21
+ Provide a short response after any handoff.
22
+ allowedHandoffs:
23
+ - handoff-specialist
24
+ tools:
25
+ - name: remember_context
26
+ description: Store user and topic in workflow context.
27
+ parameters:
28
+ type: object
29
+ properties:
30
+ topic: { type: string }
31
+ user: { type: string }
32
+ required: [topic, user]
33
+ execution:
34
+ id: remember_context
35
+ type: script
36
+ allowInsecure: true
37
+ run: |
38
+ (function() {
39
+ return {
40
+ __keystone_context: {
41
+ memory: { topic: args.topic, user: args.user },
42
+ env: { CURRENT_TOPIC: args.topic }
43
+ },
44
+ stored: true
45
+ };
46
+ })();
47
+
48
+ - id: show_context
49
+ type: shell
50
+ needs: [route]
51
+ allowInsecure: true
52
+ run: |
53
+ echo "Memory: ${{ memory.user }} on ${{ memory.topic }} (env=${{ env.CURRENT_TOPIC }})"
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: approval-process
2
3
  description: "A workflow demonstrating human-in-the-loop and conditional logic"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: batch-processor
2
3
  description: "Process multiple files in parallel"
3
4
 
@@ -14,6 +15,7 @@ steps:
14
15
  # 1. Dynamic Input Generation
15
16
  - id: list_files
16
17
  type: shell
18
+ allowInsecure: true
17
19
  run: "ls ${{ inputs.target_dir }}/*.txt"
18
20
  # Extract stdout lines into an array
19
21
  transform: "stdout.split('\\n').filter(Boolean)"
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: composition-child
2
3
  description: "A simple child workflow"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: composition-parent
2
3
  description: "A parent workflow that calls a child workflow"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: data-pipeline
2
3
  description: "A workflow that demonstrates file operations and cleanup with 'finally'"
3
4
 
@@ -20,6 +21,7 @@ steps:
20
21
 
21
22
  - id: process_data
22
23
  type: shell
24
+ allowInsecure: true
23
25
  run: |
24
26
  echo "${{ steps.read_data.output }}" | tr '[:lower:]' '[:upper:]'
25
27
  transform: "stdout.trim()"
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: decompose-implement
2
3
  description: "Implementation task sub-workflow for a decomposed problem"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: decompose-problem
2
3
  description: "Decompose a complex problem into research, implementation, and review sub-workflows"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: decompose-research
2
3
  description: "Research task sub-workflow for a decomposed problem"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: decompose-review
2
3
  description: "Review task sub-workflow for a decomposed problem"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: dev
2
3
  description: "Self-bootstrapping DevMode workflow for Keystone CLI"
3
4
 
@@ -0,0 +1,97 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: review-loop
3
+ description: "Generate, review, and refine output with a lightweight quality gate"
4
+
5
+ inputs:
6
+ goal: { type: string }
7
+ context: { type: string, default: "" }
8
+ draft: { type: string, default: "" }
9
+ attempt: { type: number, default: 1 }
10
+ maxAttempts: { type: number, default: 2 }
11
+
12
+ outputs:
13
+ draft: ${{ steps.iterate.output.draft || steps.refine.output || steps.generate.output || inputs.draft }}
14
+ review: ${{ steps.iterate.output.review || steps.review.output }}
15
+ attempts: ${{ steps.iterate.output.attempts || inputs.attempt }}
16
+
17
+ steps:
18
+ - id: generate
19
+ type: llm
20
+ agent: general
21
+ if: ${{ !inputs.draft }}
22
+ prompt: |
23
+ Generate a draft for the goal.
24
+
25
+ Goal:
26
+ ${{ inputs.goal }}
27
+
28
+ Context:
29
+ ${{ inputs.context }}
30
+
31
+ Return only the draft text.
32
+
33
+ - id: review
34
+ type: llm
35
+ agent: general
36
+ prompt: |
37
+ Review the draft for correctness, completeness, and clarity.
38
+
39
+ Goal:
40
+ ${{ inputs.goal }}
41
+
42
+ Context:
43
+ ${{ inputs.context }}
44
+
45
+ Draft:
46
+ ${{ inputs.draft || steps.generate.output }}
47
+
48
+ Identify issues, risks, and missing details. Be specific.
49
+ Return only the structured JSON required by the schema.
50
+ outputSchema:
51
+ type: object
52
+ properties:
53
+ approved:
54
+ type: boolean
55
+ issues:
56
+ type: array
57
+ items: { type: string }
58
+ suggestions:
59
+ type: array
60
+ items: { type: string }
61
+ required: [approved]
62
+
63
+ - id: refine
64
+ type: llm
65
+ agent: general
66
+ if: ${{ steps.review.output.approved == false }}
67
+ prompt: |
68
+ Improve the draft based on the review feedback.
69
+
70
+ Goal:
71
+ ${{ inputs.goal }}
72
+
73
+ Context:
74
+ ${{ inputs.context }}
75
+
76
+ Draft:
77
+ ${{ inputs.draft || steps.generate.output }}
78
+
79
+ Review feedback:
80
+ ${{ steps.review.output }}
81
+
82
+ Return only the revised draft text.
83
+
84
+ - id: iterate
85
+ type: workflow
86
+ if: ${{ steps.review.output.approved == false && inputs.attempt < inputs.maxAttempts }}
87
+ path: review-loop.yaml
88
+ inputs:
89
+ goal: ${{ inputs.goal }}
90
+ context: ${{ inputs.context }}
91
+ draft: ${{ steps.refine.output }}
92
+ attempt: ${{ inputs.attempt + 1 }}
93
+ maxAttempts: ${{ inputs.maxAttempts }}
94
+ outputMapping:
95
+ draft: draft
96
+ review: review
97
+ attempts: attempts
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: scaffold-feature
2
3
  description: "Autonomously build new Keystone workflows and agents"
3
4
 
@@ -47,6 +48,7 @@ steps:
47
48
  - id: summary
48
49
  type: shell
49
50
  needs: [write_files]
51
+ allowInsecure: true
50
52
  run: |
51
53
  echo "Scaffolding complete. Files created:"
52
54
  echo "${{ steps.generate.outputs && steps.generate.outputs.files ? steps.generate.outputs.files.map(f => f.path).join('\n') : '(dry run: no files generated)' }}"
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: scaffold-generate
2
3
  description: "Generate file contents from a file plan"
3
4
 
@@ -1,3 +1,4 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
1
2
  name: scaffold-plan
2
3
  description: "Plan the files for a new workflow and optional agents"
3
4
 
@@ -0,0 +1,6 @@
1
+ $schema: https://raw.githubusercontent.com/mhingston/keystone-cli/main/schemas/workflow.json
2
+ name: invalid-workflow
3
+ steps:
4
+ - id: step1
5
+ type: shell
6
+ # Missing 'run' property