@imbrace/cli 0.1.0
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/bin/run.js +5 -0
- package/dist/base-command.d.ts +8 -0
- package/dist/base-command.js +48 -0
- package/dist/commands/ai-agent/create.d.ts +28 -0
- package/dist/commands/ai-agent/create.js +86 -0
- package/dist/commands/ai-agent/delete.d.ts +13 -0
- package/dist/commands/ai-agent/delete.js +39 -0
- package/dist/commands/ai-agent/get.d.ts +12 -0
- package/dist/commands/ai-agent/get.js +42 -0
- package/dist/commands/ai-agent/list-models.d.ts +10 -0
- package/dist/commands/ai-agent/list-models.js +36 -0
- package/dist/commands/ai-agent/list-providers.d.ts +9 -0
- package/dist/commands/ai-agent/list-providers.js +37 -0
- package/dist/commands/ai-agent/list.d.ts +9 -0
- package/dist/commands/ai-agent/list.js +36 -0
- package/dist/commands/ai-agent/update.d.ts +30 -0
- package/dist/commands/ai-agent/update.js +100 -0
- package/dist/commands/data-board/create-field.d.ts +14 -0
- package/dist/commands/data-board/create-field.js +46 -0
- package/dist/commands/data-board/create-item.d.ts +13 -0
- package/dist/commands/data-board/create-item.js +72 -0
- package/dist/commands/data-board/create.d.ts +10 -0
- package/dist/commands/data-board/create.js +45 -0
- package/dist/commands/data-board/delete-item.d.ts +14 -0
- package/dist/commands/data-board/delete-item.js +42 -0
- package/dist/commands/data-board/export-csv.d.ts +10 -0
- package/dist/commands/data-board/export-csv.js +34 -0
- package/dist/commands/data-board/list-items.d.ts +13 -0
- package/dist/commands/data-board/list-items.js +47 -0
- package/dist/commands/data-board/list.d.ts +9 -0
- package/dist/commands/data-board/list.js +33 -0
- package/dist/commands/data-board/update-item.d.ts +14 -0
- package/dist/commands/data-board/update-item.js +57 -0
- package/dist/commands/login.d.ts +12 -0
- package/dist/commands/login.js +71 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.js +10 -0
- package/dist/commands/whoami.d.ts +9 -0
- package/dist/commands/whoami.js +29 -0
- package/dist/commands/workflow/create.d.ts +12 -0
- package/dist/commands/workflow/create.js +45 -0
- package/dist/commands/workflow/delete.d.ts +13 -0
- package/dist/commands/workflow/delete.js +40 -0
- package/dist/commands/workflow/get.d.ts +12 -0
- package/dist/commands/workflow/get.js +54 -0
- package/dist/commands/workflow/list.d.ts +9 -0
- package/dist/commands/workflow/list.js +36 -0
- package/dist/commands/workflow/node/add.d.ts +20 -0
- package/dist/commands/workflow/node/add.js +72 -0
- package/dist/commands/workflow/node/delete.d.ts +14 -0
- package/dist/commands/workflow/node/delete.js +40 -0
- package/dist/commands/workflow/node/list.d.ts +12 -0
- package/dist/commands/workflow/node/list.js +40 -0
- package/dist/commands/workflow/node/update.d.ts +15 -0
- package/dist/commands/workflow/node/update.js +47 -0
- package/dist/commands/workflow/piece/detail.d.ts +13 -0
- package/dist/commands/workflow/piece/detail.js +60 -0
- package/dist/commands/workflow/piece/list.d.ts +10 -0
- package/dist/commands/workflow/piece/list.js +40 -0
- package/dist/commands/workflow/run-detail.d.ts +12 -0
- package/dist/commands/workflow/run-detail.js +50 -0
- package/dist/commands/workflow/runs.d.ts +10 -0
- package/dist/commands/workflow/runs.js +40 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.js +36 -0
- package/dist/http.d.ts +9 -0
- package/dist/http.js +40 -0
- package/dist/select-board.d.ts +1 -0
- package/dist/select-board.js +12 -0
- package/package.json +71 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { confirm, input } from "@inquirer/prompts";
|
|
4
|
+
import { apiRequest } from "../../http.js";
|
|
5
|
+
export default class WorkflowDelete extends BaseCommand {
|
|
6
|
+
static description = "Delete a workflow";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow delete <flowId> --yes",
|
|
9
|
+
"imbrace workflow delete <flowId> --yes --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
id: Args.string({ description: "Workflow ID" }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
yes: Flags.boolean({ char: "y", description: "Skip confirmation" }),
|
|
16
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
17
|
+
};
|
|
18
|
+
async run() {
|
|
19
|
+
const { args, flags } = await this.parse(WorkflowDelete);
|
|
20
|
+
const id = args.id ?? (flags.json ? this.error("ID is required") : await input({ message: "Workflow ID:" }));
|
|
21
|
+
if (!flags.yes && !flags.json) {
|
|
22
|
+
const ok = await confirm({ message: `Delete workflow ${id}?`, default: false });
|
|
23
|
+
if (!ok) {
|
|
24
|
+
this.log("Cancelled.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const res = await apiRequest(`/workflow/${id}`, { method: "DELETE" });
|
|
30
|
+
if (flags.json) {
|
|
31
|
+
this.log(JSON.stringify(res, null, 2));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.error(`Failed: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowGet extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { input } from "@inquirer/prompts";
|
|
4
|
+
import { apiRequest } from "../../http.js";
|
|
5
|
+
export default class WorkflowGet extends BaseCommand {
|
|
6
|
+
static description = "Get details of a workflow (including node tree)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow get <flowId>",
|
|
9
|
+
"imbrace workflow get <flowId> --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
id: Args.string({ description: "Workflow ID" }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args, flags } = await this.parse(WorkflowGet);
|
|
19
|
+
const id = args.id ?? (flags.json ? this.error("ID is required") : await input({ message: "Workflow ID:" }));
|
|
20
|
+
try {
|
|
21
|
+
const res = await apiRequest(`/workflow/${id}`);
|
|
22
|
+
if (flags.json) {
|
|
23
|
+
this.log(JSON.stringify(res, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const f = res.data || {};
|
|
27
|
+
const v = f.version || {};
|
|
28
|
+
this.log(`\n ID: ${f.id || ""}`);
|
|
29
|
+
this.log(` Name: ${v.displayName || ""}`);
|
|
30
|
+
this.log(` Status: ${f.status || ""}`);
|
|
31
|
+
this.log(` Project ID: ${f.projectId || ""}`);
|
|
32
|
+
this.log(` Created: ${f.created || ""}`);
|
|
33
|
+
this.log(` Updated: ${f.updated || ""}`);
|
|
34
|
+
// Print node tree
|
|
35
|
+
this.log(`\n Node tree:`);
|
|
36
|
+
let cur = v.trigger;
|
|
37
|
+
let depth = 0;
|
|
38
|
+
while (cur && depth < 20) {
|
|
39
|
+
const indent = " ".repeat(depth);
|
|
40
|
+
const piece = cur.settings?.pieceName || "";
|
|
41
|
+
const action = cur.settings?.actionName || cur.settings?.triggerName || "";
|
|
42
|
+
this.log(` ${indent}${cur.name || "(unnamed)"} [${cur.type}] ${piece}${action ? ` :: ${action}` : ""}`);
|
|
43
|
+
cur = cur.nextAction;
|
|
44
|
+
depth++;
|
|
45
|
+
}
|
|
46
|
+
if (!v.trigger)
|
|
47
|
+
this.log(" (empty — no trigger set)");
|
|
48
|
+
this.log("");
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.error(`Failed: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../http.js";
|
|
4
|
+
export default class WorkflowList extends BaseCommand {
|
|
5
|
+
static description = "List all workflows (Activepieces flows)";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow list",
|
|
8
|
+
"imbrace workflow list --json",
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = await this.parse(WorkflowList);
|
|
15
|
+
try {
|
|
16
|
+
const res = await apiRequest("/workflow/list");
|
|
17
|
+
if (flags.json) {
|
|
18
|
+
this.log(JSON.stringify(res, null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.log(`\n Found ${res.count} workflow(s):\n`);
|
|
22
|
+
this.log(" ID NAME STATUS");
|
|
23
|
+
this.log(" ────────────────────────────────────────────────────────────────────");
|
|
24
|
+
for (const flow of res.data || []) {
|
|
25
|
+
const id = (flow.id || "").padEnd(24);
|
|
26
|
+
const name = (flow.version?.displayName || "").padEnd(36);
|
|
27
|
+
const status = flow.status || "";
|
|
28
|
+
this.log(` ${id} ${name} ${status}`);
|
|
29
|
+
}
|
|
30
|
+
this.log("");
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
this.error(`Failed: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowNodeAdd extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
flowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
piece: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
"trigger-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
"action-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
after: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
"display-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
input: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../../http.js";
|
|
4
|
+
export default class WorkflowNodeAdd extends BaseCommand {
|
|
5
|
+
static description = "Add a trigger or action node to a workflow";
|
|
6
|
+
static examples = [
|
|
7
|
+
'imbrace workflow node add <flowId> --type trigger --piece webhook --trigger-name catch_webhook --json',
|
|
8
|
+
'imbrace workflow node add <flowId> --type action --piece slack --action-name send_channel_message --input \'{"channel":"C1","text":"hi"}\' --json',
|
|
9
|
+
'imbrace workflow node add <flowId> --type action --piece ai-connector --action-name ask --after step_1 --input \'{"prompt":"hello","modelName":"gpt-4o"}\' --json',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
type: Flags.string({ description: "Node type", options: ["trigger", "action"], required: true }),
|
|
16
|
+
piece: Flags.string({ description: "Piece name (e.g. 'slack' or '@activepieces/piece-slack')", required: true }),
|
|
17
|
+
"trigger-name": Flags.string({ description: "Trigger identifier (when --type trigger)" }),
|
|
18
|
+
"action-name": Flags.string({ description: "Action identifier (when --type action)" }),
|
|
19
|
+
after: Flags.string({ description: "Place new action after this step name (default: end of chain)" }),
|
|
20
|
+
name: Flags.string({ description: "Override auto-generated step_N name" }),
|
|
21
|
+
"display-name": Flags.string({ description: "UI display name" }),
|
|
22
|
+
input: Flags.string({ description: "JSON string with field values (e.g. '{\"channel\":\"C1\",\"text\":\"hi\"}')" }),
|
|
23
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { args, flags } = await this.parse(WorkflowNodeAdd);
|
|
27
|
+
if (flags.type === "trigger" && !flags["trigger-name"]) {
|
|
28
|
+
this.error("--trigger-name is required when --type=trigger");
|
|
29
|
+
}
|
|
30
|
+
if (flags.type === "action" && !flags["action-name"]) {
|
|
31
|
+
this.error("--action-name is required when --type=action");
|
|
32
|
+
}
|
|
33
|
+
let parsedInput = {};
|
|
34
|
+
if (flags.input) {
|
|
35
|
+
try {
|
|
36
|
+
parsedInput = JSON.parse(flags.input);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
this.error(`--input is not valid JSON: ${e.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const body = {
|
|
43
|
+
type: flags.type,
|
|
44
|
+
piece: flags.piece,
|
|
45
|
+
input: parsedInput,
|
|
46
|
+
};
|
|
47
|
+
if (flags["trigger-name"])
|
|
48
|
+
body.triggerName = flags["trigger-name"];
|
|
49
|
+
if (flags["action-name"])
|
|
50
|
+
body.actionName = flags["action-name"];
|
|
51
|
+
if (flags.after)
|
|
52
|
+
body.after = flags.after;
|
|
53
|
+
if (flags.name)
|
|
54
|
+
body.name = flags.name;
|
|
55
|
+
if (flags["display-name"])
|
|
56
|
+
body.displayName = flags["display-name"];
|
|
57
|
+
try {
|
|
58
|
+
const res = await apiRequest(`/workflow/${args.flowId}/nodes`, { method: "POST", body });
|
|
59
|
+
if (flags.json) {
|
|
60
|
+
this.log(JSON.stringify(res, null, 2));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.log(`\n✅ ${res.message}`);
|
|
64
|
+
if (res.data?.stepName)
|
|
65
|
+
this.log(` Step: ${res.data.stepName} (after ${res.data.parentStep})`);
|
|
66
|
+
this.log("");
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.error(`Failed: ${error.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowNodeDelete extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
flowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
nodeName: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
import { apiRequest } from "../../../http.js";
|
|
5
|
+
export default class WorkflowNodeDelete extends BaseCommand {
|
|
6
|
+
static description = "Delete an action node from a workflow (cannot delete trigger — replace it via `node add --type trigger`)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow node delete <flowId> step_1 --yes",
|
|
9
|
+
"imbrace workflow node delete <flowId> step_2 --yes --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
13
|
+
nodeName: Args.string({ description: "Node name (e.g. 'step_1')", required: true }),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
yes: Flags.boolean({ char: "y", description: "Skip confirmation" }),
|
|
17
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(WorkflowNodeDelete);
|
|
21
|
+
if (!flags.yes && !flags.json) {
|
|
22
|
+
const ok = await confirm({ message: `Delete node "${args.nodeName}" from flow ${args.flowId}?`, default: false });
|
|
23
|
+
if (!ok) {
|
|
24
|
+
this.log("Cancelled.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const res = await apiRequest(`/workflow/${args.flowId}/nodes/${args.nodeName}`, { method: "DELETE" });
|
|
30
|
+
if (flags.json) {
|
|
31
|
+
this.log(JSON.stringify(res, null, 2));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.error(`Failed: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowNodeList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
flowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../../http.js";
|
|
4
|
+
export default class WorkflowNodeList extends BaseCommand {
|
|
5
|
+
static description = "List nodes (trigger + actions) of a workflow";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow node list <flowId>",
|
|
8
|
+
"imbrace workflow node list <flowId> --json",
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(WorkflowNodeList);
|
|
18
|
+
try {
|
|
19
|
+
const res = await apiRequest(`/workflow/${args.flowId}/nodes`);
|
|
20
|
+
if (flags.json) {
|
|
21
|
+
this.log(JSON.stringify(res, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
this.log(`\n Found ${res.count} node(s):\n`);
|
|
25
|
+
this.log(" NAME TYPE PIECE ACTION/TRIGGER");
|
|
26
|
+
this.log(" ─────────────────────────────────────────────────────────────────────────────────");
|
|
27
|
+
for (const n of res.data || []) {
|
|
28
|
+
const name = (n.name || "").padEnd(10);
|
|
29
|
+
const type = (n.type || "").padEnd(16);
|
|
30
|
+
const piece = (n.pieceName || "-").padEnd(38);
|
|
31
|
+
const at = n.actionName || n.triggerName || "-";
|
|
32
|
+
this.log(` ${name} ${type} ${piece} ${at}`);
|
|
33
|
+
}
|
|
34
|
+
this.log("");
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.error(`Failed: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowNodeUpdate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
flowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
nodeName: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
input: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
"display-name": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../../http.js";
|
|
4
|
+
export default class WorkflowNodeUpdate extends BaseCommand {
|
|
5
|
+
static description = "Update a node's input or display name (preserves piece + action/trigger)";
|
|
6
|
+
static examples = [
|
|
7
|
+
'imbrace workflow node update <flowId> step_1 --input \'{"prompt":"new prompt"}\' --json',
|
|
8
|
+
'imbrace workflow node update <flowId> step_1 --display-name "Ask AI" --json',
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
12
|
+
nodeName: Args.string({ description: "Node name (e.g. 'trigger', 'step_1')", required: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
input: Flags.string({ description: "New JSON input (replaces current)" }),
|
|
16
|
+
"display-name": Flags.string({ description: "New display name" }),
|
|
17
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(WorkflowNodeUpdate);
|
|
21
|
+
if (!flags.input && !flags["display-name"]) {
|
|
22
|
+
this.error("Provide at least --input or --display-name to update");
|
|
23
|
+
}
|
|
24
|
+
const body = {};
|
|
25
|
+
if (flags.input) {
|
|
26
|
+
try {
|
|
27
|
+
body.input = JSON.parse(flags.input);
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
this.error(`--input is not valid JSON: ${e.message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (flags["display-name"])
|
|
34
|
+
body.displayName = flags["display-name"];
|
|
35
|
+
try {
|
|
36
|
+
const res = await apiRequest(`/workflow/${args.flowId}/nodes/${args.nodeName}`, { method: "PUT", body });
|
|
37
|
+
if (flags.json) {
|
|
38
|
+
this.log(JSON.stringify(res, null, 2));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.error(`Failed: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowPieceDetail extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
piece: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
only: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { input } from "@inquirer/prompts";
|
|
4
|
+
import { apiRequest } from "../../../http.js";
|
|
5
|
+
export default class WorkflowPieceDetail extends BaseCommand {
|
|
6
|
+
static description = "Get full piece schema (actions + triggers + input fields)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow piece detail slack",
|
|
9
|
+
'imbrace workflow piece detail "@activepieces/piece-slack" --json',
|
|
10
|
+
"imbrace workflow piece detail slack --only actions",
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
piece: Args.string({ description: "Piece name (e.g. 'slack' or '@activepieces/piece-slack')" }),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
only: Flags.string({ description: "Show only one section: actions | triggers", options: ["actions", "triggers"] }),
|
|
17
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(WorkflowPieceDetail);
|
|
21
|
+
const piece = args.piece ?? (flags.json ? this.error("piece is required") : await input({ message: "Piece name (e.g. slack):" }));
|
|
22
|
+
try {
|
|
23
|
+
const res = await apiRequest(`/workflow/piece/detail?name=${encodeURIComponent(piece)}`);
|
|
24
|
+
if (flags.json) {
|
|
25
|
+
this.log(JSON.stringify(res, null, 2));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const d = res.data || {};
|
|
29
|
+
this.log(`\n ${d.displayName} (${d.name})`);
|
|
30
|
+
this.log(` ${d.description || ""}`);
|
|
31
|
+
this.log(` Version: ${d.version} Categories: ${(d.categories || []).join(", ")}`);
|
|
32
|
+
const actions = d.actions || {};
|
|
33
|
+
const triggers = d.triggers || {};
|
|
34
|
+
if (flags.only !== "triggers") {
|
|
35
|
+
this.log(`\n ACTIONS (${Object.keys(actions).length}):`);
|
|
36
|
+
for (const [name, a] of Object.entries(actions)) {
|
|
37
|
+
this.log(` ${name}`);
|
|
38
|
+
this.log(` ${a.displayName} — ${(a.description || "").slice(0, 80)}`);
|
|
39
|
+
const props = Object.keys(a.props || {}).slice(0, 6).join(", ");
|
|
40
|
+
if (props)
|
|
41
|
+
this.log(` props: ${props}${Object.keys(a.props).length > 6 ? ", ..." : ""}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (flags.only !== "actions") {
|
|
45
|
+
this.log(`\n TRIGGERS (${Object.keys(triggers).length}):`);
|
|
46
|
+
for (const [name, t] of Object.entries(triggers)) {
|
|
47
|
+
this.log(` ${name}`);
|
|
48
|
+
this.log(` ${t.displayName} — ${(t.description || "").slice(0, 80)}`);
|
|
49
|
+
const props = Object.keys(t.props || {}).slice(0, 6).join(", ");
|
|
50
|
+
if (props)
|
|
51
|
+
this.log(` props: ${props}${Object.keys(t.props).length > 6 ? ", ..." : ""}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this.log("");
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
this.error(`Failed: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowPieceList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../../http.js";
|
|
4
|
+
export default class WorkflowPieceList extends BaseCommand {
|
|
5
|
+
static description = "List available integrations (pieces) for use in workflow nodes";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow piece list",
|
|
8
|
+
'imbrace workflow piece list --search slack',
|
|
9
|
+
"imbrace workflow piece list --json",
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
search: Flags.string({ char: "s", description: "Filter by name/displayName/description (case-insensitive)" }),
|
|
13
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
14
|
+
};
|
|
15
|
+
async run() {
|
|
16
|
+
const { flags } = await this.parse(WorkflowPieceList);
|
|
17
|
+
const qs = flags.search ? `?search=${encodeURIComponent(flags.search)}` : "";
|
|
18
|
+
try {
|
|
19
|
+
const res = await apiRequest(`/workflow/piece/list${qs}`);
|
|
20
|
+
if (flags.json) {
|
|
21
|
+
this.log(JSON.stringify(res, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
this.log(`\n Found ${res.count} piece(s)${flags.search ? ` matching "${flags.search}"` : ""}:\n`);
|
|
25
|
+
this.log(" NAME DISPLAY A T");
|
|
26
|
+
this.log(" ──────────────────────────────────────────────────────────────────────────────────");
|
|
27
|
+
for (const p of res.data || []) {
|
|
28
|
+
const name = (p.name || "").padEnd(45);
|
|
29
|
+
const display = (p.displayName || "").padEnd(32);
|
|
30
|
+
const a = String(p.actions ?? 0).padStart(2);
|
|
31
|
+
const t = String(p.triggers ?? 0).padStart(2);
|
|
32
|
+
this.log(` ${name} ${display} ${a} ${t}`);
|
|
33
|
+
}
|
|
34
|
+
this.log(`\n A=actions, T=triggers. Run 'imbrace workflow piece detail --name <pieceName>' for full schema.\n`);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.error(`Failed: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowRunDetail extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
runId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { input } from "@inquirer/prompts";
|
|
4
|
+
import { apiRequest } from "../../http.js";
|
|
5
|
+
export default class WorkflowRunDetail extends BaseCommand {
|
|
6
|
+
static description = "Get details of a single workflow run (status, failed step, timing)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow run-detail <runId>",
|
|
9
|
+
"imbrace workflow run-detail <runId> --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
runId: Args.string({ description: "Run ID" }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args, flags } = await this.parse(WorkflowRunDetail);
|
|
19
|
+
const runId = args.runId ?? (flags.json ? this.error("Run ID is required") : await input({ message: "Run ID:" }));
|
|
20
|
+
try {
|
|
21
|
+
const res = await apiRequest(`/workflow/runs/${runId}`);
|
|
22
|
+
if (flags.json) {
|
|
23
|
+
this.log(JSON.stringify(res, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const r = res.data || {};
|
|
27
|
+
const dur = r.startTime && r.finishTime
|
|
28
|
+
? `${((new Date(r.finishTime).getTime() - new Date(r.startTime).getTime()) / 1000).toFixed(2)}s`
|
|
29
|
+
: "—";
|
|
30
|
+
this.log(`\n Run ID: ${r.id || ""}`);
|
|
31
|
+
this.log(` Flow ID: ${r.flowId || ""}`);
|
|
32
|
+
this.log(` Flow name: ${r.flowVersion?.displayName || ""}`);
|
|
33
|
+
this.log(` Status: ${r.status || ""}`);
|
|
34
|
+
this.log(` Environment: ${r.environment || ""}`);
|
|
35
|
+
this.log(` Started: ${r.startTime || ""}`);
|
|
36
|
+
this.log(` Finished: ${r.finishTime || ""}`);
|
|
37
|
+
this.log(` Duration: ${dur}`);
|
|
38
|
+
if (r.failedStep && Object.keys(r.failedStep).length > 0) {
|
|
39
|
+
this.log(` Failed step: ${JSON.stringify(r.failedStep)}`);
|
|
40
|
+
}
|
|
41
|
+
if (r.logsFileId) {
|
|
42
|
+
this.log(` Logs file ID: ${r.logsFileId}`);
|
|
43
|
+
}
|
|
44
|
+
this.log("");
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.error(`Failed: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowRuns extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|