Skip to content

Commit 0ada57f

Browse files
committed
Add flow_list tool, bump to 0.8.3
1 parent c4902a9 commit 0ada57f

File tree

2 files changed

+117
-2
lines changed

2 files changed

+117
-2
lines changed

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.8.2",
3+
"version": "0.8.3",
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: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { validateFlow } from "../core/validate.js";
55
import type { FlowDefinition, FlowNode, PluginConfig, BranchNode, ConditionNode, LoopNode, ParallelNode } from "../core/types.js";
66

77
// ---- OpenClaw Plugin: clawflow ---------------------------------------------------
8-
// Registers nine tools:
8+
// Registers ten tools:
99
//
1010
// flow_create — create a new flow definition and save to file
1111
// flow_delete — soft-delete a flow (moves to .bin/)
@@ -14,6 +14,7 @@ import type { FlowDefinition, FlowNode, PluginConfig, BranchNode, ConditionNode,
1414
// flow_resume — resume after approval gate
1515
// flow_send_event — push an event into a waiting flow
1616
// flow_status — inspect a running/completed flow instance
17+
// flow_list — list all saved flow definitions in the workspace
1718
// flow_transpile — convert a .flow definition to Cloudflare Workers TS
1819
// flow_edit — edit nodes in a flow definition (file or inline)
1920

@@ -678,6 +679,120 @@ Status values: running | completed | paused | waiting | failed | cancelled`,
678679
{ optional: true },
679680
);
680681

682+
// ---- flow_list ----------------------------------------------------------------
683+
684+
api.registerTool(
685+
{
686+
name: "flow_list",
687+
description: `List all saved flow definitions in the workspace.
688+
689+
Scans the flows directory for .json files and returns a summary of each flow
690+
including its name, description, trigger, version, node count, and file path.
691+
Use this to discover available flows before running or editing them.`,
692+
693+
parameters: {
694+
type: "object",
695+
properties: {
696+
dir: {
697+
type: "string",
698+
description:
699+
"Directory to scan. Defaults to workspace/flows/. Absolute paths are used as-is; relative paths resolve from the workspace root.",
700+
},
701+
},
702+
},
703+
704+
async execute(
705+
_id: string,
706+
params: { dir?: string },
707+
) {
708+
const fs = await import("fs");
709+
const path = await import("path");
710+
711+
const base = process.env.OPENCLAW_WORKSPACE ?? process.cwd();
712+
713+
let dir: string;
714+
if (!params.dir) {
715+
dir = path.join(base, "flows");
716+
} else if (params.dir.startsWith("/")) {
717+
dir = params.dir;
718+
} else {
719+
dir = path.join(base, params.dir);
720+
}
721+
722+
if (!fs.existsSync(dir)) {
723+
return {
724+
content: [
725+
{
726+
type: "text",
727+
text: `Flows directory not found: ${dir}`,
728+
},
729+
],
730+
};
731+
}
732+
733+
const files = fs.readdirSync(dir).filter((f: string) => f.endsWith(".json"));
734+
735+
if (files.length === 0) {
736+
return {
737+
content: [
738+
{
739+
type: "text",
740+
text: `No flow files found in ${dir}`,
741+
},
742+
],
743+
};
744+
}
745+
746+
const flows: Array<{
747+
file: string;
748+
flow: string;
749+
description?: string;
750+
version?: string;
751+
trigger?: unknown;
752+
nodes: number;
753+
}> = [];
754+
755+
for (const file of files) {
756+
const abs = path.join(dir, file);
757+
try {
758+
const raw = fs.readFileSync(abs, "utf-8");
759+
const def = JSON.parse(raw) as FlowDefinition;
760+
if (!def.flow || !Array.isArray(def.nodes)) continue;
761+
flows.push({
762+
file: abs,
763+
flow: def.flow,
764+
...(def.description && { description: def.description }),
765+
...(def.version && { version: def.version }),
766+
...(def.trigger && { trigger: def.trigger }),
767+
nodes: def.nodes.length,
768+
});
769+
} catch {
770+
// skip non-flow JSON files
771+
}
772+
}
773+
774+
if (flows.length === 0) {
775+
return {
776+
content: [
777+
{
778+
type: "text",
779+
text: `No valid flow definitions found in ${dir}`,
780+
},
781+
],
782+
};
783+
}
784+
785+
return {
786+
content: [
787+
{ type: "text", text: JSON.stringify(flows, null, 2) },
788+
],
789+
details: flows,
790+
};
791+
},
792+
},
793+
{ optional: true },
794+
);
795+
681796
// ---- flow_transpile -----------------------------------------------------------
682797

683798
api.registerTool(

0 commit comments

Comments
 (0)