diff --git a/README.md b/README.md index e6e63ebb..d4befa81 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ MetaBot 不是只绑定一家 — 三大顶级 AI 编码 Agent 都内置原生 { "name": "vegeta", "engine": "codex", "codex": { "model": "gpt-5.4-codex" } } ``` -Codex 支持通过本机 `codex exec --json` CLI 接入,并使用 `codex exec resume` 续接聊天会话。启动 MetaBot 前,请先执行 `codex login` 或配置好 Codex API key/profile。MetaBot 会把 `/metaskill ...` 等飞书 slash skill 调用转成 Codex 的 `$metaskill ...` 显式技能调用。 +Codex 支持通过本机 `codex exec --json` CLI 接入,并使用 `codex exec resume` 续接聊天会话。启动 MetaBot 前,请先执行 `codex login` 或配置好 Codex API key/profile。MetaBot 会把飞书侧的 `/ ...` 调用统一转成 Codex 的 `$ ...` 显式技能调用(例如安装了 `/metaschedule` 后,Codex 会收到 `$metaschedule ...`)。 ### Codex 迁移:复用 `.claude` 配置 @@ -114,7 +114,7 @@ Claude/Kimi 和 Codex 的发现路径不同。MetaBot 安装、更新和 Skill H | **代码能力** | 完整 Agent SDK(Read/Write/Edit/Bash/MCP) | 完整 | 无 | | **多 Agent** | Agent 总线 + 任务委派 + 运行时创建 | 单会话 | 有,但封闭生态 | | **共享记忆** | MetaMemory 全文搜索 + 自动同步飞书知识库 | 无 | 无 | -| **定时任务** | Cron 调度,跨重启持久化 | 无 | 有 | +| **定时任务** | CC 原生 `CronCreate` / `/loop` 即开即用,可选 `/metaschedule` 跨重启持久化 | 仅原生 `CronCreate` / `/loop` | 有 | | **自主运行** | bypassPermissions / yoloMode,全自动 | 需要人工确认 | 受限于 workflow | | **开源** | MIT,完全可控 | CLI 开源 | 闭源 SaaS | @@ -128,9 +128,9 @@ Claude/Kimi 和 Codex 的发现路径不同。MetaBot 安装、更新和 Skill H └─→ Codex CLI(codex exec --json 子进程) ↕ MetaMemory(共享知识库) - MetaSkill(Agent 工厂,产出 CLAUDE.md + AGENTS.md) - 定时调度器(Cron 任务) + 定时调度(CC 原生 CronCreate / /loop;可选 /metaschedule 持久化) Agent 总线(跨 Bot 通信,引擎无关) + Agent 工厂(可选 /metaskill,按需安装) ``` 引擎层已抽象 —— Kimi 事件流和 Codex JSONL 都被翻译成 Claude 形状的 `SDKMessage`,流式卡片、工具调用追踪、MetaMemory/调度/Agent 总线在三种引擎下表现一致。 @@ -149,7 +149,7 @@ MetaBot 支持 4 种方式与你的 Agent 团队交互: |------|------|------| | **受监督** | IM Bridge | 实时流式卡片展示每一步工具调用。人类看到 Agent 做的一切 | | **自我进化** | MetaMemory | 共享知识库。Agent 写入学到的东西,其他 Agent 检索引用 | -| **Agent 组织** | MetaSkill + 调度器 + Agent 总线 | 一个命令生成完整 Agent 团队。Agent 互相委派任务、创建新 Agent | +| **Agent 组织** | Agent 总线 + CC 原生调度(可选 MetaSkill / MetaSchedule) | Agent 互相委派任务、按需创建新 Agent;用 CC 内置 `CronCreate` / `/loop` 即可定时;要跨重启可装可选 `/metaschedule` | ## Web UI @@ -175,11 +175,12 @@ MetaBot 支持 4 种方式与你的 Agent 团队交互: | 组件 | 一句话说明 | |------|-----------| | **三引擎内核** | 每个 Bot 独立选 Claude Code / Kimi Code / Codex CLI — 完整工具链(Read/Write/Edit/Bash/Glob/Grep/WebSearch/MCP),自主模式运行 | -| **MetaSkill** | Agent 工厂。`/metaskill` 一键生成可迁移的 Agent 团队(`CLAUDE.md` / `AGENTS.md` + skills) | +| **CC 原生调度** | 直接用 Claude Code 内置的 `CronCreate` / `/loop` —— 即开即用,会话内最简单 | | **MetaMemory** | 内嵌 SQLite 知识库,全文搜索,Web UI,变更自动同步到飞书知识库 | | **IM Bridge** | 飞书、Telegram、微信(含手机端)对话任意 Agent,流式卡片 + 工具调用追踪 | | **Agent 总线** | Agent 通过 `mb talk` 互相对话,运行时创建/删除 Bot | -| **定时调度器** | Cron 周期任务 + 一次性延迟任务,跨重启持久化,忙时自动重试 | +| **MetaSchedule(可选)** | 跨重启的服务端定时调度器,Cron + 一次性延迟,HTTP API + `mb schedule` CLI。默认不装,按需 `cp src/skills/metaschedule/SKILL.md` 启用 | +| **MetaSkill(可选)** | Agent 工厂。`/metaskill` 一键生成可迁移的 Agent 团队。默认不装,按需 `cp src/skills/metaskill/` 启用 | | **飞书 Lark CLI** | 200+ 命令覆盖文档、消息、日历、任务等 11 大业务域,19 个 AI Agent Skills | | **Skill Hub** | 跨实例技能共享注册中心。`mb skills` 发布、发现、安装技能,FTS5 全文搜索 | | **Peers 联邦** | 跨实例 Bot 发现和任务路由,`mb talk alice/backend-bot` 自动路由 | @@ -223,22 +224,30 @@ MetaBot 支持 4 种方式与你的 Agent 团队交互: 搜索一下 MetaMemory 里有没有关于 API 设计规范的文档。 ``` -### MetaSkill — Agent 工厂 +### 定时任务(Claude Code 原生) + +直接用 CC 内置的 `CronCreate` 和 `/loop`,会话内即开即用: ``` -/metaskill 给这个 React Native 项目创建一个 agent 团队 —— -我需要一个前端专家、一个后端 API 专家、一个 code reviewer。 +设个每天早上9点的定时任务:搜索 Hacker News 和 TechCrunch 的 AI 新闻, +总结 Top 5,保存到 MetaMemory。 ``` -### 定时任务 - ``` -设一个每天早上9点的定时任务:搜索 Hacker News 和 TechCrunch 的 AI 新闻, -总结 Top 5,保存到 MetaMemory。 +/loop 每隔 5 分钟检查一下 PR #123 的 CI 状态,跑完为止 ``` +> 想跨重启活下来、其他 Bot 也能看到/取消?装可选的 `/metaschedule` skill +> (`cp src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/`), +> 就能用 `mb schedule cron` / HTTP API 提交到 MetaBot 服务端调度器。 + +### MetaSkill — Agent 工厂(可选) + +`/metaskill` 默认不装。先启用:`cp -r src/skills/metaskill ~/.claude/skills/`,然后: + ``` -设一个每周一早上8点的任务:review 上周的 git commit,生成进度报告。 +/metaskill 给这个 React Native 项目创建一个 agent 团队 —— +我需要一个前端专家、一个后端 API 专家、一个 code reviewer。 ``` ### Agent-to-Agent 协作 @@ -260,7 +269,8 @@ MetaBot 支持 4 种方式与你的 Agent 团队交互: ``` ``` -/metaskill 创建一个 "daily-ops" agent,每天早上8点自动运行: +(先 cp src/skills/metaskill 到 ~/.claude/skills/ 以启用 /metaskill) +/metaskill 创建一个 "daily-ops" agent,让它每天早上8点跑: 检查服务健康状态、review 昨晚的错误日志、发一份运维摘要。 ``` @@ -400,11 +410,11 @@ MetaBot 以 `bypassPermissions` 模式运行 Claude Code — 无交互式确认 | `/memory list` | 浏览知识库目录 | | `/memory search 关键词` | 搜索知识库 | | `/sync` | 同步 MetaMemory 到飞书知识库 | -| `/metaskill ...` | 生成 Agent 团队、Agent 或 Skill | +| `/metaskill ...` | 生成 Agent 团队、Agent 或 Skill(可选 skill,默认不装) | | `/help` | 帮助 | > **模型切换**:每个会话可独立设置模型。在模型名后加 `[1m]` 可启用 1M 上下文窗口(仅 Opus 4.7/4.6、Sonnet 4.6 支持),例如 `/model claude-opus-4-7[1m]`。OAuth/Pro-Max 登录用户 SDK 会丢弃 beta flag,`[1m]` 后缀是唯一可靠的 1M 开启方式。 -> **Codex Skill 调用**:飞书里仍然可以发 `/metaskill ...`。当当前会话是 Codex 引擎时,MetaBot 会自动转换为 Codex 识别的 `$metaskill ...`。 +> **Codex Skill 调用**:飞书里发的 `/ ...` 在 Codex 会话下会被 MetaBot 自动改写成 `$ ...`,例如 `$metaschedule ...`。
API 参考 @@ -453,10 +463,13 @@ mm folders # 文件夹树 # Agent 总线 mb bots # 列出所有 Bot mb talk # 与 Bot 对话 -mb schedule list # 列出定时任务 -mb schedule cron '' # 创建周期性任务 mb stats # 费用和使用统计 +# 定时任务 — 推荐 CC 原生:直接在 Claude Code 里用 CronCreate / /loop。 +# 跨重启的服务端调度(mb schedule list / cron / cancel / pause / resume) +# 由可选 /metaschedule skill 提供,按需安装: +# cp src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/ + # 飞书 Lark CLI(飞书 Bot 专属) lark-cli docs +fetch --doc <飞书链接> lark-cli im +messages-send --chat-id oc_xxx --text "Hi" diff --git a/README_EN.md b/README_EN.md index 1fc44578..06073041 100644 --- a/README_EN.md +++ b/README_EN.md @@ -67,7 +67,7 @@ MetaBot isn't locked to one vendor — all three top AI coding agents ship with { "name": "vegeta", "engine": "codex", "codex": { "model": "gpt-5.4-codex" } } ``` -Codex support uses the local `codex exec --json` CLI and resumes chat sessions with `codex exec resume`. Authenticate once with `codex login` (or configure your Codex API key/profile) before starting MetaBot. MetaBot translates Feishu slash-skill invocations like `/metaskill ...` into Codex's explicit `$metaskill ...` skill syntax. +Codex support uses the local `codex exec --json` CLI and resumes chat sessions with `codex exec resume`. Authenticate once with `codex login` (or configure your Codex API key/profile) before starting MetaBot. MetaBot translates Feishu slash-skill invocations like `/ ...` into Codex's explicit `$ ...` skill syntax (e.g. once `/metaschedule` is installed, Codex receives `$metaschedule ...`). ### Codex Migration: Reuse `.claude` Config @@ -114,7 +114,7 @@ Run your frontend bot on Claude and your backend bot on Kimi? Totally fine. The | **Code capabilities** | Full Agent SDK (Read/Write/Edit/Bash/MCP) | Full | None | | **Multi-agent** | Agent Bus + task delegation + runtime creation | Single session | Yes, but closed ecosystem | | **Shared memory** | MetaMemory with FTS + auto-sync to Wiki | None | None | -| **Scheduling** | Cron jobs, persisted across restarts | None | Yes | +| **Scheduling** | CC-native `CronCreate` / `/loop` work out of the box; opt-in `/metaschedule` for cross-restart persistence | Native `CronCreate` / `/loop` only | Yes | | **Autonomous** | bypassPermissions / yoloMode, fully automated | Requires human approval | Limited to workflows | | **Open source** | MIT, fully controllable | CLI is open source | Closed-source SaaS | @@ -128,9 +128,9 @@ Feishu/TG/WeChat → IM Bridge → Engine Router ──┬─→ Claude Code Age └─→ Codex CLI (codex exec --json subprocess) ↕ MetaMemory (shared knowledge) - MetaSkill (agent factory, emits CLAUDE.md + AGENTS.md) - Scheduler (cron tasks) + Scheduling (CC-native CronCreate / /loop; opt-in /metaschedule for persistence) Agent Bus (cross-bot comms, engine-agnostic) + Agent Factory (opt-in /metaskill) ``` The engine layer is abstracted — Kimi's event stream and Codex's JSONL stream are both translated into Claude-shaped `SDKMessage` objects, so streaming cards, tool-call tracking, MetaMemory/Scheduler/Agent Bus behave identically across all three engines. @@ -147,7 +147,7 @@ The engine layer is abstracted — Kimi's event stream and Codex's JSONL stream |--------|-----------|-------------| | **Supervised** | IM Bridge | Real-time streaming cards show every tool call. Humans see everything agents do | | **Self-Improving** | MetaMemory | Shared knowledge store. Agents write what they learn, other agents retrieve it | -| **Agent Organization** | MetaSkill + Scheduler + Agent Bus | One command generates a full agent team. Agents delegate tasks and create new agents | +| **Agent Organization** | Agent Bus + CC-native scheduling (opt-in MetaSkill / MetaSchedule) | Agents delegate tasks and spin up new bots on demand; CC's built-in `CronCreate` / `/loop` cover scheduling, and opt-in `/metaschedule` adds cross-restart persistence | Full-featured browser-based chat interface. Access at `https://your-server/web/` after starting MetaBot. @@ -171,11 +171,12 @@ Full-featured browser-based chat interface. Access at `https://your-server/web/` | Component | Description | |-----------|-------------| | **Triple Engine Kernel** | Each bot independently chooses Claude Code / Kimi Code / Codex CLI — full tool stack (Read/Write/Edit/Bash/Glob/Grep/WebSearch/MCP) in autonomous mode | -| **MetaSkill** | Agent factory. `/metaskill` generates portable agent teams (`CLAUDE.md` / `AGENTS.md` + skills) | +| **CC-Native Scheduling** | Use Claude Code's built-in `CronCreate` and `/loop` directly — zero MetaBot setup, runs in-session | | **MetaMemory** | Embedded SQLite knowledge store with full-text search, Web UI, auto-syncs to Feishu Wiki | | **IM Bridge** | Chat with any agent from Feishu, Telegram, or WeChat (including mobile). Streaming cards + tool call tracking | | **Agent Bus** | Agents talk to each other via `mb talk`. Create/remove bots at runtime | -| **Task Scheduler** | Cron recurring tasks + one-time delays, persisted across restarts, auto-retries when busy | +| **MetaSchedule (opt-in)** | Persistent server-side scheduler — cron + one-shot, survives restarts, exposes HTTP API + `mb schedule` CLI. Not installed by default; enable with `cp src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/` | +| **MetaSkill (opt-in)** | Agent factory. `/metaskill` generates portable agent teams. Not installed by default; enable with `cp -r src/skills/metaskill ~/.claude/skills/` | | **Feishu Lark CLI** | 200+ commands covering docs, messaging, calendar, tasks, and 8 more domains. 19 AI Agent Skills | | **Skill Hub** | Cross-instance skill sharing registry. `mb skills` to publish, discover, and install skills with FTS5 search | | **Peers** | Cross-instance bot discovery and task routing. `mb talk alice/backend-bot` routes automatically | @@ -220,14 +221,9 @@ under /projects/deployment. Search MetaMemory for our API design conventions. ``` -### MetaSkill — Agent Factory +### Scheduling (Claude Code native) -``` -/metaskill Create an agent team for this React Native project — -I need a frontend specialist, a backend API specialist, and a code reviewer. -``` - -### Scheduling +Use CC's built-in `CronCreate` and `/loop` — zero setup, runs inside the session: ``` Schedule a daily task at 9am: search Hacker News and TechCrunch for AI news, @@ -235,8 +231,23 @@ summarize the top 5 stories, and save the summary to MetaMemory. ``` ``` -Set up a weekly Monday 8am task: review last week's git commits, generate -a progress report, and save it to MetaMemory under /reports. +/loop poll PR #123's CI status every 5 minutes until it finishes. +``` + +> Need the schedule to survive MetaBot restarts and be visible to other bots? +> Install the opt-in `/metaschedule` skill +> (`cp src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/`), +> then use `mb schedule cron` / the HTTP API to submit jobs to MetaBot's +> persistent scheduler. + +### MetaSkill — Agent Factory (opt-in) + +`/metaskill` is not installed by default. Enable it first: +`cp -r src/skills/metaskill ~/.claude/skills/`. Then: + +``` +/metaskill Create an agent team for this React Native project — +I need a frontend specialist, a backend API specialist, and a code reviewer. ``` ### Agent-to-Agent @@ -261,6 +272,7 @@ progress against these requirements. ``` ``` +(First copy src/skills/metaskill into ~/.claude/skills/ to enable /metaskill) /metaskill Create a "daily-ops" agent that runs every morning at 8am: checks service health, reviews overnight error logs, and posts a summary. ``` @@ -401,11 +413,11 @@ MetaBot runs Claude Code in `bypassPermissions` mode — no interactive approval | `/memory list` | Browse knowledge tree | | `/memory search ` | Search knowledge base | | `/sync` | Sync MetaMemory to Feishu Wiki | -| `/metaskill ...` | Generate agent teams, agents, or skills | +| `/metaskill ...` | Generate agent teams, agents, or skills (opt-in skill — not installed by default) | | `/help` | Show help | > **Model switching**: Each session can pick its own model. Append `[1m]` to the model name to enable the 1M context window (only Opus 4.7/4.6 and Sonnet 4.6 support it), e.g. `/model claude-opus-4-7[1m]`. OAuth/Pro-Max users must use this suffix — the SDK silently drops beta headers under that auth mode. -> **Codex skills**: In Feishu you can still send `/metaskill ...`. When the session is on Codex, MetaBot converts it to Codex's `$metaskill ...` form. +> **Codex skills**: Slash invocations like `/ ...` are auto-rewritten to Codex's `$ ...` form whenever the active session runs on Codex.
API Reference @@ -454,10 +466,13 @@ mm folders # folder tree # Agent Bus mb bots # list all bots mb talk # talk to a bot -mb schedule list # list scheduled tasks -mb schedule cron '' # recurring task mb stats # cost & usage stats +# Scheduling — prefer Claude Code's native CronCreate / /loop directly in chat. +# The persistent server-side scheduler (`mb schedule list / cron / cancel / +# pause / resume`) is exposed by the opt-in /metaschedule skill. Enable with: +# cp src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/ + # Feishu Lark CLI (Feishu bots only) lark-cli docs +fetch --doc lark-cli im +messages-send --chat-id oc_xxx --text "Hi" diff --git a/bin/mb b/bin/mb index 87918e74..c865851d 100755 --- a/bin/mb +++ b/bin/mb @@ -378,9 +378,11 @@ print(json.dumps({'botName': sys.argv[1], 'source': sys.argv[2]})) SKILLS_DIR="$HOME/.claude/skills" CODEX_SKILLS_DIR="$HOME/.codex/skills" mkdir -p "$SKILLS_DIR" "$CODEX_SKILLS_DIR" - for skill in metaskill metamemory metabot voice phone-call skill-hub; do + # metaskill / metaschedule are opt-in (not in the default list); CC native + # CronCreate / /loop cover ad-hoc scheduling, and the agent-team generator + # is not used by every install. Source still ships in src/skills/*. + for skill in metamemory metabot voice phone-call skill-hub; do case "$skill" in - metaskill) src="$METABOT_SRC/src/skills/metaskill" ;; metamemory) src="$METABOT_SRC/src/memory/skill" ;; metabot) src="$METABOT_SRC/src/skills/metabot" ;; voice) src="$METABOT_SRC/src/skills/voice" ;; @@ -404,6 +406,15 @@ print(json.dumps({'botName': sys.argv[1], 'source': sys.argv[2]})) if [[ -d "$CODEX_SKILLS_DIR/feishu-doc" ]]; then rm -rf "$CODEX_SKILLS_DIR/feishu-doc" fi + # Clean up legacy metaskill — now opt-in. Users who want the agent-team + # generator can copy it back from $METABOT_SRC/src/skills/metaskill/. + if [[ -d "$SKILLS_DIR/metaskill" ]] && [[ "${KEEP_METASKILL:-}" != "1" ]]; then + rm -rf "$SKILLS_DIR/metaskill" + echo " Removed legacy: metaskill (opt-in — set KEEP_METASKILL=1 to keep)" + fi + if [[ -d "$CODEX_SKILLS_DIR/metaskill" ]] && [[ "${KEEP_METASKILL:-}" != "1" ]]; then + rm -rf "$CODEX_SKILLS_DIR/metaskill" + fi # Check if lark-cli skills were previously installed (opt-in via install.sh) has_lark_skills=false @@ -422,7 +433,17 @@ print(json.dumps({'botName': sys.argv[1], 'source': sys.argv[2]})) ws_skills_dir="$work_dir/.claude/skills" ws_codex_skills_dir="$work_dir/.codex/skills" mkdir -p "$ws_skills_dir" "$ws_codex_skills_dir" - for skill in metaskill metamemory metabot voice phone-call skill-hub; do + for skill in metamemory metabot voice phone-call skill-hub; do + if [[ -d "$SKILLS_DIR/$skill" ]]; then + for dst_root in "$ws_skills_dir" "$ws_codex_skills_dir"; do + mkdir -p "$dst_root/$skill" + cp -r "$SKILLS_DIR/$skill/." "$dst_root/$skill/" + done + fi + done + # Mirror opt-in skills (metaskill / metaschedule) to the workspace if + # the user has them installed in ~/.claude/skills/. + for skill in metaskill metaschedule; do if [[ -d "$SKILLS_DIR/$skill" ]]; then for dst_root in "$ws_skills_dir" "$ws_codex_skills_dir"; do mkdir -p "$dst_root/$skill" diff --git a/bin/metabot b/bin/metabot index eefb7a0f..511e70fa 100755 --- a/bin/metabot +++ b/bin/metabot @@ -80,9 +80,11 @@ cmd_update() { mkdir -p "$SKILLS_DIR" "$CODEX_SKILLS_DIR" info "Updating skills..." local src="" - for skill in metaskill metamemory metabot voice skill-hub; do + # metaskill / metaschedule are opt-in (not in the default list); CC native + # CronCreate / /loop already cover ad-hoc scheduling. Sources still ship in + # src/skills/* — users who want them can copy manually. + for skill in metamemory metabot voice skill-hub; do case "$skill" in - metaskill) src="$METABOT_HOME/src/skills/metaskill" ;; metamemory) src="$METABOT_HOME/src/memory/skill" ;; metabot) src="$METABOT_HOME/src/skills/metabot" ;; voice) src="$METABOT_HOME/src/skills/voice" ;; @@ -104,6 +106,14 @@ cmd_update() { if [[ -d "$CODEX_SKILLS_DIR/feishu-doc" ]]; then rm -rf "$CODEX_SKILLS_DIR/feishu-doc" fi + # Clean up legacy metaskill — now opt-in. Override with KEEP_METASKILL=1. + if [[ -d "$SKILLS_DIR/metaskill" ]] && [[ "${KEEP_METASKILL:-}" != "1" ]]; then + rm -rf "$SKILLS_DIR/metaskill" + info "Removed legacy metaskill (opt-in — set KEEP_METASKILL=1 to keep)" + fi + if [[ -d "$CODEX_SKILLS_DIR/metaskill" ]] && [[ "${KEEP_METASKILL:-}" != "1" ]]; then + rm -rf "$CODEX_SKILLS_DIR/metaskill" + fi # Update lark-cli skills only if previously installed (opt-in via install.sh) local has_lark_skills=false @@ -126,7 +136,16 @@ cmd_update() { mkdir -p "$ws_skills_dir" "$ws_codex_skills_dir" # Copy common skills - for skill in metaskill metamemory metabot voice skill-hub; do + for skill in metamemory metabot voice skill-hub; do + if [[ -d "$SKILLS_DIR/$skill" ]]; then + for dst_root in "$ws_skills_dir" "$ws_codex_skills_dir"; do + mkdir -p "$dst_root/$skill" + cp -r "$SKILLS_DIR/$skill/." "$dst_root/$skill/" + done + fi + done + # Mirror opt-in skills (metaskill / metaschedule) only when present. + for skill in metaskill metaschedule; do if [[ -d "$SKILLS_DIR/$skill" ]]; then for dst_root in "$ws_skills_dir" "$ws_codex_skills_dir"; do mkdir -p "$dst_root/$skill" diff --git a/install.ps1 b/install.ps1 index 8475d6a7..085d8397 100644 --- a/install.ps1 +++ b/install.ps1 @@ -584,7 +584,7 @@ New-Item -ItemType Directory -Path $SkillsDir -Force | Out-Null # Sanity check: the bundled skill tree must exist in the checked-out repo. # If it's missing, the user's checkout is stale (predates the skill bundling # commits) — fail with a clear message instead of cryptic Copy-Item errors. -$SkillSentinel = Join-Path $MetabotHome "src\skills\metaskill\SKILL.md" +$SkillSentinel = Join-Path $MetabotHome "src\skills\metabot\SKILL.md" if (-not (Test-Path $SkillSentinel)) { Write-Err "Bundled skill source not found at: $SkillSentinel" Write-Err "Your $MetabotHome checkout appears to be stale or incomplete." @@ -593,15 +593,14 @@ if (-not (Test-Path $SkillSentinel)) { exit 1 } -# Install metaskill -Write-Info "Installing metaskill skill..." -$metaskillDir = Join-Path $SkillsDir "metaskill\flows" -New-Item -ItemType Directory -Path $metaskillDir -Force | Out-Null -Copy-Item (Join-Path $MetabotHome "src\skills\metaskill\SKILL.md") (Join-Path $SkillsDir "metaskill\SKILL.md") -Force -Copy-Item (Join-Path $MetabotHome "src\skills\metaskill\flows\team.md") (Join-Path $SkillsDir "metaskill\flows\team.md") -Force -Copy-Item (Join-Path $MetabotHome "src\skills\metaskill\flows\agent.md") (Join-Path $SkillsDir "metaskill\flows\agent.md") -Force -Copy-Item (Join-Path $MetabotHome "src\skills\metaskill\flows\skill.md") (Join-Path $SkillsDir "metaskill\flows\skill.md") -Force -Write-Success "metaskill skill installed -> $(Join-Path $SkillsDir 'metaskill')" +# Clean up legacy metaskill skill if present — no longer installed by default. +# Users who still want the agent-team generator can copy it back from +# $MetabotHome\src\skills\metaskill\ (the source files remain bundled in the repo). +$LegacyMetaskillDir = Join-Path $SkillsDir "metaskill" +if (Test-Path $LegacyMetaskillDir) { + Remove-Item $LegacyMetaskillDir -Recurse -Force + Write-Info "Removed legacy metaskill skill from $SkillsDir (now opt-in -- see src\skills\metaskill\)" +} # Install metamemory skill Write-Info "Installing metamemory skill..." @@ -666,7 +665,11 @@ if (-not $SkipConfig) { if ($DeployWorkDir) { $SkillsDest = Join-Path $DeployWorkDir ".claude\skills" - $deploySkills = @("metaskill", "metamemory", "metabot", "voice", "skill-hub") + # metaskill (agent-team generator) and metaschedule (persistent server-side + # scheduler) are no longer deployed by default -- copy them from + # $MetabotHome\src\skills\ if needed. CC native CronCreate / /loop already + # cover ad-hoc, session-scoped scheduling. + $deploySkills = @("metamemory", "metabot", "voice", "skill-hub") if ($HasFeishu) { $deploySkills += "feishu-doc" } foreach ($skill in $deploySkills) { diff --git a/install.sh b/install.sh index 35553d72..aef33eda 100755 --- a/install.sh +++ b/install.sh @@ -759,7 +759,7 @@ mkdir -p "$SKILLS_DIR" # Sanity check: bundled skill tree must exist in the checked-out repo. # If it's missing, the user's checkout is stale (predates the skill bundling # commits) — fail with a clear message instead of cryptic cp errors. -SKILL_SENTINEL="$METABOT_HOME/src/skills/metaskill/SKILL.md" +SKILL_SENTINEL="$METABOT_HOME/src/skills/metabot/SKILL.md" if [[ ! -f "$SKILL_SENTINEL" ]]; then error "Bundled skill source not found at: $SKILL_SENTINEL" error "Your $METABOT_HOME checkout appears to be stale or incomplete." @@ -768,14 +768,13 @@ if [[ ! -f "$SKILL_SENTINEL" ]]; then exit 1 fi -# Install metaskill (bundled in src/skills/metaskill/) -info "Installing metaskill skill..." -mkdir -p "$SKILLS_DIR/metaskill/flows" -cp "$METABOT_HOME/src/skills/metaskill/SKILL.md" "$SKILLS_DIR/metaskill/SKILL.md" -cp "$METABOT_HOME/src/skills/metaskill/flows/team.md" "$SKILLS_DIR/metaskill/flows/team.md" -cp "$METABOT_HOME/src/skills/metaskill/flows/agent.md" "$SKILLS_DIR/metaskill/flows/agent.md" -cp "$METABOT_HOME/src/skills/metaskill/flows/skill.md" "$SKILLS_DIR/metaskill/flows/skill.md" -success "metaskill skill installed → $SKILLS_DIR/metaskill" +# Clean up legacy metaskill skill if present — no longer installed by default. +# Users who still want the agent-team generator can copy it back from +# $METABOT_HOME/src/skills/metaskill/ (the source files remain bundled in the repo). +if [[ -d "$SKILLS_DIR/metaskill" ]]; then + rm -rf "$SKILLS_DIR/metaskill" + info "Removed legacy metaskill skill from $SKILLS_DIR (now opt-in — see src/skills/metaskill/)" +fi # Install metamemory skill (bundled in src/memory/skill/) info "Installing metamemory skill..." @@ -894,8 +893,12 @@ fi if [[ -n "${DEPLOY_WORK_DIR:-}" ]]; then SKILLS_DEST="$DEPLOY_WORK_DIR/.claude/skills" - # Copy skills (common + lark-cli skills if Feishu) - DEPLOY_SKILLS="metaskill metamemory metabot voice skill-hub" + # Copy skills (common + lark-cli skills if Feishu). + # metaskill (agent-team generator) and metaschedule (persistent server-side + # scheduler) are no longer installed by default — copy them from + # $METABOT_HOME/src/skills/ if you want them. CC native CronCreate / /loop + # already cover ad-hoc, session-scoped scheduling. + DEPLOY_SKILLS="metamemory metabot voice skill-hub" if [[ "$SETUP_LARK_CLI" == "true" ]]; then for lark_skill in lark-base lark-calendar lark-contact lark-doc lark-drive lark-event lark-im lark-mail lark-minutes lark-openapi-explorer lark-shared lark-sheets lark-skill-maker lark-task lark-vc lark-whiteboard lark-wiki lark-workflow-meeting-summary lark-workflow-standup-report; do [[ -d "$SKILLS_DIR/$lark_skill" ]] && DEPLOY_SKILLS="$DEPLOY_SKILLS $lark_skill" diff --git a/src/api/skills-installer.ts b/src/api/skills-installer.ts index 291b6282..64fcb22b 100644 --- a/src/api/skills-installer.ts +++ b/src/api/skills-installer.ts @@ -5,8 +5,17 @@ import * as url from 'node:url'; import { execFileSync, execSync } from 'node:child_process'; import type { Logger } from '../utils/logger.js'; -/** Skills installed for all platforms. */ -const COMMON_SKILLS = ['metaskill', 'metamemory', 'metabot', 'phone-call', 'skill-hub']; +/** Skills installed for all platforms. + * + * Not in this list (opt-in only): + * - `metaskill` — agent-team generator. Source: src/skills/metaskill/ + * - `metaschedule` — MetaBot's persistent server-side scheduler. + * Source: src/skills/metaschedule/ + * + * Default ad-hoc scheduling is handled by Claude Code's native `CronCreate` + * and `/loop` tools, so the persistent scheduler skill is now opt-in. + */ +const COMMON_SKILLS = ['metamemory', 'metabot', 'phone-call', 'skill-hub']; /** Lark CLI AI Agent skills — installed via `npx skills add larksuite/cli` and * symlinked into ~/.claude/skills/ automatically. We copy them to the bot @@ -146,10 +155,17 @@ function bundledSkillSource(skill: string): string | undefined { const thisFile = url.fileURLToPath(import.meta.url); const thisDir = path.dirname(thisFile); const candidatesBySkill: Record = { + // metaskill / metaschedule are opt-in: not in COMMON_SKILLS, but bundled + // here so users who copy them into `~/.claude/skills/` get the source + // resolved correctly if they later install a bot with installSkills:true. metaskill: [ path.join(thisDir, '..', 'skills', 'metaskill'), path.join(thisDir, '..', '..', 'src', 'skills', 'metaskill'), ], + metaschedule: [ + path.join(thisDir, '..', 'skills', 'metaschedule'), + path.join(thisDir, '..', '..', 'src', 'skills', 'metaschedule'), + ], metamemory: [ path.join(thisDir, '..', 'memory', 'skill'), path.join(thisDir, '..', '..', 'src', 'memory', 'skill'), diff --git a/src/engines/claude/executor.ts b/src/engines/claude/executor.ts index 25011f80..5d413d3e 100644 --- a/src/engines/claude/executor.ts +++ b/src/engines/claude/executor.ts @@ -134,8 +134,8 @@ function createSpawnFn(explicitApiKey?: string): (options: SpawnOptions) => Spaw // Default-enable Claude Code auto-memory so Claude can write project // patterns / preferences / decisions to ~/.claude/projects//memory/ - // across sessions — the user-facing memory system the bot's skills / - // metaskill flows rely on. Users can disable by setting + // across sessions — the user-facing memory system the bot's skills + // rely on. Users can disable by setting // CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 in MetaBot's parent env. // Pinning to '0' here makes the feature immune to upstream default // changes; the user shouldn't need to keep a magic line in .env. diff --git a/src/skills/metabot/SKILL.md b/src/skills/metabot/SKILL.md index 1fb319cf..bb3595f1 100644 --- a/src/skills/metabot/SKILL.md +++ b/src/skills/metabot/SKILL.md @@ -1,11 +1,11 @@ --- name: metabot -description: "MetaBot HTTP API for agent collaboration: talk to other bots, schedule tasks, manage bots and peers. Use when the user wants to delegate work to another bot, schedule tasks, create/remove bots, or check peer status." +description: "MetaBot HTTP API for agent collaboration: talk to other bots, manage bots and peers, share skills, run voice calls. Use when the user wants to delegate work to another bot, create/remove bots, publish skills, or check peer status." --- ## MetaBot API -MetaBot exposes an HTTP API for agent-to-agent collaboration, task scheduling, and bot management. +MetaBot exposes an HTTP API for agent-to-agent collaboration, bot management, and skill sharing. Your bot name and chat ID are provided in the system prompt (look for "You are running as bot ... in chat ..."). Use those values for `botName` and `chatId` in the commands below. @@ -25,16 +25,6 @@ mb talk alice/backend-bot # Talk to a specific peer's bot # Peers mb peers # List peers and their status -# Scheduling (one-time) -mb schedule list # List all scheduled tasks -mb schedule add # Schedule a one-time future task -mb schedule cancel # Cancel a scheduled task - -# Scheduling (recurring / cron) -mb schedule cron '' # Create recurring task -mb schedule pause # Pause a recurring task -mb schedule resume # Resume a paused recurring task - # Voice Call (RTC — real-time Doubao AI) mb voice call [prompt] # Start voice call, wait for transcript mb voice transcript # Get call transcript @@ -57,6 +47,17 @@ mb metrics # Prometheus metrics mb health # Health check ``` +### Scheduling (use Claude Code native tools first) + +For ad-hoc scheduling within this session, prefer Claude Code's native scheduling tools instead of MetaBot's HTTP scheduler: + +- **`CronCreate`** — fire a prompt at a cron-matched time (recurring or one-shot). Sessions-only by default; pass `durable: true` to persist across restarts. Ideal for "remind me in 10 minutes" and "every weekday at 9 am" inside one conversation. +- **`/loop [interval] `** — turn a task into a self-paced loop with fixed or dynamic intervals (e.g. `/loop 5m check the deploy`). Best for "poll until done" workflows. + +These run inside the current Claude session, with no MetaBot server involvement, and stop when the session ends. + +If you need **persistent server-side scheduling** that survives Claude restarts and lives in MetaBot's scheduler (so other bots / your future self can list and cancel them via `mb`), invoke the optional `/metaschedule` skill — it documents the `mb schedule` / `/api/schedule` surface. The skill ships with the MetaBot source tree but is **not installed by default**; copy `src/skills/metaschedule/` into `~/.claude/skills/` (or the bot's `.claude/skills/`) to enable it. + ### Cross-Instance Agent Talk When you talk to a bot that isn't on the local instance, MetaBot automatically routes the request to the peer instance that hosts that bot. No special syntax is needed — just use `mb talk ` as usual. @@ -67,7 +68,7 @@ Use `mb bots` to see all available bots including those on peer instances (they ### API Reference (for complex operations) -For operations not covered by `mb` (creating bots, updating tasks, sendCards option), use the API directly. +For operations not covered by `mb` (creating bots, sendCards option), use the API directly. Auth header: `-H "Authorization: Bearer $METABOT_API_SECRET"` Base URL: !`echo http://localhost:${METABOT_API_PORT:-9100}` @@ -102,39 +103,6 @@ curl -s -X DELETE http://localhost:${METABOT_API_PORT:-9100}/api/bots/ \ -H "Authorization: Bearer $METABOT_API_SECRET" ``` -**Update scheduled task:** -```bash -curl -s -X PATCH http://localhost:${METABOT_API_PORT:-9100}/api/schedule/ \ - -H "Authorization: Bearer $METABOT_API_SECRET" \ - -H "Content-Type: application/json" \ - -d '{"prompt":"updated prompt","delaySeconds":7200}' -``` - -**Create recurring scheduled task (cron):** -```bash -curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule \ - -H "Authorization: Bearer $METABOT_API_SECRET" \ - -H "Content-Type: application/json" \ - -d '{"botName":"","chatId":"","prompt":"","cronExpr":"0 8 * * 1-5","timezone":"Asia/Shanghai","label":"Daily report"}' -``` -Cron format: `minute hour day month weekday` (5 fields). Examples: `0 8 * * *` = daily 8am, `0 8 * * 1-5` = weekdays 8am, `*/30 * * * *` = every 30 min. Default timezone: Asia/Shanghai. - -**Pause/resume recurring task:** -```bash -curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule//pause \ - -H "Authorization: Bearer $METABOT_API_SECRET" -curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule//resume \ - -H "Authorization: Bearer $METABOT_API_SECRET" -``` - -**Update recurring task:** -```bash -curl -s -X PATCH http://localhost:${METABOT_API_PORT:-9100}/api/schedule/ \ - -H "Authorization: Bearer $METABOT_API_SECRET" \ - -H "Content-Type: application/json" \ - -d '{"cronExpr":"0 9 * * *","prompt":"Updated prompt","timezone":"Asia/Shanghai"}' -``` - **List peers:** ```bash curl -s http://localhost:${METABOT_API_PORT:-9100}/api/peers \ diff --git a/src/skills/metaschedule/SKILL.md b/src/skills/metaschedule/SKILL.md new file mode 100644 index 00000000..84e1dbdb --- /dev/null +++ b/src/skills/metaschedule/SKILL.md @@ -0,0 +1,102 @@ +--- +name: metaschedule +description: "MetaBot's persistent server-side scheduler (cron + one-shot). Optional skill — not installed by default. Use when the user wants tasks that survive Claude session restarts, are visible to other bots, or need to run in MetaBot's PM2 process rather than this Claude session." +--- + +## MetaBot Scheduler + +> Persistent server-side scheduler. Use this when: +> - The schedule needs to outlive the current Claude session. +> - Another bot or operator may need to list, pause, or cancel it. +> - You want it to run inside MetaBot's PM2 process (not Claude's). +> +> For ad-hoc, session-scoped scheduling, prefer the Claude Code native tools `CronCreate` and `/loop` instead — they're faster, in-process, and need no MetaBot server call. + +### Quick Commands (mb shortcut) + +The `mb` shell function is pre-installed and handles auth automatically. + +```bash +# One-time delayed tasks +mb schedule list # List all scheduled tasks +mb schedule add # Schedule a one-time future task +mb schedule cancel # Cancel a scheduled task + +# Recurring (cron) +mb schedule cron '' # Create recurring task +mb schedule pause # Pause a recurring task +mb schedule resume # Resume a paused recurring task +``` + +Cron format: `minute hour day month weekday` (5 fields). Examples: +- `0 8 * * *` → daily at 8am +- `0 8 * * 1-5` → weekdays at 8am +- `*/30 * * * *`→ every 30 minutes +Default timezone: Asia/Shanghai. + +### API Reference + +Auth header: `-H "Authorization: Bearer $METABOT_API_SECRET"` +Base URL: !`echo http://localhost:${METABOT_API_PORT:-9100}` + +**Create one-time scheduled task:** +```bash +curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule \ + -H "Authorization: Bearer $METABOT_API_SECRET" \ + -H "Content-Type: application/json" \ + -d '{"botName":"","chatId":"","prompt":"","delaySeconds":3600,"label":"Reminder"}' +``` + +**Create recurring task (cron):** +```bash +curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule \ + -H "Authorization: Bearer $METABOT_API_SECRET" \ + -H "Content-Type: application/json" \ + -d '{"botName":"","chatId":"","prompt":"","cronExpr":"0 8 * * 1-5","timezone":"Asia/Shanghai","label":"Daily report"}' +``` + +**Update task (prompt, delay, or cron):** +```bash +curl -s -X PATCH http://localhost:${METABOT_API_PORT:-9100}/api/schedule/ \ + -H "Authorization: Bearer $METABOT_API_SECRET" \ + -H "Content-Type: application/json" \ + -d '{"prompt":"updated prompt","delaySeconds":7200}' + +curl -s -X PATCH http://localhost:${METABOT_API_PORT:-9100}/api/schedule/ \ + -H "Authorization: Bearer $METABOT_API_SECRET" \ + -H "Content-Type: application/json" \ + -d '{"cronExpr":"0 9 * * *","prompt":"Updated prompt","timezone":"Asia/Shanghai"}' +``` + +**Pause / resume recurring task:** +```bash +curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule//pause \ + -H "Authorization: Bearer $METABOT_API_SECRET" +curl -s -X POST http://localhost:${METABOT_API_PORT:-9100}/api/schedule//resume \ + -H "Authorization: Bearer $METABOT_API_SECRET" +``` + +**Cancel:** +```bash +curl -s -X DELETE http://localhost:${METABOT_API_PORT:-9100}/api/schedule/ \ + -H "Authorization: Bearer $METABOT_API_SECRET" +``` + +### Installation (opt-in) + +This skill is not installed by default. To enable it for one bot, copy it into the bot's working directory: + +```bash +mkdir -p /.claude/skills/metaschedule +cp $METABOT_HOME/src/skills/metaschedule/SKILL.md /.claude/skills/metaschedule/SKILL.md +# Mirror for Codex bots: +mkdir -p /.codex/skills/metaschedule +cp $METABOT_HOME/src/skills/metaschedule/SKILL.md /.codex/skills/metaschedule/SKILL.md +``` + +Or install globally so every Claude session picks it up: + +```bash +mkdir -p ~/.claude/skills/metaschedule +cp $METABOT_HOME/src/skills/metaschedule/SKILL.md ~/.claude/skills/metaschedule/SKILL.md +``` diff --git a/src/workspace/CLAUDE.md b/src/workspace/CLAUDE.md index 5c52e26b..718ba669 100644 --- a/src/workspace/CLAUDE.md +++ b/src/workspace/CLAUDE.md @@ -4,15 +4,6 @@ This workspace is managed by **MetaBot** — an AI assistant accessible via Feis ## Available Skills -### /metaskill — AI Agent Team Generator -Create AI agent teams, individual agents, or custom skills for any project. - -``` -/metaskill ios app → generates a portable agent team -/metaskill a security agent → creates a single agent -/metaskill a deploy skill → creates a custom skill -``` - ### /metamemory — Shared Knowledge Store Read and write persistent memory documents across sessions. Use the `mm` shell shortcut for quick operations: @@ -25,18 +16,37 @@ mm folders # Browse folder tree For full API (create with tags, update, delete), use the `/metamemory` skill. -### /metabot — Agent Bus, Scheduling & Bot Management +### /metabot — Agent Bus & Bot Management Use the `mb` shell shortcut for quick operations: ```bash -mb bots # List all bots -mb task # Delegate task -mb schedule list # List scheduled tasks -mb schedule add # Schedule a task +mb bots # List all bots (local + peer) +mb talk # Delegate task to a bot +mb peers # List peers and their status +mb skills # Shared skills (Skill Hub) mb health # Health check ``` -For full API (create bots, update tasks, sendCards), use the `/metabot` skill. +For full API (create bots, sendCards, Skill Hub publish/install), use the `/metabot` skill. + +### Scheduling (Claude Code native) + +Prefer Claude Code's built-in scheduling tools for ad-hoc, session-scoped tasks — no MetaBot server hop, runs in-process, stops when the session ends: + +- **`CronCreate`** — fire a prompt on a cron schedule (recurring or one-shot). Pass `durable: true` to persist across restarts. Example use cases: "remind me at 3pm", "every weekday at 9am summarize my inbox". +- **`/loop [interval] `** — turn any task into a self-paced loop. Examples: `/loop 5m check the deploy`, `/loop check every PR` (dynamic mode — you pace yourself). + +For **persistent server-side scheduling** that outlives the Claude session, is visible to other bots, and lives in MetaBot's PM2 process, install the optional `/metaschedule` skill (not installed by default). Copy `/src/skills/metaschedule/SKILL.md` into `~/.claude/skills/metaschedule/` (or the bot's `.claude/skills/`). + +### /metaskill — AI Agent Team Generator (optional) + +Not installed by default. Generates portable agent teams, individual agents, or custom skills (`CLAUDE.md` / `AGENTS.md` + SKILL files). Enable it by copying `/src/skills/metaskill/` into `~/.claude/skills/` (or the bot's `.claude/skills/`). Once installed: + +``` +/metaskill ios app → generates a portable agent team +/metaskill a security agent → creates a single agent +/metaskill a deploy skill → creates a custom skill +``` ### Feishu / Lark CLI (Feishu bots only) diff --git a/tests/skills-installer.test.ts b/tests/skills-installer.test.ts index fbd1ac9d..3286613b 100644 --- a/tests/skills-installer.test.ts +++ b/tests/skills-installer.test.ts @@ -43,9 +43,17 @@ describe('skills installer', () => { installSkillsToWorkDir(workDir, logger); - expect(readFileSync(join(workDir, '.claude/skills/metaskill/SKILL.md'), 'utf-8')).toContain('metaskill'); - expect(readFileSync(join(workDir, '.codex/skills/metaskill/SKILL.md'), 'utf-8')).toContain('metaskill'); + // `metabot` is in the default COMMON_SKILLS list, so its bundled SKILL.md + // must land in both Claude and Codex project directories. + expect(readFileSync(join(workDir, '.claude/skills/metabot/SKILL.md'), 'utf-8')).toContain('metabot'); + expect(readFileSync(join(workDir, '.codex/skills/metabot/SKILL.md'), 'utf-8')).toContain('metabot'); expect(readFileSync(join(workDir, 'AGENTS.md'), 'utf-8')).toContain('MetaBot Workspace'); + + // `metaskill` and `metaschedule` are opt-in: not deployed unless the + // user has placed them in ~/.claude/skills/. Confirm they did not slip + // into the default install. + expect(() => readFileSync(join(workDir, '.claude/skills/metaskill/SKILL.md'), 'utf-8')).toThrow(); + expect(() => readFileSync(join(workDir, '.claude/skills/metaschedule/SKILL.md'), 'utf-8')).toThrow(); } finally { if (priorHome === undefined) delete process.env.HOME; else process.env.HOME = priorHome;