From 8699b2355dacf44929e6c73b8d15c36125424961 Mon Sep 17 00:00:00 2001 From: Tao Date: Wed, 25 Feb 2026 21:27:52 +1000 Subject: [PATCH] feat: update core manager and startup scripts --- openclaw-manager.js | 606 +++++++++++++++++++++----------------------- start.bat | 100 ++++---- start.sh | 111 ++++---- 3 files changed, 398 insertions(+), 419 deletions(-) diff --git a/openclaw-manager.js b/openclaw-manager.js index 12c7545..1249413 100644 --- a/openclaw-manager.js +++ b/openclaw-manager.js @@ -1,6 +1,6 @@ #!/usr/bin/env node // ================================================================ -// OpenClaw Manager v0.5.2 +// OpenClaw Manager v0.6.0 // 跨平台本地管理工具 (Windows / macOS / Linux) // // 用法: @@ -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.5.2'; +const APP_VERSION = '0.6.0'; // --port 参数 const portIdx = process.argv.indexOf('--port'); if (portIdx !== -1 && process.argv[portIdx + 1]) PORT = parseInt(process.argv[portIdx + 1]) || 3333; @@ -353,6 +353,40 @@ async function handleApi(req, res, urlObj, body) { return; } + // POST /api/agents/main — create or update main agent (set Bot Token) + if (method === 'POST' && pathname === '/api/agents/main') { + const { botToken, name, model } = body; + if (!botToken || !botToken.trim()) { + res.writeHead(400); res.end(JSON.stringify({ error: 'Bot Token is required' })); return; + } + const cfg = await readConfig(); + // Set bot token + if (!cfg.channels) cfg.channels = {}; + if (!cfg.channels.telegram) cfg.channels.telegram = {}; + cfg.channels.telegram.botToken = botToken.trim(); + cfg.channels.telegram.enabled = true; + // Ensure main agent exists + if (!cfg.agents) cfg.agents = { defaults: {}, list: [] }; + if (!cfg.agents.list) cfg.agents.list = []; + let mainAgent = cfg.agents.list.find(a => a.id === 'main'); + if (!mainAgent) { + mainAgent = { id: 'main' }; + cfg.agents.list.push(mainAgent); + } + if (name) mainAgent.name = name.trim(); + if (model) mainAgent.model = { primary: model }; + // Ensure main catch-all binding exists + if (!cfg.bindings) cfg.bindings = []; + const hasMainBinding = cfg.bindings.some(b => b.agentId === 'main' && !b.match?.peer); + if (!hasMainBinding) { + cfg.bindings.push({ agentId: 'main', match: { channel: 'telegram', accountId: 'default' } }); + } + const bakPath = await writeConfig(cfg, 'create'); + res.writeHead(200); + res.end(JSON.stringify({ ok: true, configBackup: bakPath })); + return; + } + // POST /api/agents if (method === 'POST' && pathname === '/api/agents') { const { agentId, displayName, groupId, workspaceFolder, model, purpose, personality, initialMemory } = body; @@ -1207,27 +1241,6 @@ const MAIN_HTML_CSS = String.raw`*, *::before, *::after { box-sizing: border-box } body { background:var(--bg); color:var(--text); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; min-height:100vh; } -/* ── Landing Page ── */ -.landing { position:fixed; inset:0; background:var(--bg); z-index:999; display:flex; align-items:center; justify-content:center; flex-direction:column; padding:30px; } -.landing-logo { font-size:38px; margin-bottom:8px; } -.landing-title { font-size:26px; font-weight:700; color:var(--accent); margin-bottom:6px; } -.landing-sub { font-size:14px; color:var(--muted); margin-bottom:36px; } -.landing-lang { display:flex; gap:8px; margin-bottom:36px; } -.lang-btn { background:var(--surface); border:1px solid var(--border); color:var(--muted); border-radius:20px; padding:5px 16px; font-size:13px; cursor:pointer; transition:all .15s; } -.lang-btn.active { background:rgba(108,99,255,.15); border-color:var(--accent); color:var(--accent); } -.mode-cards { display:grid; grid-template-columns:1fr 1fr; gap:20px; max-width:680px; width:100%; margin-bottom:24px; } -.mode-card { background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:28px 24px; cursor:pointer; transition:all .2s; position:relative; } -.mode-card:hover:not(.disabled) { border-color:var(--accent); background:rgba(108,99,255,.06); transform:translateY(-2px); } -.mode-card.disabled { opacity:.5; cursor:not-allowed; } -.mode-card .mc-icon { font-size:32px; margin-bottom:12px; } -.mode-card .mc-title { font-size:16px; font-weight:700; margin-bottom:8px; } -.mode-card .mc-desc { font-size:13px; color:var(--muted); margin-bottom:14px; line-height:1.6; } -.mode-card .mc-reqs { font-size:12px; color:var(--muted); background:rgba(0,0,0,.2); border-radius:6px; padding:8px 12px; line-height:1.7; } -.mode-card .mc-badge { position:absolute; top:16px; right:16px; font-size:10px; padding:3px 10px; border-radius:20px; } -.mode-card .mc-badge.active { background:rgba(34,197,94,.15); color:var(--success); } -.mode-card .mc-badge.soon { background:rgba(245,158,11,.15); color:var(--warn); } -.enter-btn { background:var(--accent); color:#fff; border:none; border-radius:8px; padding:12px 36px; font-size:15px; font-weight:600; cursor:pointer; transition:all .2s; } -.enter-btn:hover { background:var(--accent-h); transform:translateY(-1px); } /* ── Toolbar ── */ header { background:var(--surface); border-bottom:1px solid var(--border); padding:0 20px; display:flex; align-items:center; gap:12px; height:52px; position:sticky; top:0; z-index:50; } @@ -1260,7 +1273,7 @@ nav { background:var(--surface); border-bottom:1px solid var(--border); display: .tab.active { color:var(--accent); border-bottom-color:var(--accent); } /* ── Main ── */ -main { padding:20px; max-width:980px; margin:0 auto; } +main { padding:20px; max-width:1280px; margin:0 auto; } .panel { display:none; } .panel.active { display:block; } .sec-hdr { display:flex; align-items:center; justify-content:space-between; margin-bottom:16px; } @@ -1282,6 +1295,37 @@ main { padding:20px; max-width:980px; margin:0 auto; } .inline-sel { background:var(--bg); border:1px solid var(--border); color:var(--text); border-radius:6px; padding:5px 8px; font-size:12px; } .inline-sel:focus { outline:none; border-color:var(--accent); } +/* Agents split layout */ +.agents-split { display:flex; gap:20px; height:calc(100vh - 160px); } +.agents-left { flex:0 0 40%; display:flex; flex-direction:column; gap:12px; overflow-y:auto; } +.agents-right { flex:1; overflow-y:auto; padding-right:4px; } +.agents-left-btns { display:flex; gap:8px; } +.agents-left-btns .btn-primary { flex:1; } + +/* Add form */ +.add-form { background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:16px; } +.add-form h3 { font-size:15px; margin-bottom:12px; font-weight:600; } +.add-form .guide-box { background:rgba(108,99,255,.06); border:1px solid rgba(108,99,255,.2); border-radius:8px; padding:12px; margin-bottom:14px; font-size:12px; line-height:1.8; color:var(--muted); } +.add-form .guide-box summary { cursor:pointer; font-weight:600; color:var(--text); font-size:13px; margin-bottom:6px; } +.add-form .guide-box ol { margin:6px 0 0 18px; padding:0; } +.add-form .guide-box li { margin-bottom:4px; } +.add-form .guide-box code { background:rgba(255,255,255,.08); padding:1px 5px; border-radius:3px; font-size:11px; } + +/* Agent tree */ +.agent-tree-root { margin-bottom:16px; } +.agent-tree-root .tree-main { background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:12px 14px; cursor:pointer; } +.agent-tree-root .tree-main:hover { border-color:var(--accent); } +.agent-tree-root .tree-main .tree-title { font-size:14px; font-weight:600; display:flex; align-items:center; gap:8px; } +.agent-tree-root .tree-main .tree-meta { font-size:11px; color:var(--muted); margin-top:4px; } +.tree-children { margin-left:20px; border-left:2px solid var(--border); padding-left:14px; margin-top:6px; } +.tree-child { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:10px 12px; margin-bottom:8px; } +.tree-child:hover { border-color:var(--accent); } +.tree-child .tree-title { font-size:13px; font-weight:600; display:flex; align-items:center; gap:6px; } +.tree-child .tree-meta { font-size:11px; color:var(--muted); margin-top:3px; } +.tree-actions { display:flex; gap:6px; align-items:center; margin-top:8px; flex-wrap:wrap; } +.tree-actions select { font-size:12px; padding:4px 8px; background:var(--bg); border:1px solid var(--border); border-radius:6px; color:var(--text); } +.tree-actions button { font-size:11px; padding:4px 10px; } + /* ── Buttons ── */ button { cursor:pointer; font-size:13px; font-weight:500; border:none; border-radius:6px; padding:6px 13px; transition:all .15s; } .btn-primary { background:var(--accent); color:#fff; } @@ -1414,58 +1458,14 @@ code { font-size:12px; background:rgba(0,0,0,.3); padding:2px 6px; border-radius .fav-manage-cmd { font-size:11px; color:var(--muted); font-family:monospace; max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }`; const MAIN_HTML_BODY = String.raw` - - - -
- -
OpenClaw Manager
-
选择运行模式
- -
- - -
- -
- -
- 可用 -
🤖
-
Sub-agent 模式
-
通过主 Bot 账号绑定多个子 Agent 到不同群组,共用同一个 Token。
-
- 需要:
- • Telegram Bot Token(主账号)
- • 各群组的 Group ID
- • 已安装 OpenClaw -
-
- -
- 敬请期待 -
🌐
-
Multi-agent 模式
-
为每个场景创建完全独立的 Bot,彻底隔离配置与对话历史。
-
- 需要:
- • 每个 Bot 独立的 Token
- • 独立的 OpenClaw 配置目录
- • 独立的服务器进程 -
-
-
- -
- -