@lark-apaas/openclaw-scripts-diagnose-cli 0.1.1-alpha.7 → 0.1.1-alpha.8

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.cjs CHANGED
@@ -1078,7 +1078,6 @@ function startAsyncReset(ctxBase64) {
1078
1078
  //#region src/reset.ts
1079
1079
  const STEPS = [
1080
1080
  "备份当前配置",
1081
- "下载技术栈模板",
1082
1081
  "生成默认配置",
1083
1082
  "杀掉 openclaw 进程",
1084
1083
  "重装 openclaw",
@@ -1089,7 +1088,14 @@ const STEPS = [
1089
1088
  ];
1090
1089
  const TOTAL_STEPS = STEPS.length;
1091
1090
  const CORE_BACKUP_PATH = "/home/gem/workspace/.force/openclaw/core-backup.json";
1092
- const TMP_RESET_DIR = "/tmp/openclaw-reset";
1091
+ /**
1092
+ * Directory holding the bundled openclaw template (openclaw.json + scripts/).
1093
+ * Synced from git@code.byted.org:apaas/miaoda-openclaw-template.git via
1094
+ * scripts/sync-template.sh and published alongside dist/.
1095
+ *
1096
+ * At runtime, __dirname points to dist/, so the template lives one level up.
1097
+ */
1098
+ const TEMPLATE_DIR = node_path.default.resolve(__dirname, "..", "template");
1093
1099
  function writeResultFile(resultFile, result) {
1094
1100
  const dir = node_path.default.dirname(resultFile);
1095
1101
  if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
@@ -1143,16 +1149,7 @@ function backupCurrentConfig(configPath) {
1143
1149
  } catch {}
1144
1150
  node_fs.default.copyFileSync(configPath, configPath + ".bak." + (maxN + 1));
1145
1151
  }
1146
- /** Step 2: Download/copy template zip and extract to TMP_RESET_DIR. Returns srcDir. */
1147
- function downloadAndExtractTemplate(zipDownloadURL) {
1148
- if (!node_fs.default.existsSync(TMP_RESET_DIR)) node_fs.default.mkdirSync(TMP_RESET_DIR, { recursive: true });
1149
- const zipPath = node_path.default.join(TMP_RESET_DIR, "template.zip");
1150
- if (zipDownloadURL.startsWith("http://") || zipDownloadURL.startsWith("https://")) shell(`curl -sSL -o '${zipPath}' '${zipDownloadURL}'`, 12e4);
1151
- else shell(`cp "${zipDownloadURL}" '${zipPath}'`, 1e4);
1152
- shell(`unzip -o '${zipPath}' -d '${TMP_RESET_DIR}'`, 6e4);
1153
- return findSrcDir(TMP_RESET_DIR);
1154
- }
1155
- /** Step 3: Replace $$__XXX__ placeholders and write default config. */
1152
+ /** Step 2: Replace $$__XXX__ placeholders and write default config. */
1156
1153
  function generateDefaultConfig(srcDir, configPath, templateVars) {
1157
1154
  const srcConfigPath = node_path.default.join(srcDir, "openclaw.json");
1158
1155
  if (!fileExists(srcConfigPath)) throw new Error("template openclaw.json not found at " + srcConfigPath);
@@ -1160,14 +1157,14 @@ function generateDefaultConfig(srcDir, configPath, templateVars) {
1160
1157
  for (const [placeholder, value] of Object.entries(templateVars)) content = content.split(placeholder).join(value);
1161
1158
  node_fs.default.writeFileSync(configPath, content, "utf-8");
1162
1159
  }
1163
- /** Step 4: Kill all openclaw processes. */
1160
+ /** Step 3: Kill all openclaw processes. */
1164
1161
  function killOpenclawProcesses() {
1165
1162
  try {
1166
1163
  shell("pkill -f openclaw-gateway || true", 5e3);
1167
1164
  } catch {}
1168
1165
  shell("sleep 2", 5e3);
1169
1166
  }
1170
- /** Step 5: Reinstall openclaw to the version specified in template. */
1167
+ /** Step 4: Reinstall openclaw to the version specified in template. */
1171
1168
  function reinstallOpenclaw(srcDir) {
1172
1169
  const version = loadJSON5().parse(node_fs.default.readFileSync(node_path.default.join(srcDir, "openclaw.json"), "utf-8")).meta?.lastTouchedVersion;
1173
1170
  try {
@@ -1176,7 +1173,7 @@ function reinstallOpenclaw(srcDir) {
1176
1173
  shell(`npm i -g openclaw@${version || "latest"}`, 6e5);
1177
1174
  shell("openclaw doctor --fix", 12e4);
1178
1175
  }
1179
- /** Step 6: Merge core-backup.json into config + ensure allowedOrigins. */
1176
+ /** Step 5: Merge core-backup.json into config + ensure allowedOrigins. */
1180
1177
  function mergeCoreBackupAndOrigins(configPath, vars) {
1181
1178
  const JSON5 = loadJSON5();
1182
1179
  if (fileExists(CORE_BACKUP_PATH)) {
@@ -1211,7 +1208,7 @@ function mergeCoreBackupAndOrigins(configPath, vars) {
1211
1208
  node_fs.default.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
1212
1209
  }
1213
1210
  }
1214
- /** Step 7: Copy startup scripts from template to agent dir. */
1211
+ /** Step 6: Copy startup scripts from template to agent dir. */
1215
1212
  function copyStartupScripts(srcDir, configDir) {
1216
1213
  const srcScriptsDir = node_path.default.join(srcDir, "scripts");
1217
1214
  const targetScriptsDir = node_path.default.join(configDir, "scripts");
@@ -1219,39 +1216,39 @@ function copyStartupScripts(srcDir, configDir) {
1219
1216
  if (!node_fs.default.existsSync(targetScriptsDir)) node_fs.default.mkdirSync(targetScriptsDir, { recursive: true });
1220
1217
  shell(`cp -r '${srcScriptsDir}'/* '${targetScriptsDir}/'`, 1e4);
1221
1218
  }
1222
- /** Step 8: Reinstall all plugins via openclaw CLI. */
1219
+ /** Step 7: Reinstall all plugins via openclaw CLI. */
1223
1220
  function reinstallPlugins() {
1224
1221
  try {
1225
1222
  shell("openclaw plugins update --all", 3e5);
1226
1223
  } catch {}
1227
1224
  }
1228
- /** Step 9: Write secrets/provider key files and restart openclaw. */
1225
+ /** Step 8: Write secrets/provider key files and restart openclaw. */
1229
1226
  function writeSecretsAndRestart(vars, resetData, configDir) {
1230
1227
  if (resetData.secretsContent && vars.secretsFilePath) writeFile(vars.secretsFilePath, resetData.secretsContent);
1231
1228
  if (resetData.providerKeyContent && vars.providerFilePath) writeFile(vars.providerFilePath, resetData.providerKeyContent);
1232
1229
  const restartScript = node_path.default.join(configDir, "scripts", "restart.sh");
1233
1230
  if (fileExists(restartScript)) shell(`bash '${restartScript}'`, 3e4);
1234
1231
  }
1235
- /** Clean up temporary reset directory. */
1236
- function cleanup() {
1237
- try {
1238
- node_fs.default.rmSync(TMP_RESET_DIR, {
1239
- recursive: true,
1240
- force: true
1241
- });
1242
- } catch {}
1243
- }
1244
1232
  /**
1245
- * Run the 9-step reset process. Called from the worker entry point.
1233
+ * Run the 8-step reset process. Called from the worker entry point.
1246
1234
  *
1247
1235
  * Each step is an independent function. The orchestrator handles progress
1248
1236
  * reporting, error handling, and process-level exception guards.
1237
+ *
1238
+ * The openclaw.json / scripts/*.sh template files are bundled with this CLI
1239
+ * (see TEMPLATE_DIR) and synced from the miaoda-openclaw-template repo via
1240
+ * scripts/sync-template.sh, so no runtime download is required.
1249
1241
  */
1250
1242
  function runReset(input, taskId, resultFile) {
1251
1243
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
1252
1244
  const { configPath, vars, resetData } = input;
1253
1245
  const configDir = node_path.default.dirname(configPath);
1246
+ const srcDir = TEMPLATE_DIR;
1254
1247
  let currentStep = 0;
1248
+ if (!node_fs.default.existsSync(node_path.default.join(srcDir, "openclaw.json"))) {
1249
+ markFailed(resultFile, 0, `bundled template not found at ${srcDir}`, startedAt);
1250
+ process.exit(1);
1251
+ }
1255
1252
  process.on("uncaughtException", (err) => {
1256
1253
  markFailed(resultFile, currentStep, `uncaught exception: ${err.message}`, startedAt);
1257
1254
  process.exit(1);
@@ -1269,38 +1266,25 @@ function runReset(input, taskId, resultFile) {
1269
1266
  step(1);
1270
1267
  backupCurrentConfig(configPath);
1271
1268
  step(2);
1272
- const srcDir = downloadAndExtractTemplate(resetData.zipDownloadURL);
1273
- step(3);
1274
1269
  generateDefaultConfig(srcDir, configPath, resetData.templateVars);
1275
- step(4);
1270
+ step(3);
1276
1271
  killOpenclawProcesses();
1277
- step(5);
1272
+ step(4);
1278
1273
  reinstallOpenclaw(srcDir);
1279
- step(6);
1274
+ step(5);
1280
1275
  mergeCoreBackupAndOrigins(configPath, vars);
1281
- step(7);
1276
+ step(6);
1282
1277
  copyStartupScripts(srcDir, configDir);
1283
- step(8);
1278
+ step(7);
1284
1279
  reinstallPlugins();
1285
- step(9);
1280
+ step(8);
1286
1281
  writeSecretsAndRestart(vars, resetData, configDir);
1287
- cleanup();
1288
1282
  markDone(resultFile, startedAt);
1289
1283
  } catch (e) {
1290
1284
  markFailed(resultFile, currentStep, e.message, startedAt);
1291
1285
  process.exit(1);
1292
1286
  }
1293
1287
  }
1294
- /** Find the source directory within the extracted zip (openclaw.json location). */
1295
- function findSrcDir(baseDir) {
1296
- if (node_fs.default.existsSync(node_path.default.join(baseDir, "openclaw.json"))) return baseDir;
1297
- const entries = node_fs.default.readdirSync(baseDir, { withFileTypes: true });
1298
- for (const entry of entries) if (entry.isDirectory()) {
1299
- const candidate = node_path.default.join(baseDir, entry.name);
1300
- if (node_fs.default.existsSync(node_path.default.join(candidate, "openclaw.json"))) return candidate;
1301
- }
1302
- return baseDir;
1303
- }
1304
1288
  //#endregion
1305
1289
  //#region src/get-reset-task.ts
1306
1290
  /**
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "@lark-apaas/openclaw-scripts-diagnose-cli",
3
- "version": "0.1.1-alpha.7",
3
+ "version": "0.1.1-alpha.8",
4
4
  "description": "CLI for OpenClaw config diagnose and repair with JSON5 support",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {
7
7
  "mclaw-diagnose": "./dist/index.cjs"
8
8
  },
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "template"
11
12
  ],
12
13
  "scripts": {
13
14
  "build": "tsdown",
14
15
  "test": "vitest run",
15
16
  "test:watch": "vitest",
16
17
  "test:integration": "vitest run --config vitest.integration.config.ts",
18
+ "sync:template": "bash scripts/sync-template.sh",
17
19
  "prepublishOnly": "npm run build"
18
20
  },
19
21
  "keywords": [
@@ -0,0 +1,522 @@
1
+ {
2
+ "meta": {
3
+ "lastTouchedVersion": "2026.4.9",
4
+ "lastTouchedAt": "2026-04-11T09:30:21.703Z"
5
+ },
6
+ "wizard": {
7
+ "lastRunAt": "2026-03-30T14:54:56.160Z",
8
+ "lastRunVersion": "2026.3.24",
9
+ "lastRunCommand": "doctor",
10
+ "lastRunMode": "local"
11
+ },
12
+ "update": {
13
+ "checkOnStart": false
14
+ },
15
+ "browser": {
16
+ "enabled": true,
17
+ "color": "#00AA00",
18
+ "executablePath": "/usr/bin/chromium-browser",
19
+ "headless": true,
20
+ "noSandbox": true,
21
+ "defaultProfile": "openclaw",
22
+ "extraArgs": [
23
+ "--window-size=1920,1080",
24
+ "--test-type",
25
+ "--disable-gpu",
26
+ "--no-sandbox"
27
+ ]
28
+ },
29
+ "secrets": {
30
+ "providers": {
31
+ "miaoda-provider": {
32
+ "source": "file",
33
+ "path": "$$__MIAODA_PROVIDER_FILEPATH__",
34
+ "mode": "singleValue"
35
+ },
36
+ "miaoda-secret-provider": {
37
+ "source": "file",
38
+ "path": "$$__MIAODA_OPENCLAW_SECRETS_FILEPATH__",
39
+ "mode": "json"
40
+ }
41
+ }
42
+ },
43
+ "models": {
44
+ "providers": {
45
+ "miaoda": {
46
+ "baseUrl": "$$__MIAODA_PROVIDER_BASE_URL__",
47
+ "apiKey": {
48
+ "source": "file",
49
+ "provider": "miaoda-provider",
50
+ "id": "value"
51
+ },
52
+ "api": "openai-completions",
53
+ "headers": {
54
+ "x-api-key": {
55
+ "source": "file",
56
+ "provider": "miaoda-secret-provider",
57
+ "id": "/models_providers_miaoda_headers_x_api_key"
58
+ }
59
+ },
60
+ "models": [
61
+ {
62
+ "id": "miaoda-model-auto",
63
+ "name": "妙搭",
64
+ "reasoning": false,
65
+ "input": [
66
+ "text"
67
+ ],
68
+ "cost": {
69
+ "input": 0,
70
+ "output": 0,
71
+ "cacheRead": 0,
72
+ "cacheWrite": 0
73
+ },
74
+ "contextWindow": 200000,
75
+ "maxTokens": 8192
76
+ },
77
+ {
78
+ "id": "miaoda-auto-multimodal",
79
+ "name": "妙搭多模态",
80
+ "reasoning": false,
81
+ "input": [
82
+ "text",
83
+ "image"
84
+ ],
85
+ "cost": {
86
+ "input": 0,
87
+ "output": 0,
88
+ "cacheRead": 0,
89
+ "cacheWrite": 0
90
+ },
91
+ "contextWindow": 200000,
92
+ "maxTokens": 8192
93
+ },
94
+ {
95
+ "id": "miaoda-model-flash",
96
+ "name": "妙搭 Flash",
97
+ "reasoning": false,
98
+ "input": [
99
+ "text"
100
+ ],
101
+ "cost": {
102
+ "input": 0,
103
+ "output": 0,
104
+ "cacheRead": 0,
105
+ "cacheWrite": 0
106
+ },
107
+ "contextWindow": 200000,
108
+ "maxTokens": 8192
109
+ }
110
+ ]
111
+ }
112
+ }
113
+ },
114
+ "agents": {
115
+ "defaults": {
116
+ "model": {
117
+ "primary": "miaoda/miaoda-model-auto"
118
+ },
119
+ "imageModel": "miaoda/miaoda-auto-multimodal",
120
+ "imageGenerationModel": {
121
+ "primary": "miaoda/miaoda-image-gen"
122
+ },
123
+ "models": {
124
+ "miaoda/miaoda-model-auto": {
125
+ "alias": "Miaoda Auto"
126
+ },
127
+ "miaoda/miaoda-auto-multimodal": {
128
+ "alias": "Miaoda Multimodal"
129
+ },
130
+ "miaoda/miaoda-model-flash": {
131
+ "alias": "Miaoda Flash"
132
+ }
133
+ },
134
+ "workspace": "$$__MIAODA_WORKSPACE_DIR__/workspace",
135
+ "compaction": {
136
+ "mode": "safeguard",
137
+ "reserveTokensFloor": 50000
138
+ },
139
+ "verboseDefault": "off",
140
+ "blockStreamingCoalesce": {
141
+ "minChars": 20,
142
+ "maxChars": 800,
143
+ "idleMs": 300
144
+ },
145
+ "humanDelay": {
146
+ "mode": "off"
147
+ },
148
+ "heartbeat": {
149
+ "every": "4h",
150
+ "activeHours": {
151
+ "start": "08:00",
152
+ "end": "22:00"
153
+ },
154
+ "model": "miaoda/miaoda-model-flash"
155
+ },
156
+ "maxConcurrent": 4,
157
+ "subagents": {
158
+ "maxConcurrent": 8
159
+ }
160
+ }
161
+ },
162
+ "tools": {
163
+ "profile": "full",
164
+ "alsoAllow": [
165
+ "feishu_bitable_app",
166
+ "feishu_bitable_app_table",
167
+ "feishu_bitable_app_table_field",
168
+ "feishu_bitable_app_table_record",
169
+ "feishu_bitable_app_table_view",
170
+ "feishu_calendar_calendar",
171
+ "feishu_calendar_event",
172
+ "feishu_calendar_event_attendee",
173
+ "feishu_calendar_freebusy",
174
+ "feishu_chat",
175
+ "feishu_chat_members",
176
+ "feishu_create_doc",
177
+ "feishu_doc_comments",
178
+ "feishu_doc_media",
179
+ "feishu_drive_file",
180
+ "feishu_fetch_doc",
181
+ "feishu_get_user",
182
+ "feishu_im_bot_image",
183
+ "feishu_im_user_fetch_resource",
184
+ "feishu_im_user_get_messages",
185
+ "feishu_im_user_get_thread_messages",
186
+ "feishu_im_user_message",
187
+ "feishu_im_user_search_messages",
188
+ "feishu_oauth",
189
+ "feishu_oauth_batch_auth",
190
+ "feishu_search_doc_wiki",
191
+ "feishu_search_user",
192
+ "feishu_sheet",
193
+ "feishu_task_comment",
194
+ "feishu_task_subtask",
195
+ "feishu_task_task",
196
+ "feishu_task_tasklist",
197
+ "feishu_update_doc",
198
+ "feishu_wiki_space",
199
+ "feishu_wiki_space_node"
200
+ ],
201
+ "deny": [
202
+ "web_fetch",
203
+ "tts",
204
+ "agents_list",
205
+ "feishu_task_task",
206
+ "feishu_task_tasklist",
207
+ "feishu_task_comment",
208
+ "feishu_task_subtask",
209
+ "feishu_bitable_app_table_view",
210
+ "feishu_doc_comments",
211
+ "feishu_doc_media",
212
+ "feishu_drive_file",
213
+ "feishu_wiki_space",
214
+ "feishu_wiki_space_node",
215
+ "feishu_sheet"
216
+ ],
217
+ "web": {
218
+ "search": {
219
+ "provider": "miaoda"
220
+ }
221
+ },
222
+ "media": {
223
+ "image": {
224
+ "models": [
225
+ {
226
+ "provider": "miaoda"
227
+ }
228
+ ]
229
+ },
230
+ "audio": {
231
+ "models": [
232
+ {
233
+ "provider": "miaoda"
234
+ }
235
+ ]
236
+ }
237
+ },
238
+ "sessions": {
239
+ "visibility": "all"
240
+ }
241
+ },
242
+ "messages": {
243
+ "ackReactionScope": "group-mentions"
244
+ },
245
+ "commands": {
246
+ "native": "auto",
247
+ "nativeSkills": "auto",
248
+ "restart": true,
249
+ "ownerDisplay": "raw"
250
+ },
251
+ "session": {
252
+ "dmScope": "per-channel-peer"
253
+ },
254
+ "channels": {
255
+ "feishu": {
256
+ "enabled": true,
257
+ "appId": "$$__FEISHU_APP_ID__",
258
+ "appSecret": {
259
+ "source": "file",
260
+ "provider": "miaoda-secret-provider",
261
+ "id": "/channels_feishu_app_secret"
262
+ },
263
+ "domain": "feishu",
264
+ "requireMention": true,
265
+ "dmPolicy": "allowlist",
266
+ "allowFrom": [
267
+ "$$__FEISHU_OPEN_ID__"
268
+ ],
269
+ "groupPolicy": "allowlist",
270
+ "groupAllowFrom": [
271
+ "$$__FEISHU_OPEN_ID__"
272
+ ],
273
+ "groups": {
274
+ "*": {
275
+ "enabled": true
276
+ }
277
+ },
278
+ "streaming": true,
279
+ "threadSession": true,
280
+ "footer": {
281
+ "elapsed": false,
282
+ "status": false
283
+ }
284
+ }
285
+ },
286
+ "discovery": {
287
+ "mdns": {
288
+ "mode": "off"
289
+ }
290
+ },
291
+ "gateway": {
292
+ "port": 18789,
293
+ "mode": "local",
294
+ "bind": "loopback",
295
+ "controlUi": {
296
+ "allowedOrigins": [
297
+ "$$__MIAODA_DOMAIN__",
298
+ "$$__MIAODA_ORIGIN__"
299
+ ],
300
+ "dangerouslyDisableDeviceAuth": true
301
+ },
302
+ "auth": {
303
+ "mode": "token",
304
+ "token": "$$__CLAW_TOKEN__"
305
+ },
306
+ "trustedProxies": [
307
+ "::1",
308
+ "127.0.0.1"
309
+ ],
310
+ "tailscale": {
311
+ "mode": "off",
312
+ "resetOnExit": false
313
+ }
314
+ },
315
+ "skills": {
316
+ "install": {
317
+ "nodeManager": "npm"
318
+ },
319
+ "entries": {
320
+ "1password": {
321
+ "enabled": false
322
+ },
323
+ "apple-notes": {
324
+ "enabled": false
325
+ },
326
+ "apple-reminders": {
327
+ "enabled": false
328
+ },
329
+ "bear-notes": {
330
+ "enabled": false
331
+ },
332
+ "bluebubbles": {
333
+ "enabled": false
334
+ },
335
+ "blucli": {
336
+ "enabled": false
337
+ },
338
+ "camsnap": {
339
+ "enabled": false
340
+ },
341
+ "coding-agent": {
342
+ "enabled": false
343
+ },
344
+ "discord": {
345
+ "enabled": false
346
+ },
347
+ "eightctl": {
348
+ "enabled": false
349
+ },
350
+ "gemini": {
351
+ "enabled": false
352
+ },
353
+ "gifgrep": {
354
+ "enabled": false
355
+ },
356
+ "gog": {
357
+ "enabled": false
358
+ },
359
+ "goplaces": {
360
+ "enabled": false
361
+ },
362
+ "imsg": {
363
+ "enabled": false
364
+ },
365
+ "model-usage": {
366
+ "enabled": false
367
+ },
368
+ "notion": {
369
+ "enabled": false
370
+ },
371
+ "openai-image-gen": {
372
+ "enabled": false
373
+ },
374
+ "openai-whisper": {
375
+ "enabled": false
376
+ },
377
+ "openai-whisper-api": {
378
+ "enabled": false
379
+ },
380
+ "openhue": {
381
+ "enabled": false
382
+ },
383
+ "oracle": {
384
+ "enabled": false
385
+ },
386
+ "ordercli": {
387
+ "enabled": false
388
+ },
389
+ "peekaboo": {
390
+ "enabled": false
391
+ },
392
+ "sag": {
393
+ "enabled": false
394
+ },
395
+ "slack": {
396
+ "enabled": false
397
+ },
398
+ "sonoscli": {
399
+ "enabled": false
400
+ },
401
+ "spotify-player": {
402
+ "enabled": false
403
+ },
404
+ "summarize": {
405
+ "enabled": false
406
+ },
407
+ "things-mac": {
408
+ "enabled": false
409
+ },
410
+ "trello": {
411
+ "enabled": false
412
+ },
413
+ "voice-call": {
414
+ "enabled": false
415
+ },
416
+ "wacli": {
417
+ "enabled": false
418
+ },
419
+ "xurl": {
420
+ "enabled": false
421
+ },
422
+ "feishu-task": {
423
+ "enabled": false
424
+ },
425
+ "gh-issues": {
426
+ "enabled": false
427
+ },
428
+ "github": {
429
+ "enabled": false
430
+ },
431
+ "tmux": {
432
+ "enabled": false
433
+ },
434
+ "blogwatcher": {
435
+ "enabled": false
436
+ },
437
+ "himalaya": {
438
+ "enabled": false
439
+ },
440
+ "video-frames": {
441
+ "enabled": false
442
+ },
443
+ "obsidian": {
444
+ "enabled": false
445
+ }
446
+ }
447
+ },
448
+ "plugins": {
449
+ "allow": [
450
+ "openclaw-lark",
451
+ "openclaw-extension-miaoda",
452
+ "openclaw-extension-miaoda-coding",
453
+ "browser"
454
+ ],
455
+ "entries": {
456
+ "feishu": {
457
+ "enabled": false
458
+ },
459
+ "openclaw-extension-miaoda": {
460
+ "enabled": true,
461
+ "config": {
462
+ "greeting": {
463
+ "message": "👋 Hi,我是**$$__MIAODA_CLAW_NAME__**,一只生活在飞书里的 🦞 小龙虾,打个招呼,我们开始认识一下?",
464
+ "targets": [
465
+ "$$__FEISHU_OPEN_ID__"
466
+ ]
467
+ }
468
+ }
469
+ },
470
+ "openclaw-lark": {
471
+ "enabled": true
472
+ },
473
+ "openclaw-extension-miaoda-coding": {
474
+ "enabled": true
475
+ },
476
+ "browser": {
477
+ "enabled": true
478
+ }
479
+ },
480
+ "installs": {
481
+ "openclaw-lark": {
482
+ "source": "npm",
483
+ "spec": "@lark-apaas/openclaw-lark",
484
+ "installPath": "./extensions/openclaw-lark",
485
+ "version": "2026.4.3",
486
+ "resolvedName": "@lark-apaas/openclaw-lark",
487
+ "resolvedVersion": "2026.4.3",
488
+ "resolvedSpec": "@lark-apaas/openclaw-lark@2026.4.3",
489
+ "integrity": "sha512-1eJ2WCvAYsnM9TPwPbEoD3nJtqNSOP2zOBV/3Vb9YQRg1kJJspEly5yCjiZt1wew4UhyN8Tcrp/XV78Qn747GA==",
490
+ "shasum": "e8d8cf05f8cb96cf5de4bca097c527eb9116e655",
491
+ "resolvedAt": "2026-04-03T06:27:44.706Z",
492
+ "installedAt": "2026-04-03T06:28:10.547Z"
493
+ },
494
+ "openclaw-extension-miaoda": {
495
+ "source": "npm",
496
+ "installPath": "./extensions/openclaw-extension-miaoda",
497
+ "version": "1.0.9",
498
+ "installedAt": "2026-04-11T09:27:06.639Z",
499
+ "spec": "@lark-apaas/openclaw-extension-miaoda@1.0.9",
500
+ "resolvedVersion": "1.0.9",
501
+ "resolvedName": "@lark-apaas/openclaw-extension-miaoda",
502
+ "resolvedSpec": "@lark-apaas/openclaw-extension-miaoda@1.0.9",
503
+ "resolvedAt": "2026-04-11T09:27:06.639Z",
504
+ "integrity": "sha512-McNeuPAUDLrMhT3yZuwk9A7pI262r2CK1N1KNQP6VuzymkDUjx2sTcJPCEBB3bFkdXd0yUU983/OhJiaJo+JWg==",
505
+ "shasum": "a3c75886e40b63f39a33a2660932f8afdae6a514"
506
+ },
507
+ "openclaw-extension-miaoda-coding": {
508
+ "source": "npm",
509
+ "spec": "@lark-apaas/openclaw-extension-miaoda-coding",
510
+ "installPath": "./extensions/openclaw-extension-miaoda-coding",
511
+ "version": "1.0.8",
512
+ "resolvedName": "@lark-apaas/openclaw-extension-miaoda-coding",
513
+ "resolvedVersion": "1.0.8",
514
+ "resolvedSpec": "@lark-apaas/openclaw-extension-miaoda-coding@1.0.8",
515
+ "integrity": "sha512-uxlLtgH2CTwz56UTaZD+n/x1p2a3Q01o3Og7oLUJCm6izWHXFEI1SQhNnCPggrfSam49KFir8xB64tY4T9dt2Q==",
516
+ "shasum": "058eadf5bc71ae87f79b5096b9d96f4afb89a9db",
517
+ "resolvedAt": "2026-04-09T11:33:36.208Z",
518
+ "installedAt": "2026-04-09T11:33:37.171Z"
519
+ }
520
+ }
521
+ }
522
+ }
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+
3
+ log() { echo "[restart.sh] $(date '+%Y-%m-%d %H:%M:%S') $*"; }
4
+
5
+ gw_alive() {
6
+ pgrep -f "openclaw-gateway|openclaw gateway" | grep -vw "$$" >/dev/null 2>&1
7
+ }
8
+
9
+ if [ -d "/run/systemd/system/" ]; then
10
+ log "systemd detected, restarting via systemctl..."
11
+ sudo systemctl restart openclaw
12
+ log "systemctl restart exit code: $?"
13
+ else
14
+ log "killing openclaw-gateway processes..."
15
+ PIDS_GW=$(pgrep -f "openclaw-gateway|openclaw gateway" | grep -vw "$$" || true)
16
+ if [ -n "$PIDS_GW" ]; then
17
+ log "killing gateway pids: $(echo $PIDS_GW | tr '\n' ' ')"
18
+ kill -9 $PIDS_GW 2>&1
19
+ else
20
+ log "no openclaw-gateway processes found"
21
+ fi
22
+
23
+ for i in $(seq 1 50); do
24
+ gw_alive || break
25
+ sleep 0.1
26
+ done
27
+
28
+ if gw_alive; then
29
+ log "ERROR: openclaw-gateway still alive after 5s, abort"
30
+ exit 1
31
+ fi
32
+ log "openclaw-gateway stopped"
33
+
34
+ log "starting openclaw gateway..."
35
+ nohup openclaw gateway run --port 18789 > /tmp/openclaw-gateway.log 2>&1 &
36
+ log "gateway started (pid=$!)"
37
+ fi
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ if [ -d "/run/systemd/system/" ]; then
3
+ sudo systemctl start openclaw
4
+ else
5
+ nohup openclaw gateway run --port 18789 > /tmp/openclaw-gateway.log 2>&1 &
6
+ fi
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ lsof -nP -iTCP:18789 -sTCP:LISTEN -t | xargs -r kill -9