bot-runner-reuse

bot-runner-reuse is a cursor rule for Cursor from zhangdszq/teamclaw. It costs 0 tokens per session (876 once invoked), scanned A, original, Apache-2.0.

An architecture rule for sharing bot business logic across Telegram, DingTalk, and Feishu integrations. Each bot handles platform communication while common behavior lives in a shared layer.

In plain words
What is it for?
Use it when adding or changing bot behavior: put reusable functions in bot-base.ts and pass each platform’s send-message functions into the shared runner.
Why use it?
It prevents duplicated code and keeps changes to AI calls, personas, conversation history, and message storage consistent across bots.

Cursor rule for Cursor

Written for Cursor: installed under .cursor/.

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/zhangdszq/teamclaw/bot-runner-reuse
Clone the repo
git clone --depth 1 https://github.com/zhangdszq/teamclaw

Made for: Cursor.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for bot-runner-reuse

README.md
[![agentmods](https://agentmods.dev/badge/rules/zhangdszq/teamclaw/bot-runner-reuse.svg)](https://agentmods.dev/rules/zhangdszq/teamclaw/bot-runner-reuse)
Your own site
<a href="https://agentmods.dev/rules/zhangdszq/teamclaw/bot-runner-reuse"><img src="https://agentmods.dev/badge/rules/zhangdszq/teamclaw/bot-runner-reuse.svg" alt="Measured on agentmods" height="20"></a>
Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 876 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00000 $0.00876
Opus 5 $0.00000 $0.00438
Sonnet 5 $0.00000 $0.00175
Haiku 4.5 $0.00000 $0.00088

Measured 6d ago against content hash c3abcbf0e77a, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-06, from the pricing page.

Security

Grade A, and why

bot-runner-reuse scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 6d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.cursor/rules/bot-runner-reuse.mdc · 100 lines

How it starts

The opening of the file, as written. The whole thing — 100 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Bot / Runner 复用架构规范

核心原则

业务逻辑(AI 调用、persona 构建、历史上下文、消息持久化)必须提取到共享层,各 bot 只负责平台 I/O。

共享层位置:src/electron/libs/bot-base.ts


❌ 禁止:在 bot 文件内重复实现

以下函数在 telegram/dingtalk/feishu 三个 bot 里各有一份,不要再复制

// ❌ BAD — 每个 bot 各自有一份 buildQueryEnv
function buildQueryEnv(): Record<string, string | undefined> {
  const settings = loadUserSettings();
  const apiKey = settings.anthropicAuthToken || process.env.ANTHROPIC_API_KEY || "";
  // ... 三处完全相同
}

// ❌ BAD — runClaudeQuery 写死在 telegram-bot.ts 里
async function runClaudeQuery(session, prompt, opts) {
  const env = buildQueryEnv();  // 内嵌逻辑
  // ... 50 行重复逻辑
}

✅ 正确:从 bot-base.ts 导入共享函数

// bot-base.ts — 共享层
export function buildQueryEnv(): Record<string, string | undefined>
export function buildStructuredPersona(opts: BaseBotOptions, extras?: string[]): string
export function buildHistoryContext(history: ConvMessage[], assistantId?: string): string
export async function runClaudeQueryBase(
  opts: BaseBotOptions,
  userText: string,
  sendReply: (text: string) => Promise<void>,  // 平台回调,由各 bot 传入
  sendFile?: (path: string) => Promise<void>,
): Promise<void>
export async function persistReply(assistantId: string, role: string, content: string): Promise<void>

// telegram-bot.ts — 只负责平台 I/O
import { buildQueryEnv, buildStructuredPersona, runClaudeQueryBase } from "./bot-base.js";

bot.on("message", async (ctx) => {
  await runClaudeQueryBase(opts, ctx.message.text, (reply) => ctx.reply(reply));
  //                                                 ↑ Telegram 专属的发送函数
});

✅ Runner 复用规范

多个 assistant 共享同一 runner,通过 assistantId 隔离会话,不要为每个 assistant 新建独立 runner 实例:

// ❌ BAD — 为每个 bot 硬编码 session 前缀
const sessionId = `tg-${chatId}`;   // telegram-bot.ts
const sessionId = `dt-${senderStaffId}`;  // dingtalk-bot.ts

// ✅ GOOD — 统一格式,由 bot-base 生成
export function buildSessionId(platform: BotPlatformType, assistantId: string, userId: string) {
  return `${platform}:${assistantId}:${userId}`;
}

Read the full file on GitHub · 100 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 6d ago First seen · 100 lines · 0 tokens per session scan A c3abcbf0e77a

Subscribe to this mod's changes

bot-runner-reuse is a cursor rule published in the GitHub repository zhangdszq/teamclaw (113 stars, last pushed 5mo ago), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 876 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.