@openclaw/lobster 2026.5.24-beta.2 → 2026.5.26-beta.1
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/dist/index.js +14 -6
- package/node_modules/@clawdbot/lobster/README.md +50 -1
- package/node_modules/@clawdbot/lobster/dist/src/cli.js +295 -94
- package/node_modules/@clawdbot/lobster/dist/src/cli.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/commands_list.js +8 -6
- package/node_modules/@clawdbot/lobster/dist/src/commands/commands_list.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/approve.js +16 -16
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/ask.js +52 -41
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/ask.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/dedupe.js +10 -7
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/dedupe.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/diff_last.js +10 -10
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/email_triage.js +85 -67
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/email_triage.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/exec.js +48 -34
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/exec.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/gog_gmail_search.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/gog_gmail_send.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/group_by.js +9 -9
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/head.js +6 -6
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/json.js +3 -3
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke.js +219 -185
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_task_invoke.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/map.js +21 -17
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/map.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/openclaw_invoke.js +36 -33
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/openclaw_invoke.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/pick.js +13 -10
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/pick.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/sort.js +9 -9
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/state.js +19 -19
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/table.js +14 -15
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/table.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/template.js +73 -19
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/template.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/where.js +29 -22
- package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/where.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/commands/workflows/workflows_list.js +4 -4
- package/node_modules/@clawdbot/lobster/dist/src/commands/workflows/workflows_run.js +18 -18
- package/node_modules/@clawdbot/lobster/dist/src/commands/workflows/workflows_run.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/core/cost_tracker.js +73 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/cost_tracker.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/filters.js +102 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/filters.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/index.js +6 -6
- package/node_modules/@clawdbot/lobster/dist/src/core/retry.js +85 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/retry.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/core/tool_runtime.js +57 -57
- package/node_modules/@clawdbot/lobster/dist/src/core/tool_runtime.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/parser.js +18 -18
- package/node_modules/@clawdbot/lobster/dist/src/pipeline_resume_state.js +28 -31
- package/node_modules/@clawdbot/lobster/dist/src/pipeline_resume_state.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/read_line.js +11 -11
- package/node_modules/@clawdbot/lobster/dist/src/read_line.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/index.js +4 -4
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/pr-monitor.js +61 -53
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/pr-monitor.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/stages/pr-view.js +33 -26
- package/node_modules/@clawdbot/lobster/dist/src/recipes/github/stages/pr-view.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/renderers/json.js +2 -2
- package/node_modules/@clawdbot/lobster/dist/src/resume.js +51 -49
- package/node_modules/@clawdbot/lobster/dist/src/resume.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/runtime.js +10 -10
- package/node_modules/@clawdbot/lobster/dist/src/sdk/Lobster.js +49 -41
- package/node_modules/@clawdbot/lobster/dist/src/sdk/Lobster.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/index.js +6 -6
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/approve.js +3 -3
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/approve.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/diff.js +22 -20
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/diff.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/exec.js +21 -17
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/exec.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/primitives/state.js +18 -18
- package/node_modules/@clawdbot/lobster/dist/src/sdk/runtime.js +7 -7
- package/node_modules/@clawdbot/lobster/dist/src/sdk/runtime.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/sdk/token.js +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/shell.js +14 -14
- package/node_modules/@clawdbot/lobster/dist/src/state/store.js +37 -33
- package/node_modules/@clawdbot/lobster/dist/src/state/store.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/token.js +4 -4
- package/node_modules/@clawdbot/lobster/dist/src/validation.js +31 -1
- package/node_modules/@clawdbot/lobster/dist/src/validation.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/file.js +1367 -379
- package/node_modules/@clawdbot/lobster/dist/src/workflows/file.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/github_pr_monitor.js +35 -31
- package/node_modules/@clawdbot/lobster/dist/src/workflows/github_pr_monitor.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/src/workflows/graph.js +234 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/graph.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/src/workflows/registry.js +24 -21
- package/node_modules/@clawdbot/lobster/dist/src/workflows/registry.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/approval_id.test.js +87 -77
- package/node_modules/@clawdbot/lobster/dist/test/approval_id.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/approve_preview.test.js +9 -9
- package/node_modules/@clawdbot/lobster/dist/test/clawd_invoke.test.js +41 -38
- package/node_modules/@clawdbot/lobster/dist/test/clawd_invoke.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/clawd_invoke_legacy.test.js +20 -20
- package/node_modules/@clawdbot/lobster/dist/test/cli_run_file_args_json.test.js +15 -21
- package/node_modules/@clawdbot/lobster/dist/test/cli_run_file_args_json.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/commands_list.test.js +14 -14
- package/node_modules/@clawdbot/lobster/dist/test/condition_comparison.test.js +127 -0
- package/node_modules/@clawdbot/lobster/dist/test/condition_comparison.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/core_tool_runtime.test.js +57 -57
- package/node_modules/@clawdbot/lobster/dist/test/cost_tracker.test.js +126 -0
- package/node_modules/@clawdbot/lobster/dist/test/cost_tracker.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/dedupe.test.js +20 -18
- package/node_modules/@clawdbot/lobster/dist/test/dedupe.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/diff_last.test.js +39 -15
- package/node_modules/@clawdbot/lobster/dist/test/diff_last.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/doctor.test.js +11 -11
- package/node_modules/@clawdbot/lobster/dist/test/dry_run.test.js +232 -178
- package/node_modules/@clawdbot/lobster/dist/test/dry_run.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/email_triage.test.js +3 -1
- package/node_modules/@clawdbot/lobster/dist/test/email_triage.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/exec_stdin.test.js +9 -9
- package/node_modules/@clawdbot/lobster/dist/test/for_each.test.js +211 -0
- package/node_modules/@clawdbot/lobster/dist/test/for_each.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/github_pr_notify_format.test.js +14 -14
- package/node_modules/@clawdbot/lobster/dist/test/github_pr_summary.test.js +25 -25
- package/node_modules/@clawdbot/lobster/dist/test/group_by.test.js +21 -23
- package/node_modules/@clawdbot/lobster/dist/test/group_by.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/llm_invoke.test.js +60 -60
- package/node_modules/@clawdbot/lobster/dist/test/llm_invoke.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/llm_task_invoke.test.js +119 -113
- package/node_modules/@clawdbot/lobster/dist/test/llm_task_invoke.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/map.test.js +20 -18
- package/node_modules/@clawdbot/lobster/dist/test/map.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/multi_approval_resume.test.js +23 -23
- package/node_modules/@clawdbot/lobster/dist/test/multi_approval_resume.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/on_error.test.js +151 -0
- package/node_modules/@clawdbot/lobster/dist/test/on_error.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/openclaw_invoke_alias.test.js +10 -10
- package/node_modules/@clawdbot/lobster/dist/test/parallel.test.js +171 -0
- package/node_modules/@clawdbot/lobster/dist/test/parallel.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/parser.test.js +22 -22
- package/node_modules/@clawdbot/lobster/dist/test/parser.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/read_line.test.js +11 -11
- package/node_modules/@clawdbot/lobster/dist/test/read_line.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/resume.test.js +45 -39
- package/node_modules/@clawdbot/lobster/dist/test/resume.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/sdk_lobster.test.js +23 -23
- package/node_modules/@clawdbot/lobster/dist/test/shell.test.js +21 -21
- package/node_modules/@clawdbot/lobster/dist/test/sort.test.js +27 -25
- package/node_modules/@clawdbot/lobster/dist/test/sort.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/state.test.js +35 -19
- package/node_modules/@clawdbot/lobster/dist/test/state.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/step_retry.test.js +210 -0
- package/node_modules/@clawdbot/lobster/dist/test/step_retry.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/step_timeout.test.js +154 -0
- package/node_modules/@clawdbot/lobster/dist/test/step_timeout.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/template.test.js +25 -23
- package/node_modules/@clawdbot/lobster/dist/test/template.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/template_filters.test.js +107 -0
- package/node_modules/@clawdbot/lobster/dist/test/template_filters.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/tool_envelope_version.test.js +8 -8
- package/node_modules/@clawdbot/lobster/dist/test/tool_mode.test.js +21 -21
- package/node_modules/@clawdbot/lobster/dist/test/tool_mode.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/validation.test.js +28 -0
- package/node_modules/@clawdbot/lobster/dist/test/validation.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/workflow_args_env.test.js +17 -17
- package/node_modules/@clawdbot/lobster/dist/test/workflow_args_env.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/workflow_composition.test.js +238 -0
- package/node_modules/@clawdbot/lobster/dist/test/workflow_composition.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/workflow_file.test.js +551 -217
- package/node_modules/@clawdbot/lobster/dist/test/workflow_file.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/dist/test/workflow_graph.test.js +97 -0
- package/node_modules/@clawdbot/lobster/dist/test/workflow_graph.test.js.map +1 -0
- package/node_modules/@clawdbot/lobster/dist/test/workflows.test.js +15 -7
- package/node_modules/@clawdbot/lobster/dist/test/workflows.test.js.map +1 -1
- package/node_modules/@clawdbot/lobster/package.json +39 -34
- package/npm-shrinkwrap.json +8 -9
- package/package.json +5 -7
package/dist/index.js
CHANGED
|
@@ -7,12 +7,10 @@ import path from "node:path";
|
|
|
7
7
|
import { Readable, Writable } from "node:stream";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
|
-
import AjvPkg from "ajv";
|
|
11
10
|
//#region extensions/lobster/src/lobster-ajv-cache.ts
|
|
12
11
|
const installedSymbol = Symbol.for("openclaw.lobster.ajv-compile-cache.installed");
|
|
13
12
|
const cacheSymbol = Symbol.for("openclaw.lobster.ajv-compile-cache.entries");
|
|
14
13
|
const maxEntries = 512;
|
|
15
|
-
const AjvCtor = AjvPkg;
|
|
16
14
|
function stableJsonStringify(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
17
15
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
18
16
|
if (seen.has(value)) throw new TypeError("Cannot cache cyclic JSON schema");
|
|
@@ -60,7 +58,17 @@ function rememberCompiledValidator(params) {
|
|
|
60
58
|
validate
|
|
61
59
|
});
|
|
62
60
|
}
|
|
63
|
-
function
|
|
61
|
+
async function resolveLobsterAjvConstructor(packageEntryPath) {
|
|
62
|
+
const ajvModule = await import(pathToFileURL(createRequire(packageEntryPath).resolve("ajv")).href);
|
|
63
|
+
return ajvModule.default ?? ajvModule;
|
|
64
|
+
}
|
|
65
|
+
async function installLobsterAjvCompileCache(packageEntryPath) {
|
|
66
|
+
let AjvCtor;
|
|
67
|
+
try {
|
|
68
|
+
AjvCtor = await resolveLobsterAjvConstructor(packageEntryPath);
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
64
72
|
const proto = AjvCtor.prototype;
|
|
65
73
|
if (proto[installedSymbol]) return;
|
|
66
74
|
const originalCompile = proto.compile;
|
|
@@ -230,9 +238,9 @@ async function withTimeout(timeoutMs, fn) {
|
|
|
230
238
|
});
|
|
231
239
|
}
|
|
232
240
|
async function loadEmbeddedToolRuntimeFromPackage(options = {}) {
|
|
233
|
-
installLobsterAjvCompileCache();
|
|
234
241
|
const importModule = options.importModule ?? (async (specifier) => await import(specifier));
|
|
235
|
-
const
|
|
242
|
+
const packageEntryPath = (options.resolvePackageEntry ?? ((specifier) => lobsterRequire.resolve(specifier)))("@clawdbot/lobster");
|
|
243
|
+
await installLobsterAjvCompileCache(packageEntryPath);
|
|
236
244
|
let coreLoadError;
|
|
237
245
|
try {
|
|
238
246
|
return toEmbeddedToolRuntime(await importModule([
|
|
@@ -245,7 +253,7 @@ async function loadEmbeddedToolRuntimeFromPackage(options = {}) {
|
|
|
245
253
|
}
|
|
246
254
|
let fallbackLoadError;
|
|
247
255
|
try {
|
|
248
|
-
const packageRoot = findLobsterPackageRoot(
|
|
256
|
+
const packageRoot = findLobsterPackageRoot(packageEntryPath);
|
|
249
257
|
const coreRuntimeUrl = pathToFileURL(path.join(packageRoot, "dist/src/core/index.js")).href;
|
|
250
258
|
return toEmbeddedToolRuntime(await importModule(coreRuntimeUrl), coreRuntimeUrl);
|
|
251
259
|
} catch (error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Lobster
|
|
1
|
+
# 🦞 Lobster
|
|
2
2
|
|
|
3
3
|
An OpenClaw-native workflow shell: typed (JSON-first) pipelines, jobs, and approval gates.
|
|
4
4
|
|
|
@@ -208,6 +208,38 @@ Notes:
|
|
|
208
208
|
- `pipeline:` shares the same args/env/results model as shell steps, so later steps can still reference `$step.stdout` or `$step.json`.
|
|
209
209
|
- If you need a human checkpoint before an LLM call, use a dedicated `approval:` step in the workflow file rather than `approve` inside the nested pipeline.
|
|
210
210
|
- `cwd`, `env`, `stdin`, `when`, and `condition` work for both shell and pipeline steps.
|
|
211
|
+
- Use `retry`, `timeout_ms`, and `on_error` per step to control transient-failure behavior and recovery.
|
|
212
|
+
- Approval steps can optionally enforce identity constraints:
|
|
213
|
+
- `approval.required_approver` (or `requiredApprover`) requires an exact approver id.
|
|
214
|
+
- `approval.require_different_approver` (or `requireDifferentApprover`) requires approver id to differ from initiator.
|
|
215
|
+
- `approval.initiated_by` (or `initiatedBy`) sets the initiator id for comparison.
|
|
216
|
+
- `LOBSTER_APPROVAL_INITIATED_BY` can provide a default initiator id at run time.
|
|
217
|
+
- `LOBSTER_APPROVAL_APPROVED_BY` is used at resume/approval time for identity checks.
|
|
218
|
+
|
|
219
|
+
## Visualizing workflows
|
|
220
|
+
|
|
221
|
+
Use `lobster graph` to inspect workflow structure before execution.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
lobster graph --file path/to/workflow.lobster
|
|
225
|
+
lobster graph --file path/to/workflow.lobster --format mermaid
|
|
226
|
+
lobster graph --file path/to/workflow.lobster --format dot
|
|
227
|
+
lobster graph --file path/to/workflow.lobster --format ascii
|
|
228
|
+
lobster graph --file path/to/workflow.lobster --args-json '{"location":"Seattle"}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
What gets visualized:
|
|
232
|
+
|
|
233
|
+
- each workflow step as a node (`run`, `pipeline`, `approval`, etc.)
|
|
234
|
+
- data-flow edges from `stdin: $step.stdout` / `$step.json` references
|
|
235
|
+
- conditional dependencies from `when:` / `condition:` expressions
|
|
236
|
+
- approval gates as diamond-shaped nodes in `mermaid` and `dot` output
|
|
237
|
+
|
|
238
|
+
Format notes:
|
|
239
|
+
|
|
240
|
+
- `mermaid` (default): emits `flowchart TD` text for GitHub/Markdown rendering
|
|
241
|
+
- `dot`: emits Graphviz DOT syntax
|
|
242
|
+
- `ascii`: emits a terminal-friendly node/edge list
|
|
211
243
|
|
|
212
244
|
## Calling LLMs from workflows
|
|
213
245
|
|
|
@@ -233,6 +265,23 @@ Built-in providers today:
|
|
|
233
265
|
|
|
234
266
|
`llm_task.invoke` remains available as a backward-compatible alias for the OpenClaw provider.
|
|
235
267
|
|
|
268
|
+
### `pipeline:` vs `run:` for LLM calls
|
|
269
|
+
|
|
270
|
+
- Use `pipeline:` for `llm.invoke` and `llm_task.invoke` (they are Lobster pipeline stages, not shell executables).
|
|
271
|
+
- Use `run:` only for real binaries in your shell (for example `openclaw.invoke`).
|
|
272
|
+
|
|
273
|
+
Example (`stdin` from a prior step is passed to the LLM as artifacts):
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
steps:
|
|
277
|
+
- id: make_words
|
|
278
|
+
run: echo "One two three four five six"
|
|
279
|
+
|
|
280
|
+
- id: count_words
|
|
281
|
+
pipeline: llm_task.invoke --prompt "How many words have been pasted below?"
|
|
282
|
+
stdin: $make_words.stdout
|
|
283
|
+
```
|
|
284
|
+
|
|
236
285
|
## Calling OpenClaw tools from workflows
|
|
237
286
|
|
|
238
287
|
Shell `run:` steps execute in your system shell, so OpenClaw tool calls there must be real executables.
|