@clawtrail/init 2.2.0 → 2.4.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.
Files changed (2) hide show
  1. package/dist/index.js +111 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ async function configureOpenClaw(staging, apiKey) {
117
117
  config.agents ??= {};
118
118
  config.agents.defaults ??= {};
119
119
  config.agents.defaults.heartbeat = {
120
- every: "30s",
120
+ every: "5m",
121
121
  target: "last"
122
122
  };
123
123
  config.skills ??= {};
@@ -132,7 +132,7 @@ async function configureOpenClaw(staging, apiKey) {
132
132
  await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
133
133
  return {
134
134
  configPath: "~/.openclaw/openclaw.json",
135
- heartbeat: "every 30s",
135
+ heartbeat: "every 5m",
136
136
  hasApiKey: !!apiKey
137
137
  };
138
138
  }
@@ -254,12 +254,114 @@ async function restartGateway(oldVersion, newVersion) {
254
254
  return false;
255
255
  }
256
256
  }
257
+ async function handleUninstall(staging) {
258
+ console.log(chalk.yellow.bold("\n Uninstalling ClawTrail...\n"));
259
+ const openclawDir = path.join(os.homedir(), ".openclaw");
260
+ const skillFolder = staging ? "clawtrail-staging" : "clawtrail";
261
+ const removed = [];
262
+ const spinner1 = ora("Removing skill files...").start();
263
+ const filesToRemove = [
264
+ path.join(openclawDir, "workspace", "HEARTBEAT.md"),
265
+ path.join(openclawDir, "skills", skillFolder, "SKILL.md")
266
+ ];
267
+ for (const filePath of filesToRemove) {
268
+ try {
269
+ await fs.unlink(filePath);
270
+ removed.push(filePath.replace(os.homedir(), "~"));
271
+ } catch {
272
+ }
273
+ }
274
+ try {
275
+ await fs.rmdir(path.join(openclawDir, "skills", skillFolder));
276
+ } catch {
277
+ }
278
+ if (removed.length > 0) {
279
+ spinner1.succeed(chalk.green(`Removed ${removed.length} skill files`));
280
+ } else {
281
+ spinner1.info(chalk.gray("No skill files found to remove"));
282
+ }
283
+ const spinner2 = ora("Cleaning OpenClaw config...").start();
284
+ const configPath = path.join(openclawDir, "openclaw.json");
285
+ let configCleaned = false;
286
+ try {
287
+ const raw = await fs.readFile(configPath, "utf-8");
288
+ const config = JSON5.parse(raw);
289
+ if (config.agents?.defaults?.heartbeat) {
290
+ delete config.agents.defaults.heartbeat;
291
+ if (Object.keys(config.agents.defaults).length === 0) delete config.agents.defaults;
292
+ if (Object.keys(config.agents).length === 0) delete config.agents;
293
+ }
294
+ if (config.skills?.entries?.clawtrail) {
295
+ delete config.skills.entries.clawtrail;
296
+ if (Object.keys(config.skills.entries).length === 0) delete config.skills.entries;
297
+ if (Object.keys(config.skills).length === 0) delete config.skills;
298
+ }
299
+ if (config.skills?.entries?.["clawtrail-staging"]) {
300
+ delete config.skills.entries["clawtrail-staging"];
301
+ if (Object.keys(config.skills.entries).length === 0) delete config.skills.entries;
302
+ if (Object.keys(config.skills).length === 0) delete config.skills;
303
+ }
304
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
305
+ configCleaned = true;
306
+ spinner2.succeed(chalk.green("Removed ClawTrail config from openclaw.json"));
307
+ } catch {
308
+ spinner2.info(chalk.gray("No openclaw.json found or nothing to clean"));
309
+ }
310
+ let gatewayRestarted = false;
311
+ if (isGatewayRunning()) {
312
+ const cleared = await clearOpenClawSessions();
313
+ const spinner3 = ora("Restarting gateway...").start();
314
+ try {
315
+ try {
316
+ execSync("pkill -f openclaw-gateway", { stdio: "pipe" });
317
+ } catch {
318
+ }
319
+ await new Promise((r) => setTimeout(r, 2e3));
320
+ try {
321
+ const logPath = path.join(os.homedir(), "openclaw-gateway.log");
322
+ execSync(`nohup openclaw-gateway > ${logPath} 2>&1 &`, {
323
+ stdio: "pipe",
324
+ shell: "/bin/bash"
325
+ });
326
+ } catch {
327
+ }
328
+ await new Promise((r) => setTimeout(r, 4e3));
329
+ gatewayRestarted = isGatewayRunning();
330
+ if (gatewayRestarted) {
331
+ spinner3.succeed(
332
+ chalk.green(`Gateway restarted \u2014 ${cleared} cached sessions cleared`)
333
+ );
334
+ } else {
335
+ spinner3.warn(chalk.yellow("Gateway killed but may not have restarted"));
336
+ }
337
+ } catch (err) {
338
+ const message = err instanceof Error ? err.message : String(err);
339
+ spinner3.fail(chalk.red(`Gateway restart failed: ${message}`));
340
+ }
341
+ }
342
+ console.log(chalk.yellow.bold("\n \u2500\u2500\u2500 Uninstall Summary \u2500\u2500\u2500\n"));
343
+ if (removed.length > 0) {
344
+ for (const f of removed) {
345
+ console.log(chalk.white(" Removed: ") + chalk.red(f));
346
+ }
347
+ }
348
+ if (configCleaned) {
349
+ console.log(chalk.white(" Config: ") + chalk.green("cleaned ~/.openclaw/openclaw.json"));
350
+ }
351
+ if (gatewayRestarted) {
352
+ console.log(chalk.white(" Gateway: ") + chalk.green("restarted (ClawTrail skill removed)"));
353
+ }
354
+ console.log(chalk.yellow("\n ClawTrail has been uninstalled.\n"));
355
+ console.log(
356
+ chalk.gray(" To reinstall: ") + chalk.cyan("npx @clawtrail/init@latest\n")
357
+ );
358
+ }
257
359
  async function main() {
258
360
  console.log(chalk.cyan.bold("\n ClawTrail Agent Installer\n"));
259
361
  const program = new Command();
260
362
  program.name("clawtrail-init").description(
261
363
  "Install ClawTrail skill files, configure heartbeat, and optionally register an agent"
262
- ).version("2.2.0").option(
364
+ ).version("2.4.0").option(
263
365
  "-d, --dir <path>",
264
366
  "Download directory for skill files",
265
367
  "./clawtrail-skills"
@@ -276,7 +378,11 @@ async function main() {
276
378
  ).option(
277
379
  "--api-key <key>",
278
380
  "Existing API key (skip registration, just configure)"
279
- ).option("--no-restart", "Skip gateway restart after updating files").action(async (options) => {
381
+ ).option("--no-restart", "Skip gateway restart after updating files").option("--uninstall", "Remove ClawTrail skill files, config, and restart gateway").action(async (options) => {
382
+ if (options.uninstall) {
383
+ await handleUninstall(options.staging);
384
+ return;
385
+ }
280
386
  const staging = options.staging;
281
387
  const env = staging ? "staging" : "production";
282
388
  const hasOpenClaw = await detectOpenClaw();
@@ -366,7 +472,7 @@ async function main() {
366
472
  try {
367
473
  ocConfig = await configureOpenClaw(staging, apiKey);
368
474
  spinner.succeed(
369
- chalk.green(`Heartbeat configured: ${chalk.cyan("every 30s")}`)
475
+ chalk.green(`Heartbeat configured: ${chalk.cyan("every 5m")}`)
370
476
  );
371
477
  } catch (err) {
372
478
  spinner.warn(chalk.yellow(`Config failed: ${err.message}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawtrail/init",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "CLI installer for ClawTrail AI agent skill files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {