agentapprove 0.1.0 → 0.1.1

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/cli.js +81 -91
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -2318,7 +2318,7 @@ import { homedir, hostname, platform } from "os";
2318
2318
  import { join, dirname, basename } from "path";
2319
2319
  import { execSync, spawnSync } from "child_process";
2320
2320
  import { randomBytes, createHash } from "crypto";
2321
- var VERSION = "0.1.0";
2321
+ var VERSION = "0.1.1";
2322
2322
  function getApiUrl() {
2323
2323
  return process.env.AGENTAPPROVE_API || "https://api.agentapprove.com";
2324
2324
  }
@@ -2444,7 +2444,7 @@ var AGENTS = {
2444
2444
  configPath: join(homedir(), ".openclaw", "openclaw.json"),
2445
2445
  hooksKey: "plugins",
2446
2446
  hooks: [
2447
- { name: "agentapprove", file: "openclaw-plugin.js", description: "Tool approval + event monitoring", isApprovalHook: true, isPlugin: true }
2447
+ { name: "agentapprove", file: "@agentapprove/openclaw", description: "Tool approval + event monitoring", isApprovalHook: true, isPlugin: true }
2448
2448
  ]
2449
2449
  }
2450
2450
  };
@@ -3009,7 +3009,7 @@ async function pushConfigToCloud(config) {
3009
3009
  return false;
3010
3010
  }
3011
3011
  }
