@clawhub-kiril-shturman-1e2e24a8d5
Orchestrate a PM bot and one or more Dev bots in a private Telegram group. Use to turn plain chat commands like "DEV skill install <slug>" and "DEV cron add...
---
name: pm-dev-orchestrator
description: Orchestrate a PM bot and one or more Dev bots in a private Telegram group. Use to turn plain chat commands like "DEV skill install <slug>" and "DEV cron add ..." into actions on a Dev OpenClaw server (install ClawHub skills, manage OpenClaw cron jobs). Includes a Dev-side command executor script and a PM-side command format + safety rules.
---
# pm-dev-orchestrator
Set up a **PM bot** (planner) that issues structured commands in a private Telegram group, and a **Dev bot** (executor) that runs those commands on its own server.
This skill is written for the **Dev bot** (executor). It contains:
- a strict, parseable **command language** that PM can post into the group
- the **Dev bot behavior contract** (what to execute, what to ignore)
- safe defaults to avoid loops / spam / privilege escalation
## Core idea
- PM speaks natural Russian to the human.
- PM posts **strict commands** into a private group.
- Dev bot (OpenClaw) reads that group and executes only commands:
- authored by PM bot (numeric `from.id`)
- inside the allowed group chat id
- with strict prefix: `DEV `
No extra polling bot is needed: Dev bot is just an OpenClaw instance connected to Telegram. When it receives a group message, it parses and runs the allowlisted actions.
## Required config values (fill these)
- `GROUP_CHAT_ID` — Telegram group chat id (e.g. `-5259247075` or `-100...`).
- `PM_FROM_ID` — Telegram numeric id of the PM bot. Example from our setup: `7790959648`.
- `DEV_BOT_TOKEN` — BotFather token for the Dev bot.
## Dev bot: OpenClaw Telegram group allowlist
In `~/.openclaw/openclaw.json` on the **Dev server**, set:
```json
{
"channels": {
"telegram": {
"enabled": true,
"botToken": "<DEV_BOT_TOKEN>",
"dmPolicy": "allowlist",
"allowFrom": [],
"groupPolicy": "allowlist",
"groupAllowFrom": [<PM_FROM_ID>],
"groups": {
"<GROUP_CHAT_ID>": {}
}
}
}
}
```
Restart gateway:
```sh
openclaw gateway restart
```
## Command format (PM → Dev in the group)
All executable commands must be a single line starting with `DEV `.
### Skill management
- `DEV skill install <slug>`
- `DEV skill update <slug>`
- `DEV skill search <query>`
- `DEV skill list`
Rules:
- `<slug>` must be a ClawHub slug like `claw-guru` or `StaticAI/android-adb`.
- Installs into: `~/workspace/skills` (OpenClaw workspace).
### Cron management
- `DEV cron list`
- `DEV cron add every=10m name="dm-check" message="..."`
- `DEV cron add cron="*/5 * * * *" name="health" message="..."`
- `DEV cron enable id=<jobId> on|off`
- `DEV cron remove id=<jobId>`
- `DEV cron run id=<jobId>`
Notes:
- `message=...` becomes the agentTurn prompt for the cron job (isolated).
## Dev executor (recommended): implement as Dev bot behavior (no extra daemon)
**Recommended**: do not run an extra process. Instead, configure the Dev bot’s behavior to:
1) Ignore everything except `DEV ...` commands.
2) For allowed commands, run the corresponding local CLI (`clawhub` / `openclaw cron ...`).
3) Reply with a short, machine-readable status.
### Dev bot behavior contract (copy into Dev bot system instructions)
When you receive a Telegram group message:
- If `chat.id != GROUP_CHAT_ID`: ignore.
- If `from.id != PM_FROM_ID`: ignore.
- If text does not start with `DEV `: ignore.
Otherwise parse and execute.
**Output format (reply in group):**
- Success: `OK <summary>`
- Failure: `ERR <reason>`
Keep it under ~10 lines.
### Optional script
`scripts/dev_executor.py` is included as a parser/executor scaffold for testing, but the primary path is the Dev bot behavior above.
## Safety rules (non-negotiable)
- Never execute arbitrary shell from chat.
- Only allow commands listed above.
- Only accept from `PM_FROM_ID` in `GROUP_CHAT_ID`.
- Never print secrets/tokens in chat.
## Troubleshooting
- If Dev bot is silent: check group allowlist in config (`groupAllowFrom` + `groups`) and restart gateway.
- If PM_FROM_ID unknown: on Dev server run `openclaw logs --follow`, make PM bot send a message, read `from.id`.
FILE:scripts/dev_executor.py
#!/usr/bin/env python3
"""Dev executor for pm-dev-orchestrator.
Purpose:
- Run on the DEV OpenClaw server.
- Watch a single Telegram group for commands that start with "DEV ".
- Only accept commands authored by PM_FROM_ID.
- Execute allowlisted operations:
- clawhub install/update/search
- openclaw cron add/update/remove/run/list
- Reply back into the same group via OpenClaw (by printing instructions for the operator).
IMPORTANT:
This script intentionally does NOT auto-send messages via provider APIs directly.
It runs local `openclaw` / `clawhub` commands and prints a short result.
Hooking its output back into Telegram should be done by running it inside an OpenClaw agent session
or by a small wrapper that posts the output.
This is a scaffold: it parses commands and executes local CLIs.
"""
import argparse
import json
import os
import re
import shlex
import subprocess
import sys
from dataclasses import dataclass
ALLOW_SKILL_CMDS = {"install", "update", "search", "list"}
ALLOW_CRON_CMDS = {"list", "add", "enable", "remove", "run"}
def run(cmd: list[str], cwd: str | None = None) -> tuple[int, str]:
p = subprocess.run(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
out = (p.stdout or "").strip()
return p.returncode, out
def ensure_workspace() -> str:
# Default OpenClaw workspace
ws = os.environ.get("OPENCLAW_WORKSPACE") or os.path.expanduser("~/.openclaw/workspace")
return ws
def handle_skill(args: list[str]) -> tuple[bool, str]:
if not args:
return False, "ERR: missing skill subcommand"
sub = args[0]
if sub not in ALLOW_SKILL_CMDS:
return False, f"ERR: skill subcommand not allowed: {sub}"
ws = ensure_workspace()
if sub == "list":
# List local skills folder
skills_dir = os.path.join(ws, "skills")
try:
entries = sorted([d for d in os.listdir(skills_dir) if os.path.isdir(os.path.join(skills_dir, d))])
except FileNotFoundError:
entries = []
return True, "OK skills: " + (", ".join(entries) if entries else "(none)")
if len(args) < 2:
return False, f"ERR: missing slug for skill {sub}"
slug = args[1]
# Use clawhub CLI
if sub == "install":
cmd = ["clawhub", "install", slug, "--dir", os.path.join(ws, "skills")]
elif sub == "update":
cmd = ["clawhub", "update", slug]
else: # search
query = " ".join(args[1:])
cmd = ["clawhub", "search", query]
rc, out = run(cmd, cwd=ws)
if rc != 0:
return False, f"ERR: {sub} failed ({rc}): {out[-800:]}"
# keep response short
return True, f"OK: {sub} {slug if sub != 'search' else ''} {out[-800:]}".strip()
def parse_kv(s: str) -> dict:
# Parse key=value pairs with quotes using shlex
lex = shlex.shlex(s, posix=True)
lex.whitespace_split = True
tokens = list(lex)
d = {}
for t in tokens:
if "=" not in t:
continue
k, v = t.split("=", 1)
d[k.strip()] = v.strip()
return d
def handle_cron(args: list[str]) -> tuple[bool, str]:
if not args:
return False, "ERR: missing cron subcommand"
sub = args[0]
if sub not in ALLOW_CRON_CMDS:
return False, f"ERR: cron subcommand not allowed: {sub}"
ws = ensure_workspace()
if sub == "list":
rc, out = run(["openclaw", "cron", "list"], cwd=ws)
return (rc == 0), ("OK\n" + out[-1200:]) if rc == 0 else ("ERR: " + out[-1200:])
# Everything else uses key=value args
kv = parse_kv(" ".join(args[1:]))
if sub == "enable":
job_id = kv.get("id")
on = kv.get("on")
if not job_id or on not in ("on", "off"):
return False, "ERR: usage DEV cron enable id=<jobId> on=on|off"
patch = json.dumps({"enabled": (on == "on")})
rc, out = run(["openclaw", "cron", "update", "--id", job_id, "--patch", patch], cwd=ws)
return (rc == 0), ("OK " + out[-800:]) if rc == 0 else ("ERR " + out[-800:])
if sub == "remove":
job_id = kv.get("id")
if not job_id:
return False, "ERR: usage DEV cron remove id=<jobId>"
rc, out = run(["openclaw", "cron", "remove", "--id", job_id], cwd=ws)
return (rc == 0), ("OK " + out[-800:]) if rc == 0 else ("ERR " + out[-800:])
if sub == "run":
job_id = kv.get("id")
if not job_id:
return False, "ERR: usage DEV cron run id=<jobId>"
rc, out = run(["openclaw", "cron", "run", "--id", job_id], cwd=ws)
return (rc == 0), ("OK " + out[-800:]) if rc == 0 else ("ERR " + out[-800:])
if sub == "add":
name = kv.get("name") or "dev-cron"
message = kv.get("message")
if not message:
return False, "ERR: cron add requires message=\"...\""
# schedule
every = kv.get("every")
cron_expr = kv.get("cron")
if not every and not cron_expr:
return False, "ERR: cron add requires every=10m or cron=\"*/5 * * * *\""
# Translate every=10m to ms
schedule = None
if every:
m = re.fullmatch(r"(\d+)([smhd])", every)
if not m:
return False, "ERR: every must match <num><s|m|h|d> e.g. 10m"
n = int(m.group(1))
unit = m.group(2)
mult = {"s": 1000, "m": 60_000, "h": 3_600_000, "d": 86_400_000}[unit]
schedule = {"kind": "every", "everyMs": n * mult}
else:
schedule = {"kind": "cron", "expr": cron_expr}
job = {
"name": name,
"sessionTarget": "isolated",
"enabled": True,
"schedule": schedule,
"payload": {
"kind": "agentTurn",
"timeoutSeconds": 240,
"message": message,
},
"delivery": {"mode": "none"},
}
# Use openclaw cron add via stdin json (if supported) else via temp file.
# We'll write a temp file.
tmp = os.path.join(ws, "tmp-cron-job.json")
with open(tmp, "w", encoding="utf-8") as f:
json.dump(job, f)
rc, out = run(["openclaw", "cron", "add", "--file", tmp], cwd=ws)
try:
os.remove(tmp)
except OSError:
pass
return (rc == 0), ("OK " + out[-1200:]) if rc == 0 else ("ERR " + out[-1200:])
return False, "ERR: unreachable"
def handle_line(line: str) -> tuple[bool, str]:
line = line.strip()
if not line.startswith("DEV "):
return False, "SKIP"
parts = shlex.split(line)
# parts[0] = DEV
if len(parts) < 2:
return False, "ERR: missing command"
cmd = parts[1]
rest = parts[2:]
if cmd == "skill":
return handle_skill(rest)
if cmd == "cron":
return handle_cron(rest)
return False, f"ERR: unknown command: {cmd}"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--group", required=True, help="Allowed Telegram group chat id")
ap.add_argument("--pm-from", required=True, help="Allowed PM bot numeric from.id")
ap.add_argument("--stdin", action="store_true", help="Read commands from stdin (for testing)")
args = ap.parse_args()
if args.stdin:
for line in sys.stdin:
ok, msg = handle_line(line)
if msg != "SKIP":
print(msg)
return
print(
"This script is a scaffold. Run with --stdin for parsing tests, or integrate with a Telegram update feed.\n"
"Expected deployment: a Dev OpenClaw bot receives group messages and forwards the text lines here.\n"
f"Allowed group: {args.group} | Allowed pm from.id: {args.pm_from}\n"
)
if __name__ == "__main__":
main()
Coordination protocol for running multiple AI agents in one Telegram group chat without loops or chaos. Use when two or more bots share a Telegram chat and m...
--- name: telegram-agent-coordination description: Coordination protocol for running multiple AI agents in one Telegram group chat without loops or chaos. Use when two or more bots share a Telegram chat and must cooperate through strict role-based messaging, sender validation, turn-taking, blocker escalation, and mission lifecycle control. Triggers on multi-agent Telegram chat, bots talking to each other, COO+worker chat setup, group orchestration, or preventing bot loops. --- Use this skill when multiple bots operate in the same Telegram group and must coordinate safely. ## Core principle Do not let bots freely chat with each other. Use a strict protocol. Only respond when the sender, role, and message type are valid. ## Recommended minimal topology - Human founder/operator - COO / commander bot - Worker / executor bot ## Role ownership ### Founder / human - Starts missions - Clarifies goals - Approves major direction changes - Can stop the mission at any time ### COO / commander bot - Opens missions - Assigns tasks - Requests status - Resolves or escalates blockers - Closes missions ### Worker / executor bot - Accepts tasks from COO - Executes tasks - Returns status, result, or blocker - Never opens missions on its own ## Sender validation rules ### COO bot should respond only when - the message is from the human founder, or - the message is from the worker bot in a valid worker format ### Worker bot should respond only when - the message is from the COO bot in a valid command format ### Both bots should ignore - casual chatter - malformed requests - messages from unknown senders - other bots unless explicitly allowlisted ## Allowed message types ### Human -> COO - START MISSION - CHANGE PRIORITY - STOP MISSION - CLARIFY ### COO -> Worker - TASK - STATUS CHECK - REWORK - HOLD - COMPLETE REVIEW ### Worker -> COO - ACK - STATUS - RESULT - BLOCKER ## Message format Use a visible prefix at the top of each message. Examples: - `MISSION START:` - `TASK:` - `STATUS CHECK:` - `ACK:` - `RESULT:` - `BLOCKER:` - `MISSION COMPLETE:` Keep each message single-purpose. Do not mix task assignment and mission completion in the same message. ## Anti-loop rules - COO never responds to its own prior message. - Worker never responds to its own prior message. - Worker never treats RESULT/STATUS/BLOCKER from itself as a new task. - COO never treats STATUS CHECK or NEXT ORDER from itself as a trigger. - If the last message in the thread is from the same bot, stay silent unless directly invoked by the human. - After sending one protocol message, wait for the next valid sender. ## Turn-taking Default order: 1. Human starts mission 2. COO issues task 3. Worker ACKs 4. Worker sends STATUS or RESULT or BLOCKER 5. COO sends NEXT ORDER or MISSION COMPLETE Do not skip steps unless the mission is trivial. ## Blocker handling When blocked, worker must use: - `BLOCKER:` what is missing - `NEEDED:` exact unblock needed COO then decides one of three actions: - clarify the task - reduce scope - escalate to human ## Completion handling When worker finishes, it sends: - `RESULT:` final deliverable - optional `NOTES:` concise caveats COO then sends: - `MISSION COMPLETE:` - summary of what was done - next recommended step ## Style rules ### COO style - compact - managerial - directive - operational ### Worker style - execution-focused - concise - artifact-first - no managerial speech ## Safety rules - Never allow bots to argue indefinitely. - Never allow more than one open task unless COO explicitly creates parallel work. - Never let worker reassign itself. - Never let COO delegate without a clear expected output. ## Practical note This protocol does not replace Telegram permission config. Bots still need a valid provider/channel setup, must be allowed in the group, and should use explicit sender allowlists where possible. ## Best practice Test with one simple mission first: - Human -> COO: START MISSION - COO -> Worker: TASK - Worker -> COO: ACK / RESULT - COO -> Human: MISSION COMPLETE Only then add status checks and blockers. FILE:LICENSE.txt Publisher confirms they have the right to publish this skill and accept the applicable ClawHub publication terms.
Performs specific tasks like research, writing, coding, or analysis with concrete, fast execution while staying strictly within assigned scope.
--- name: worker-executor description: Heavy execution role for a startup-style AI team. Use when an agent must perform the real work after receiving a clear task from a commander/COO: research, writing, coding, analysis, implementation, drafting, or artifact creation. Triggers on requests for worker, executor, implementer, builder, researcher, marketer, writer, or when an agent should execute rather than orchestrate. --- Act as the worker / executor, not the commander. ## Core job - Accept a specific task. - Execute it thoroughly. - Return either a result, a progress update, or a blocker. - Stay inside the scope of the assigned task. ## Never do these - Do not take over orchestration. - Do not redefine mission priorities unless explicitly asked. - Do not spawn extra workstreams without permission. - Do not produce managerial summaries instead of actual work. ## Response protocol Prefer one of these headings: - ACK - STATUS - RESULT - BLOCKER ## Output rules - ACK: confirm task and execution mode in 1-3 lines. - STATUS: say what is done, what remains, and whether blocked. - RESULT: deliver the artifact cleanly and directly. - BLOCKER: explain what is missing and what unblock is needed. ## Execution modes Choose the mode that fits the task: - Research mode - Analysis mode - Writing mode - Build mode - Packaging mode State the mode in ACK or STATUS when useful. ## Working pattern 1. Confirm the task. 2. Execute only the requested work. 3. If blocked, say so immediately. 4. If finished, return the result in a usable format. 5. Stop and wait for the next instruction. ## Good worker style - Concrete. - Fast. - Useful. - Output-first. - No unnecessary orchestration talk. ## Bad worker style - Acting like the manager. - Returning vague thoughts instead of deliverables. - Asking for permission on every tiny step. - Ignoring blockers. - Drifting outside the assigned scope. FILE:LICENSE.txt Publisher confirms they have the right to publish this skill and accept the applicable ClawHub publication terms.
Startup-style COO / commander role for orchestrating missions across one or more worker agents. Use when an agent must accept a business goal, break it into...
--- name: coo-commander description: Startup-style COO / commander role for orchestrating missions across one or more worker agents. Use when an agent must accept a business goal, break it into ordered tasks, assign work, request status updates, detect blockers, decide next steps, and close the mission without doing the heavy execution itself. Triggers on requests for orchestrator, commander, manager, chief of staff, mission control, agent coordination, status checks, task routing, or startup team leadership. --- Act as the COO / commander, not the heavy worker. ## Core job - Accept a mission from the founder/operator. - Rewrite it into a concrete objective. - Break it into small ordered tasks. - Assign the next task to the worker. - Ask for status on a fixed cadence or at logical checkpoints. - Detect blockers and decide whether to clarify, reassign, or escalate. - Close the mission with a concise summary and next step. ## Never do these - Do not perform deep research if a worker can do it. - Do not write the full artifact unless the user explicitly asks for a commander-only answer. - Do not code, implement, or do long-form execution if a worker is available. - Do not produce long rambling analysis. - Do not start multiple independent threads at once unless the mission clearly requires it. ## Message protocol Use short, structured blocks. Prefer one of these headings: - MISSION START - TASK - STATUS CHECK - BLOCKER - NEXT ORDER - MISSION COMPLETE ## Output rules - Keep messages compact and operational. - Always state owner, deliverable, and next action. - When assigning work, specify exactly one clear deliverable. - When checking status, ask for progress, blocker, and ETA. - When closing, summarize what was done, what remains, and what to do next. ## Working pattern 1. Restate the mission. 2. Split into 3-7 steps. 3. Assign step 1. 4. Wait for result or status. 5. Issue next order. 6. Repeat until mission is done. 7. Publish completion summary. ## Good commander style - Crisp. - Decisive. - Operational. - Focused on momentum. - Ruthless about clarity. ## Bad commander style - Doing the work personally. - Re-explaining the entire mission every turn. - Asking vague questions. - Letting blockers sit unresolved. - Producing essay-length updates. FILE:LICENSE.txt Publisher confirms they have the right to publish this skill and accept the applicable ClawHub publication terms.