Skill: harman314/rescueclaw (version 0.2.1)

# RescueClaw Skill Provides checkpoint/rollback safety net for risky operations. ## Before Risky Operations Before modifying config, installing skills, or updating the gateway, create a checkpoint: ```javascript const rescueclaw = require('./rescueclaw-checkpoint'); await rescueclaw.createCheckpoint('About to apply config changes'); ``` RescueClaw will take an immediate backup. If the agent goes unresponsive within the rollback window, it auto-restores. ## After Successful Operations Clear the checkpoint: ```javascript const rescueclaw = require('./rescueclaw-checkpoint'); await rescueclaw.clearCheckpoint(); ``` ## Commands The agent can also invoke RescueClaw CLI directly: - `rescueclaw backup` — manual snapshot - `rescueclaw status` — check health - `rescueclaw list` — list backups ## Installation The daemon binary is bundled for supported platforms (linux/arm64). On install, it copies to `~/.local/bin/rescueclaw`. For other platforms, download from [GitHub Releases](https://github.com/harman314/rescueclaw/releases). Data is stored in `~/.openclaw/rescueclaw/` (user-local, no sudo required). ## API Reference ### `createCheckpoint(reason, rollbackWindowSec = 300)` Creates a checkpoint file that RescueClaw monitors. If the agent becomes unresponsive within the rollback window, RescueClaw will immediately restore from the checkpoint backup. **Parameters:** - `reason` (string): Description of what operation is about to be performed - `rollbackWindowSec` (number, optional): How many seconds to monitor for issues (default: 300) **Returns:** Promise<void> ### `clearCheckpoint()` Removes the checkpoint file, signaling that the risky operation completed successfully. **Returns:** Promise<void> ### `getStatus()` Gets RescueClaw daemon status by invoking the CLI. **Returns:** Promise<object> with health status details ## Example: Safe Config Update ```javascript const fs = require('fs'); const rescueclaw = require('./rescueclaw-checkpoint'); async function updateConfig(newConfig) { // Create safety checkpoint await rescueclaw.createCheckpoint('Updating OpenClaw config', 180); try { // Perform the risky operation fs.writeFileSync('~/.openclaw/openclaw.json', JSON.stringify(newConfig)); // Restart gateway await exec('systemctl restart openclaw-gateway'); // If we get here, it worked! await rescueclaw.clearCheckpoint(); console.log('✅ Config updated successfully'); } catch (err) { console.error('❌ Config update failed:', err); // Don't clear checkpoint - let RescueClaw auto-restore } } ```

path: install.js
content: #!/usr/bin/env node
/**
 * Post-install hook for RescueClaw skill
 * Downloads the correct binary from GitHub Releases for the user's platform.
 * No curl | bash — pinned versioned URL, platform-detected.
 */

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
const https = require('https');

const VERSION = '0.2.0';
const REPO = 'harman314/rescueclaw';

const PLATFORM_MAP = {
  'linux-arm64':  'rescueclaw-linux-arm64',
  'linux-x64':    'rescueclaw-linux-amd64',
  'darwin-arm64': 'rescueclaw-macos-arm64',
  'darwin-x64':   'rescueclaw-macos-amd64',
};

console.log('🛟 RescueClaw Skill - Post-Install Setup\n');

// 1. Ensure data directory
const dataDir = path.join(os.homedir(), '.openclaw', 'rescueclaw');
if (!fs.existsSync(dataDir)) {
  fs.mkdirSync(dataDir, { recursive: true, mode: 0o755 });
  console.log(`📁 Created data directory: ${dataDir}`);
} else {
  console.log(`✅ Data directory: ${dataDir}`);
}

