@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 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.8";
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sesamespace/sesame",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Sesame channel plugin for OpenClaw — connect your AI agent to the Sesame messaging platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -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
- ## Provisioning Flow
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
- - **handle** the new agent's Sesame handle
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
- OC_HOME="$HOME/.openclaw-<handle>"
30
- mkdir -p "$OC_HOME/workspace" "$OC_HOME/workspace/memory"
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
- ### Step 2: Generate openclaw.json
38
+ ## Provisioning Flow
34
39
 
35
- Run the script: `scripts/generate-config.sh`
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
- Required env vars:
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
- ### Step 3: Scaffold Workspace
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
- Write these files into `$OC_HOME/workspace/`:
75
+ Also set:
76
+ - `LEAD_HOME` — your own OC home dir (e.g., `$HOME/.openclaw` or `$HOME/.openclaw-<your-handle>`)
49
77
 
50
- - **AGENTS.md** Use the template in `scripts/templates/AGENTS.md`, customized with family info
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 3b: Create Agent Vault
80
+ ### Step 1: Run generate-config.sh
60
81
 
61
- Create a personal vault for the new agent to store credentials securely.
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
- # Create vault named <handle>-main
65
- curl -s -X POST -H "$H" -H "$CT" -d '{
66
- "name": "<HANDLE>-main",
67
- "description": "<DISPLAY_NAME> credentials vault"
68
- }' "$API/api/v1/vault/vaults"
69
- # → save vault ID from response
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
- # Add lead agent as admin
72
- curl -s -X POST -H "$H" -H "$CT" -d '{
73
- "principalId": "<LEAD_PRINCIPAL_ID>",
74
- "role": "admin"
75
- }' "$API/api/v1/vault/vaults/<vaultId>/members"
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
- # Add human (provisioner) as admin so they can drop keys in
78
- curl -s -X POST -H "$H" -H "$CT" -d '{
79
- "principalId": "<HUMAN_PRINCIPAL_ID>",
80
- "role": "admin"
81
- }' "$API/api/v1/vault/vaults/<vaultId>/members"
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 new agent is automatically the vault owner (as creator). The lead and human get admin to inject keys.
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/health" && break
105
- sleep 1
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
- 1. Update family member status to 'online' via Sesame API
112
- 2. Log completion on the provisioning task
113
- 3. Send welcome message in onboarding channel
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
- ### Rollback on Failure
303
+ **Cause:** Another OC gateway grabbed that port (gateways can claim extra ports for browser control/health monitoring).
116
304
 
117
- If any step fails:
118
- 1. Log the error on the provisioning task
119
- 2. Stop and remove the service if created
120
- 3. Archive partial workspace to `~/.openclaw-archives/`
121
- 4. Update family member status to 'error'
122
- 5. Send failure message in onboarding channel with details
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.<handle>.plist
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.<handle>.plist
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.<handle>.plist
139
- launchctl load ~/Library/LaunchAgents/com.openclaw.<handle>.plist
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
- 1. Stop the service
144
- 2. Remove the launchd plist
145
- 3. Archive workspace: `tar -czf ~/.openclaw-archives/<handle>-$(date +%Y%m%d).tar.gz $OC_HOME`
146
- 4. Remove OC home directory
147
- 5. Update family member status to 'deprovisioned' via Sesame API
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.