@sesamespace/sesame 0.2.8 → 0.2.9
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/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/agent-provisioner/SKILL.md +342 -78
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* heartbeats, reconnection, and message routing automatically.
|
|
14
14
|
*/
|
|
15
15
|
// Plugin version (injected from package.json at build time, fallback to static)
|
|
16
|
-
const PLUGIN_VERSION = "0.2.
|
|
16
|
+
const PLUGIN_VERSION = "0.2.9";
|
|
17
17
|
/** Standard headers for Sesame API calls */
|
|
18
18
|
function sesameHeaders(apiKey, json = true) {
|
|
19
19
|
const h = {
|
package/package.json
CHANGED
|
@@ -7,149 +7,413 @@ description: Provision and manage OpenClaw agent siblings on the same host. Use
|
|
|
7
7
|
|
|
8
8
|
Provision new OpenClaw instances on this host as part of an agent family.
|
|
9
9
|
|
|
10
|
+
**Full docs:** https://sesame.space/docs/families.md
|
|
11
|
+
|
|
10
12
|
## When to Use
|
|
11
13
|
|
|
12
14
|
- A provisioning task is assigned to you (title starts with "Provision agent:")
|
|
13
15
|
- A lifecycle command arrives (start/stop/restart/deprovision) for a family member
|
|
14
16
|
- You need to register this host as a family or update shared resources
|
|
15
17
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
When you receive a provisioning task, extract the details from the task context and the onboarding channel messages. You need:
|
|
18
|
+
## Script & Template Locations
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
- **principalId** — their Sesame principal ID
|
|
22
|
-
- **apiKey** — their Sesame API key (from the provision response, shared via secure channel)
|
|
23
|
-
- **llmApiKey** — their LLM provider API key
|
|
24
|
-
- **llmProvider** — anthropic, openrouter, or openai
|
|
25
|
-
|
|
26
|
-
### Step 1: Create OC Home Directory
|
|
20
|
+
All scripts and templates are in the skill directory. Resolve paths like this:
|
|
27
21
|
|
|
28
22
|
```bash
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
SKILL_DIR="$HOME/.openclaw/skills/agent-provisioner"
|
|
24
|
+
# If using a profile: SKILL_DIR="$HOME/.openclaw-<your-handle>/skills/agent-provisioner"
|
|
25
|
+
|
|
26
|
+
# Scripts:
|
|
27
|
+
# $SKILL_DIR/scripts/generate-config.sh
|
|
28
|
+
# $SKILL_DIR/scripts/create-launchd-service.sh
|
|
29
|
+
# $SKILL_DIR/scripts/check-family-health.sh
|
|
30
|
+
#
|
|
31
|
+
# Templates:
|
|
32
|
+
# $SKILL_DIR/scripts/templates/AGENTS.md
|
|
33
|
+
# $SKILL_DIR/scripts/templates/TOOLS.md
|
|
34
|
+
# $SKILL_DIR/scripts/templates/MEMORY.md
|
|
35
|
+
# $SKILL_DIR/scripts/templates/BOOTSTRAP.md
|
|
31
36
|
```
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
## Provisioning Flow
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
### Step 0: Parse the Provisioning Task
|
|
41
|
+
|
|
42
|
+
The task's `context.notes` field contains a **JSON string** with everything you need. Parse it:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"principalId": "uuid-of-new-agent",
|
|
47
|
+
"handle": "new-agent-handle",
|
|
48
|
+
"displayName": "New Agent Name",
|
|
49
|
+
"sesameApiKey": "sk_sesame_...",
|
|
50
|
+
"llmProvider": "anthropic",
|
|
51
|
+
"llmApiKey": "sk-ant-...",
|
|
52
|
+
"inheritCredentials": true,
|
|
53
|
+
"model": "anthropic/claude-opus-4-6",
|
|
54
|
+
"gatewayPort": 18793,
|
|
55
|
+
"ocHomeDir": "~/.openclaw-new-agent-handle",
|
|
56
|
+
"familyId": "uuid-of-family",
|
|
57
|
+
"familyName": "My Family",
|
|
58
|
+
"dmChannelId": "uuid-of-dm-channel",
|
|
59
|
+
"onboardingChannelId": "uuid-of-onboarding-channel"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
- `OC_HOME` — home directory for new agent
|
|
39
|
-
- `HANDLE` — agent handle
|
|
40
|
-
- `SESAME_API_KEY` — Sesame API key
|
|
41
|
-
- `LLM_PROVIDER` — anthropic|openrouter|openai
|
|
42
|
-
- `LLM_API_KEY` — LLM API key
|
|
43
|
-
- `GATEWAY_PORT` — unique port (check existing family members, use next available from 18790+)
|
|
44
|
-
- `MODEL` — (optional) model override, defaults to provider default
|
|
63
|
+
**Map these to env vars for the scripts:**
|
|
45
64
|
|
|
46
|
-
|
|
65
|
+
| Task Context Field | Script Env Var | Notes |
|
|
66
|
+
|-------------------|---------------|-------|
|
|
67
|
+
| `handle` | `HANDLE` | |
|
|
68
|
+
| `sesameApiKey` | `SESAME_API_KEY` | |
|
|
69
|
+
| `llmProvider` | `LLM_PROVIDER` | `anthropic`, `openrouter`, or `openai` |
|
|
70
|
+
| `llmApiKey` | `LLM_API_KEY` | May be null — if so, use `inheritCredentials` |
|
|
71
|
+
| `gatewayPort` | `GATEWAY_PORT` | |
|
|
72
|
+
| `ocHomeDir` | `OC_HOME` | Expand `~` to `$HOME` |
|
|
73
|
+
| `model` | `MODEL` | Optional, defaults to provider default |
|
|
47
74
|
|
|
48
|
-
|
|
75
|
+
Also set:
|
|
76
|
+
- `LEAD_HOME` — your own OC home dir (e.g., `$HOME/.openclaw` or `$HOME/.openclaw-<your-handle>`)
|
|
49
77
|
|
|
50
|
-
|
|
51
|
-
- **SOUL.md** — Generate based on personality seed. If none provided, write a good default that emphasizes competence, helpfulness, and having opinions.
|
|
52
|
-
- **TOOLS.md** — Use `scripts/templates/TOOLS.md` as base, fill in Sesame API details and shared resource docs
|
|
53
|
-
- **USER.md** — Pre-populate with what you know about the human from your own USER.md (filter appropriately)
|
|
54
|
-
- **MEMORY.md** — Use `scripts/templates/MEMORY.md` as base, fill in people, projects, and platform lessons from lead's MEMORY.md
|
|
55
|
-
- **IDENTITY.md** — Leave mostly blank for the new agent to fill in
|
|
56
|
-
- **HEARTBEAT.md** — Copy your own or use a sensible default
|
|
57
|
-
- **BOOTSTRAP.md** — Use `scripts/templates/BOOTSTRAP.md`, fill in all variables
|
|
78
|
+
**If `llmApiKey` is null and `inheritCredentials` is true:** The script will copy your auth files to the new agent. This is the default.
|
|
58
79
|
|
|
59
|
-
### Step
|
|
80
|
+
### Step 1: Run generate-config.sh
|
|
60
81
|
|
|
61
|
-
|
|
82
|
+
This creates the entire OC directory structure, copies extensions/skills from you (the lead), and writes `openclaw.json`:
|
|
62
83
|
|
|
63
84
|
```bash
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
85
|
+
export OC_HOME="$HOME/.openclaw-$HANDLE" # expand ~ from task context
|
|
86
|
+
export HANDLE="<from task>"
|
|
87
|
+
export SESAME_API_KEY="<from task>"
|
|
88
|
+
export LLM_PROVIDER="<from task>"
|
|
89
|
+
export LLM_API_KEY="<from task>" # omit if null + inheritCredentials
|
|
90
|
+
export GATEWAY_PORT="<from task>"
|
|
91
|
+
export MODEL="<from task>" # optional
|
|
92
|
+
export LEAD_HOME="$HOME/.openclaw" # YOUR oc home dir
|
|
93
|
+
|
|
94
|
+
bash "$SKILL_DIR/scripts/generate-config.sh"
|
|
95
|
+
```
|
|
70
96
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
97
|
+
**What this creates:**
|
|
98
|
+
```
|
|
99
|
+
$OC_HOME/
|
|
100
|
+
├── openclaw.json # Gateway config
|
|
101
|
+
├── agents/main/agent/
|
|
102
|
+
│ ├── auth.json # LLM auth (copied or generated)
|
|
103
|
+
│ └── auth-profiles.json # Copied from lead
|
|
104
|
+
├── extensions/sesame/ # Copied from lead
|
|
105
|
+
├── skills/sesame/ # Copied from lead
|
|
106
|
+
├── workspace/
|
|
107
|
+
│ └── memory/
|
|
108
|
+
└── logs/
|
|
109
|
+
```
|
|
76
110
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
111
|
+
### Step 2: Scaffold Workspace Files
|
|
112
|
+
|
|
113
|
+
Write these files into `$OC_HOME/workspace/`. Use the templates in `$SKILL_DIR/scripts/templates/` as a base.
|
|
114
|
+
|
|
115
|
+
**Template variables to replace:**
|
|
116
|
+
|
|
117
|
+
| Variable | Value |
|
|
118
|
+
|----------|-------|
|
|
119
|
+
| `{{HANDLE}}` | Agent handle from task |
|
|
120
|
+
| `{{DISPLAY_NAME}}` | Display name from task |
|
|
121
|
+
| `{{PRINCIPAL_ID}}` | Principal ID from task |
|
|
122
|
+
| `{{WORKSPACE_ID}}` | Your workspace ID (from your own TOOLS.md or wake response) |
|
|
123
|
+
| `{{LEAD_NAME}}` | Your display name |
|
|
124
|
+
| `{{FAMILY_NAME}}` | Family name from task |
|
|
125
|
+
| `{{HOST_NAME}}` | Your machine's hostname |
|
|
126
|
+
| `{{HOST_OS}}` | `darwin` or `linux` |
|
|
127
|
+
| `{{HOST_ARCH}}` | `arm64`, `x86_64`, etc. |
|
|
128
|
+
| `{{HUMAN_NAME}}` | The human's display name |
|
|
129
|
+
| `{{HUMAN_HANDLE}}` | The human's Sesame handle |
|
|
130
|
+
| `{{HUMAN_PRINCIPAL_ID}}` | The provisioner's principal ID (from task `provisionedBy` or onboarding channel) |
|
|
131
|
+
| `{{HUMAN_ROLE}}` | Brief description of the human |
|
|
132
|
+
| `{{HUMAN_NOTES}}` | Personality notes about the human |
|
|
133
|
+
| `{{API_URL}}` | `https://api.sesame.space` |
|
|
134
|
+
| `{{DM_CHANNEL_ID}}` | DM channel from task |
|
|
135
|
+
| `{{ONBOARDING_CHANNEL_ID}}` | Onboarding channel from task |
|
|
136
|
+
| `{{SHARED_RESOURCES}}` | Shared repos, tools (from your family resources or TOOLS.md) |
|
|
137
|
+
| `{{PEOPLE_CONTEXT}}` | Key people list from your MEMORY.md |
|
|
138
|
+
| `{{ACTIVE_PROJECTS}}` | Active projects from your knowledge |
|
|
139
|
+
| `{{SIBLING_LIST}}` | Names of existing family siblings |
|
|
140
|
+
| `{{CONVENTIONS}}` | Team conventions |
|
|
141
|
+
| `{{SHARED_RESOURCES_DOCS}}` | Docs about shared resources |
|
|
142
|
+
|
|
143
|
+
**Files to write:**
|
|
144
|
+
|
|
145
|
+
| File | Source | Notes |
|
|
146
|
+
|------|--------|-------|
|
|
147
|
+
| `AGENTS.md` | Template | Replace `{{LEAD_NAME}}` |
|
|
148
|
+
| `TOOLS.md` | Template | Replace all connection/family variables |
|
|
149
|
+
| `MEMORY.md` | Template | Fill in people, projects from your own MEMORY.md |
|
|
150
|
+
| `BOOTSTRAP.md` | Template | Replace all variables — this is the agent's first-run guide |
|
|
151
|
+
| `SOUL.md` | **Generate** | Based on `metadata.personalitySeed` from the family member. If none, write a default emphasizing competence, helpfulness, and having opinions. |
|
|
152
|
+
| `USER.md` | **Generate** | Pre-populate with what you know about the human |
|
|
153
|
+
| `IDENTITY.md` | **Write blank** | Just the template — agent fills this in |
|
|
154
|
+
| `HEARTBEAT.md` | **Copy yours** or write empty with comments |
|
|
155
|
+
|
|
156
|
+
### Step 3: Create Agent Vault
|
|
157
|
+
|
|
158
|
+
Create a personal vault so the human can drop credentials in.
|
|
159
|
+
|
|
160
|
+
**Use your own Sesame API key for these calls** (you're the lead, you're the caller):
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
API="https://api.sesame.space"
|
|
164
|
+
KEY="<your sesame api key from your openclaw.json>"
|
|
165
|
+
H="Authorization: Bearer $KEY"
|
|
166
|
+
CT="Content-Type: application/json"
|
|
167
|
+
|
|
168
|
+
# 1. Create vault
|
|
169
|
+
VAULT_RESPONSE=$(curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
170
|
+
\"name\": \"${HANDLE}-main\",
|
|
171
|
+
\"description\": \"${DISPLAY_NAME} credentials vault\"
|
|
172
|
+
}" "$API/api/v1/vault/vaults")
|
|
173
|
+
|
|
174
|
+
VAULT_ID=$(echo "$VAULT_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['id'])")
|
|
175
|
+
|
|
176
|
+
# 2. Add new agent as vault owner
|
|
177
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
178
|
+
\"principalId\": \"${PRINCIPAL_ID}\",
|
|
179
|
+
\"role\": \"owner\"
|
|
180
|
+
}" "$API/api/v1/vault/vaults/$VAULT_ID/members"
|
|
181
|
+
|
|
182
|
+
# 3. Add human as admin (so they can drop keys in)
|
|
183
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
184
|
+
\"principalId\": \"${HUMAN_PRINCIPAL_ID}\",
|
|
185
|
+
\"role\": \"admin\"
|
|
186
|
+
}" "$API/api/v1/vault/vaults/$VAULT_ID/members"
|
|
82
187
|
```
|
|
83
188
|
|
|
84
|
-
The
|
|
85
|
-
Reference the vault name (`<handle>-main`) in the agent's TOOLS.md template.
|
|
189
|
+
**Note:** The vault creator (you) is auto-added. The human may also be auto-added as admin if they're a workspace human. If you get a 409 "Already a member", that's fine — skip it.
|
|
86
190
|
|
|
87
191
|
### Step 4: Create and Start Service
|
|
88
192
|
|
|
89
193
|
**macOS (launchd):**
|
|
90
194
|
```bash
|
|
91
|
-
scripts/create-launchd-service.sh "$HANDLE" "$OC_HOME" "$GATEWAY_PORT"
|
|
195
|
+
bash "$SKILL_DIR/scripts/create-launchd-service.sh" "$HANDLE" "$OC_HOME" "$GATEWAY_PORT"
|
|
92
196
|
```
|
|
93
197
|
|
|
94
198
|
**Linux (systemd):**
|
|
95
199
|
```bash
|
|
96
|
-
scripts/create-systemd-service.sh "$HANDLE" "$OC_HOME" "$GATEWAY_PORT"
|
|
200
|
+
bash "$SKILL_DIR/scripts/create-systemd-service.sh" "$HANDLE" "$OC_HOME" "$GATEWAY_PORT"
|
|
97
201
|
```
|
|
98
202
|
|
|
99
203
|
### Step 5: Verify Health
|
|
100
204
|
|
|
205
|
+
Wait for the gateway to come online. The gateway serves a web UI on its port, so a successful HTTP response means it's running:
|
|
206
|
+
|
|
101
207
|
```bash
|
|
102
|
-
# Wait up to 30 seconds for the agent to come online
|
|
103
208
|
for i in $(seq 1 30); do
|
|
104
|
-
curl -s "http://localhost:$GATEWAY_PORT/
|
|
105
|
-
|
|
209
|
+
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$GATEWAY_PORT/" 2>/dev/null)
|
|
210
|
+
if [ "$STATUS" = "200" ]; then
|
|
211
|
+
echo "Gateway is up!"
|
|
212
|
+
break
|
|
213
|
+
fi
|
|
214
|
+
sleep 2
|
|
106
215
|
done
|
|
107
216
|
```
|
|
108
217
|
|
|
218
|
+
Also check the logs for Sesame WebSocket connection:
|
|
219
|
+
```bash
|
|
220
|
+
tail -5 "$OC_HOME/logs/stdout.log" | grep -i "authenticated"
|
|
221
|
+
# Should see: [sesame] Authenticated successfully
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**If the gateway doesn't start**, check:
|
|
225
|
+
```bash
|
|
226
|
+
# Check the process
|
|
227
|
+
launchctl list | grep "$HANDLE"
|
|
228
|
+
# Exit code 0 = running, non-zero = crashed
|
|
229
|
+
|
|
230
|
+
# Check error logs
|
|
231
|
+
cat "$OC_HOME/logs/stderr.log" | tail -20
|
|
232
|
+
```
|
|
233
|
+
|
|
109
234
|
### Step 6: Report Success
|
|
110
235
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
236
|
+
```bash
|
|
237
|
+
# 1. Update family member status
|
|
238
|
+
curl -s -X PATCH -H "$H" -H "$CT" -d '{"status": "online"}' \
|
|
239
|
+
"$API/api/v1/families/$FAMILY_ID/members/$PRINCIPAL_ID"
|
|
240
|
+
|
|
241
|
+
# 2. Log completion on the provisioning task
|
|
242
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
243
|
+
\"type\": \"progress\",
|
|
244
|
+
\"message\": \"Agent $HANDLE is online on port $GATEWAY_PORT. Sesame connected, vault created.\"
|
|
245
|
+
}" "$API/api/v1/tasks/$TASK_ID/activity"
|
|
246
|
+
|
|
247
|
+
# 3. Mark task done
|
|
248
|
+
curl -s -X PATCH -H "$H" -H "$CT" -d '{"status": "done"}' \
|
|
249
|
+
"$API/api/v1/tasks/$TASK_ID"
|
|
250
|
+
|
|
251
|
+
# 4. Send welcome message in onboarding channel
|
|
252
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
253
|
+
\"content\": \"Welcome! I've provisioned $DISPLAY_NAME. They should be online and running through their BOOTSTRAP.md now.\",
|
|
254
|
+
\"intent\": \"chat\"
|
|
255
|
+
}" "$API/api/v1/channels/$ONBOARDING_CHANNEL_ID/messages"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Rollback on Failure
|
|
261
|
+
|
|
262
|
+
**If any step fails, do ALL of these** (in order):
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# 1. Stop the service (if created)
|
|
266
|
+
launchctl unload "$HOME/Library/LaunchAgents/com.openclaw.${HANDLE}.plist" 2>/dev/null
|
|
267
|
+
rm -f "$HOME/Library/LaunchAgents/com.openclaw.${HANDLE}.plist"
|
|
268
|
+
|
|
269
|
+
# 2. Archive partial workspace (don't delete — may need for debugging)
|
|
270
|
+
mkdir -p "$HOME/.openclaw-archives"
|
|
271
|
+
if [ -d "$OC_HOME" ]; then
|
|
272
|
+
tar -czf "$HOME/.openclaw-archives/${HANDLE}-$(date +%Y%m%d-%H%M%S).tar.gz" "$OC_HOME"
|
|
273
|
+
rm -rf "$OC_HOME"
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
# 3. Update family member status to error
|
|
277
|
+
curl -s -X PATCH -H "$H" -H "$CT" -d '{"status": "error"}' \
|
|
278
|
+
"$API/api/v1/families/$FAMILY_ID/members/$PRINCIPAL_ID"
|
|
279
|
+
|
|
280
|
+
# 4. Log the error on the task
|
|
281
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
282
|
+
\"type\": \"blocker\",
|
|
283
|
+
\"message\": \"Provisioning failed: <describe what went wrong>. Workspace archived to ~/.openclaw-archives/. Member status set to error.\"
|
|
284
|
+
}" "$API/api/v1/tasks/$TASK_ID/activity"
|
|
285
|
+
|
|
286
|
+
# 5. Notify in onboarding channel
|
|
287
|
+
curl -s -X POST -H "$H" -H "$CT" -d "{
|
|
288
|
+
\"content\": \"⚠️ Provisioning of $HANDLE failed: <error details>. I've archived the partial state and set status to error. Manual intervention may be needed.\",
|
|
289
|
+
\"intent\": \"error\"
|
|
290
|
+
}" "$API/api/v1/channels/$ONBOARDING_CHANNEL_ID/messages"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Do NOT leave a half-provisioned agent running.** A partial state with a crashed gateway is worse than a clean error.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Troubleshooting
|
|
298
|
+
|
|
299
|
+
### Port Conflicts
|
|
300
|
+
|
|
301
|
+
**Symptom:** `Port XXXXX is already in use` in stderr.log
|
|
114
302
|
|
|
115
|
-
|
|
303
|
+
**Cause:** Another OC gateway grabbed that port (gateways can claim extra ports for browser control/health monitoring).
|
|
116
304
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
305
|
+
**Fix:**
|
|
306
|
+
```bash
|
|
307
|
+
# Check what's using the port
|
|
308
|
+
/usr/sbin/lsof -nP -iTCP:$PORT -sTCP:LISTEN
|
|
309
|
+
|
|
310
|
+
# Pick the next available port
|
|
311
|
+
for p in $(seq 18790 18810); do
|
|
312
|
+
/usr/sbin/lsof -nP -iTCP:$p -sTCP:LISTEN >/dev/null 2>&1 || { echo "Port $p is free"; break; }
|
|
313
|
+
done
|
|
314
|
+
|
|
315
|
+
# Update config and plist, then restart
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Auth/LLM Key Issues
|
|
319
|
+
|
|
320
|
+
**Symptom:** `No API key found for provider anthropic` in logs
|
|
321
|
+
|
|
322
|
+
**Cause:** `auth.json` wasn't created or copied correctly.
|
|
323
|
+
|
|
324
|
+
**Fix:** Check `$OC_HOME/agents/main/agent/auth.json` exists and has the right format:
|
|
325
|
+
```json
|
|
326
|
+
{
|
|
327
|
+
"anthropic": {
|
|
328
|
+
"type": "api_key",
|
|
329
|
+
"key": "sk-ant-..."
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Sesame Plugin Not Connecting
|
|
335
|
+
|
|
336
|
+
**Symptom:** No `[sesame] Authenticated successfully` in stdout.log
|
|
337
|
+
|
|
338
|
+
**Cause:** Sesame extension not copied, or API key invalid.
|
|
339
|
+
|
|
340
|
+
**Fix:**
|
|
341
|
+
```bash
|
|
342
|
+
# Check extension exists
|
|
343
|
+
ls "$OC_HOME/extensions/sesame/dist/index.js"
|
|
344
|
+
|
|
345
|
+
# Check API key in config
|
|
346
|
+
cat "$OC_HOME/openclaw.json" | python3 -c "import sys,json; print(json.load(sys.stdin)['channels']['sesame']['apiKey'][:20])"
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Gateway Crashes on Startup (Exit Code 1)
|
|
350
|
+
|
|
351
|
+
**Causes (in order of likelihood):**
|
|
352
|
+
1. Port conflict (see above)
|
|
353
|
+
2. Missing auth files
|
|
354
|
+
3. Invalid openclaw.json syntax
|
|
355
|
+
4. Missing extensions
|
|
356
|
+
|
|
357
|
+
**Debug:**
|
|
358
|
+
```bash
|
|
359
|
+
cat "$OC_HOME/logs/stderr.log" | tail -20
|
|
360
|
+
# or run manually to see immediate output:
|
|
361
|
+
openclaw --profile "$HANDLE" gateway run
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Never Run `openclaw update` on Yourself
|
|
365
|
+
|
|
366
|
+
`openclaw update` restarts the global binary — this kills the calling agent. To update a sibling:
|
|
367
|
+
1. Stop their service: `launchctl unload ...`
|
|
368
|
+
2. The global package is shared — updating from any profile updates all
|
|
369
|
+
3. Reload their service: `launchctl load ...`
|
|
370
|
+
|
|
371
|
+
---
|
|
123
372
|
|
|
124
373
|
## Lifecycle Commands
|
|
125
374
|
|
|
126
375
|
### Start
|
|
127
376
|
```bash
|
|
128
|
-
launchctl load ~/Library/LaunchAgents/com.openclaw
|
|
377
|
+
launchctl load ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
129
378
|
```
|
|
130
379
|
|
|
131
380
|
### Stop
|
|
132
381
|
```bash
|
|
133
|
-
launchctl unload ~/Library/LaunchAgents/com.openclaw
|
|
382
|
+
launchctl unload ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
134
383
|
```
|
|
135
384
|
|
|
136
385
|
### Restart
|
|
137
386
|
```bash
|
|
138
|
-
launchctl unload ~/Library/LaunchAgents/com.openclaw
|
|
139
|
-
|
|
387
|
+
launchctl unload ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
388
|
+
sleep 2
|
|
389
|
+
launchctl load ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
140
390
|
```
|
|
141
391
|
|
|
142
|
-
### Deprovision
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
392
|
+
### Deprovision (Full Removal)
|
|
393
|
+
```bash
|
|
394
|
+
# 1. Stop service
|
|
395
|
+
launchctl unload ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
396
|
+
rm ~/Library/LaunchAgents/com.openclaw.$HANDLE.plist
|
|
397
|
+
|
|
398
|
+
# 2. Archive workspace
|
|
399
|
+
mkdir -p ~/.openclaw-archives
|
|
400
|
+
tar -czf ~/.openclaw-archives/${HANDLE}-$(date +%Y%m%d).tar.gz "$OC_HOME"
|
|
401
|
+
|
|
402
|
+
# 3. Remove OC home
|
|
403
|
+
rm -rf "$OC_HOME"
|
|
404
|
+
|
|
405
|
+
# 4. Update Sesame
|
|
406
|
+
curl -s -X PATCH -H "$H" -H "$CT" -d '{"status": "deprovisioned"}' \
|
|
407
|
+
"$API/api/v1/families/$FAMILY_ID/members/$PRINCIPAL_ID"
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
148
411
|
|
|
149
412
|
## Family Health Reporting
|
|
150
413
|
|
|
151
414
|
On heartbeat, check all family members:
|
|
152
415
|
```bash
|
|
153
|
-
scripts/check-family-health.sh
|
|
416
|
+
bash "$SKILL_DIR/scripts/check-family-health.sh"
|
|
154
417
|
```
|
|
418
|
+
|
|
155
419
|
Reports gateway health for each sibling and posts snapshot to Sesame.
|