docs: rename Clawdbot/Moltbot references to OpenClaw

This commit is contained in:
vignesh07
2026-02-24 11:23:33 -08:00
parent 61218be567
commit 00cedaeba6
14 changed files with 85 additions and 74 deletions
+15 -15
View File
@@ -1,20 +1,20 @@
# Lobster # Lobster
A Moltbot-native workflow shell: typed (JSON-first) pipelines, jobs, and approval gates. An OpenClaw-native workflow shell: typed (JSON-first) pipelines, jobs, and approval gates.
## Example of lobster at work ## Example of Lobster at work
Moltbot or any other AI agent can use `lobster` as a workflow engine and not construct a query every time - thus saving tokens, providing room for determinism, and resumability. OpenClaw (or any other AI agent) can use `lobster` as a workflow engine and avoid re-planning every step — saving tokens while improving determinism and resumability.
### Watching a PR that hasn't had changes ### Watching a PR that hasn't had changes
``` ```
node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo\":\"moltbot/moltbot\",\"pr\":1152}'" node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo\":\"openclaw/openclaw\",\"pr\":1152}'"
[ [
{ {
"kind": "github.pr.monitor", "kind": "github.pr.monitor",
"repo": "moltbot/moltbot", "repo": "openclaw/openclaw",
"prNumber": 1152, "prNumber": 1152,
"key": "github.pr:moltbot/moltbot#1152", "key": "github.pr:openclaw/openclaw#1152",
"changed": false, "changed": false,
"summary": { "summary": {
"changedFields": [], "changedFields": [],
@@ -36,7 +36,7 @@ node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo
"state": "OPEN", "state": "OPEN",
"title": "feat: Add optional lobster plugin tool (typed workflows, approvals/resume)", "title": "feat: Add optional lobster plugin tool (typed workflows, approvals/resume)",
"updatedAt": "2026-01-18T20:16:56Z", "updatedAt": "2026-01-18T20:16:56Z",
"url": "https://github.com/moltbot/moltbot/pull/1152" "url": "https://github.com/openclaw/openclaw/pull/1152"
} }
} }
] ]
@@ -44,13 +44,13 @@ node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo
### And a PR that has a state change (in this case an approved PR) ### And a PR that has a state change (in this case an approved PR)
``` ```
node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo\":\"moltbot/moltbot\",\"pr\":1200}'" node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo\":\"openclaw/openclaw\",\"pr\":1200}'"
[ [
{ {
"kind": "github.pr.monitor", "kind": "github.pr.monitor",
"repo": "moltbot/moltbot", "repo": "openclaw/openclaw",
"prNumber": 1200, "prNumber": 1200,
"key": "github.pr:moltbot/moltbot#1200", "key": "github.pr:openclaw/openclaw#1200",
"changed": true, "changed": true,
"summary": { "summary": {
"changedFields": [ "changedFields": [
@@ -76,7 +76,7 @@ node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo
}, },
"url": { "url": {
"from": null, "from": null,
"to": "https://github.com/moltbot/moltbot/pull/1200" "to": "https://github.com/openclaw/openclaw/pull/1200"
}, },
"state": { "state": {
"from": null, "from": null,
@@ -124,7 +124,7 @@ node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo
"state": "MERGED", "state": "MERGED",
"title": "feat(tui): add syntax highlighting for code blocks", "title": "feat(tui): add syntax highlighting for code blocks",
"updatedAt": "2026-01-19T05:06:09Z", "updatedAt": "2026-01-19T05:06:09Z",
"url": "https://github.com/moltbot/moltbot/pull/1200" "url": "https://github.com/openclaw/openclaw/pull/1200"
} }
} }
] ]
@@ -136,7 +136,7 @@ node bin/lobster.js "workflows.run --name github.pr.monitor --args-json '{\"repo
- Typed pipelines (objects/arrays), not text pipes. - Typed pipelines (objects/arrays), not text pipes.
- Local-first execution. - Local-first execution.
- No new auth surface: Lobster must not own OAuth/tokens. - No new auth surface: Lobster must not own OAuth/tokens.
- Composable macros that Moltbot can invoke in one step to save tokens. - Composable macros that OpenClaw (or any agent) can invoke in one step to save tokens.
## Quick start ## Quick start
@@ -159,11 +159,11 @@ From this folder:
- `exec --stdin raw|json|jsonl`: feed pipeline input into subprocess stdin - `exec --stdin raw|json|jsonl`: feed pipeline input into subprocess stdin
- `where`, `pick`, `head`: data shaping - `where`, `pick`, `head`: data shaping
- `json`, `table`: renderers - `json`, `table`: renderers
- `approve`: approval gate (TTY prompt or `--emit` for Moltbot integration) - `approve`: approval gate (TTY prompt or `--emit` for OpenClaw integration)
## Next steps ## Next steps
- Moltbot integration: ship as an optional Moltbot plugin tool. - OpenClaw integration: ship as an optional OpenClaw plugin tool.
## Workflow files ## Workflow files
+23 -23
View File
@@ -2,26 +2,26 @@
## One-liner ## One-liner
**Lobster is safe automation for Clawdbot — workflows that ask before acting.** **Lobster is safe automation for OpenClaw — workflows that ask before acting.**
--- ---
## What is Lobster? ## What is Lobster?
Lobster is a workflow runtime for Clawdbot. It lets you define multi-step automations that: Lobster is a workflow runtime for OpenClaw. It lets you define multi-step automations that:
- Run deterministically (no LLM re-planning each step) - Run deterministically (no LLM re-planning each step)
- Halt at checkpoints and ask for approval before side effects - Halt at checkpoints and ask for approval before side effects
- Resume exactly where they left off - Resume exactly where they left off
- Remember what they've already processed - Remember what they've already processed
Think of it as **IFTTT/Zapier for Clawdbot, but with human checkpoints**. Think of it as **IFTTT/Zapier for OpenClaw, but with human checkpoints**.
--- ---
## The Problem Lobster Solves ## The Problem Lobster Solves
### Today's workflow in Clawdbot ### Today's workflow in OpenClaw
``` ```
User: "Check my email, draft replies to anything urgent, and send them" User: "Check my email, draft replies to anything urgent, and send them"
@@ -46,7 +46,7 @@ What happens:
### With Lobster ### With Lobster
``` ```
Clawdbot calls: lobster.run("email.triage") OpenClaw calls: lobster.run("email.triage")
What happens: What happens:
1. Lobster fetches emails (deterministic) 1. Lobster fetches emails (deterministic)
@@ -63,7 +63,7 @@ Tomorrow: Lobster remembers cursor, only processes new emails
--- ---
## Why Lobster Makes Clawdbot Better ## Why Lobster Makes OpenClaw Better
| Without Lobster | With Lobster | | Without Lobster | With Lobster |
|-----------------|--------------| |-----------------|--------------|
@@ -85,7 +85,7 @@ Workflows can persist state: "last processed email ID", "last PR SHA seen", etc.
--- ---
## How Lobster Fits with Clawdbot ## How Lobster Fits with OpenClaw
``` ```
┌─────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────┐
@@ -95,7 +95,7 @@ Workflows can persist state: "last processed email ID", "last PR SHA seen", etc.
┌─────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────┐
│ Clawdbot OpenClaw │
│ - Understands intent │ │ - Understands intent │
│ - Chooses appropriate tool/workflow │ │ - Chooses appropriate tool/workflow │
│ - Presents results and approval prompts │ │ - Presents results and approval prompts │
@@ -105,15 +105,15 @@ Workflows can persist state: "last processed email ID", "last PR SHA seen", etc.
┌─────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────┐
│ Lobster │ │ Lobster │
│ - Executes deterministic pipeline │ │ - Executes deterministic pipeline │
│ - Calls Clawdbot tools (gmail, trello, etc) │ - Calls OpenClaw tools (gmail, trello, etc) │
│ - Halts at approval checkpoints │ │ - Halts at approval checkpoints │
│ - Returns structured result + resume token │ │ - Returns structured result + resume token │
└─────────────────────────────────────────────────┘ └─────────────────────────────────────────────────┘
``` ```
**Key insight:** Lobster doesn't replace Clawdbot. It's the execution layer that makes Clawdbot's automations safe and efficient. **Key insight:** Lobster doesn't replace OpenClaw. It's the execution layer that makes OpenClaw's automations safe and efficient.
- **Clawdbot** = the brain (understands what you want) - **OpenClaw** = the brain (understands what you want)
- **Lobster** = the hands (executes workflows safely) - **Lobster** = the hands (executes workflows safely)
- **Tools/Skills** = the capabilities (gmail, trello, github, etc.) - **Tools/Skills** = the capabilities (gmail, trello, github, etc.)
@@ -121,7 +121,7 @@ Workflows can persist state: "last processed email ID", "last PR SHA seen", etc.
## Who Should Use Lobster? ## Who Should Use Lobster?
### Average Clawdbot users (invisible benefit) ### Average OpenClaw users (invisible benefit)
They don't need to know Lobster exists. They just notice: They don't need to know Lobster exists. They just notice:
- "Set up daily email triage" works better - "Set up daily email triage" works better
- Automations ask before sending/posting - Automations ask before sending/posting
@@ -133,7 +133,7 @@ They can:
- Write new workflows for their specific needs - Write new workflows for their specific needs
- Share workflows with the community - Share workflows with the community
### The Clawdbot ecosystem ### The OpenClaw ecosystem
- Workflow recipes become a new category of shareable assets - Workflow recipes become a new category of shareable assets
- Skills stay simple (just expose APIs) - Skills stay simple (just expose APIs)
- Lobster handles the orchestration layer - Lobster handles the orchestration layer
@@ -151,21 +151,21 @@ They can:
| Temporal | But 80/20 version for personal workflows | | Temporal | But 80/20 version for personal workflows |
**Best analogy for most people:** **Best analogy for most people:**
> "Lobster is Zapier for Clawdbot, except it asks you before doing anything irreversible." > "Lobster is Zapier for OpenClaw, except it asks you before doing anything irreversible."
--- ---
## Why Not Build This Into Clawdbot Core? ## Why Not Build This Into OpenClaw Core?
It could be. But the plugin architecture is intentional: It could be. But the plugin architecture is intentional:
1. **Core stays small** — Clawdbot is already complex 1. **Core stays small**OpenClaw is already complex
2. **Faster iteration** — Lobster can evolve without core releases 2. **Faster iteration** — Lobster can evolve without core releases
3. **Opt-in** — Not everyone needs workflow automation 3. **Opt-in** — Not everyone needs workflow automation
4. **Community** — Easier to contribute workflows than core changes 4. **Community** — Easier to contribute workflows than core changes
5. **Ecosystem proof** — If plugins work for Lobster, they work for other capabilities 5. **Ecosystem proof** — If plugins work for Lobster, they work for other capabilities
Pete (Clawdbot creator) explicitly built the plugin boundary to enable this pattern. Lobster is the first proof that it works. OpenClaw explicitly provides a plugin boundary to enable this pattern. Lobster is the first proof that it works.
--- ---
@@ -221,9 +221,9 @@ Other automation tools either:
- Don't integrate with your AI assistant - Don't integrate with your AI assistant
Lobster is: Lobster is:
- Native to Clawdbot (uses the same tools you already have) - Native to OpenClaw (uses the same tools you already have)
- Safe by default (approvals are a language primitive) - Safe by default (approvals are a language primitive)
- Invisible when you want (Clawdbot uses it automatically) - Invisible when you want (OpenClaw uses it automatically)
- Customizable when you need (write your own workflows) - Customizable when you need (write your own workflows)
--- ---
@@ -232,8 +232,8 @@ Lobster is:
- **Not a terminal replacement** — You don't switch your shell to Lobster - **Not a terminal replacement** — You don't switch your shell to Lobster
- **Not a general programming language** — It's for workflows, not apps - **Not a general programming language** — It's for workflows, not apps
- **Not trying to replace Clawdbot** — It makes Clawdbot better - **Not trying to replace OpenClaw** — It makes OpenClaw better
- **Not managing your secrets** — Clawdbot handles auth, Lobster orchestrates - **Not managing your secrets** — OpenClaw handles auth, Lobster orchestrates
--- ---
@@ -241,9 +241,9 @@ Lobster is:
| Question | Answer | | Question | Answer |
|----------|--------| |----------|--------|
| What is it? | Workflow runtime for Clawdbot | | What is it? | Workflow runtime for OpenClaw |
| One-liner? | Safe automation — workflows that ask before acting | | One-liner? | Safe automation — workflows that ask before acting |
| Why use it? | Cheaper, safer, stateful automations | | Why use it? | Cheaper, safer, stateful automations |
| Who uses it? | Everyone (invisibly) or power users (directly) | | Who uses it? | Everyone (invisibly) or power users (directly) |
| Why not in core? | Plugin architecture — core stays small, capabilities are extensions | | Why not in core? | Plugin architecture — core stays small, capabilities are extensions |
| Best analogy? | Zapier for Clawdbot, but with approval checkpoints | | Best analogy? | Zapier for OpenClaw, but with approval checkpoints |
+4 -4
View File
@@ -43,16 +43,16 @@
"approval", "approval",
"pipeline", "pipeline",
"lobster", "lobster",
"clawdbot" "openclaw"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/clawdbot/lobster.git" "url": "git+https://github.com/openclaw/lobster.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/clawdbot/lobster/issues" "url": "https://github.com/openclaw/lobster/issues"
}, },
"homepage": "https://github.com/clawdbot/lobster#readme", "homepage": "https://github.com/openclaw/lobster#readme",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ajv": "^8.17.1", "ajv": "^8.17.1",
+1 -1
View File
@@ -449,7 +449,7 @@ function writeToolEnvelope(payload) {
} }
function helpText() { function helpText() {
return `lobster — Clawdbot-native typed shell\n\n` + return `lobster — OpenClaw-native typed shell\n\n` +
`Usage:\n` + `Usage:\n` +
` lobster '<pipeline>'\n` + ` lobster '<pipeline>'\n` +
` lobster run --mode tool '<pipeline>'\n` + ` lobster run --mode tool '<pipeline>'\n` +
+1 -1
View File
@@ -14,7 +14,7 @@ export const commandsListCommand: LobsterCommand = {
`Usage:\n` + `Usage:\n` +
` commands.list\n\n` + ` commands.list\n\n` +
`Notes:\n` + `Notes:\n` +
` - Intended for agents (e.g. Clawdbot) to discover available pipeline stages dynamically.\n` + ` - Intended for agents (e.g. OpenClaw) to discover available pipeline stages dynamically.\n` +
` - Output includes name/description plus optional metadata (argsSchema/examples/sideEffects) when provided by commands.\n` ` - Output includes name/description plus optional metadata (argsSchema/examples/sideEffects) when provided by commands.\n`
); );
}, },
+13 -8
View File
@@ -1,11 +1,14 @@
export const clawdInvokeCommand = { export const clawdInvokeCommand = {
name: 'clawd.invoke', name: 'clawd.invoke',
meta: { meta: {
description: 'Call a local Clawdbot tool endpoint', description: 'Call a local OpenClaw tool endpoint',
argsSchema: { argsSchema: {
type: 'object', type: 'object',
properties: { properties: {
url: { type: 'string', description: 'Clawdbot control URL (or CLAWD_URL)' }, url: {
type: 'string',
description: 'OpenClaw control URL (or OPENCLAW_URL / CLAWD_URL)',
},
token: { type: 'string', description: 'Bearer token (or CLAWD_TOKEN)' }, token: { type: 'string', description: 'Bearer token (or CLAWD_TOKEN)' },
tool: { type: 'string', description: 'Tool name (e.g. message, cron, github, etc.)' }, tool: { type: 'string', description: 'Tool name (e.g. message, cron, github, etc.)' },
action: { type: 'string', description: 'Tool action' }, action: { type: 'string', description: 'Tool action' },
@@ -21,14 +24,16 @@ export const clawdInvokeCommand = {
sideEffects: ['calls_clawd_tool'], sideEffects: ['calls_clawd_tool'],
}, },
help() { help() {
return `clawd.invoke — call a local Clawdbot tool endpoint\n\n` + return `clawd.invoke — call a local OpenClaw tool endpoint\n\n` +
`Usage:\n` + `Usage:\n` +
` clawd.invoke --tool message --action send --args-json '{"provider":"telegram","to":"...","message":"..."}'\n` + ` clawd.invoke --tool message --action send --args-json '{"provider":"telegram","to":"...","message":"..."}'\n` +
` clawd.invoke --tool message --action send --args-json '{...}' --dry-run\n` + ` clawd.invoke --tool message --action send --args-json '{...}' --dry-run\n` +
` ... | clawd.invoke --tool message --action send --each --item-key message --args-json '{"provider":"telegram","to":"..."}'\n\n` + ` ... | clawd.invoke --tool message --action send --each --item-key message --args-json '{"provider":"telegram","to":"..."}'\n\n` +
`Config:\n` + `Config:\n` +
` - Uses CLAWD_URL env var by default (or pass --url).\n` + ` - Uses OPENCLAW_URL env var by default (or pass --url).\n` +
` - Optional Bearer token via CLAWD_TOKEN env var (or pass --token).\n` + ` - Backward compatible: CLAWD_URL is also supported.\n` +
` - Optional Bearer token via OPENCLAW_TOKEN env var (or pass --token).\n` +
` - Backward compatible: CLAWD_TOKEN is also supported.\n` +
` - Optional attribution via --session-key <sessionKey>.\n\n` + ` - Optional attribution via --session-key <sessionKey>.\n\n` +
`Notes:\n` + `Notes:\n` +
` - This is a thin transport bridge. Lobster should not own OAuth/secrets.\n`; ` - This is a thin transport bridge. Lobster should not own OAuth/secrets.\n`;
@@ -37,14 +42,14 @@ export const clawdInvokeCommand = {
const each = Boolean(args.each); const each = Boolean(args.each);
const itemKey = String(args.itemKey ?? args['item-key'] ?? 'item'); const itemKey = String(args.itemKey ?? args['item-key'] ?? 'item');
const url = String(args.url ?? ctx.env.CLAWD_URL ?? '').trim(); const url = String(args.url ?? ctx.env.OPENCLAW_URL ?? ctx.env.CLAWD_URL ?? '').trim();
if (!url) throw new Error('clawd.invoke requires --url or CLAWD_URL'); if (!url) throw new Error('clawd.invoke requires --url or OPENCLAW_URL');
const tool = args.tool; const tool = args.tool;
const action = args.action; const action = args.action;
if (!tool || !action) throw new Error('clawd.invoke requires --tool and --action'); if (!tool || !action) throw new Error('clawd.invoke requires --tool and --action');
const token = String(args.token ?? ctx.env.CLAWD_TOKEN ?? '').trim(); const token = String(args.token ?? ctx.env.OPENCLAW_TOKEN ?? ctx.env.CLAWD_TOKEN ?? '').trim();
let toolArgs = {}; let toolArgs = {};
if (args['args-json']) { if (args['args-json']) {
+1 -1
View File
@@ -233,7 +233,7 @@ export const emailTriageCommand = {
} }
const model = String(args.model ?? '').trim(); const model = String(args.model ?? '').trim();
// Model is optional when running under Clawdbot (llm_task.invoke will use Clawdbot defaults). // Model is optional when running under OpenClaw (llm_task.invoke will use OpenClaw defaults).
if (!ctx?.registry) throw new Error('email.triage (LLM mode) requires ctx.registry'); if (!ctx?.registry) throw new Error('email.triage (LLM mode) requires ctx.registry');
const llmCmd = ctx.registry.get('llm_task.invoke'); const llmCmd = ctx.registry.get('llm_task.invoke');
+18 -12
View File
@@ -26,7 +26,7 @@ const payloadSchema = {
type: 'object', type: 'object',
properties: { properties: {
prompt: { type: 'string', minLength: 1 }, prompt: { type: 'string', minLength: 1 },
// In direct mode, the remote likely requires model; in CLAWD mode, Clawdbot can default. // In direct mode, the remote likely requires model; in OPENCLAW mode, OpenClaw can default.
model: { type: 'string', minLength: 1 }, model: { type: 'string', minLength: 1 },
artifacts: { type: 'array', items: artifactSchema }, artifacts: { type: 'array', items: artifactSchema },
artifactHashes: { type: 'array', items: { type: 'string', minLength: 10 } }, artifactHashes: { type: 'array', items: { type: 'string', minLength: 10 } },
@@ -151,7 +151,7 @@ type Transport = 'clawd';
export const llmTaskInvokeCommand = { export const llmTaskInvokeCommand = {
name: 'llm_task.invoke', name: 'llm_task.invoke',
meta: { meta: {
description: 'Call Clawdbot llm-task tool with typed payloads and caching', description: 'Call OpenClaw llm-task tool with typed payloads and caching',
argsSchema: { argsSchema: {
type: 'object', type: 'object',
properties: { properties: {
@@ -160,7 +160,11 @@ export const llmTaskInvokeCommand = {
description: 'Bearer token (or CLAWD_TOKEN). Optional if unauthenticated.', description: 'Bearer token (or CLAWD_TOKEN). Optional if unauthenticated.',
}, },
prompt: { type: 'string', description: 'Primary prompt / instructions' }, prompt: { type: 'string', description: 'Primary prompt / instructions' },
model: { type: 'string', description: 'Model identifier (optional; Clawdbot default will be used if omitted in CLAWD mode)' }, model: {
type: 'string',
description:
'Model identifier (optional; OpenClaw default will be used if omitted in OPENCLAW mode)',
},
'artifacts-json': { type: 'string', description: 'JSON array of artifacts to send' }, 'artifacts-json': { type: 'string', description: 'JSON array of artifacts to send' },
'metadata-json': { type: 'string', description: 'JSON object of metadata to include' }, 'metadata-json': { type: 'string', description: 'JSON object of metadata to include' },
'output-schema': { type: 'string', description: 'JSON schema LLM output must satisfy' }, 'output-schema': { type: 'string', description: 'JSON schema LLM output must satisfy' },
@@ -179,15 +183,17 @@ export const llmTaskInvokeCommand = {
}, },
help() { help() {
return ( return (
`llm_task.invoke — call Clawdbot llm-task tool with caching and schema validation\n\n` + `llm_task.invoke — call OpenClaw llm-task tool with caching and schema validation\n\n` +
`Usage:\n` + `Usage:\n` +
` llm_task.invoke --prompt 'Write summary'\n` + ` llm_task.invoke --prompt 'Write summary'\n` +
` llm_task.invoke --model claude-3-sonnet --prompt 'Write summary'\n` + ` llm_task.invoke --model claude-3-sonnet --prompt 'Write summary'\n` +
` cat artifacts.json | llm_task.invoke --prompt 'Score each item'\n` + ` cat artifacts.json | llm_task.invoke --prompt 'Score each item'\n` +
` ... | llm_task.invoke --prompt 'Plan next steps' --output-schema '{"type":"object"}'\n\n` + ` ... | llm_task.invoke --prompt 'Plan next steps' --output-schema '{"type":"object"}'\n\n` +
`Config:\n` + `Config:\n` +
` - Requires CLAWD_URL (Clawdbot gateway).\n` + ` - Requires OPENCLAW_URL (OpenClaw gateway).\n` +
` - Optional CLAWD_TOKEN for auth.\n\n` + ` - Backward compatible: CLAWD_URL is also supported.\n` +
` - Optional OPENCLAW_TOKEN for auth.\n` +
` - Backward compatible: CLAWD_TOKEN is also supported.\n\n` +
`Features:\n` + `Features:\n` +
` - Typed payload validation before invoking tool.\n` + ` - Typed payload validation before invoking tool.\n` +
` - Run-state + file cache so resumes do not re-call the LLM.\n` + ` - Run-state + file cache so resumes do not re-call the LLM.\n` +
@@ -197,17 +203,17 @@ export const llmTaskInvokeCommand = {
async run({ input, args, ctx }) { async run({ input, args, ctx }) {
const env = ctx.env ?? process.env; const env = ctx.env ?? process.env;
const clawdUrl = String(env.CLAWD_URL ?? '').trim(); const clawdUrl = String(env.OPENCLAW_URL ?? env.CLAWD_URL ?? '').trim();
const transport: Transport = 'clawd'; const transport: Transport = 'clawd';
if (!clawdUrl) { if (!clawdUrl) {
throw new Error('llm_task.invoke requires CLAWD_URL (run via Clawdbot gateway)'); throw new Error('llm_task.invoke requires OPENCLAW_URL (run via OpenClaw gateway)');
} }
const prompt = extractPrompt(args); const prompt = extractPrompt(args);
if (!prompt) throw new Error('llm_task.invoke requires --prompt or positional text'); if (!prompt) throw new Error('llm_task.invoke requires --prompt or positional text');
const model = String(args.model ?? env.LLM_TASK_MODEL ?? '').trim(); const model = String(args.model ?? env.LLM_TASK_MODEL ?? '').trim();
// Model is optional in Clawdbot mode (Clawdbot llm-task tool can use its default model). // Model is optional in OpenClaw mode (OpenClaw llm-task tool can use its default model).
const schemaVersion = args['schema-version'] const schemaVersion = args['schema-version']
? String(args['schema-version']).trim() ? String(args['schema-version']).trim()
@@ -279,7 +285,7 @@ export const llmTaskInvokeCommand = {
} }
const endpoint = buildClawdEndpoint(clawdUrl); const endpoint = buildClawdEndpoint(clawdUrl);
const token = String(args.token ?? env.CLAWD_TOKEN ?? '').trim(); const token = String(args.token ?? env.OPENCLAW_TOKEN ?? env.CLAWD_TOKEN ?? '').trim();
const validator = userOutputSchema ? ajv.compile(userOutputSchema) : null; const validator = userOutputSchema ? ajv.compile(userOutputSchema) : null;
@@ -425,7 +431,7 @@ function computeCacheKey({
}) { }) {
const payload = { const payload = {
prompt, prompt,
// If model is omitted (Clawdbot default), keep caching stable but explicit. // If model is omitted (OpenClaw default), keep caching stable but explicit.
model: model || 'clawd-default', model: model || 'clawd-default',
schemaVersion, schemaVersion,
artifactHashes, artifactHashes,
@@ -464,7 +470,7 @@ async function invokeRemoteViaClawd({ endpoint, token, payload }: { endpoint: UR
throw new Error('Response was not JSON'); throw new Error('Response was not JSON');
} }
// Clawdbot tool router envelope: { ok, result, error } // OpenClaw tool router envelope: { ok, result, error }
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && 'ok' in parsed) { if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && 'ok' in parsed) {
if (parsed.ok !== true) { if (parsed.ok !== true) {
const msg = parsed?.error?.message ?? 'Unknown error'; const msg = parsed?.error?.message ?? 'Unknown error';
+1 -1
View File
@@ -8,7 +8,7 @@ export const workflowsListCommand = {
sideEffects: [], sideEffects: [],
}, },
help() { help() {
return `workflows.list — list available Lobster workflows\n\nUsage:\n workflows.list\n\nNotes:\n - Intended for Clawdbot to discover workflows dynamically.\n`; return `workflows.list — list available Lobster workflows\n\nUsage:\n workflows.list\n\nNotes:\n - Intended for OpenClaw to discover workflows dynamically.\n`;
}, },
async run({ input }) { async run({ input }) {
// Drain input. // Drain input.
+1 -1
View File
@@ -26,7 +26,7 @@ export const workflowsRunCommand = {
sideEffects: [], sideEffects: [],
}, },
help() { help() {
return `workflows.run — run a named Lobster workflow\n\nUsage:\n workflows.run --name <workflow> [--args-json '{...}']\n\nExample:\n workflows.run --name github.pr.monitor.notify --args-json '{"repo":"clawdbot/clawdbot","pr":1152}'\n`; return `workflows.run — run a named Lobster workflow\n\nUsage:\n workflows.run --name <workflow> [--args-json '{...}']\n\nExample:\n workflows.run --name github.pr.monitor.notify --args-json '{"repo":"openclaw/openclaw","pr":1152}'\n`;
}, },
async run({ input, args, ctx }) { async run({ input, args, ctx }) {
// Drain input. // Drain input.
+1 -1
View File
@@ -1,7 +1,7 @@
/** /**
* Recipe entrypoints. * Recipe entrypoints.
* *
* Core Lobster intentionally keeps only Clawdbot-first recipes here. * Core Lobster intentionally keeps only OpenClaw-first recipes here.
*/ */
export * from "./github/index.js"; export * from "./github/index.js";
+4 -4
View File
@@ -5,7 +5,7 @@ export const workflowRegistry = {
argsSchema: { argsSchema: {
type: 'object', type: 'object',
properties: { properties: {
repo: { type: 'string', description: 'owner/repo (e.g. clawdbot/clawdbot)' }, repo: { type: 'string', description: 'owner/repo (e.g. openclaw/openclaw)' },
pr: { type: 'number', description: 'Pull request number' }, pr: { type: 'number', description: 'Pull request number' },
key: { type: 'string', description: 'Optional state key override.' }, key: { type: 'string', description: 'Optional state key override.' },
changesOnly: { type: 'boolean', description: 'If true, suppress output when unchanged.' }, changesOnly: { type: 'boolean', description: 'If true, suppress output when unchanged.' },
@@ -15,7 +15,7 @@ export const workflowRegistry = {
}, },
examples: [ examples: [
{ {
args: { repo: 'clawdbot/clawdbot', pr: 1152 }, args: { repo: 'openclaw/openclaw', pr: 1152 },
description: 'Monitor a PR and report when it changes.', description: 'Monitor a PR and report when it changes.',
}, },
], ],
@@ -27,7 +27,7 @@ export const workflowRegistry = {
argsSchema: { argsSchema: {
type: 'object', type: 'object',
properties: { properties: {
repo: { type: 'string', description: 'owner/repo (e.g. clawdbot/clawdbot)' }, repo: { type: 'string', description: 'owner/repo (e.g. openclaw/openclaw)' },
pr: { type: 'number', description: 'Pull request number' }, pr: { type: 'number', description: 'Pull request number' },
key: { type: 'string', description: 'Optional state key override.' }, key: { type: 'string', description: 'Optional state key override.' },
}, },
@@ -35,7 +35,7 @@ export const workflowRegistry = {
}, },
examples: [ examples: [
{ {
args: { repo: 'clawdbot/clawdbot', pr: 1152 }, args: { repo: 'openclaw/openclaw', pr: 1152 },
description: 'Emit "PR updated" message only when changed.', description: 'Emit "PR updated" message only when changed.',
}, },
], ],
+1 -1
View File
@@ -139,7 +139,7 @@ test("email.triage --llm uses llm_task.invoke to draft replies (and can emit dra
bodyLog.push(parsed); bodyLog.push(parsed);
res.writeHead(200, { "content-type": "application/json" }); res.writeHead(200, { "content-type": "application/json" });
// Clawdbot tool router envelope -> llm-task tool envelope // OpenClaw tool router envelope -> llm-task tool envelope
res.end( res.end(
JSON.stringify({ JSON.stringify({
ok: true, ok: true,
+1 -1
View File
@@ -308,7 +308,7 @@ test('llm_task.invoke uses CLAWD_URL (/tools/invoke) without requiring --url/--m
const parsed = JSON.parse(buf || '{}'); const parsed = JSON.parse(buf || '{}');
bodyLog.push(parsed); bodyLog.push(parsed);
// This is the Clawdbot tool router envelope. // This is the OpenClaw tool router envelope.
res.writeHead(200, { 'content-type': 'application/json' }); res.writeHead(200, { 'content-type': 'application/json' });
res.end( res.end(
JSON.stringify({ JSON.stringify({