clawport-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BRANDING.md +5 -4
- package/CLAUDE.md +16 -2
- package/LICENSE +21 -0
- package/README.md +36 -5
- package/SETUP.md +18 -2
- package/app/docs/page.tsx +8 -0
- package/app/page.tsx +1 -1
- package/bin/clawport.mjs +149 -0
- package/components/docs/BestPracticesSection.tsx +612 -0
- package/components/docs/GettingStartedSection.tsx +21 -1
- package/components/docs/TroubleshootingSection.tsx +65 -0
- package/lib/agents.json +6 -6
- package/package.json +8 -4
- package/scripts/setup.mjs +5 -1
- /package/components/{ManorMap.tsx → OrgMap.tsx} +0 -0
package/BRANDING.md
CHANGED
|
@@ -42,8 +42,8 @@ TypeScript interfaces, function names, component names, and variable names. Thes
|
|
|
42
42
|
| `setPortalSubtitle` (setter) | Same as `setPortalName` | |
|
|
43
43
|
| `setPortalEmoji` (setter) | Same as `setPortalName` | |
|
|
44
44
|
| `setPortalIcon` (setter) | Same as `setPortalName` | |
|
|
45
|
-
| `OrgMap` (component) | `components/
|
|
46
|
-
| `OrgMapProps` (interface) | `components/
|
|
45
|
+
| `OrgMap` (component) | `components/OrgMap.tsx`, `app/page.tsx`, `docs/COMPONENTS.md` | React Flow org chart component. |
|
|
46
|
+
| `OrgMapProps` (interface) | `components/OrgMap.tsx` | Props type for OrgMap. |
|
|
47
47
|
| `HomePage` (component) | `app/page.tsx` | Home page component. |
|
|
48
48
|
| `handleIconUpload` (function) | `app/settings/page.tsx` | Icon upload handler. |
|
|
49
49
|
| `iconInputRef` (ref) | `app/settings/page.tsx` | File input ref. |
|
|
@@ -77,8 +77,9 @@ Changing these breaks existing users' saved data. Requires a migration function
|
|
|
77
77
|
|
|
78
78
|
| Location | Current Value |
|
|
79
79
|
|----------|---------------|
|
|
80
|
-
| `package.json` `name` | `clawport` |
|
|
81
|
-
| `package-lock.json` `name` | `clawport` |
|
|
80
|
+
| `package.json` `name` | `clawport-ui` |
|
|
81
|
+
| `package-lock.json` `name` | `clawport-ui` |
|
|
82
|
+
| npm package | [`clawport-ui`](https://www.npmjs.com/package/clawport-ui) |
|
|
82
83
|
| Git clone URLs in docs | `https://github.com/openclaw/clawport.git` |
|
|
83
84
|
|
|
84
85
|
## 7. Workspace Paths
|
package/CLAUDE.md
CHANGED
|
@@ -10,6 +10,19 @@ npx tsc --noEmit # Type-check (expect 0 errors)
|
|
|
10
10
|
npx next build # Production build
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
### CLI (global install)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g clawport-ui
|
|
17
|
+
clawport setup # Auto-detect config, write .env.local into package dir
|
|
18
|
+
clawport dev # Start dev server
|
|
19
|
+
clawport start # Build + start production server
|
|
20
|
+
clawport status # Check gateway reachability + env config
|
|
21
|
+
clawport help # Show usage
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The CLI resolves its own package root via `import.meta.url`, so all commands work regardless of the user's current working directory. Entry point: `bin/clawport.mjs`.
|
|
25
|
+
|
|
13
26
|
## Project Overview
|
|
14
27
|
|
|
15
28
|
ClawPort is a Next.js 16 dashboard for managing OpenClaw AI agents. It provides an org chart (Org Map), direct agent chat with multimodal support, cron monitoring, and memory browsing. All AI calls route through the OpenClaw gateway -- no separate API keys needed.
|
|
@@ -187,11 +200,12 @@ Used by: `lib/memory.ts`, `lib/cron-runs.ts`, `lib/kanban/chat-store.ts`, `lib/c
|
|
|
187
200
|
| `AgentAvatar.tsx` | Agent emoji/image avatar with optional background |
|
|
188
201
|
| `DynamicFavicon.tsx` | Updates favicon based on portal emoji/icon settings |
|
|
189
202
|
|
|
190
|
-
### Scripts
|
|
203
|
+
### Scripts & CLI
|
|
191
204
|
|
|
192
205
|
| File | Purpose |
|
|
193
206
|
|------|---------|
|
|
194
|
-
| `
|
|
207
|
+
| `bin/clawport.mjs` | CLI entry point -- `clawport dev`, `clawport setup`, `clawport status`, etc. Resolves package root via `import.meta.url` |
|
|
208
|
+
| `scripts/setup.mjs` | `npm run setup` / `clawport setup` -- auto-detects WORKSPACE_PATH, OPENCLAW_BIN, gateway token; writes `.env.local`. Accepts `--cwd=<path>` flag for CLI usage |
|
|
195
209
|
|
|
196
210
|
## Testing
|
|
197
211
|
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 John Rice
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -14,14 +14,24 @@ ClawPort is an open-source dashboard for managing, monitoring, and talking direc
|
|
|
14
14
|
- [OpenClaw](https://openclaw.ai) installed and running
|
|
15
15
|
- OpenClaw gateway started (`openclaw gateway run`)
|
|
16
16
|
|
|
17
|
-
### Quick Start
|
|
17
|
+
### Quick Start (npm)
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
cd clawport
|
|
20
|
+
# Install globally
|
|
21
|
+
npm install -g clawport-ui
|
|
23
22
|
|
|
24
|
-
#
|
|
23
|
+
# Auto-detect your OpenClaw config
|
|
24
|
+
clawport setup
|
|
25
|
+
|
|
26
|
+
# Start the dev server
|
|
27
|
+
clawport dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Quick Start (from source)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git clone https://github.com/JohnRiceML/clawport-ui.git
|
|
34
|
+
cd clawport-ui
|
|
25
35
|
npm install
|
|
26
36
|
|
|
27
37
|
# Auto-detect your OpenClaw config and write .env.local
|
|
@@ -257,6 +267,27 @@ npx next build # Production build
|
|
|
257
267
|
|
|
258
268
|
---
|
|
259
269
|
|
|
270
|
+
## npm
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
npm install -g clawport-ui
|
|
274
|
+
clawport help
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Published as [`clawport-ui`](https://www.npmjs.com/package/clawport-ui) on npm.
|
|
278
|
+
|
|
279
|
+
### CLI Commands
|
|
280
|
+
|
|
281
|
+
| Command | Description |
|
|
282
|
+
|---------|-------------|
|
|
283
|
+
| `clawport dev` | Start the development server |
|
|
284
|
+
| `clawport start` | Build and start the production server |
|
|
285
|
+
| `clawport setup` | Auto-detect OpenClaw config and write `.env.local` |
|
|
286
|
+
| `clawport status` | Check gateway reachability and current config |
|
|
287
|
+
| `clawport help` | Show usage |
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
260
291
|
## License
|
|
261
292
|
|
|
262
293
|
MIT
|
package/SETUP.md
CHANGED
|
@@ -15,8 +15,12 @@ This guide walks you through getting ClawPort running against your own OpenClaw
|
|
|
15
15
|
## 1. Install ClawPort
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
# Install globally from npm
|
|
19
|
+
npm install -g clawport-ui
|
|
20
|
+
|
|
21
|
+
# Or clone the repo
|
|
22
|
+
git clone https://github.com/JohnRiceML/clawport-ui.git
|
|
23
|
+
cd clawport-ui
|
|
20
24
|
npm install
|
|
21
25
|
```
|
|
22
26
|
|
|
@@ -27,6 +31,10 @@ npm install
|
|
|
27
31
|
The fastest way is the auto-setup script:
|
|
28
32
|
|
|
29
33
|
```bash
|
|
34
|
+
# If installed globally via npm
|
|
35
|
+
clawport setup
|
|
36
|
+
|
|
37
|
+
# Or if running from source
|
|
30
38
|
npm run setup
|
|
31
39
|
```
|
|
32
40
|
|
|
@@ -119,6 +127,10 @@ Leave this running while you use ClawPort. If the gateway isn't running, chat an
|
|
|
119
127
|
## 4. Run ClawPort
|
|
120
128
|
|
|
121
129
|
```bash
|
|
130
|
+
# If installed globally via npm
|
|
131
|
+
clawport dev
|
|
132
|
+
|
|
133
|
+
# Or if running from source
|
|
122
134
|
npm run dev
|
|
123
135
|
```
|
|
124
136
|
|
|
@@ -246,6 +258,10 @@ Your `agents.json` should be an array of agent objects. Here's the minimal requi
|
|
|
246
258
|
## 6. Production Build
|
|
247
259
|
|
|
248
260
|
```bash
|
|
261
|
+
# If installed globally via npm
|
|
262
|
+
clawport start
|
|
263
|
+
|
|
264
|
+
# Or if running from source
|
|
249
265
|
npx next build
|
|
250
266
|
npm start
|
|
251
267
|
```
|
package/app/docs/page.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import { CronSystemSection } from "@/components/docs/CronSystemSection";
|
|
|
9
9
|
import { ThemingSection } from "@/components/docs/ThemingSection";
|
|
10
10
|
import { ComponentsSection } from "@/components/docs/ComponentsSection";
|
|
11
11
|
import { TroubleshootingSection } from "@/components/docs/TroubleshootingSection";
|
|
12
|
+
import { BestPracticesSection } from "@/components/docs/BestPracticesSection";
|
|
12
13
|
|
|
13
14
|
/* ─── Section Definitions ──────────────────────────────────────── */
|
|
14
15
|
|
|
@@ -42,6 +43,13 @@ const SECTIONS: DocSectionDef[] = [
|
|
|
42
43
|
description: "Registry, hierarchy, customization",
|
|
43
44
|
component: AgentsSection,
|
|
44
45
|
},
|
|
46
|
+
{
|
|
47
|
+
id: "best-practices",
|
|
48
|
+
label: "Best Practices",
|
|
49
|
+
emoji: "\u{1F3AF}",
|
|
50
|
+
description: "Hierarchy, memory, tools, naming",
|
|
51
|
+
component: BestPracticesSection,
|
|
52
|
+
},
|
|
45
53
|
{
|
|
46
54
|
id: "api-reference",
|
|
47
55
|
label: "API Reference",
|
package/app/page.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import { GridView } from "@/components/GridView"
|
|
|
12
12
|
import { FeedView } from "@/components/FeedView"
|
|
13
13
|
|
|
14
14
|
const OrgMap = dynamic(
|
|
15
|
-
() => import("@/components/
|
|
15
|
+
() => import("@/components/OrgMap").then((m) => ({ default: m.OrgMap })),
|
|
16
16
|
{
|
|
17
17
|
ssr: false,
|
|
18
18
|
loading: () => (
|
package/bin/clawport.mjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { dirname, resolve } from 'node:path'
|
|
5
|
+
import { spawn } from 'node:child_process'
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
7
|
+
import { execSync } from 'node:child_process'
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Resolve package root (where app/, lib/, etc. live)
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
14
|
+
const PKG_ROOT = resolve(dirname(__filename), '..')
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Helpers
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
const green = (s) => `\x1b[32m${s}\x1b[0m`
|
|
21
|
+
const yellow = (s) => `\x1b[33m${s}\x1b[0m`
|
|
22
|
+
const red = (s) => `\x1b[31m${s}\x1b[0m`
|
|
23
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`
|
|
24
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`
|
|
25
|
+
|
|
26
|
+
function run(cmd, args = []) {
|
|
27
|
+
const child = spawn(cmd, args, {
|
|
28
|
+
cwd: PKG_ROOT,
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
shell: true,
|
|
31
|
+
})
|
|
32
|
+
child.on('close', (code) => process.exit(code ?? 0))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Commands
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
function showHelp() {
|
|
40
|
+
console.log(`
|
|
41
|
+
${bold('ClawPort')} -- AI Agent Dashboard
|
|
42
|
+
|
|
43
|
+
${bold('Usage:')} clawport <command>
|
|
44
|
+
|
|
45
|
+
${bold('Commands:')}
|
|
46
|
+
${green('dev')} Start the development server (next dev)
|
|
47
|
+
${green('start')} Build and start the production server
|
|
48
|
+
${green('setup')} Run the setup wizard (auto-detect OpenClaw config)
|
|
49
|
+
${green('status')} Check gateway reachability and current config
|
|
50
|
+
${green('help')} Show this help message
|
|
51
|
+
|
|
52
|
+
${bold('Examples:')}
|
|
53
|
+
${dim('$ clawport setup # Configure your OpenClaw connection')}
|
|
54
|
+
${dim('$ clawport dev # Start dev server on localhost:3000')}
|
|
55
|
+
${dim('$ clawport status # Check if gateway is reachable')}
|
|
56
|
+
|
|
57
|
+
${dim(`Package root: ${PKG_ROOT}`)}
|
|
58
|
+
`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function cmdDev() {
|
|
62
|
+
console.log(`\n ${bold('Starting ClawPort dev server...')}\n`)
|
|
63
|
+
run('npx', ['next', 'dev'])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function cmdStart() {
|
|
67
|
+
console.log(`\n ${bold('Building and starting ClawPort...')}\n`)
|
|
68
|
+
run('npx', ['next', 'build', '&&', 'npx', 'next', 'start'])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function cmdSetup() {
|
|
72
|
+
console.log()
|
|
73
|
+
run('node', [resolve(PKG_ROOT, 'scripts/setup.mjs'), `--cwd=${PKG_ROOT}`])
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function cmdStatus() {
|
|
77
|
+
console.log()
|
|
78
|
+
console.log(bold(' ClawPort Status'))
|
|
79
|
+
console.log()
|
|
80
|
+
|
|
81
|
+
// Check gateway
|
|
82
|
+
let gatewayUp = false
|
|
83
|
+
try {
|
|
84
|
+
const result = execSync(
|
|
85
|
+
'curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:18789/ 2>/dev/null',
|
|
86
|
+
{ encoding: 'utf-8', timeout: 5000 }
|
|
87
|
+
).trim()
|
|
88
|
+
gatewayUp = result && result !== '000'
|
|
89
|
+
} catch {
|
|
90
|
+
// gateway not reachable
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (gatewayUp) {
|
|
94
|
+
console.log(` ${green('+')} Gateway reachable at ${dim('localhost:18789')}`)
|
|
95
|
+
} else {
|
|
96
|
+
console.log(` ${red('x')} Gateway not responding at ${dim('localhost:18789')}`)
|
|
97
|
+
console.log(` ${dim('Start it with: openclaw gateway run')}`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check .env.local
|
|
101
|
+
const envPath = resolve(PKG_ROOT, '.env.local')
|
|
102
|
+
console.log()
|
|
103
|
+
if (existsSync(envPath)) {
|
|
104
|
+
console.log(` ${green('+')} .env.local found`)
|
|
105
|
+
const content = readFileSync(envPath, 'utf-8')
|
|
106
|
+
const lines = content.split('\n').filter((l) => l && !l.startsWith('#'))
|
|
107
|
+
for (const line of lines) {
|
|
108
|
+
const [key, ...rest] = line.split('=')
|
|
109
|
+
const value = rest.join('=')
|
|
110
|
+
if (key === 'OPENCLAW_GATEWAY_TOKEN' && value) {
|
|
111
|
+
console.log(` ${dim(key)}=${dim(value.slice(0, 8) + '...' + value.slice(-4))}`)
|
|
112
|
+
} else if (key && value) {
|
|
113
|
+
console.log(` ${dim(key)}=${dim(value)}`)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
console.log(` ${yellow('!')} No .env.local found`)
|
|
118
|
+
console.log(` ${dim('Run: clawport setup')}`)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
console.log()
|
|
122
|
+
console.log(` ${dim(`Package root: ${PKG_ROOT}`)}`)
|
|
123
|
+
console.log()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Main
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
const command = process.argv[2]
|
|
131
|
+
|
|
132
|
+
switch (command) {
|
|
133
|
+
case 'dev':
|
|
134
|
+
cmdDev()
|
|
135
|
+
break
|
|
136
|
+
case 'start':
|
|
137
|
+
cmdStart()
|
|
138
|
+
break
|
|
139
|
+
case 'setup':
|
|
140
|
+
cmdSetup()
|
|
141
|
+
break
|
|
142
|
+
case 'status':
|
|
143
|
+
cmdStatus()
|
|
144
|
+
break
|
|
145
|
+
case 'help':
|
|
146
|
+
default:
|
|
147
|
+
showHelp()
|
|
148
|
+
break
|
|
149
|
+
}
|
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Heading,
|
|
3
|
+
SubHeading,
|
|
4
|
+
Paragraph,
|
|
5
|
+
CodeBlock,
|
|
6
|
+
InlineCode,
|
|
7
|
+
Table,
|
|
8
|
+
BulletList,
|
|
9
|
+
NumberedList,
|
|
10
|
+
Callout,
|
|
11
|
+
InfoCard,
|
|
12
|
+
} from "./DocSection";
|
|
13
|
+
|
|
14
|
+
export function BestPracticesSection() {
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<Heading>Best Practices</Heading>
|
|
18
|
+
<Paragraph>
|
|
19
|
+
This guide covers the patterns and conventions behind a production agent
|
|
20
|
+
team. Every example uses real agents from the bundled registry so you can
|
|
21
|
+
see exactly how hierarchy, memory, tools, and crons come together.
|
|
22
|
+
</Paragraph>
|
|
23
|
+
|
|
24
|
+
{/* ─── Hierarchy ──────────────────────────────────────── */}
|
|
25
|
+
|
|
26
|
+
<SubHeading>Hierarchy Design</SubHeading>
|
|
27
|
+
<Paragraph>
|
|
28
|
+
A well-structured agent team follows a clear chain of command. The
|
|
29
|
+
pattern is: one orchestrator at the top, team leads in the middle, and
|
|
30
|
+
specialist leaf agents at the bottom. Each level has a distinct
|
|
31
|
+
responsibility.
|
|
32
|
+
</Paragraph>
|
|
33
|
+
|
|
34
|
+
<InfoCard title="The Three Tiers">
|
|
35
|
+
<Table
|
|
36
|
+
headers={["Tier", "Role", "Example"]}
|
|
37
|
+
rows={[
|
|
38
|
+
[
|
|
39
|
+
"Orchestrator",
|
|
40
|
+
"Top-level coordinator. Holds team memory, routes work, delivers briefings.",
|
|
41
|
+
<><strong key="j">Jarvis</strong> -- the root node. reportsTo: null.</>,
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
"Team Lead",
|
|
45
|
+
"Owns a domain. Manages a sub-team and runs pipelines end-to-end.",
|
|
46
|
+
<>
|
|
47
|
+
<strong key="v">VERA</strong> (Strategy),{" "}
|
|
48
|
+
<strong key="l">LUMEN</strong> (SEO),{" "}
|
|
49
|
+
<strong key="h">HERALD</strong> (LinkedIn)
|
|
50
|
+
</>,
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
"Specialist",
|
|
54
|
+
"Does one thing well. Reports up, never manages others.",
|
|
55
|
+
<>
|
|
56
|
+
<strong key="t">TRACE</strong> (Market Research),{" "}
|
|
57
|
+
<strong key="q">QUILL</strong> (LinkedIn Writer),{" "}
|
|
58
|
+
<strong key="s">SCOUT</strong> (Content Scout)
|
|
59
|
+
</>,
|
|
60
|
+
],
|
|
61
|
+
]}
|
|
62
|
+
/>
|
|
63
|
+
</InfoCard>
|
|
64
|
+
|
|
65
|
+
<Paragraph>
|
|
66
|
+
The bundled registry ships 22 agents organized into five teams:
|
|
67
|
+
</Paragraph>
|
|
68
|
+
|
|
69
|
+
<CodeBlock title="Team Structure">
|
|
70
|
+
{`Jarvis (Orchestrator)
|
|
71
|
+
|
|
|
72
|
+
+-- VERA (Strategy)
|
|
73
|
+
| +-- Robin (Field Intel)
|
|
74
|
+
| +-- TRACE (Market Research)
|
|
75
|
+
| +-- PROOF (Validation Design)
|
|
76
|
+
|
|
|
77
|
+
+-- LUMEN (SEO)
|
|
78
|
+
| +-- SCOUT (Content Scout)
|
|
79
|
+
| +-- ANALYST (SEO Analyst)
|
|
80
|
+
| +-- STRATEGIST (Content Strategy)
|
|
81
|
+
| +-- WRITER (Content Writer)
|
|
82
|
+
| +-- AUDITOR (Quality Gate)
|
|
83
|
+
|
|
|
84
|
+
+-- HERALD (LinkedIn)
|
|
85
|
+
| +-- QUILL (LinkedIn Writer)
|
|
86
|
+
| +-- MAVEN (LinkedIn Strategist)
|
|
87
|
+
|
|
|
88
|
+
+-- Pulse (Trend Radar) -- standalone
|
|
89
|
+
+-- ECHO (Community Voice) -- standalone
|
|
90
|
+
+-- SAGE (ICP Expert) -- standalone
|
|
91
|
+
+-- KAZE (Flight Monitor) -- standalone
|
|
92
|
+
+-- SPARK (Tech Discovery) -- standalone
|
|
93
|
+
+-- SCRIBE (Memory Architect)-- standalone`}
|
|
94
|
+
</CodeBlock>
|
|
95
|
+
|
|
96
|
+
<Callout type="tip">
|
|
97
|
+
Standalone agents (no direct reports) report directly to the
|
|
98
|
+
orchestrator. Keep this list short -- if you have more than 8-10 direct
|
|
99
|
+
reports on the root node, it's time to group them under a team lead.
|
|
100
|
+
</Callout>
|
|
101
|
+
|
|
102
|
+
<SubHeading>Hierarchy Rules</SubHeading>
|
|
103
|
+
<NumberedList
|
|
104
|
+
items={[
|
|
105
|
+
<>
|
|
106
|
+
<strong>One root.</strong> Exactly one agent has{" "}
|
|
107
|
+
<InlineCode>{"\"reportsTo\": null"}</InlineCode>. This is your
|
|
108
|
+
orchestrator (Jarvis).
|
|
109
|
+
</>,
|
|
110
|
+
<>
|
|
111
|
+
<strong>Team leads own pipelines.</strong> LUMEN owns the full SEO
|
|
112
|
+
pipeline (SCOUT to AUDITOR). HERALD owns the LinkedIn pipeline
|
|
113
|
+
(QUILL + MAVEN). Each lead is responsible for end-to-end delivery.
|
|
114
|
+
</>,
|
|
115
|
+
<>
|
|
116
|
+
<strong>Leaf agents are specialists.</strong> They do one thing and
|
|
117
|
+
report up. TRACE does market research. QUILL writes posts. AUDITOR
|
|
118
|
+
runs the quality gate. No scope creep.
|
|
119
|
+
</>,
|
|
120
|
+
<>
|
|
121
|
+
<strong>Max depth of 3.</strong> Jarvis to Robin to TRACE is
|
|
122
|
+
three levels. Going deeper adds latency and coordination overhead
|
|
123
|
+
with little benefit.
|
|
124
|
+
</>,
|
|
125
|
+
<>
|
|
126
|
+
<strong>Keep directReports consistent.</strong> If agent B has{" "}
|
|
127
|
+
<InlineCode>{"\"reportsTo\": \"A\""}</InlineCode>, then agent A's
|
|
128
|
+
directReports array must include B's id. The Org Map renders from
|
|
129
|
+
these relationships.
|
|
130
|
+
</>,
|
|
131
|
+
]}
|
|
132
|
+
/>
|
|
133
|
+
|
|
134
|
+
{/* ─── SOUL.md ────────────────────────────────────────── */}
|
|
135
|
+
|
|
136
|
+
<SubHeading>SOUL.md -- Agent Character Documents</SubHeading>
|
|
137
|
+
<Paragraph>
|
|
138
|
+
Every agent has a SOUL.md file that defines its personality, expertise,
|
|
139
|
+
and operating constraints. This is not a system prompt -- it's a
|
|
140
|
+
character document. The agent reads it to understand who it is.
|
|
141
|
+
</Paragraph>
|
|
142
|
+
|
|
143
|
+
<CodeBlock title="Recommended SOUL.md Structure">
|
|
144
|
+
{`# AGENT_NAME -- Role Title
|
|
145
|
+
|
|
146
|
+
## Identity
|
|
147
|
+
Who the agent is. Personality traits. Communication style.
|
|
148
|
+
First-person voice: "I am VERA, the Chief Strategy Officer."
|
|
149
|
+
|
|
150
|
+
## Expertise
|
|
151
|
+
What domains this agent knows deeply.
|
|
152
|
+
What it should be consulted on vs. what it defers.
|
|
153
|
+
|
|
154
|
+
## Operating Rules
|
|
155
|
+
Hard constraints. What it must always/never do.
|
|
156
|
+
Output format requirements.
|
|
157
|
+
|
|
158
|
+
## Relationships
|
|
159
|
+
Who it reports to. Who reports to it.
|
|
160
|
+
How it collaborates with peer agents.
|
|
161
|
+
|
|
162
|
+
## Memory
|
|
163
|
+
What it remembers between sessions.
|
|
164
|
+
Where its persistent knowledge lives.`}
|
|
165
|
+
</CodeBlock>
|
|
166
|
+
|
|
167
|
+
<BulletList
|
|
168
|
+
items={[
|
|
169
|
+
<>
|
|
170
|
+
<strong>Be specific about personality.</strong> HERALD is described
|
|
171
|
+
as brash and direct. SAGE is contemplative and precise. Distinct
|
|
172
|
+
voices prevent all agents from sounding the same.
|
|
173
|
+
</>,
|
|
174
|
+
<>
|
|
175
|
+
<strong>Define what the agent does NOT do.</strong> SCRIBE (Memory
|
|
176
|
+
Architect) is a "silent worker" -- it never initiates conversation.
|
|
177
|
+
SAGE (ICP Expert) is read-only -- it never writes to external
|
|
178
|
+
systems.
|
|
179
|
+
</>,
|
|
180
|
+
<>
|
|
181
|
+
<strong>Include output format examples.</strong> If the agent
|
|
182
|
+
produces Market Briefs, show the exact format. TRACE returns
|
|
183
|
+
structured TAM/competitor/pricing data, not prose.
|
|
184
|
+
</>,
|
|
185
|
+
<>
|
|
186
|
+
<strong>Keep it under 500 lines.</strong> Long SOUL files dilute
|
|
187
|
+
the agent's focus. If you need more detail, link to reference docs.
|
|
188
|
+
</>,
|
|
189
|
+
]}
|
|
190
|
+
/>
|
|
191
|
+
|
|
192
|
+
<Callout type="note">
|
|
193
|
+
SOUL.md files live in your OpenClaw workspace at the path defined by
|
|
194
|
+
each agent's <InlineCode>soulPath</InlineCode> field. ClawPort reads
|
|
195
|
+
and displays them on the agent detail page.
|
|
196
|
+
</Callout>
|
|
197
|
+
|
|
198
|
+
{/* ─── Naming ─────────────────────────────────────────── */}
|
|
199
|
+
|
|
200
|
+
<SubHeading>Naming Conventions</SubHeading>
|
|
201
|
+
<Paragraph>
|
|
202
|
+
Agent naming follows a simple pattern that signals the agent's scope
|
|
203
|
+
at a glance:
|
|
204
|
+
</Paragraph>
|
|
205
|
+
|
|
206
|
+
<Table
|
|
207
|
+
headers={["Pattern", "When to Use", "Examples"]}
|
|
208
|
+
rows={[
|
|
209
|
+
[
|
|
210
|
+
"UPPERCASE",
|
|
211
|
+
"Agents that are part of a pipeline or team. Feels like a callsign.",
|
|
212
|
+
"VERA, LUMEN, HERALD, SCOUT, QUILL, ECHO, SAGE",
|
|
213
|
+
],
|
|
214
|
+
[
|
|
215
|
+
"Title Case",
|
|
216
|
+
"Standalone agents with more personality. The orchestrator or personal-feeling agents.",
|
|
217
|
+
"Jarvis, Robin, Pulse",
|
|
218
|
+
],
|
|
219
|
+
]}
|
|
220
|
+
/>
|
|
221
|
+
|
|
222
|
+
<Paragraph>
|
|
223
|
+
Ids are always lowercase slugs:{" "}
|
|
224
|
+
<InlineCode>vera</InlineCode>,{" "}
|
|
225
|
+
<InlineCode>lumen</InlineCode>,{" "}
|
|
226
|
+
<InlineCode>herald</InlineCode>. The display name in the{" "}
|
|
227
|
+
<InlineCode>name</InlineCode> field is what users see in the UI.
|
|
228
|
+
</Paragraph>
|
|
229
|
+
|
|
230
|
+
{/* ─── Tools ──────────────────────────────────────────── */}
|
|
231
|
+
|
|
232
|
+
<SubHeading>Tool Assignment</SubHeading>
|
|
233
|
+
<Paragraph>
|
|
234
|
+
Follow the principle of least privilege. Each agent gets only the tools
|
|
235
|
+
it needs for its job -- nothing more.
|
|
236
|
+
</Paragraph>
|
|
237
|
+
|
|
238
|
+
<Table
|
|
239
|
+
headers={["Tool", "Purpose", "Who Gets It"]}
|
|
240
|
+
rows={[
|
|
241
|
+
[
|
|
242
|
+
<InlineCode key="r">read</InlineCode>,
|
|
243
|
+
"Read files from workspace",
|
|
244
|
+
"Almost everyone. The base capability.",
|
|
245
|
+
],
|
|
246
|
+
[
|
|
247
|
+
<InlineCode key="w">write</InlineCode>,
|
|
248
|
+
"Write/create files",
|
|
249
|
+
"Agents that produce artifacts (WRITER, ANALYST, STRATEGIST)",
|
|
250
|
+
],
|
|
251
|
+
[
|
|
252
|
+
<InlineCode key="e">exec</InlineCode>,
|
|
253
|
+
"Run shell commands",
|
|
254
|
+
"Orchestrator + leads who run pipelines (Jarvis, LUMEN, HERALD)",
|
|
255
|
+
],
|
|
256
|
+
[
|
|
257
|
+
<InlineCode key="ws">web_search</InlineCode>,
|
|
258
|
+
"Search the web",
|
|
259
|
+
"Research agents (TRACE, Robin, SCOUT, Pulse, SPARK)",
|
|
260
|
+
],
|
|
261
|
+
[
|
|
262
|
+
<InlineCode key="wf">web_fetch</InlineCode>,
|
|
263
|
+
"Fetch a specific URL",
|
|
264
|
+
"Agents that scrape or monitor (ECHO, KAZE, Robin)",
|
|
265
|
+
],
|
|
266
|
+
[
|
|
267
|
+
<InlineCode key="m">message</InlineCode>,
|
|
268
|
+
"Send messages to other agents",
|
|
269
|
+
"Agents that coordinate (Jarvis, Robin, Pulse, HERALD)",
|
|
270
|
+
],
|
|
271
|
+
[
|
|
272
|
+
<InlineCode key="ss">sessions_spawn</InlineCode>,
|
|
273
|
+
"Spawn sub-agent sessions",
|
|
274
|
+
"Only orchestrator + team leads (Jarvis, VERA)",
|
|
275
|
+
],
|
|
276
|
+
[
|
|
277
|
+
<InlineCode key="ms">memory_search</InlineCode>,
|
|
278
|
+
"Search across team memory",
|
|
279
|
+
"Orchestrator only (Jarvis)",
|
|
280
|
+
],
|
|
281
|
+
[
|
|
282
|
+
<InlineCode key="tt">tts</InlineCode>,
|
|
283
|
+
"Text-to-speech",
|
|
284
|
+
"Orchestrator only (Jarvis)",
|
|
285
|
+
],
|
|
286
|
+
]}
|
|
287
|
+
/>
|
|
288
|
+
|
|
289
|
+
<Callout type="warning">
|
|
290
|
+
Giving <InlineCode>exec</InlineCode> to a leaf agent is almost always
|
|
291
|
+
a mistake. If a specialist needs to run a command, it should ask its
|
|
292
|
+
team lead to do it. This keeps the blast radius small.
|
|
293
|
+
</Callout>
|
|
294
|
+
|
|
295
|
+
<InfoCard title="Tool Assignment Examples">
|
|
296
|
+
<CodeBlock>
|
|
297
|
+
{`// SAGE -- read-only knowledge agent
|
|
298
|
+
"tools": ["read"]
|
|
299
|
+
|
|
300
|
+
// SCOUT -- web researcher
|
|
301
|
+
"tools": ["web_search", "web_fetch", "read"]
|
|
302
|
+
|
|
303
|
+
// WRITER -- content producer
|
|
304
|
+
"tools": ["read", "write"]
|
|
305
|
+
|
|
306
|
+
// HERALD -- team lead running a pipeline
|
|
307
|
+
"tools": ["web_search", "web_fetch", "read", "write", "message", "exec"]
|
|
308
|
+
|
|
309
|
+
// Jarvis -- orchestrator with full access
|
|
310
|
+
"tools": ["exec", "read", "write", "edit", "web_search", "tts", "message", "sessions_spawn", "memory_search"]`}
|
|
311
|
+
</CodeBlock>
|
|
312
|
+
</InfoCard>
|
|
313
|
+
|
|
314
|
+
{/* ─── Memory ─────────────────────────────────────────── */}
|
|
315
|
+
|
|
316
|
+
<SubHeading>Memory Architecture</SubHeading>
|
|
317
|
+
<Paragraph>
|
|
318
|
+
Agent memory uses a three-tier system. Each tier serves a different
|
|
319
|
+
purpose, and together they give agents both short-term recall and
|
|
320
|
+
long-term knowledge.
|
|
321
|
+
</Paragraph>
|
|
322
|
+
|
|
323
|
+
<InfoCard title="The Three Memory Tiers">
|
|
324
|
+
<Table
|
|
325
|
+
headers={["Tier", "What", "Lifespan", "Who Manages"]}
|
|
326
|
+
rows={[
|
|
327
|
+
[
|
|
328
|
+
"1. Daily Logs",
|
|
329
|
+
"Raw output from each agent session. Unedited, timestamped.",
|
|
330
|
+
"7-14 days (then compressed or archived)",
|
|
331
|
+
"Each agent writes its own",
|
|
332
|
+
],
|
|
333
|
+
[
|
|
334
|
+
"2. MEMORY.md",
|
|
335
|
+
"Curated, compressed knowledge. The agent's persistent brain.",
|
|
336
|
+
"Indefinite (updated weekly)",
|
|
337
|
+
<>
|
|
338
|
+
<strong>SCRIBE</strong> runs weekly compression
|
|
339
|
+
</>,
|
|
340
|
+
],
|
|
341
|
+
[
|
|
342
|
+
"3. Team Memory",
|
|
343
|
+
"Shared knowledge across agents. Market data, ICP profiles, strategy docs.",
|
|
344
|
+
"Indefinite",
|
|
345
|
+
"Team leads + orchestrator",
|
|
346
|
+
],
|
|
347
|
+
]}
|
|
348
|
+
/>
|
|
349
|
+
</InfoCard>
|
|
350
|
+
|
|
351
|
+
<SubHeading>Tier 1: Daily Logs</SubHeading>
|
|
352
|
+
<Paragraph>
|
|
353
|
+
Every time an agent runs, it writes a log file. These are the raw
|
|
354
|
+
session transcripts -- what the agent did, what it found, what it
|
|
355
|
+
produced. Daily logs are high-volume and low-curation.
|
|
356
|
+
</Paragraph>
|
|
357
|
+
<CodeBlock title="Daily log path pattern">
|
|
358
|
+
{`$WORKSPACE_PATH/agents/<agent-id>/logs/YYYY-MM-DD.md`}
|
|
359
|
+
</CodeBlock>
|
|
360
|
+
|
|
361
|
+
<SubHeading>Tier 2: MEMORY.md</SubHeading>
|
|
362
|
+
<Paragraph>
|
|
363
|
+
Each agent has a MEMORY.md file that persists its key knowledge between
|
|
364
|
+
sessions. Unlike daily logs (which are raw), MEMORY.md is curated --
|
|
365
|
+
only the important patterns, decisions, and facts survive.
|
|
366
|
+
</Paragraph>
|
|
367
|
+
<CodeBlock title="MEMORY.md structure">
|
|
368
|
+
{`# Agent Name -- Memory
|
|
369
|
+
|
|
370
|
+
## Key Patterns
|
|
371
|
+
- Pattern 1 confirmed across 3+ sessions
|
|
372
|
+
- Pattern 2 from last week's research
|
|
373
|
+
|
|
374
|
+
## Active Context
|
|
375
|
+
- Current project status
|
|
376
|
+
- Open questions / blockers
|
|
377
|
+
|
|
378
|
+
## Learned Preferences
|
|
379
|
+
- User prefers X over Y
|
|
380
|
+
- Always include Z in output`}
|
|
381
|
+
</CodeBlock>
|
|
382
|
+
<Paragraph>
|
|
383
|
+
<strong>SCRIBE</strong> (Memory Architect) runs weekly to compress daily
|
|
384
|
+
logs into each agent's MEMORY.md. SCRIBE reads the raw logs, extracts
|
|
385
|
+
durable insights, and updates the memory file -- discarding
|
|
386
|
+
session-specific noise. This keeps MEMORY.md concise and high-signal.
|
|
387
|
+
</Paragraph>
|
|
388
|
+
|
|
389
|
+
<SubHeading>Tier 3: Team Memory (Shared)</SubHeading>
|
|
390
|
+
<Paragraph>
|
|
391
|
+
Some knowledge needs to be shared across agents. Market intelligence,
|
|
392
|
+
ICP profiles, competitive analysis, and brand voice docs all live in a
|
|
393
|
+
shared team-memory directory. Any agent with{" "}
|
|
394
|
+
<InlineCode>read</InlineCode> access to the workspace can reference
|
|
395
|
+
these files.
|
|
396
|
+
</Paragraph>
|
|
397
|
+
<CodeBlock title="Team memory path">
|
|
398
|
+
{`$WORKSPACE_PATH/team-memory/
|
|
399
|
+
market-brief.md -- TRACE's latest research
|
|
400
|
+
icp-profile.md -- SAGE's ICP knowledge
|
|
401
|
+
competitor-map.md -- Robin's competitive intel
|
|
402
|
+
brand-voice.md -- Voice profile for content agents
|
|
403
|
+
content-calendar.md -- MAVEN's editorial calendar`}
|
|
404
|
+
</CodeBlock>
|
|
405
|
+
|
|
406
|
+
<Callout type="tip">
|
|
407
|
+
Team memory files are the glue between agents. When STRATEGIST needs
|
|
408
|
+
market context, it reads TRACE's market brief. When WRITER needs brand
|
|
409
|
+
voice, it reads the voice profile. No agent-to-agent API calls needed
|
|
410
|
+
-- just shared files.
|
|
411
|
+
</Callout>
|
|
412
|
+
|
|
413
|
+
{/* ─── Communication ──────────────────────────────────── */}
|
|
414
|
+
|
|
415
|
+
<SubHeading>Agent Communication</SubHeading>
|
|
416
|
+
<Paragraph>
|
|
417
|
+
Agents communicate through files, not direct API calls. This is
|
|
418
|
+
intentional -- file-based communication is debuggable, auditable, and
|
|
419
|
+
doesn't create tight coupling.
|
|
420
|
+
</Paragraph>
|
|
421
|
+
|
|
422
|
+
<NumberedList
|
|
423
|
+
items={[
|
|
424
|
+
<>
|
|
425
|
+
<strong>Upstream (reporting up):</strong> An agent writes its output
|
|
426
|
+
to a file. The team lead or orchestrator reads it on the next run.
|
|
427
|
+
Example: SCOUT writes topic suggestions, LUMEN reads them to
|
|
428
|
+
brief STRATEGIST.
|
|
429
|
+
</>,
|
|
430
|
+
<>
|
|
431
|
+
<strong>Downstream (delegating):</strong> A team lead writes a
|
|
432
|
+
brief file that the specialist reads. Example: HERALD writes an
|
|
433
|
+
angle brief, QUILL reads it and drafts the post.
|
|
434
|
+
</>,
|
|
435
|
+
<>
|
|
436
|
+
<strong>Cross-team (shared context):</strong> Agents read from
|
|
437
|
+
team-memory. Example: STRATEGIST reads SAGE's ICP profile and
|
|
438
|
+
ECHO's community voice data to pick the right content angle.
|
|
439
|
+
</>,
|
|
440
|
+
]}
|
|
441
|
+
/>
|
|
442
|
+
|
|
443
|
+
<Callout type="note">
|
|
444
|
+
The <InlineCode>message</InlineCode> tool exists for real-time
|
|
445
|
+
coordination (e.g., Pulse alerting LUMEN about a trending topic), but
|
|
446
|
+
the default communication channel is always files. Messages are for
|
|
447
|
+
urgency; files are for substance.
|
|
448
|
+
</Callout>
|
|
449
|
+
|
|
450
|
+
{/* ─── Crons ──────────────────────────────────────────── */}
|
|
451
|
+
|
|
452
|
+
<SubHeading>Cron Patterns</SubHeading>
|
|
453
|
+
<Paragraph>
|
|
454
|
+
Cron jobs are the heartbeat of an autonomous agent team. Each cron
|
|
455
|
+
follows the same philosophy: one fetch, one decision, one output.
|
|
456
|
+
</Paragraph>
|
|
457
|
+
|
|
458
|
+
<BulletList
|
|
459
|
+
items={[
|
|
460
|
+
<>
|
|
461
|
+
<strong>Assign crons to the right tier.</strong> Research crons go
|
|
462
|
+
on leaf agents (SCOUT, TRACE, ECHO). Pipeline crons go on team
|
|
463
|
+
leads (LUMEN, HERALD). Briefing crons go on the orchestrator
|
|
464
|
+
(Jarvis).
|
|
465
|
+
</>,
|
|
466
|
+
<>
|
|
467
|
+
<strong>Stagger schedules.</strong> Don't run all crons at the same
|
|
468
|
+
time. Space them out so upstream agents finish before downstream
|
|
469
|
+
agents read their output.
|
|
470
|
+
</>,
|
|
471
|
+
<>
|
|
472
|
+
<strong>Keep crons focused.</strong> Each cron does one thing.
|
|
473
|
+
"Scan subreddits" is a good cron. "Scan subreddits, analyze
|
|
474
|
+
sentiment, write a blog post, and publish" is four crons pretending
|
|
475
|
+
to be one.
|
|
476
|
+
</>,
|
|
477
|
+
<>
|
|
478
|
+
<strong>Error isolation.</strong> If a cron fails, it should only
|
|
479
|
+
affect its own output. Other agents reading stale data is better
|
|
480
|
+
than a cascade failure.
|
|
481
|
+
</>,
|
|
482
|
+
]}
|
|
483
|
+
/>
|
|
484
|
+
|
|
485
|
+
<Table
|
|
486
|
+
headers={["Cron", "Agent", "Schedule", "Pattern"]}
|
|
487
|
+
rows={[
|
|
488
|
+
[
|
|
489
|
+
"Community scan",
|
|
490
|
+
<strong key="e">ECHO</strong>,
|
|
491
|
+
"Weekly",
|
|
492
|
+
"Fetch subreddit posts, extract customer language, write to team-memory",
|
|
493
|
+
],
|
|
494
|
+
[
|
|
495
|
+
"Trend radar",
|
|
496
|
+
<strong key="p">Pulse</strong>,
|
|
497
|
+
"Every other day",
|
|
498
|
+
"Scan trending signals, write hot topics file, message LUMEN if urgent",
|
|
499
|
+
],
|
|
500
|
+
[
|
|
501
|
+
"Flight monitor",
|
|
502
|
+
<strong key="k">KAZE</strong>,
|
|
503
|
+
"Daily",
|
|
504
|
+
"Check flight prices, message Jarvis if deal found under threshold",
|
|
505
|
+
],
|
|
506
|
+
[
|
|
507
|
+
"Memory compression",
|
|
508
|
+
<strong key="s">SCRIBE</strong>,
|
|
509
|
+
"Weekly",
|
|
510
|
+
"Read daily logs, compress into MEMORY.md, archive old logs",
|
|
511
|
+
],
|
|
512
|
+
[
|
|
513
|
+
"Content pipeline",
|
|
514
|
+
<strong key="l">LUMEN</strong>,
|
|
515
|
+
"Weekly",
|
|
516
|
+
"Orchestrate SCOUT -> ANALYST -> STRATEGIST -> WRITER -> AUDITOR",
|
|
517
|
+
],
|
|
518
|
+
]}
|
|
519
|
+
/>
|
|
520
|
+
|
|
521
|
+
{/* ─── Voice ──────────────────────────────────────────── */}
|
|
522
|
+
|
|
523
|
+
<SubHeading>Voice System</SubHeading>
|
|
524
|
+
<Paragraph>
|
|
525
|
+
Agents that interact directly with the operator can have an ElevenLabs
|
|
526
|
+
voice ID assigned. This enables text-to-speech on their responses in
|
|
527
|
+
the chat interface. Not every agent needs a voice -- only those the
|
|
528
|
+
operator talks to regularly.
|
|
529
|
+
</Paragraph>
|
|
530
|
+
|
|
531
|
+
<BulletList
|
|
532
|
+
items={[
|
|
533
|
+
<>
|
|
534
|
+
<strong>Give voices to conversational agents.</strong> Jarvis
|
|
535
|
+
(orchestrator), VERA (strategy advisor), Pulse (trend alerts) --
|
|
536
|
+
agents you chat with benefit from voice.
|
|
537
|
+
</>,
|
|
538
|
+
<>
|
|
539
|
+
<strong>Skip voices for pipeline workers.</strong> SCOUT, ANALYST,
|
|
540
|
+
WRITER, AUDITOR run in pipelines and rarely need to speak. Don't
|
|
541
|
+
waste voice slots on them.
|
|
542
|
+
</>,
|
|
543
|
+
<>
|
|
544
|
+
Set <InlineCode>voiceId</InlineCode> to{" "}
|
|
545
|
+
<InlineCode>null</InlineCode> for agents without voice. The UI
|
|
546
|
+
hides the TTS button when voiceId is null.
|
|
547
|
+
</>,
|
|
548
|
+
]}
|
|
549
|
+
/>
|
|
550
|
+
|
|
551
|
+
{/* ─── Design Principles ──────────────────────────────── */}
|
|
552
|
+
|
|
553
|
+
<SubHeading>Design Principles</SubHeading>
|
|
554
|
+
|
|
555
|
+
<InfoCard title="1. Agents are characters, not functions">
|
|
556
|
+
<Paragraph>
|
|
557
|
+
Each agent has a name, a personality, and a role title. They're not
|
|
558
|
+
interchangeable worker threads -- they're team members with distinct
|
|
559
|
+
expertise. VERA thinks strategically. ECHO listens to communities.
|
|
560
|
+
KAZE watches flights. This makes the team legible and memorable.
|
|
561
|
+
</Paragraph>
|
|
562
|
+
</InfoCard>
|
|
563
|
+
|
|
564
|
+
<InfoCard title="2. Least privilege, always">
|
|
565
|
+
<Paragraph>
|
|
566
|
+
An agent should have exactly the tools it needs and nothing more. SAGE
|
|
567
|
+
is read-only because it's a knowledge base, not an actor. SCRIBE has{" "}
|
|
568
|
+
<InlineCode>exec</InlineCode> because it needs to run file operations
|
|
569
|
+
during memory compression. If you're unsure whether an agent needs a
|
|
570
|
+
tool, start without it. You can always add it later.
|
|
571
|
+
</Paragraph>
|
|
572
|
+
</InfoCard>
|
|
573
|
+
|
|
574
|
+
<InfoCard title="3. Files over messages">
|
|
575
|
+
<Paragraph>
|
|
576
|
+
Prefer file-based communication over real-time messages. Files are
|
|
577
|
+
inspectable, diffable, and persist across sessions. Messages are for
|
|
578
|
+
urgent signals only (e.g., Pulse alerting about a breaking trend).
|
|
579
|
+
Everything else goes through shared files in team-memory.
|
|
580
|
+
</Paragraph>
|
|
581
|
+
</InfoCard>
|
|
582
|
+
|
|
583
|
+
<InfoCard title="4. One agent, one job">
|
|
584
|
+
<Paragraph>
|
|
585
|
+
Resist the urge to make Swiss Army knife agents. TRACE does market
|
|
586
|
+
research -- it doesn't also write blog posts. QUILL writes LinkedIn
|
|
587
|
+
posts -- it doesn't also analyze metrics. When an agent's description
|
|
588
|
+
needs the word "and" more than once, split it into two agents.
|
|
589
|
+
</Paragraph>
|
|
590
|
+
</InfoCard>
|
|
591
|
+
|
|
592
|
+
<InfoCard title="5. Depth of 3, max">
|
|
593
|
+
<Paragraph>
|
|
594
|
+
Jarvis to Robin to TRACE is three levels. Going deeper adds latency
|
|
595
|
+
and makes the chain of command confusing. If you need more
|
|
596
|
+
specialization, add lateral agents (more direct reports) instead of
|
|
597
|
+
deeper nesting.
|
|
598
|
+
</Paragraph>
|
|
599
|
+
</InfoCard>
|
|
600
|
+
|
|
601
|
+
<InfoCard title="6. Let SCRIBE handle memory">
|
|
602
|
+
<Paragraph>
|
|
603
|
+
Don't make every agent manage its own memory compression. SCRIBE
|
|
604
|
+
exists specifically to read daily logs, extract patterns, and update
|
|
605
|
+
MEMORY.md files. This single responsibility keeps memory consistent
|
|
606
|
+
and prevents agents from spending cycles on housekeeping instead of
|
|
607
|
+
their actual job.
|
|
608
|
+
</Paragraph>
|
|
609
|
+
</InfoCard>
|
|
610
|
+
</>
|
|
611
|
+
);
|
|
612
|
+
}
|
|
@@ -41,7 +41,27 @@ export function GettingStartedSection() {
|
|
|
41
41
|
]}
|
|
42
42
|
/>
|
|
43
43
|
|
|
44
|
-
<SubHeading>Quick Start</SubHeading>
|
|
44
|
+
<SubHeading>Quick Start (npm)</SubHeading>
|
|
45
|
+
<CodeBlock title="terminal">
|
|
46
|
+
{`# Install globally
|
|
47
|
+
npm install -g clawport-ui
|
|
48
|
+
|
|
49
|
+
# Run the setup wizard (auto-detects your OpenClaw config)
|
|
50
|
+
clawport setup
|
|
51
|
+
|
|
52
|
+
# Start the dev server
|
|
53
|
+
clawport dev`}
|
|
54
|
+
</CodeBlock>
|
|
55
|
+
<Callout type="warning">
|
|
56
|
+
If you get <InlineCode>EACCES: permission denied</InlineCode> or{" "}
|
|
57
|
+
<InlineCode>EEXIST</InlineCode> errors during install, your npm cache
|
|
58
|
+
has broken permissions (usually from a previous{" "}
|
|
59
|
+
<InlineCode>sudo npm install</InlineCode>). Fix it with:{" "}
|
|
60
|
+
<InlineCode>sudo chown -R $(whoami) ~/.npm</InlineCode> then retry.
|
|
61
|
+
See the Troubleshooting section for full details.
|
|
62
|
+
</Callout>
|
|
63
|
+
|
|
64
|
+
<SubHeading>Quick Start (from source)</SubHeading>
|
|
45
65
|
<CodeBlock title="terminal">
|
|
46
66
|
{`# Clone the repo
|
|
47
67
|
git clone https://github.com/openclaw/clawport.git
|
|
@@ -17,6 +17,71 @@ export function TroubleshootingSection() {
|
|
|
17
17
|
Common issues and their solutions when running ClawPort.
|
|
18
18
|
</Paragraph>
|
|
19
19
|
|
|
20
|
+
{/* ── npm install permission errors ──────────────────────── */}
|
|
21
|
+
<SubHeading>
|
|
22
|
+
EACCES / permission denied during npm install -g
|
|
23
|
+
</SubHeading>
|
|
24
|
+
<Paragraph>
|
|
25
|
+
If you see errors like <InlineCode>EACCES: permission denied</InlineCode>,{" "}
|
|
26
|
+
<InlineCode>EEXIST</InlineCode>, or{" "}
|
|
27
|
+
<InlineCode>Invalid response body while trying to fetch</InlineCode> when
|
|
28
|
+
running <InlineCode>npm install -g clawport-ui</InlineCode>, your npm
|
|
29
|
+
cache directory has broken permissions. This usually happens if{" "}
|
|
30
|
+
<InlineCode>npm install -g</InlineCode> was previously run with{" "}
|
|
31
|
+
<InlineCode>sudo</InlineCode>.
|
|
32
|
+
</Paragraph>
|
|
33
|
+
<Paragraph>
|
|
34
|
+
Fix it in three steps:
|
|
35
|
+
</Paragraph>
|
|
36
|
+
<NumberedList
|
|
37
|
+
items={[
|
|
38
|
+
<>
|
|
39
|
+
<strong style={{ color: "var(--text-primary)" }}>
|
|
40
|
+
Fix cache permissions
|
|
41
|
+
</strong>
|
|
42
|
+
</>,
|
|
43
|
+
<>
|
|
44
|
+
<strong style={{ color: "var(--text-primary)" }}>
|
|
45
|
+
Fix global node_modules permissions
|
|
46
|
+
</strong>
|
|
47
|
+
</>,
|
|
48
|
+
<>
|
|
49
|
+
<strong style={{ color: "var(--text-primary)" }}>
|
|
50
|
+
Retry the install
|
|
51
|
+
</strong>
|
|
52
|
+
</>,
|
|
53
|
+
]}
|
|
54
|
+
/>
|
|
55
|
+
<CodeBlock title="terminal">
|
|
56
|
+
{`# 1. Fix npm cache ownership
|
|
57
|
+
sudo chown -R $(whoami) ~/.npm
|
|
58
|
+
|
|
59
|
+
# 2. Fix global node_modules ownership (find your prefix first)
|
|
60
|
+
npm prefix -g
|
|
61
|
+
# Then fix permissions on that path, e.g.:
|
|
62
|
+
sudo chown -R $(whoami) /usr/local/lib/node_modules
|
|
63
|
+
sudo chown -R $(whoami) /usr/local/bin
|
|
64
|
+
|
|
65
|
+
# 3. Retry without sudo
|
|
66
|
+
npm install -g clawport-ui`}
|
|
67
|
+
</CodeBlock>
|
|
68
|
+
<Paragraph>
|
|
69
|
+
If that still fails, clear the cache entirely and retry:
|
|
70
|
+
</Paragraph>
|
|
71
|
+
<CodeBlock title="terminal">
|
|
72
|
+
{`npm cache clean --force
|
|
73
|
+
npm install -g clawport-ui`}
|
|
74
|
+
</CodeBlock>
|
|
75
|
+
<Callout type="warning">
|
|
76
|
+
Never use <InlineCode>sudo npm install -g</InlineCode> -- it creates
|
|
77
|
+
root-owned files in your user's npm cache and global directories, which
|
|
78
|
+
causes permission errors on every future install. If your setup requires
|
|
79
|
+
sudo for global installs, consider using{" "}
|
|
80
|
+
<InlineCode>nvm</InlineCode> (Node Version Manager) instead, which
|
|
81
|
+
installs Node and global packages in your home directory with no
|
|
82
|
+
permission issues.
|
|
83
|
+
</Callout>
|
|
84
|
+
|
|
20
85
|
{/* ── Issue 1 ────────────────────────────────────────────── */}
|
|
21
86
|
<SubHeading>
|
|
22
87
|
"Missing required environment variable: WORKSPACE_PATH"
|
package/lib/agents.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"reportsTo": null,
|
|
7
7
|
"directReports": ["vera", "lumen", "herald", "pulse", "echo", "sage", "kaze", "spark", "scribe"],
|
|
8
8
|
"soulPath": "SOUL.md",
|
|
9
|
-
"voiceId":
|
|
9
|
+
"voiceId": null,
|
|
10
10
|
"color": "#f5c518",
|
|
11
11
|
"emoji": "\ud83e\udd16",
|
|
12
12
|
"tools": ["exec", "read", "write", "edit", "web_search", "tts", "message", "sessions_spawn", "memory_search"],
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"reportsTo": "jarvis",
|
|
21
21
|
"directReports": ["robin"],
|
|
22
22
|
"soulPath": "agents/vera/SOUL.md",
|
|
23
|
-
"voiceId":
|
|
23
|
+
"voiceId": null,
|
|
24
24
|
"color": "#a855f7",
|
|
25
25
|
"emoji": "\u265f\ufe0f",
|
|
26
26
|
"tools": ["web_search", "web_fetch", "read", "write", "sessions_spawn"],
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"reportsTo": "vera",
|
|
35
35
|
"directReports": ["trace", "proof"],
|
|
36
36
|
"soulPath": "agents/robin/SOUL.md",
|
|
37
|
-
"voiceId":
|
|
37
|
+
"voiceId": null,
|
|
38
38
|
"color": "#3b82f6",
|
|
39
39
|
"emoji": "\ud83e\udd85",
|
|
40
40
|
"tools": ["web_search", "web_fetch", "read", "write", "message"],
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"reportsTo": "jarvis",
|
|
77
77
|
"directReports": ["scout", "analyst", "strategist", "writer", "auditor"],
|
|
78
78
|
"soulPath": "agents/seo-team/SOUL.md",
|
|
79
|
-
"voiceId":
|
|
79
|
+
"voiceId": null,
|
|
80
80
|
"color": "#22c55e",
|
|
81
81
|
"emoji": "\ud83d\udd26",
|
|
82
82
|
"tools": ["web_search", "web_fetch", "read", "write", "exec"],
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
"reportsTo": "jarvis",
|
|
203
203
|
"directReports": [],
|
|
204
204
|
"soulPath": "agents/pulse/SOUL.md",
|
|
205
|
-
"voiceId":
|
|
205
|
+
"voiceId": null,
|
|
206
206
|
"color": "#eab308",
|
|
207
207
|
"emoji": "\ud83c\udf0a",
|
|
208
208
|
"tools": ["web_search", "web_fetch", "read", "write", "message"],
|
|
@@ -258,7 +258,7 @@
|
|
|
258
258
|
"reportsTo": "jarvis",
|
|
259
259
|
"directReports": [],
|
|
260
260
|
"soulPath": "agents/spark/SOUL.md",
|
|
261
|
-
"voiceId":
|
|
261
|
+
"voiceId": null,
|
|
262
262
|
"color": "#f59e0b",
|
|
263
263
|
"emoji": "\u26a1",
|
|
264
264
|
"tools": ["web_fetch", "web_search", "message"],
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawport-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Open-source dashboard for managing, monitoring, and chatting with your OpenClaw AI agents.",
|
|
5
5
|
"homepage": "https://clawport.dev",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/
|
|
8
|
+
"url": "https://github.com/JohnRiceML/clawport-ui.git"
|
|
9
9
|
},
|
|
10
10
|
"bugs": {
|
|
11
|
-
"url": "https://github.com/
|
|
11
|
+
"url": "https://github.com/JohnRiceML/clawport-ui/issues"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"openclaw",
|
|
@@ -19,12 +19,16 @@
|
|
|
19
19
|
"next.js"
|
|
20
20
|
],
|
|
21
21
|
"license": "MIT",
|
|
22
|
+
"bin": {
|
|
23
|
+
"clawport": "./bin/clawport.mjs"
|
|
24
|
+
},
|
|
22
25
|
"scripts": {
|
|
23
26
|
"dev": "next dev",
|
|
24
27
|
"build": "next build",
|
|
25
28
|
"start": "next start",
|
|
26
29
|
"test": "vitest run",
|
|
27
|
-
"setup": "node scripts/setup.mjs"
|
|
30
|
+
"setup": "node scripts/setup.mjs",
|
|
31
|
+
"prepublishOnly": "npx tsc --noEmit && vitest run"
|
|
28
32
|
},
|
|
29
33
|
"dependencies": {
|
|
30
34
|
"@xyflow/react": "^12.10.1",
|
package/scripts/setup.mjs
CHANGED
|
@@ -155,8 +155,12 @@ async function main() {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
// Support --cwd flag for CLI usage (clawport setup writes .env.local into the package dir)
|
|
159
|
+
const cwdFlag = process.argv.find((a) => a.startsWith('--cwd='))
|
|
160
|
+
const targetDir = cwdFlag ? cwdFlag.split('=')[1] : process.cwd()
|
|
161
|
+
|
|
158
162
|
// Check if .env.local already exists
|
|
159
|
-
const envPath = resolve(
|
|
163
|
+
const envPath = resolve(targetDir, '.env.local')
|
|
160
164
|
if (existsSync(envPath)) {
|
|
161
165
|
const overwrite = await ask(` ${yellow('?')} .env.local already exists. Overwrite? (y/N) `)
|
|
162
166
|
if (overwrite.toLowerCase() !== 'y') {
|
|
File without changes
|