Skip to content

Commit 01f2539

Browse files
committed
Require approval before flow_run, bump to 0.9.4
Register a before_tool_call hook that returns requireApproval for flow_run invocations. Flows can have side effects (HTTP, exec, agent delegation) so explicit user consent is required before each run.
1 parent 13ad685 commit 01f2539

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@clawnify/clawflow",
3-
"version": "0.9.3",
3+
"version": "0.9.4",
44
"description": "The n8n for agents. A declarative, AI-native workflow format that agents can read, write, and run.",
55
"type": "module",
66
"main": "./dist/index.js",

src/plugin/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ import type { FlowDefinition, FlowNode, PluginConfig, BranchNode, ConditionNode,
2121

2222
interface PluginApi {
2323
registerTool: (def: object, opts?: { optional?: boolean }) => void;
24+
registerHook?: (
25+
name: string,
26+
handler: (event: { tool?: string; params?: unknown; [k: string]: unknown }) =>
27+
| { requireApproval?: boolean; prompt?: string; block?: boolean }
28+
| void
29+
| Promise<{ requireApproval?: boolean; prompt?: string; block?: boolean } | void>,
30+
opts?: { priority?: number },
31+
) => void;
2432
config?: {
2533
plugins?: { entries?: Record<string, { config?: PluginConfig }> };
2634
gateway?: { port?: number; host?: string };
@@ -66,6 +74,27 @@ function register(api: PluginApi) {
6674
});
6775
}
6876

77+
// ---- Approval gate for flow_run -----------------------------------------------
78+
// Pause and prompt the user before any flow_run invocation. Flows can have
79+
// side effects (HTTP, exec, agent delegation) so we require explicit consent.
80+
if (api.registerHook) {
81+
api.registerHook("before_tool_call", (event) => {
82+
if (event.tool !== "flow_run") return;
83+
const p = (event.params ?? {}) as { file?: string; flow?: { flow?: string }; version?: number; draft?: boolean };
84+
const target = p.file ?? p.flow?.flow ?? "inline flow";
85+
const variant =
86+
p.version != null ? ` v${p.version}` : p.draft ? " (draft)" : "";
87+
return {
88+
requireApproval: true,
89+
prompt: `Run clawflow "${target}"${variant}?`,
90+
};
91+
});
92+
} else {
93+
api.logger?.warn(
94+
"clawflow: registerHook unavailable — flow_run will run without approval gate. Update OpenClaw to enable.",
95+
);
96+
}
97+
6998
// ---- Shared helpers ------------------------------------------------------------
7099

71100
/** Resolve a file param to an absolute path using workspace conventions. */

0 commit comments

Comments
 (0)