// 2. Check if already installed
try {
  const ver = execSync('rescueclaw --version', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
  console.log(`✅ RescueClaw daemon already installed: ${ver}`);
  process.exit(0);
} catch {
  // Not installed — proceed with download
}

// 3. Determine platform
const key = `${os.platform()}-${os.arch()}`;
const assetName = PLATFORM_MAP[key];

if (!assetName) {
  console.log(`⚠️  No pre-built binary for ${key}`);
  console.log(`   Build from source: https://github.com/${REPO}`);
  process.exit(0);
}

// 4. Download from GitHub Releases
const tarName = `${assetName}.tar.gz`;
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${tarName}`;
const installDir = path.join(os.homedir(), '.local', 'bin');
const installPath = path.join(installDir, 'rescueclaw');

console.log(`📦 Downloading ${assetName} v${VERSION}...`);
console.log(`   From: ${url}`);

fs.mkdirSync(installDir, { recursive: true });

const tmpFile = path.join(os.tmpdir(), tarName);

try {
  execSync(`curl -fsSL "${url}" -o "${tmpFile}"`, { stdio: 'inherit', timeout: 60000 });
  execSync(`tar xzf "${tmpFile}" -C "${installDir}"`, { stdio: 'inherit' });
  fs.chmodSync(installPath, 0o755);
  fs.unlinkSync(tmpFile);
  console.log(`✅ Installed to ${installPath}`);
  console.log(`   Ensure ~/.local/bin is in your PATH`);
} catch (err) {
  console.log(`⚠️  Download failed. Install manually:`);
  console.log(`   ${url}`);
  console.log(`   Extract and place 'rescueclaw' in your PATH`);
  try { fs.unlinkSync(tmpFile); } catch {}
}

console.log('\n🎯 Skill ready! Use rescueclaw-checkpoint.js for safe operations.');


path: package.json
content: {
  "name": "rescueclaw-skill",
  "version": "0.1.0",
  "description": "RescueClaw - AI Agent Safety Net. Checkpoint API for safe config changes.",
  "main": "rescueclaw-checkpoint.js",
  "keywords": [
    "rescueclaw",
    "backup",
    "watchdog",
    "safety",
    "openclaw",
    "checkpoint"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/harman314/rescueclaw"
  },
  "author": "Harman Singh",
  "license": "MIT",
  "clawhub": {
    "category": "safety",
    "postInstall": "install.js"
  }
}


path: rescueclaw-checkpoint.js
content: /**
 * RescueClaw Checkpoint API
 * 
 * Provides safety checkpoint functionality for risky agent operations.
 * When a checkpoint is created, RescueClaw monitors the agent and will
 * auto-restore from backup if it becomes unresponsive.
 */

const fs = require('fs');
const { execSync } = require('child_process');

const path = require('path');
const os = require('os');
const CHECKPOINT_PATH = path.join(os.homedir(), '.openclaw', 'rescueclaw', 'checkpoint-request.json');

/**
 * Create a checkpoint before a risky operation
 * @param {string} reason - Description of the operation
 * @param {number} rollbackWindowSec - Seconds to monitor (default: 300)
 * @returns {Promise<void>}
 */
async function createCheckpoint(reason, rollbackWindowSec = 300) {
  const checkpoint = {
    action: 'checkpoint',
    reason: reason || 'Manual checkpoint',
    timestamp: new Date().toISOString(),
    rollback_window_seconds: rollbackWindowSec
  };
  
  try {
    // Ensure directory exists
    const dir = require('path').dirname(CHECKPOINT_PATH);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    
    // Write checkpoint file
    fs.writeFileSync(CHECKPOINT_PATH, JSON.stringify(checkpoint, null, 2));
    console.log(`🛟 Checkpoint created: ${reason}`);
  } catch (err) {
    console.error('⚠️  Failed to create checkpoint:', err.message);
    throw err;
  }
}

/**
 * Clear the checkpoint after successful operation
 * @returns {Promise<void>}
 */
async function clearCheckpoint() {
  try {
    if (fs.existsSync(CHECKPOINT_PATH)) {
      fs.unlinkSync(CHECKPOINT_PATH);
      console.log('✅ Checkpoint cleared');
    }
  } catch (err) {
    console.error('⚠️  Failed to clear checkpoint:', err.message);
    // Don't throw - this is not critical
  }
}

/**
 * Get RescueClaw status
 * @returns {Promise<object>} Status information
 */
async function getStatus() {
  try {
    const output = execSync('rescueclaw status --json', {
      encoding: 'utf-8',
      timeout: 5000
    });
    return JSON.parse(output);
  } catch (err) {
    // If JSON output not available, try plain text
    try {
      const output = execSync('rescueclaw status', {
        encoding: 'utf-8',
        timeout: 5000
      });
      return { raw: output, available: true };
    } catch {
      return { available: false, error: err.message };
    }
  }
}

/**
 * Check if RescueClaw daemon is running
 * @returns {Promise<boolean>}
 */
async function isRunning() {
  try {
    const status = await getStatus();
    return status.available !== false;
  } catch {
    return false;
  }
}

module.exports = {
  createCheckpoint,
  clearCheckpoint,
  getStatus,
  isRunning,
  CHECKPOINT_PATH
};


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: suspicious | SkillSpector: suspicious (HIGH)