3012
- function installHooksForAgent(agentId, hooksDir, mode = "approval") {
3012
+ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
3013
3013
  const agent = AGENTS[agentId];
3014
3014
  if (!agent) {
3015
3015
  return { success: false, backupPath: null, hooks: [] };
@@ -3021,6 +3021,40 @@ function installHooksForAgent(agentId, hooksDir, mode = "approval") {
3021
3021
  }
3022
3022
  const hooksConfig = config[agent.hooksKey];
3023
3023
  const installedHooks = [];
3024
+ if (agentId === "openclaw") {
3025
+ const installResult = installOpenClawPluginViaCli();
3026
+ if (!installResult.success) {
3027
+ return { success: false, backupPath, hooks: [], error: installResult.error };
3028
+ }
3029
+ if (!config.plugins) {
3030
+ config.plugins = {};
3031
+ }
3032
+ const plugins = config.plugins;
3033
+ if (!plugins.entries) {
3034
+ plugins.entries = {};
3035
+ }
3036
+ const entries = plugins.entries;
3037
+ entries.agentapprove = {
3038
+ enabled: mode === "approval",
3039
+ config: {
3040
+ apiUrl: API_URL,
3041
+ timeout: 300,
3042
+ failBehavior: "ask",
3043
+ privacyTier: "full"
3044
+ }
3045
+ };
3046
+ if (!config.hooks) {
3047
+ config.hooks = {};
3048
+ }
3049
+ const hooks = config.hooks;
3050
+ if (!hooks.internal) {
3051
+ hooks.internal = {};
3052
+ }
3053
+ hooks.internal.enabled = true;
3054
+ writeJsonConfig(agent.configPath, config);
3055
+ installedHooks.push("agentapprove");
3056
+ return { success: true, backupPath, hooks: installedHooks };
3057
+ }
3024
3058
  const hooksToInstall = mode === "observe" ? agent.hooks.filter((h2) => !h2.isApprovalHook) : agent.hooks;
3025
3059
  for (const hook of hooksToInstall) {
3026
3060
  const hookPath = join(hooksDir, hook.file);
@@ -3152,65 +3186,6 @@ function installHooksForAgent(agentId, hooksDir, mode = "approval") {
3152
3186
  cleanedArray.push(hookEntry);
3153
3187
  hooksConfig[hook.name] = cleanedArray;
3154
3188
  installedHooks.push(hook.name);
3155
- } else if (agentId === "openclaw") {
3156
- const extensionsDir = join(homedir(), ".openclaw", "extensions", "agentapprove");
3157
- mkdirSync(extensionsDir, { recursive: true });
3158
- const pluginSrc = join(hooksDir, "openclaw-plugin.js");
3159
- if (existsSync(pluginSrc)) {
3160
- copyFileSync(pluginSrc, join(extensionsDir, "index.js"));
3161
- }
3162
- const manifest = {
3163
- id: "agentapprove",
3164
- name: "Agent Approve",
3165
- description: "Mobile approval for AI agent tool execution",
3166
- version: VERSION,
3167
- homepage: "https://agentapprove.com",
3168
- configSchema: {
3169
- type: "object",
3170
- additionalProperties: false,
3171
- properties: {
3172
- apiUrl: { type: "string", default: API_URL },
3173
- timeout: { type: "number", default: 300 },
3174
- failBehavior: { type: "string", enum: ["allow", "deny", "ask"], default: "ask" },
3175
- privacyTier: { type: "string", enum: ["minimal", "summary", "full"], default: "full" },
3176
- debug: { type: "boolean", default: false }
3177
- }
3178
- }
3179
- };
3180
- writeFileSync(join(extensionsDir, "openclaw.plugin.json"), JSON.stringify(manifest, null, 2));
3181
- const pkgJson = {
3182
- name: "@agentapprove/openclaw",
3183
- version: VERSION,
3184
- main: "./index.js",
3185
- openclaw: { extensions: ["./index.js"] }
3186
- };
3187
- writeFileSync(join(extensionsDir, "package.json"), JSON.stringify(pkgJson, null, 2));
3188
- if (!config.plugins) {
3189
- config.plugins = {};
3190
- }
3191
- const plugins = config.plugins;
3192
- if (!plugins.entries) {
3193
- plugins.entries = {};
3194
- }
3195
- const entries = plugins.entries;
3196
- entries.agentapprove = {
3197
- enabled: mode === "approval",
3198
- config: {
3199
- apiUrl: API_URL,
3200
- timeout: 300,
3201
- failBehavior: "ask",
3202
- privacyTier: "full"
3203
- }
3204
- };
3205
- if (!config.hooks) {
3206
- config.hooks = {};
3207
- }
3208
- const hooks = config.hooks;
3209
- if (!hooks.internal) {
3210
- hooks.internal = {};
3211
- }
3212
- hooks.internal.enabled = true;
3213
- installedHooks.push("agentapprove");
3214
3189
  }
3215
3190
  }
3216
3191
  if (mode === "observe") {
@@ -3360,34 +3335,34 @@ function getManualInstructions(agentId, hooksDir) {
3360
3335
  }
3361
3336
  return JSON.stringify({ version: 1, hooks: hooksObj }, null, 2);
3362
3337
  } else if (agentId === "openclaw") {
3363
- return [
3364
- "# Install the Agent Approve plugin for OpenClaw:",
3365
- "#",
3366
- "# Option 1: Via npm (when published)",
3367
- "# openclaw plugins install @agentapprove/openclaw",
3368
- "#",
3369
- "# Option 2: Manual install",
3370
- "# 1. Copy the plugin bundle to ~/.openclaw/extensions/agentapprove/",
3371
- "# 2. Add to your OpenClaw config (~/.openclaw/openclaw.json):",
3372
- JSON.stringify({
3373
- plugins: {
3374
- entries: {
3375
- agentapprove: {
3376
- enabled: true,
3377
- config: {
3378
- apiUrl: API_URL,
3379
- timeout: 300,
3380
- failBehavior: "ask",
3381
- privacyTier: "full"
3382
- }
3338
+ const configJson = JSON.stringify({
3339
+ plugins: {
3340
+ entries: {
3341
+ agentapprove: {
3342
+ enabled: true,
3343
+ config: {
3344
+ apiUrl: API_URL,
3345
+ timeout: 300,
3346
+ failBehavior: "ask",
3347
+ privacyTier: "full"
3383
3348
  }
3384
3349
  }
3385
- },
3386
- hooks: {
3387
- internal: { enabled: true }
3388
3350
  }
3389
- }, null, 2),
3390
- "# 3. Restart the OpenClaw gateway"
3351
+ },
3352
+ hooks: {
3353
+ internal: { enabled: true }
3354
+ }
3355
+ }, null, 2);
3356
+ return [
3357
+ "Install the Agent Approve plugin for OpenClaw:",
3358
+ "",
3359
+ " openclaw plugins install @agentapprove/openclaw",
3360
+ "",
3361
+ "Then add to your OpenClaw config (~/.openclaw/openclaw.json):",
3362
+ "",
3363
+ configJson,
3364
+ "",
3365
+ "Restart the OpenClaw gateway to activate."
3391
3366
  ].join(`
3392
3367
  `);
3393
3368
  }
@@ -3440,8 +3415,7 @@ var HOOK_FILES = [
3440
3415
  "github-stop.sh",
3441
3416
  "github-subagent-start.sh",
3442
3417
  "github-subagent-stop.sh",
3443
- "github-precompact.sh",
3444
- "openclaw-plugin.js"
3418
+ "github-precompact.sh"
3445
3419
  ];
3446
3420
  async function copyHookScripts(hooksDir, token) {
3447
3421
  let downloaded = 0;
@@ -3473,6 +3447,15 @@ async function copyHookScripts(hooksDir, token) {
3473
3447
  }
3474
3448
  return { downloaded, failed };
3475
3449
  }
3450
+ function installOpenClawPluginViaCli() {
3451
+ try {
3452
+ execSync("openclaw plugins install @agentapprove/openclaw", { stdio: "pipe" });
3453
+ return { success: true };
3454
+ } catch (err) {
3455
+ const message = err instanceof Error ? err.message : "unknown error";
3456
+ return { success: false, error: message };
3457
+ }
3458
+ }
3476
3459
  var SYSTEM_DEPS = [
3477
3460
  {
3478
3461
  name: "curl",
@@ -4025,8 +4008,9 @@ Backups will be created with timestamp`, "Files to be modified");
4025
4008
  for (const agentId of selectedAgents) {
4026
4009
  const agent = AGENTS[agentId];
4027
4010
  const spinner = _2();
4028
- spinner.start(`Configuring ${agent.name}`);
4029
- const result = installHooksForAgent(agentId, hooksDir, installMode);
4011
+ const spinnerMsg = agentId === "openclaw" ? `Installing ${agent.name} plugin` : `Configuring ${agent.name}`;
4012
+ spinner.start(spinnerMsg);
4013
+ const result = await installHooksForAgent(agentId, hooksDir, installMode);
4030
4014
  if (result.success) {
4031
4015
  const installedHookNames = result.hooks.join(", ");
4032
4016
  const backupMsg = result.backupPath ? source_default.dim(` (backup created)`) : "";
@@ -4053,6 +4037,12 @@ Backups will be created with timestamp`, "Files to be modified");
4053
4037
  }
4054
4038
  } else {
4055
4039
  spinner.stop(`${agent.name} configuration failed`);
4040
+ if (agentId === "openclaw") {
4041
+ v2.warn(`Could not install @agentapprove/openclaw via OpenClaw CLI.
4042
+ ` + ` Error: ${result.error || "unknown"}
4043
+ ` + ` Install manually: openclaw plugins install @agentapprove/openclaw
4044
+ ` + ` Then re-run: npx agentapprove`);
4045
+ }
4056
4046
  }
4057
4047
  }
4058
4048
  } else {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "agentapprove",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Approve AI agent actions from your iPhone or Apple Watch",
5
5
  "type": "module",
6
6
  "bin": {
7
- "agentapprove": "./dist/cli.js"
7
+ "agentapprove": "dist/cli.js"
8
8
  },
9
9
  "scripts": {
10
10
  "dev": "bun --watch src/cli.ts",