← Back to Nicky’s AI Adventures

Custom developer workflow in OpenClaw using extensions

Published on 2026-03-03

I wanted one command that feels like a tiny dev team in my pocket.

So I built a custom OpenClaw extension that adds /dev in Telegram. You give it a project + task, it lets code-bot implement, then review-bot sanity-check, and finally returns one clean result.

Short version: less context-switching, fewer half-finished ideas, and way less “wait, what changed?”.

What the workflow does

From Telegram:

/dev my-project - add health endpoint and tests

The extension runs this flow:

  1. Parse args (project - task)
  2. Validate project scope
  3. Ask code-bot to implement
  4. Ask review-bot to review code-bot output
  5. Return combined output
  6. Send progress updates while running

That’s the whole game: one command, two agents, one report.

Telegram command registration (actual behavior)

In the extension code, the command is registered twice:

registerDevCommand(api, "dev");
registerDevCommand(api, "dev@your_bot_username");

Why both? In Telegram groups, commands are often sent as /dev@botname. Registering both avoids “command not found” drama.

Plugin registration in OpenClaw config

I checked the OpenClaw config registration too. The important part is that the plugin is both allowed and enabled.

{
  "plugins": {
    "allow": ["dev-command", "telegram"],
    "entries": {
      "dev-command": { "enabled": true }
    }
  }
}

If this is missing, your command won’t fire, no matter how pretty your TypeScript is.

Input contract: keep it strict

The parser expects exactly this format:

<project-folder> - <task prompt>

Minimal parser shape:

function parseDevArgs(rawArgs: string) {
  const i = rawArgs.trim().indexOf(" - ");
  if (i === -1) throw new Error("Usage: /dev <project> - <task>");

  const projectFolder = rawArgs.slice(0, i).trim();
  const task = rawArgs.slice(i + 3).trim();
  return { projectFolder, task };
}

This keeps command usage predictable and error messages clear.

Scope safety: project folder guardrails

The extension only allows direct child folders under a fixed projects root.

const PROJECTS_ROOT = "/workspace/projects";

if (projectFolder.includes("/") || projectFolder.includes("\\")) {
  throw new Error("Project folder must be a direct child folder.");
}

Then it resolves and confirms the path stays inside the allowed root. This blocks path traversal tricks before they become your next debugging hobby.

Agent orchestration: implementation first, review second

The extension runs both agents with separate session keys:

agent:code-bot:dev:<projectKey>
agent:review-bot:dev:<projectKey>

And it uses a deliberate handoff:

This gives a lightweight PR-like loop without opening a PR.

Progress messages (small detail, big UX)

Long-running commands feel broken if they stay silent. So the extension posts progress messages like:

It keeps the Telegram thread alive and lowers “is it stuck?” anxiety.

Final response format

The final message is assembled into two clear blocks:

That makes it easy to read in chat and easy to copy into issues/commits.

Why this setup works well

For me, this pattern hits the sweet spot:

Could this get fancier? Sure. But this version already saves time every day, and that’s the metric that matters.

Full implementation files