diff --git a/DEVLOG.md b/DEVLOG.md
index 153d610..2eada5f 100644
--- a/DEVLOG.md
+++ b/DEVLOG.md
@@ -1,10 +1,35 @@
# OpenClaw Manager — 开发日志
-> 最后更新:2026-03-01
-> 当前版本:v0.9.0
+> 最后更新:2026-03-17
+> 当前版本:v0.9.4
---
+## v0.9.4 更新日志(2026-03-17)
+
+### New Features
+
+- **Skills & Tools 自动配置**:创建 Agent / Sub-Agent 时自动加载默认 Skills 和 Tool Groups
+ - 默认 Skills:`memory-continuity`, `agent-workflow`, `execution-agent-dispatch`, `session-logs`
+ - 默认 Tool Groups:`group:fs`, `group:runtime`, `group:memory`, `sessions_spawn`, `subagents`
+ - 创建表单新增可折叠的 Skills & Tools 选择面板,支持 checkbox 多选
+ - 提供「仅默认」「全选」「清空」快捷按钮
+ - 不展开 / 不修改则自动使用默认预设,开箱即用
+- 支持的可选 Skills:browser-use, github, gh-issues, coding-agent, execution-agent-planner, discord, weather, summarize, healthcheck
+- 四个创建端点(Telegram Agent/Sub、Discord Agent/Sub)均支持 `skills` + `toolGroups` 字段
+
+### Backend
+
+- 新增 `applySkillsTools()` 服务端辅助函数,统一处理 skills/tools 的默认值回退逻辑
+- `POST /api/agents/bot`、`POST /api/agents/discord`、`POST /api/agents/discord-sub`、`POST /api/agents` 均已适配
+
+### UI
+
+- Skills & Tools Picker:深色风格 checkbox 网格,嵌入创建表单底部
+- 新增专用 CSS 样式(`.skills-picker`、`.sp-grid`、`.sp-item`、`.sp-actions`)
+- 新增 i18n 字符串支持中英文标签
+
+---
## v0.9.0 更新日志(2026-03-01)
diff --git a/README.md b/README.md
index 7d8bbc1..403e345 100644
--- a/README.md
+++ b/README.md
@@ -156,7 +156,7 @@ That is why OCM should be thought of as a **control panel for an existing OpenCl
## Features by area
-- **Agent Management** — Add main agents and sub-agents through a guided setup flow. View all agents in a tree structure with model selection, workspace browsing, and inline configuration.
+- **Agent Management** — Add main agents and sub-agents through a guided setup flow. View all agents in a tree structure with model selection, workspace browsing, and inline configuration. New agents automatically get default Skills and Tool Groups, or you can customize them via the built-in Skills & Tools picker.
- **Usage Statistics** — Real token usage data parsed directly from OpenClaw session files. Breakdown by model, agent, and day with a visual chart.
- **Model & Auth** — Configure models from your registered provider list. Follow built-in guides for provider authentication setup.
- **Built-in CLI** — Available from any page (top-right **Terminal** + bottom dock). Run OpenClaw commands with **real-time streaming output**, **Tab completion**, built-in presets, and your own saved favorites.
@@ -166,6 +166,7 @@ That is why OCM should be thought of as a **control panel for an existing OpenCl
## What's New (v0.9.x)
+- **Skills & Tools auto-config (v0.9.4)**: new agents/sub-agents automatically get default Skills (memory-continuity, agent-workflow, execution-agent-dispatch, session-logs) and Tool Groups (fs, runtime, memory, sessions_spawn, subagents). A collapsible Skills & Tools picker in the creation form lets you customize per agent.
- **Discord support (v0.9.x)**: add agent/sub-agent flows for Discord (main agent binds channel; sub-agent binds thread).
- **README screenshots gallery**: screenshots grouped into a collapsible section so the homepage stays shorter.
- **Built-in CLI terminal**: run OpenClaw commands from any page with streaming output, presets, favorites, and Tab completion.
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 28bc2ff..6da0cc1 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -2,6 +2,11 @@
This is a user-facing summary derived from `DEVLOG.md`.
+## v0.9.4
+- **Skills & Tools auto-config**: New agents/sub-agents now automatically get default Skills (memory-continuity, agent-workflow, execution-agent-dispatch, session-logs) and Tool Groups (fs, runtime, memory, sessions_spawn, subagents).
+- Agent creation forms include a collapsible Skills & Tools picker with checkbox multi-select and quick-action buttons (Default / All / None).
+- All 4 creation endpoints (Telegram/Discord × Agent/Sub-Agent) support `skills` and `toolGroups` fields.
+
## v0.9.0
- Agents: Telegram + Discord support in Add Agent / Add Sub-Agent wizard (main agent binds channel; sub-agent binds thread).
- UI: top-center OCM version badge; improved Telegram/Discord setup guides.
diff --git a/docs/USAGE_GUIDE.en.md b/docs/USAGE_GUIDE.en.md
index ef0d8d8..cdb1039 100644
--- a/docs/USAGE_GUIDE.en.md
+++ b/docs/USAGE_GUIDE.en.md
@@ -138,8 +138,9 @@ Click `+ Add Agent` and fill:
- workspace path (recommended: separate folder per agent)
- model (dropdown is sourced from `openclaw models list`)
- the BotFather token
+- **Skills & Tools** (optional): expand the collapsible picker at the bottom to customize. By default, new agents get: `memory-continuity`, `agent-workflow`, `execution-agent-dispatch`, `session-logs` as Skills, and `group:fs`, `group:runtime`, `group:memory`, `sessions_spawn`, `subagents` as Tool Groups. Use the quick-action buttons (Default / All / None) to adjust.
-OCM writes the agent + Telegram account/binding into `openclaw.json`.
+OCM writes the agent + Telegram account/binding + skills + tool groups into `openclaw.json`.
---
@@ -176,6 +177,7 @@ Send a message in the new group. In logs you should see something like:
- paste the Group ID
- set workspace (recommended: its own folder)
- choose model
+- **Skills & Tools** (optional): same picker as Add Agent — defaults are pre-selected, expand to customize
**Step 4 — Allowlist (optional but recommended)**
diff --git a/docs/USAGE_GUIDE.zh-CN.md b/docs/USAGE_GUIDE.zh-CN.md
index b19588a..c1a024b 100644
--- a/docs/USAGE_GUIDE.zh-CN.md
+++ b/docs/USAGE_GUIDE.zh-CN.md
@@ -123,8 +123,9 @@ bash start.sh
- workspace 路径(建议独立目录)
- 选择模型(下拉来自 `openclaw models list`,更不容易选错)
- 填入刚拿到的 bot token
+- **Skills & Tools**(可选):展开表单底部的折叠面板可自定义。默认预设:Skills 包含 `memory-continuity`、`agent-workflow`、`execution-agent-dispatch`、`session-logs`;Tool Groups 包含 `group:fs`、`group:runtime`、`group:memory`、`sessions_spawn`、`subagents`。提供「仅默认 / 全选 / 清空」快捷按钮。
-保存后,OCM 会把这颗主 Agent 写进 `openclaw.json`,并把 bot token 绑定到对应 `accountId`。
+保存后,OCM 会把主 Agent + skills + tools 写进 `openclaw.json`,并把 bot token 绑定到对应 `accountId`。
---
@@ -159,6 +160,7 @@ openclaw gateway logs --follow
- 填 Group ID
- workspace(建议单独目录)
- 选择模型
+- **Skills & Tools**(可选):和 Add Agent 相同的选择器,默认预设已勾选,展开可自定义
#### Step 4:写 allowlist(推荐)
如果你启用了 Telegram 的 allowlist(例如 `channels.telegram.allowFrom`),
diff --git a/openclaw-manager.js b/openclaw-manager.js
index d17ceef..457f240 100644
--- a/openclaw-manager.js
+++ b/openclaw-manager.js
@@ -24,7 +24,7 @@ const SCRIPT_DIR = __dirname;
const MANAGER_CONFIG = path.join(SCRIPT_DIR, 'manager-config.json');
let PORT = 3333;
let HOST = '0.0.0.0';
-const APP_VERSION = '0.9.3';
+const APP_VERSION = '0.9.4';
// --port 参数
const portIdx = process.argv.indexOf('--port');
if (portIdx !== -1 && process.argv[portIdx + 1]) PORT = parseInt(process.argv[portIdx + 1]) || 3333;
@@ -63,6 +63,17 @@ function refreshPaths() {
CONFIG_PATH = path.join(OPENCLAW_DIR, 'openclaw.json');
}
+// ── Default Skills & Tool Groups for new agents ─────────────
+const DEFAULT_SKILLS = ['memory-continuity', 'agent-workflow', 'execution-agent-dispatch', 'session-logs'];
+const DEFAULT_TOOL_GROUPS = ['group:fs', 'group:runtime', 'group:memory', 'sessions_spawn', 'subagents'];
+
+function applySkillsTools(agentEntry, skills, toolGroups) {
+ const s = (Array.isArray(skills) && skills.length > 0) ? skills : DEFAULT_SKILLS;
+ const tg = (Array.isArray(toolGroups) && toolGroups.length > 0) ? toolGroups : DEFAULT_TOOL_GROUPS;
+ agentEntry.skills = s;
+ agentEntry.tools = { alsoAllow: tg };
+}
+
// ── 已知模型列表 ──────────────────────────────────────────────
const KNOWN_MODELS = [
{ id: '__default__', label: '使用全局默认模型' },
@@ -461,7 +472,7 @@ async function handleApi(req, res, urlObj, body) {
// POST /api/agents/bot — create agent with its own bot token
if (method === 'POST' && pathname === '/api/agents/bot') {
- const { botToken, agentId, name, model, workspace, purpose, personality } = body;
+ const { botToken, agentId, name, model, workspace, purpose, personality, skills, toolGroups } = body;
if (!botToken || !botToken.trim()) {
res.writeHead(400); res.end(JSON.stringify({ error: 'Bot Token is required' })); return;
}
@@ -507,6 +518,7 @@ async function handleApi(req, res, urlObj, body) {
const wsAlias = `~/.openclaw/workspaces/${workspace}`;
const agentEntry = { id: agentId, name: name || agentId, workspace: wsAlias };
if (model && model !== '__default__') agentEntry.model = { primary: model };
+ applySkillsTools(agentEntry, skills, toolGroups);
cfg.agents.list.push(agentEntry);
// Add binding
if (!cfg.bindings) cfg.bindings = [];
@@ -540,7 +552,7 @@ async function handleApi(req, res, urlObj, body) {
// POST /api/agents/discord — create top-level Discord agent (single bot, channel binding)
if (method === 'POST' && pathname === '/api/agents/discord') {
- const { agentId, name, workspaceFolder, model, purpose, personality, guildId, channelId } = body;
+ const { agentId, name, workspaceFolder, model, purpose, personality, guildId, channelId, skills, toolGroups } = body;
if (!agentId || !/^[a-zA-Z0-9_-]+$/.test(agentId)) {
res.writeHead(400); res.end(JSON.stringify({ error: 'Agent ID must contain only alphanumeric characters, underscores, or dashes' })); return;
}
@@ -566,6 +578,7 @@ async function handleApi(req, res, urlObj, body) {
const wsPath = path.join(OPENCLAW_DIR, 'workspaces', folder);
const agentEntry = { id: agentId, name: name || agentId, workspace: wsAlias };
if (model && model !== '__default__') agentEntry.model = { primary: model };
+ applySkillsTools(agentEntry, skills, toolGroups);
cfg.agents.list.push(agentEntry);
if (!cfg.bindings) cfg.bindings = [];
@@ -609,7 +622,7 @@ async function handleApi(req, res, urlObj, body) {
// POST /api/agents/discord-sub — create Discord sub-agent (thread-only binding, grouping under parentAgentId)
if (method === 'POST' && pathname === '/api/agents/discord-sub') {
- const { agentId, displayName, workspaceFolder, model, purpose, personality, initialMemory, parentAgentId, guildId, threadId } = body;
+ const { agentId, displayName, workspaceFolder, model, purpose, personality, initialMemory, parentAgentId, guildId, threadId, skills, toolGroups } = body;
if (!agentId || !/^[a-zA-Z0-9_-]+$/.test(agentId)) {
res.writeHead(400); res.end(JSON.stringify({ error: 'Agent ID must contain only alphanumeric characters, underscores, or dashes' })); return;
}
@@ -635,6 +648,7 @@ async function handleApi(req, res, urlObj, body) {
const wsPath = path.join(OPENCLAW_DIR, 'workspaces', folder);
const agentEntry = { id: agentId, name: displayName || agentId, workspace: wsAlias, parentAgentId: String(parentAgentId).trim() };
if (model && model !== '__default__') agentEntry.model = { primary: model };
+ applySkillsTools(agentEntry, skills, toolGroups);
cfg.agents.list.push(agentEntry);
if (!cfg.bindings) cfg.bindings = [];
@@ -679,7 +693,7 @@ async function handleApi(req, res, urlObj, body) {
// POST /api/agents — create sub-agent (shares parent bot)
if (method === 'POST' && pathname === '/api/agents') {
- const { agentId, displayName, groupId, workspaceFolder, model, purpose, personality, initialMemory, parentAgentId, telegramUserId } = body;
+ const { agentId, displayName, groupId, workspaceFolder, model, purpose, personality, initialMemory, parentAgentId, telegramUserId, skills, toolGroups } = body;
if (!agentId || !/^[a-zA-Z0-9_-]+$/.test(agentId)) {
res.writeHead(400); res.end(JSON.stringify({ error: 'Agent ID must contain only alphanumeric characters, underscores, or dashes' })); return;
}
@@ -708,6 +722,7 @@ async function handleApi(req, res, urlObj, body) {
const wsAlias= `~/.openclaw/workspaces/${folder}`;
const agentEntry = { id: agentId, name: displayName || agentId, workspace: wsAlias, parentAgentId: String(parentAgentId).trim() };
if (model && model !== '__default__') agentEntry.model = { primary: model };
+ applySkillsTools(agentEntry, skills, toolGroups);
cfg.agents.list.push(agentEntry);
// Binding uses parent's accountId
const parentAccountId = parentBinding.match.accountId;
@@ -1726,6 +1741,19 @@ header { background:var(--surface); border-bottom:1px solid var(--border); paddi
.lang-toggle { background:var(--border); border:none; color:var(--muted); border-radius:6px; padding:5px 10px; font-size:12px; cursor:pointer; }
.lang-toggle:hover { background:#3a3f5c; color:var(--text); }
+/* skills/tools picker */
+.skills-picker { background:var(--bg); border:1px solid var(--border); border-radius:10px; padding:12px 14px; margin-top:4px; }
+.skills-picker summary { font-size:13px; font-weight:600; cursor:pointer; color:var(--text); user-select:none; }
+.skills-picker summary:hover { color:var(--accent); }
+.skills-picker .sp-grid { display:grid; grid-template-columns:1fr 1fr; gap:4px 16px; margin-top:8px; }
+.skills-picker label.sp-item { display:flex; align-items:center; gap:6px; font-size:12.5px; color:var(--muted); cursor:pointer; padding:3px 0; }
+.skills-picker label.sp-item:hover { color:var(--text); }
+.skills-picker label.sp-item input[type=checkbox] { accent-color:var(--accent); width:14px; height:14px; }
+.skills-picker .sp-actions { display:flex; gap:8px; margin-top:8px; padding-top:8px; border-top:1px solid var(--border); }
+.skills-picker .sp-actions button { font-size:11px; padding:3px 10px; border-radius:6px; border:1px solid var(--border); background:var(--surface); color:var(--muted); cursor:pointer; }
+.skills-picker .sp-actions button:hover { color:var(--text); border-color:var(--accent); }
+.sp-section-title { font-size:11px; font-weight:700; color:var(--accent); text-transform:uppercase; letter-spacing:.5px; margin:8px 0 4px; grid-column:1/-1; }
+
/* centered version badge */
.top-version{ position:absolute; left:50%; transform:translateX(-50%); font-size:12px; font-weight:800; letter-spacing:.3px; color:var(--text); background:rgba(108,99,255,.18); border:1px solid rgba(108,99,255,.45); padding:4px 12px; border-radius:999px; box-shadow:0 6px 18px rgba(0,0,0,.25); }
.ver-old{ display:none; }
@@ -2564,6 +2592,9 @@ const I18N = {
'wiz.soul':'性格关键词','wiz.soulHint':'(逗号分隔,选填)','wiz.soulPh':'幽默、直接、有条理...',
'wiz.soulTip':'留空则使用默认成长型提示词(推荐)',
'wiz.memory':'初始记忆','wiz.memoryHint':'(MEMORY.md,选填)','wiz.memoryPh':'例如:群组主要用中文交流。用户偏好简洁回复。',
+ 'wiz.skillsTools':'Skills & Tools 配置','wiz.skillsHint':'不选择则使用默认预设(推荐)',
+ 'wiz.skillsSection':'Skills(能力)','wiz.toolsSection':'Tool Groups(权限)',
+ 'wiz.spSelectDefault':'仅默认','wiz.spSelectAll':'全选','wiz.spSelectNone':'清空',
'wiz.preview':'即将创建:','wiz.group':'群组','wiz.modelLabel':'模型','wiz.globalDefault':'全局默认',
'wiz.soulYes':'含性格关键词','wiz.soulDefault':'默认成长型提示词(推荐)',
'wiz.autoBackup':'自动备份当前 openclaw.json ✓',
@@ -2984,6 +3015,78 @@ function showAddForm(type) {
applyLang();
}
+// ── Skills / Tools picker helper ──────────────────────────
+const AVAILABLE_SKILLS = [
+ { id:'memory-continuity', label:'Memory Continuity', isDefault:true },
+ { id:'agent-workflow', label:'Agent Workflow', isDefault:true },
+ { id:'execution-agent-dispatch', label:'Execution Dispatch', isDefault:true },
+ { id:'session-logs', label:'Session Logs', isDefault:true },
+ { id:'browser-use', label:'Browser Use', isDefault:false },
+ { id:'github', label:'GitHub', isDefault:false },
+ { id:'gh-issues', label:'GitHub Issues', isDefault:false },
+ { id:'coding-agent', label:'Coding Agent', isDefault:false },
+ { id:'execution-agent-planner', label:'Execution Planner', isDefault:false },
+ { id:'discord', label:'Discord', isDefault:false },
+ { id:'weather', label:'Weather', isDefault:false },
+ { id:'summarize', label:'Summarize', isDefault:false },
+ { id:'healthcheck', label:'Healthcheck', isDefault:false },
+];
+const AVAILABLE_TOOL_GROUPS = [
+ { id:'group:fs', label:'Filesystem (group:fs)', isDefault:true },
+ { id:'group:runtime', label:'Runtime (group:runtime)', isDefault:true },
+ { id:'group:memory', label:'Memory (group:memory)', isDefault:true },
+ { id:'sessions_spawn', label:'Sessions Spawn', isDefault:true },
+ { id:'subagents', label:'Subagents', isDefault:true },
+];
+
+function buildSkillsToolsPicker(prefix) {
+ let html = '' + t('wiz.skillsTools') + ' ' + t('wiz.skillsHint') + '
';
+ html += '