@agentapprove/openclaw 0.1.4 → 0.1.6
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 +173 -32
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -154,7 +154,7 @@ function deriveEpochKey(rootKeyHex, epoch) {
|
|
|
154
154
|
}
|
|
155
155
|
return current;
|
|
156
156
|
}
|
|
157
|
-
function migrateRootKey() {
|
|
157
|
+
function migrateRootKey(debug = false) {
|
|
158
158
|
if (!existsSync2(E2E_KEY_FILE) || existsSync2(E2E_ROOT_KEY_FILE)) return;
|
|
159
159
|
try {
|
|
160
160
|
copyFileSync(E2E_KEY_FILE, E2E_ROOT_KEY_FILE);
|
|
@@ -173,12 +173,12 @@ function migrateRootKey() {
|
|
|
173
173
|
};
|
|
174
174
|
writeFileSync2(E2E_ROTATION_FILE, JSON.stringify(config, null, 2), { mode: 384 });
|
|
175
175
|
}
|
|
176
|
-
debugLog("Migrated e2e-key to e2e-root-key");
|
|
176
|
+
if (debug) debugLog("Migrated e2e-key to e2e-root-key");
|
|
177
177
|
} catch {
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
function checkAndRotateKeys(currentKeyHex) {
|
|
181
|
-
migrateRootKey();
|
|
180
|
+
function checkAndRotateKeys(currentKeyHex, debug = false) {
|
|
181
|
+
migrateRootKey(debug);
|
|
182
182
|
if (!existsSync2(E2E_ROTATION_FILE) || !existsSync2(E2E_ROOT_KEY_FILE)) {
|
|
183
183
|
return currentKeyHex;
|
|
184
184
|
}
|
|
@@ -217,7 +217,7 @@ function checkAndRotateKeys(currentKeyHex) {
|
|
|
217
217
|
writeFileSync2(E2E_ROTATION_FILE, JSON.stringify(rotCfg, null, 2), { mode: 384 });
|
|
218
218
|
} catch {
|
|
219
219
|
}
|
|
220
|
-
debugLog(`E2E key rotated: epoch ${currentEpoch} -> ${expectedEpoch}`);
|
|
220
|
+
if (debug) debugLog(`E2E key rotated: epoch ${currentEpoch} -> ${expectedEpoch}`);
|
|
221
221
|
return newKey;
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -293,7 +293,7 @@ function loadConfig(openclawConfig, logger) {
|
|
|
293
293
|
const timeout = openclawConfig?.timeout || parseInt(process.env.AGENTAPPROVE_TIMEOUT || "", 10) || parseInt(parseConfigValue(fileContent, "AGENTAPPROVE_TIMEOUT") || "", 10) || 300;
|
|
294
294
|
const failBehavior = openclawConfig?.failBehavior || process.env.AGENTAPPROVE_FAIL_BEHAVIOR || parseConfigValue(fileContent, "AGENTAPPROVE_FAIL_BEHAVIOR") || "ask";
|
|
295
295
|
const privacyTier = openclawConfig?.privacyTier || process.env.AGENTAPPROVE_PRIVACY || parseConfigValue(fileContent, "AGENTAPPROVE_PRIVACY") || "full";
|
|
296
|
-
const debug = openclawConfig?.debug || process.env.AGENTAPPROVE_DEBUG === "true" || parseConfigValue(fileContent, "AGENTAPPROVE_DEBUG") === "true" || false;
|
|
296
|
+
const debug = openclawConfig?.debug || process.env.AGENTAPPROVE_DEBUG === "true" || process.env.AGENTAPPROVE_DEBUG_LOG === "true" || parseConfigValue(fileContent, "AGENTAPPROVE_DEBUG") === "true" || parseConfigValue(fileContent, "AGENTAPPROVE_DEBUG_LOG") === "true" || false;
|
|
297
297
|
const agentName = process.env.AGENTAPPROVE_AGENT_NAME || parseConfigValue(fileContent, "AGENTAPPROVE_OPENCLAW_NAME") || "OpenClaw";
|
|
298
298
|
const e2eEnabled = process.env.AGENTAPPROVE_E2E_ENABLED === "true" || parseConfigValue(fileContent, "AGENTAPPROVE_E2E_ENABLED") === "true";
|
|
299
299
|
const e2eUserKeyPath = join3(homedir3(), ".agentapprove", "e2e-key");
|
|
@@ -316,7 +316,7 @@ function loadConfig(openclawConfig, logger) {
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
if (e2eUserKey) {
|
|
319
|
-
e2eUserKey = checkAndRotateKeys(e2eUserKey) || e2eUserKey;
|
|
319
|
+
e2eUserKey = checkAndRotateKeys(e2eUserKey, debug) || e2eUserKey;
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
if (debug) {
|
|
@@ -331,7 +331,7 @@ function loadConfig(openclawConfig, logger) {
|
|
|
331
331
|
failBehavior,
|
|
332
332
|
privacyTier,
|
|
333
333
|
debug,
|
|
334
|
-
hookVersion: "1.1.
|
|
334
|
+
hookVersion: "1.1.3",
|
|
335
335
|
agentName,
|
|
336
336
|
e2eEnabled,
|
|
337
337
|
e2eUserKey,
|
|
@@ -453,12 +453,142 @@ function applyEventPrivacyFilter(event, privacyTier) {
|
|
|
453
453
|
return filtered;
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
// src/config-sync.ts
|
|
457
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync4, renameSync } from "fs";
|
|
458
|
+
import { join as join4 } from "path";
|
|
459
|
+
import { homedir as homedir4 } from "os";
|
|
460
|
+
function getAADir() {
|
|
461
|
+
return process.env.__AGENTAPPROVE_TEST_DIR || join4(homedir4(), ".agentapprove");
|
|
462
|
+
}
|
|
463
|
+
function getEnvPath() {
|
|
464
|
+
return join4(getAADir(), "env");
|
|
465
|
+
}
|
|
466
|
+
function getRotationFile() {
|
|
467
|
+
return join4(getAADir(), "e2e-rotation.json");
|
|
468
|
+
}
|
|
469
|
+
var VALID_PRIVACY = /* @__PURE__ */ new Set(["minimal", "summary", "full"]);
|
|
470
|
+
var VALID_FAIL = /* @__PURE__ */ new Set(["allow", "deny", "ask"]);
|
|
471
|
+
function updateEnvValues(updates) {
|
|
472
|
+
const envPath = getEnvPath();
|
|
473
|
+
if (!existsSync4(envPath)) return;
|
|
474
|
+
const validUpdates = Object.fromEntries(
|
|
475
|
+
Object.entries(updates).filter(([, v]) => !/[`$(){};<>|&!\\]/.test(v))
|
|
476
|
+
);
|
|
477
|
+
const updateKeys = new Set(Object.keys(validUpdates));
|
|
478
|
+
if (updateKeys.size === 0) return;
|
|
479
|
+
try {
|
|
480
|
+
const content = readFileSync5(envPath, "utf-8");
|
|
481
|
+
const lines = content.split("\n");
|
|
482
|
+
const filtered = lines.filter((line) => {
|
|
483
|
+
const trimmed = line.replace(/^export\s+/, "").trim();
|
|
484
|
+
const eqIdx = trimmed.indexOf("=");
|
|
485
|
+
if (eqIdx <= 0) return true;
|
|
486
|
+
return !updateKeys.has(trimmed.slice(0, eqIdx));
|
|
487
|
+
});
|
|
488
|
+
for (const [key, value] of Object.entries(validUpdates)) {
|
|
489
|
+
filtered.push(`export ${key}=${value}`);
|
|
490
|
+
}
|
|
491
|
+
const tmpPath = `${envPath}.tmp.${process.pid}`;
|
|
492
|
+
writeFileSync3(tmpPath, filtered.join("\n"), { mode: 384 });
|
|
493
|
+
renameSync(tmpPath, envPath);
|
|
494
|
+
} catch {
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function syncRotationConfig(serverPeriod, serverStartedAt, debug) {
|
|
498
|
+
const rotationFile = getRotationFile();
|
|
499
|
+
if (!existsSync4(rotationFile)) return;
|
|
500
|
+
try {
|
|
501
|
+
const raw = readFileSync5(rotationFile, "utf-8");
|
|
502
|
+
const config = JSON.parse(raw);
|
|
503
|
+
const currentPeriod = config.periodSeconds ?? 0;
|
|
504
|
+
const newPeriod = serverPeriod ?? 0;
|
|
505
|
+
let needsUpdate = false;
|
|
506
|
+
if (typeof newPeriod === "number" && newPeriod !== currentPeriod) {
|
|
507
|
+
config.periodSeconds = newPeriod;
|
|
508
|
+
needsUpdate = true;
|
|
509
|
+
}
|
|
510
|
+
if (serverStartedAt && (!config.startedAt || config.startedAt === "null")) {
|
|
511
|
+
config.startedAt = serverStartedAt;
|
|
512
|
+
needsUpdate = true;
|
|
513
|
+
}
|
|
514
|
+
if (needsUpdate) {
|
|
515
|
+
const tmpPath = `${rotationFile}.tmp.${process.pid}`;
|
|
516
|
+
writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
517
|
+
renameSync(tmpPath, rotationFile);
|
|
518
|
+
if (debug) {
|
|
519
|
+
debugLog(`E2E rotation synced: periodSeconds=${newPeriod}`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
} catch {
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
function processConfigSync(parsed, config) {
|
|
526
|
+
const sync = parsed.configSync;
|
|
527
|
+
if (!sync || !sync.configSetAt) return;
|
|
528
|
+
const localSetAt = getLocalConfigSetAt();
|
|
529
|
+
if (sync.configSetAt <= localSetAt) return;
|
|
530
|
+
if (config.debug) {
|
|
531
|
+
debugLog(`Config sync: server=${sync.configSetAt} > local=${localSetAt}, updating...`);
|
|
532
|
+
}
|
|
533
|
+
const envUpdates = {};
|
|
534
|
+
if (sync.privacyTier && VALID_PRIVACY.has(sync.privacyTier)) {
|
|
535
|
+
envUpdates["AGENTAPPROVE_PRIVACY"] = sync.privacyTier;
|
|
536
|
+
config.privacyTier = sync.privacyTier;
|
|
537
|
+
if (config.debug) debugLog(`Config synced: privacy=${sync.privacyTier}`);
|
|
538
|
+
}
|
|
539
|
+
if (sync.timeoutSeconds != null) {
|
|
540
|
+
const t = sync.timeoutSeconds;
|
|
541
|
+
if (t >= 30 && t <= 600) {
|
|
542
|
+
envUpdates["AGENTAPPROVE_TIMEOUT"] = String(t);
|
|
543
|
+
config.timeout = t;
|
|
544
|
+
if (config.debug) debugLog(`Config synced: timeout=${t}`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (sync.failBehavior && VALID_FAIL.has(sync.failBehavior)) {
|
|
548
|
+
envUpdates["AGENTAPPROVE_FAIL_BEHAVIOR"] = sync.failBehavior;
|
|
549
|
+
config.failBehavior = sync.failBehavior;
|
|
550
|
+
if (config.debug) debugLog(`Config synced: failBehavior=${sync.failBehavior}`);
|
|
551
|
+
}
|
|
552
|
+
if (sync.e2eEnabled === true || sync.e2eEnabled === false) {
|
|
553
|
+
envUpdates["AGENTAPPROVE_E2E_ENABLED"] = String(sync.e2eEnabled);
|
|
554
|
+
config.e2eEnabled = sync.e2eEnabled;
|
|
555
|
+
if (config.debug) debugLog(`Config synced: e2eEnabled=${sync.e2eEnabled}`);
|
|
556
|
+
}
|
|
557
|
+
syncRotationConfig(sync.e2eRotationPeriod, sync.e2eRotationStartedAt, config.debug);
|
|
558
|
+
if (config.e2eEnabled && config.e2eUserKey) {
|
|
559
|
+
const rotatedKey = checkAndRotateKeys(config.e2eUserKey, config.debug);
|
|
560
|
+
if (rotatedKey && rotatedKey !== config.e2eUserKey) {
|
|
561
|
+
config.e2eUserKey = rotatedKey;
|
|
562
|
+
if (config.debug) debugLog(`Key rotated after config sync`);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
envUpdates["AGENTAPPROVE_CONFIG_SET_AT"] = String(sync.configSetAt);
|
|
566
|
+
updateEnvValues(envUpdates);
|
|
567
|
+
}
|
|
568
|
+
function getLocalConfigSetAt() {
|
|
569
|
+
const envPath = getEnvPath();
|
|
570
|
+
if (!existsSync4(envPath)) return 0;
|
|
571
|
+
try {
|
|
572
|
+
const content = readFileSync5(envPath, "utf-8");
|
|
573
|
+
for (const raw of content.split("\n")) {
|
|
574
|
+
const line = raw.replace(/^export\s+/, "").trim();
|
|
575
|
+
if (line.startsWith("AGENTAPPROVE_CONFIG_SET_AT=")) {
|
|
576
|
+
const val = line.slice("AGENTAPPROVE_CONFIG_SET_AT=".length).replace(/^["']|["']$/g, "");
|
|
577
|
+
const num = parseInt(val, 10);
|
|
578
|
+
return isNaN(num) ? 0 : num;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
} catch {
|
|
582
|
+
}
|
|
583
|
+
return 0;
|
|
584
|
+
}
|
|
585
|
+
|
|
456
586
|
// src/api-client.ts
|
|
457
587
|
var cachedPluginHash;
|
|
458
|
-
function getPluginHash(pluginPath) {
|
|
588
|
+
function getPluginHash(pluginPath, debug = false) {
|
|
459
589
|
if (!cachedPluginHash) {
|
|
460
590
|
cachedPluginHash = computePluginHash(pluginPath);
|
|
461
|
-
if (cachedPluginHash) {
|
|
591
|
+
if (cachedPluginHash && debug) {
|
|
462
592
|
debugLog(`Plugin hash computed: ${cachedPluginHash.slice(0, 16)}...`);
|
|
463
593
|
}
|
|
464
594
|
}
|
|
@@ -515,7 +645,7 @@ async function sendApprovalRequest(request, config, pluginPath) {
|
|
|
515
645
|
payload = applyPrivacyFilter(request, config.privacyTier);
|
|
516
646
|
}
|
|
517
647
|
const bodyStr = JSON.stringify(payload);
|
|
518
|
-
const pluginHash = getPluginHash(pluginPath);
|
|
648
|
+
const pluginHash = getPluginHash(pluginPath, config.debug);
|
|
519
649
|
const hmacHeaders = buildHMACHeaders(bodyStr, config.token, config.hookVersion, pluginHash);
|
|
520
650
|
const headers = {
|
|
521
651
|
"Authorization": `Bearer ${config.token}`,
|
|
@@ -532,11 +662,14 @@ async function sendApprovalRequest(request, config, pluginPath) {
|
|
|
532
662
|
if (response.status !== 200) {
|
|
533
663
|
throw new Error(`API returned status ${response.status}: ${response.body.slice(0, 200)}`);
|
|
534
664
|
}
|
|
665
|
+
let parsed;
|
|
535
666
|
try {
|
|
536
|
-
|
|
667
|
+
parsed = JSON.parse(response.body);
|
|
537
668
|
} catch {
|
|
538
669
|
throw new Error(`Failed to parse API response: ${response.body.slice(0, 200)}`);
|
|
539
670
|
}
|
|
671
|
+
processConfigSync(parsed, config);
|
|
672
|
+
return parsed;
|
|
540
673
|
}
|
|
541
674
|
async function sendEvent(event, config, pluginPath) {
|
|
542
675
|
if (!config.token) return;
|
|
@@ -554,7 +687,7 @@ async function sendEvent(event, config, pluginPath) {
|
|
|
554
687
|
}
|
|
555
688
|
}
|
|
556
689
|
const bodyStr = JSON.stringify(payload);
|
|
557
|
-
const pluginHash = getPluginHash(pluginPath);
|
|
690
|
+
const pluginHash = getPluginHash(pluginPath, config.debug);
|
|
558
691
|
const hmacHeaders = buildHMACHeaders(bodyStr, config.token, config.hookVersion, pluginHash);
|
|
559
692
|
const headers = {
|
|
560
693
|
"Authorization": `Bearer ${config.token}`,
|
|
@@ -570,6 +703,13 @@ async function sendEvent(event, config, pluginPath) {
|
|
|
570
703
|
if (config.debug) {
|
|
571
704
|
debugLog(`send_event response: ${response.body.slice(0, 200)}`);
|
|
572
705
|
}
|
|
706
|
+
if (response.status === 200) {
|
|
707
|
+
try {
|
|
708
|
+
const parsed = JSON.parse(response.body);
|
|
709
|
+
processConfigSync(parsed, config);
|
|
710
|
+
} catch {
|
|
711
|
+
}
|
|
712
|
+
}
|
|
573
713
|
} catch (err) {
|
|
574
714
|
if (config.debug) {
|
|
575
715
|
debugLog(`Failed to send ${eventType || "event"}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -588,10 +728,7 @@ var gatewaySessionId = randomBytes2(12).toString("hex");
|
|
|
588
728
|
var DEDUP_WINDOW_MS = 1200;
|
|
589
729
|
var DEDUP_MAX_SIZE = 300;
|
|
590
730
|
var recentCompletions = /* @__PURE__ */ new Map();
|
|
591
|
-
function resolveConversationId(
|
|
592
|
-
for (const id of candidates) {
|
|
593
|
-
if (id && id.trim()) return id;
|
|
594
|
-
}
|
|
731
|
+
function resolveConversationId() {
|
|
595
732
|
return gatewaySessionId;
|
|
596
733
|
}
|
|
597
734
|
function isDuplicateCompletion(toolName, params) {
|
|
@@ -715,10 +852,14 @@ function register(api) {
|
|
|
715
852
|
}
|
|
716
853
|
api.logger.info(`Agent Approve: Plugin loaded (privacy: ${config.privacyTier}, fail: ${config.failBehavior})`);
|
|
717
854
|
if (config.debug) {
|
|
718
|
-
|
|
855
|
+
const e2eStatus = !config.e2eEnabled ? "disabled" : !config.e2eUserKey ? "enabled (key missing)" : "enabled";
|
|
856
|
+
debugLog(
|
|
857
|
+
`Plugin loaded: v${config.hookVersion}, api=${config.apiUrl}, privacy=${config.privacyTier}, e2e=${e2eStatus}, debug=${config.debug}`
|
|
858
|
+
);
|
|
859
|
+
debugLog(`Full config: agent=${config.agentName}, timeout=${config.timeout}s, fail=${config.failBehavior}`);
|
|
719
860
|
}
|
|
720
861
|
api.on("before_tool_call", async (event, ctx) => {
|
|
721
|
-
const conversationId = resolveConversationId(
|
|
862
|
+
const conversationId = resolveConversationId();
|
|
722
863
|
const { toolType, displayName } = classifyTool(event.toolName, event.params);
|
|
723
864
|
const command = extractCommand(event.toolName, event.params);
|
|
724
865
|
const request = {
|
|
@@ -758,7 +899,7 @@ function register(api) {
|
|
|
758
899
|
}
|
|
759
900
|
});
|
|
760
901
|
api.on("after_tool_call", async (event, ctx) => {
|
|
761
|
-
const conversationId = resolveConversationId(
|
|
902
|
+
const conversationId = resolveConversationId();
|
|
762
903
|
if (isDuplicateCompletion(event.toolName, event.params)) {
|
|
763
904
|
if (config.debug) {
|
|
764
905
|
debugLog(`Skipping duplicate tool_complete for "${event.toolName}"`);
|
|
@@ -783,7 +924,7 @@ function register(api) {
|
|
|
783
924
|
}, config, pluginFilePath);
|
|
784
925
|
});
|
|
785
926
|
api.on("session_start", async (event, ctx) => {
|
|
786
|
-
const conversationId = resolveConversationId(
|
|
927
|
+
const conversationId = resolveConversationId();
|
|
787
928
|
if (config.debug) {
|
|
788
929
|
debugLog(`Session started: ${event.sessionId}${event.resumedFrom ? ` (resumed from ${event.resumedFrom})` : ""}`);
|
|
789
930
|
}
|
|
@@ -797,7 +938,7 @@ function register(api) {
|
|
|
797
938
|
}, config, pluginFilePath);
|
|
798
939
|
});
|
|
799
940
|
api.on("session_end", async (event, ctx) => {
|
|
800
|
-
const conversationId = resolveConversationId(
|
|
941
|
+
const conversationId = resolveConversationId();
|
|
801
942
|
if (config.debug) {
|
|
802
943
|
debugLog(`Session ended: ${event.sessionId} (${event.messageCount} messages, ${event.durationMs ?? "?"}ms)`);
|
|
803
944
|
}
|
|
@@ -813,7 +954,7 @@ function register(api) {
|
|
|
813
954
|
}, config, pluginFilePath);
|
|
814
955
|
});
|
|
815
956
|
api.on("llm_input", async (event, ctx) => {
|
|
816
|
-
const conversationId = resolveConversationId(
|
|
957
|
+
const conversationId = resolveConversationId();
|
|
817
958
|
if (config.debug) {
|
|
818
959
|
debugLog(`LLM input: model=${event.model}, prompt length=${event.prompt?.length ?? 0}`);
|
|
819
960
|
}
|
|
@@ -830,7 +971,7 @@ function register(api) {
|
|
|
830
971
|
}, config, pluginFilePath);
|
|
831
972
|
});
|
|
832
973
|
api.on("llm_output", async (event, ctx) => {
|
|
833
|
-
const conversationId = resolveConversationId(
|
|
974
|
+
const conversationId = resolveConversationId();
|
|
834
975
|
const responseText = event.assistantTexts?.join("\n") || "";
|
|
835
976
|
const textLength = responseText.length;
|
|
836
977
|
if (config.debug) {
|
|
@@ -850,7 +991,7 @@ function register(api) {
|
|
|
850
991
|
}, config, pluginFilePath);
|
|
851
992
|
});
|
|
852
993
|
api.on("agent_end", async (event, ctx) => {
|
|
853
|
-
const conversationId = resolveConversationId(
|
|
994
|
+
const conversationId = resolveConversationId();
|
|
854
995
|
if (config.debug) {
|
|
855
996
|
debugLog(`Agent ended: success=${event.success}${event.durationMs ? `, duration=${event.durationMs}ms` : ""}${event.error ? `, error=${event.error}` : ""}`);
|
|
856
997
|
}
|
|
@@ -867,7 +1008,7 @@ function register(api) {
|
|
|
867
1008
|
}, config, pluginFilePath);
|
|
868
1009
|
});
|
|
869
1010
|
api.on("before_compaction", async (event, ctx) => {
|
|
870
|
-
const conversationId = resolveConversationId(
|
|
1011
|
+
const conversationId = resolveConversationId();
|
|
871
1012
|
if (config.debug) {
|
|
872
1013
|
debugLog(`Context compaction: ${event.messageCount} messages${event.tokenCount ? `, ${event.tokenCount} tokens` : ""}`);
|
|
873
1014
|
}
|
|
@@ -882,7 +1023,7 @@ function register(api) {
|
|
|
882
1023
|
}, config, pluginFilePath);
|
|
883
1024
|
});
|
|
884
1025
|
api.on("subagent_spawned", async (event, ctx) => {
|
|
885
|
-
const conversationId = resolveConversationId(
|
|
1026
|
+
const conversationId = resolveConversationId();
|
|
886
1027
|
if (config.debug) {
|
|
887
1028
|
debugLog(`Subagent spawned: ${event.agentId} (${event.mode}${event.label ? `, label=${event.label}` : ""})`);
|
|
888
1029
|
}
|
|
@@ -899,7 +1040,7 @@ function register(api) {
|
|
|
899
1040
|
}, config, pluginFilePath);
|
|
900
1041
|
});
|
|
901
1042
|
api.on("subagent_ended", async (event, ctx) => {
|
|
902
|
-
const conversationId = resolveConversationId(
|
|
1043
|
+
const conversationId = resolveConversationId();
|
|
903
1044
|
if (config.debug) {
|
|
904
1045
|
debugLog(`Subagent ended: ${event.targetKind} reason=${event.reason}${event.outcome ? `, outcome=${event.outcome}` : ""}`);
|
|
905
1046
|
}
|
|
@@ -932,8 +1073,8 @@ function register(api) {
|
|
|
932
1073
|
eventType: eventTypeMap[event.action] || "command_event",
|
|
933
1074
|
agent: config.agentName,
|
|
934
1075
|
hookType: "command_event",
|
|
935
|
-
sessionId: resolveConversationId(
|
|
936
|
-
conversationId: resolveConversationId(
|
|
1076
|
+
sessionId: resolveConversationId(),
|
|
1077
|
+
conversationId: resolveConversationId(),
|
|
937
1078
|
timestamp: event.timestamp.toISOString()
|
|
938
1079
|
}, config, pluginFilePath);
|
|
939
1080
|
},
|
|
@@ -955,8 +1096,8 @@ function register(api) {
|
|
|
955
1096
|
eventType: isInbound ? "user_prompt" : "response",
|
|
956
1097
|
agent: config.agentName,
|
|
957
1098
|
hookType: "session_event",
|
|
958
|
-
sessionId: resolveConversationId(
|
|
959
|
-
conversationId: resolveConversationId(
|
|
1099
|
+
sessionId: resolveConversationId(),
|
|
1100
|
+
conversationId: resolveConversationId(),
|
|
960
1101
|
timestamp: event.timestamp.toISOString(),
|
|
961
1102
|
cwd: channelLabel
|
|
962
1103
|
};
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw",
|
|
3
3
|
"name": "Agent Approve",
|
|
4
4
|
"description": "Mobile approval for AI agent tool execution. Approve or deny tool calls from your iPhone and Apple Watch.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.6",
|
|
6
6
|
"homepage": "https://agentapprove.com",
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/package.json
CHANGED