From ea79b26b79fed00b2d9f7e062d2d5efd48e9c9b2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 23 Jan 2026 02:59:16 +0000 Subject: [PATCH] feat: extend lobster tool run args --- CHANGELOG.md | 1 + docs/tools/lobster.md | 91 ++++++++++++++++++++++++++ extensions/lobster/src/lobster-tool.ts | 8 ++- 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b22ffb3d2..3671f12ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Docs: https://docs.clawd.bot - Highlight: OpenProse plugin skill pack with `/prose` slash command, plugin-shipped skills, and docs. https://docs.clawd.bot/prose - TUI: run local shell commands with `!` after per-session consent, and warn when local exec stays disabled. (#1463) Thanks @vignesh07. - Highlight: Lobster optional plugin tool for typed workflows + approval gates. https://docs.clawd.bot/tools/lobster +- Lobster: allow workflow file args via `argsJson` in the plugin tool. https://docs.clawd.bot/tools/lobster - Agents: add identity avatar config support and Control UI avatar rendering. (#1329, #1424) Thanks @dlauer. - Memory: prevent CLI hangs by deferring vector probes, adding sqlite-vec/embedding timeouts, and showing sync progress early. - Docs: add troubleshooting entry for gateway.mode blocking gateway start. https://docs.clawd.bot/gateway/troubleshooting diff --git a/docs/tools/lobster.md b/docs/tools/lobster.md index e20987b74..7b88f5073 100644 --- a/docs/tools/lobster.md +++ b/docs/tools/lobster.md @@ -11,6 +11,10 @@ read_when: Lobster is a workflow shell that lets Clawdbot run multi-step tool sequences as a single, deterministic operation with explicit approval checkpoints. +## Hook + +Your assistant can build the tools that manage itself. Ask for a workflow, and 30 minutes later you have a CLI plus pipelines that run as one call. Lobster is the missing piece: deterministic pipelines, explicit approvals, and resumable state. + ## Why Today, complex workflows require many back-and-forth tool calls. Each call costs tokens, and the LLM has to orchestrate every step. Lobster moves that orchestration into a typed runtime: @@ -24,6 +28,73 @@ Today, complex workflows require many back-and-forth tool calls. Each call costs Clawdbot launches the local `lobster` CLI in **tool mode** and parses a JSON envelope from stdout. If the pipeline pauses for approval, the tool returns a `resumeToken` so you can continue later. +## Pattern: small CLI + JSON pipes + approvals + +Build tiny commands that speak JSON, then chain them into a single Lobster call. (Example command names below — swap in your own.) + +```bash +inbox list --json +inbox categorize --json +inbox apply --json +``` + +```json +{ + "action": "run", + "pipeline": "exec --json --shell 'inbox list --json' | exec --stdin json --shell 'inbox categorize --json' | exec --stdin json --shell 'inbox apply --json' | approve --preview-from-stdin --limit 5 --prompt 'Apply changes?'", + "timeoutMs": 30000 +} +``` + +If the pipeline requests approval, resume with the token: + +```json +{ + "action": "resume", + "token": "", + "approve": true +} +``` + +AI triggers the workflow; Lobster executes the steps. Approval gates keep side effects explicit and auditable. + +Example: map input items into tool calls: + +```bash +gog.gmail.search --query 'newer_than:1d' \ + | clawd.invoke --tool message --action send --each --item-key message --args-json '{"provider":"telegram","to":"..."}' +``` + +## Workflow files (.lobster) + +Lobster can run YAML/JSON workflow files with `name`, `args`, `steps`, `env`, `condition`, and `approval` fields. In Clawdbot tool calls, set `pipeline` to the file path. + +```yaml +name: inbox-triage +args: + tag: + default: "family" +steps: + - id: collect + command: inbox list --json + - id: categorize + command: inbox categorize --json + stdin: $collect.stdout + - id: approve + command: inbox apply --approve + stdin: $categorize.stdout + approval: required + - id: execute + command: inbox apply --execute + stdin: $categorize.stdout + condition: $approve.approved +``` + +Notes: + +- `stdin: $step.stdout` and `stdin: $step.json` pass a prior step’s output. +- `condition` (or `when`) can gate steps on `$step.approved`. + ## Install Lobster Install the Lobster CLI on the **same host** that runs the Clawdbot Gateway (see the [Lobster repo](https://github.com/clawdbot/lobster)), and ensure `lobster` is on `PATH`. @@ -115,6 +186,16 @@ Run a pipeline in tool mode. } ``` +Run a workflow file with args: + +```json +{ + "action": "run", + "pipeline": "/path/to/inbox-triage.lobster", + "argsJson": "{\"tag\":\"family\"}" +} +``` + ### `resume` Continue a halted workflow after approval. @@ -133,6 +214,7 @@ Continue a halted workflow after approval. - `cwd`: Working directory for the pipeline (defaults to the current process working directory). - `timeoutMs`: Kill the subprocess if it exceeds this duration (default: 20000). - `maxStdoutBytes`: Kill the subprocess if stdout exceeds this size (default: 512000). +- `argsJson`: JSON string passed to `lobster run --args-json` (workflow files only). ## Output envelope @@ -151,6 +233,8 @@ If `requiresApproval` is present, inspect the prompt and decide: - `approve: true` → resume and continue side effects - `approve: false` → cancel and finalize the workflow +Use `approve --preview-from-stdin --limit N` to attach a JSON preview to approval requests without custom jq/heredoc glue. Resume tokens are now compact: Lobster stores workflow resume state under its state dir and hands back a small token key. + ## OpenProse OpenProse pairs well with Lobster: use `/prose` to orchestrate multi-agent prep, then run a Lobster pipeline for deterministic approvals. If a Prose program needs Lobster, allow the `lobster` tool for sub-agents via `tools.subagents.tools`. See [OpenProse](/prose). @@ -173,3 +257,10 @@ OpenProse pairs well with Lobster: use `/prose` to orchestrate multi-agent prep, - [Plugins](/plugin) - [Plugin tool authoring](/plugins/agent-tools) + +## Case study: community workflows + +One public example: a “second brain” CLI + Lobster pipelines that manage three Markdown vaults (personal, partner, shared). The CLI emits JSON for stats, inbox listings, and stale scans; Lobster chains those commands into workflows like `weekly-review`, `inbox-triage`, `memory-consolidation`, and `shared-task-sync`, each with approval gates. AI handles judgment (categorization) when available and falls back to deterministic rules when not. + +- Thread: https://x.com/plattenschieber/status/2014508656335770033 +- Repo: https://github.com/bloomedai/brain-cli diff --git a/extensions/lobster/src/lobster-tool.ts b/extensions/lobster/src/lobster-tool.ts index 60c0a2429..368389ab8 100644 --- a/extensions/lobster/src/lobster-tool.ts +++ b/extensions/lobster/src/lobster-tool.ts @@ -159,6 +159,7 @@ export function createLobsterTool(api: ClawdbotPluginApi) { // NOTE: Prefer string enums in tool schemas; some providers reject unions/anyOf. action: Type.Unsafe<"run" | "resume">({ type: "string", enum: ["run", "resume"] }), pipeline: Type.Optional(Type.String()), + argsJson: Type.Optional(Type.String()), token: Type.Optional(Type.String()), approve: Type.Optional(Type.Boolean()), lobsterPath: Type.Optional(Type.String()), @@ -181,7 +182,12 @@ export function createLobsterTool(api: ClawdbotPluginApi) { if (action === "run") { const pipeline = typeof params.pipeline === "string" ? params.pipeline : ""; if (!pipeline.trim()) throw new Error("pipeline required"); - return ["run", "--mode", "tool", pipeline]; + const argv = ["run", "--mode", "tool", pipeline]; + const argsJson = typeof params.argsJson === "string" ? params.argsJson : ""; + if (argsJson.trim()) { + argv.push("--args-json", argsJson); + } + return argv; } if (action === "resume") { const token = typeof params.token === "string" ? params.token : "";