@imbrace/cli 0.1.0 → 0.3.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/README.md +443 -0
- package/dist/commands/ai-agent/create.d.ts +5 -0
- package/dist/commands/ai-agent/create.js +11 -0
- package/dist/commands/ai-agent/list-files.d.ts +10 -0
- package/dist/commands/ai-agent/list-files.js +40 -0
- package/dist/commands/ai-agent/list-folders.d.ts +10 -0
- package/dist/commands/ai-agent/list-folders.js +39 -0
- package/dist/commands/ai-agent/list-providers.js +1 -1
- package/dist/commands/ai-agent/update.d.ts +5 -0
- package/dist/commands/ai-agent/update.js +16 -0
- package/dist/commands/docs.d.ts +10 -0
- package/dist/commands/docs.js +39 -0
- package/dist/commands/workflow/conn/create.d.ts +15 -0
- package/dist/commands/workflow/conn/create.js +69 -0
- package/dist/commands/workflow/conn/delete.d.ts +13 -0
- package/dist/commands/workflow/conn/delete.js +39 -0
- package/dist/commands/workflow/conn/get.d.ts +12 -0
- package/dist/commands/workflow/conn/get.js +42 -0
- package/dist/commands/workflow/conn/list.d.ts +9 -0
- package/dist/commands/workflow/conn/list.js +37 -0
- package/dist/commands/workflow/create.d.ts +1 -0
- package/dist/commands/workflow/create.js +4 -0
- package/dist/commands/workflow/disable.d.ts +12 -0
- package/dist/commands/workflow/disable.js +30 -0
- package/dist/commands/workflow/enable.d.ts +12 -0
- package/dist/commands/workflow/enable.js +34 -0
- package/dist/commands/workflow/folder/create.d.ts +12 -0
- package/dist/commands/workflow/folder/create.js +43 -0
- package/dist/commands/workflow/folder/delete.d.ts +13 -0
- package/dist/commands/workflow/folder/delete.js +39 -0
- package/dist/commands/workflow/folder/get.d.ts +12 -0
- package/dist/commands/workflow/folder/get.js +38 -0
- package/dist/commands/workflow/folder/list.d.ts +9 -0
- package/dist/commands/workflow/folder/list.js +35 -0
- package/dist/commands/workflow/folder/update.d.ts +13 -0
- package/dist/commands/workflow/folder/update.js +30 -0
- package/dist/commands/workflow/list.d.ts +1 -0
- package/dist/commands/workflow/list.js +7 -1
- package/dist/commands/workflow/mcp/create.d.ts +12 -0
- package/dist/commands/workflow/mcp/create.js +44 -0
- package/dist/commands/workflow/mcp/delete.d.ts +13 -0
- package/dist/commands/workflow/mcp/delete.js +39 -0
- package/dist/commands/workflow/mcp/get.d.ts +12 -0
- package/dist/commands/workflow/mcp/get.js +40 -0
- package/dist/commands/workflow/mcp/list.d.ts +9 -0
- package/dist/commands/workflow/mcp/list.js +36 -0
- package/dist/commands/workflow/mcp/rotate-token.d.ts +13 -0
- package/dist/commands/workflow/mcp/rotate-token.js +46 -0
- package/dist/commands/workflow/move.d.ts +13 -0
- package/dist/commands/workflow/move.js +35 -0
- package/dist/commands/workflow/node/add-raw.d.ts +15 -0
- package/dist/commands/workflow/node/add-raw.js +70 -0
- package/dist/commands/workflow/publish.d.ts +12 -0
- package/dist/commands/workflow/publish.js +30 -0
- package/dist/commands/workflow/run.d.ts +14 -0
- package/dist/commands/workflow/run.js +50 -0
- package/llms.txt +625 -0
- package/package.json +12 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../../http.js";
|
|
4
|
+
export default class WorkflowFolderUpdate extends BaseCommand {
|
|
5
|
+
static description = "Rename a folder";
|
|
6
|
+
static examples = [
|
|
7
|
+
'imbrace workflow folder update <folderId> --name "New Name" --json',
|
|
8
|
+
];
|
|
9
|
+
static args = {
|
|
10
|
+
folderId: Args.string({ description: "Folder ID", required: true }),
|
|
11
|
+
};
|
|
12
|
+
static flags = {
|
|
13
|
+
name: Flags.string({ char: "n", description: "New folder name", required: true }),
|
|
14
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(WorkflowFolderUpdate);
|
|
18
|
+
try {
|
|
19
|
+
const res = await apiRequest(`/workflow/folder/${args.folderId}`, { method: "PUT", body: { name: flags.name } });
|
|
20
|
+
if (flags.json) {
|
|
21
|
+
this.log(JSON.stringify(res, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
this.error(`Failed: ${error.message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -3,6 +3,7 @@ export default class WorkflowList extends BaseCommand {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
+
"folder-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
7
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
8
|
};
|
|
8
9
|
run(): Promise<void>;
|
|
@@ -6,14 +6,20 @@ export default class WorkflowList extends BaseCommand {
|
|
|
6
6
|
static examples = [
|
|
7
7
|
"imbrace workflow list",
|
|
8
8
|
"imbrace workflow list --json",
|
|
9
|
+
"imbrace workflow list --folder-id <folderId>",
|
|
10
|
+
"imbrace workflow list --folder-id NULL # only unfiled flows",
|
|
9
11
|
];
|
|
10
12
|
static flags = {
|
|
13
|
+
"folder-id": Flags.string({
|
|
14
|
+
description: "Filter to flows in this folder. Use 'NULL' to show only unfiled flows. Use 'imbrace workflow folder list' to discover folder IDs.",
|
|
15
|
+
}),
|
|
11
16
|
json: Flags.boolean({ description: "Output as JSON" }),
|
|
12
17
|
};
|
|
13
18
|
async run() {
|
|
14
19
|
const { flags } = await this.parse(WorkflowList);
|
|
20
|
+
const qs = flags["folder-id"] ? `?folderId=${encodeURIComponent(flags["folder-id"])}` : "";
|
|
15
21
|
try {
|
|
16
|
-
const res = await apiRequest(
|
|
22
|
+
const res = await apiRequest(`/workflow/list${qs}`);
|
|
17
23
|
if (flags.json) {
|
|
18
24
|
this.log(JSON.stringify(res, null, 2));
|
|
19
25
|
return;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowMcpCreate extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"project-id": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
"id-only": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { 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 WorkflowMcpCreate extends BaseCommand {
|
|
6
|
+
static description = "Create a new MCP (Model Context Protocol) server. The token is shown once at creation — save it.";
|
|
7
|
+
static examples = [
|
|
8
|
+
'imbrace workflow mcp create --name "My MCP" --json',
|
|
9
|
+
'imbrace workflow mcp create --name "Claude MCP" --id-only',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
name: Flags.string({ char: "n", description: "MCP server name (required)" }),
|
|
13
|
+
"project-id": Flags.string({ description: "Project ID. Auto-discovered if omitted." }),
|
|
14
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
15
|
+
"id-only": Flags.boolean({ description: "Print only the new MCP ID (pipe-friendly)" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { flags } = await this.parse(WorkflowMcpCreate);
|
|
19
|
+
const nonInteractive = flags.json || flags["id-only"];
|
|
20
|
+
const name = flags.name ?? (nonInteractive ? this.error("--name is required with --json or --id-only") : await input({ message: "MCP name:" }));
|
|
21
|
+
const body = { name };
|
|
22
|
+
if (flags["project-id"])
|
|
23
|
+
body.projectId = flags["project-id"];
|
|
24
|
+
try {
|
|
25
|
+
const res = await apiRequest("/workflow/mcp/create", { method: "POST", body });
|
|
26
|
+
if (flags["id-only"]) {
|
|
27
|
+
this.log(res.data?.id ?? "");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (flags.json) {
|
|
31
|
+
this.log(JSON.stringify(res, null, 2));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const m = res.data || {};
|
|
35
|
+
this.log(`\n✅ ${res.message}`);
|
|
36
|
+
this.log(` ID: ${m.id}`);
|
|
37
|
+
this.log(` Token: ${m.token}`);
|
|
38
|
+
this.log(`\n ⚠️ Save the token now — it WON'T be shown again. Use 'mcp rotate-token <id>' to issue a new one.\n`);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
this.error(`Failed: ${error.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowMcpDelete extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
mcpId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 WorkflowMcpDelete extends BaseCommand {
|
|
6
|
+
static description = "Delete an MCP server. Any client using its token will lose access.";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow mcp delete <mcpId> --yes",
|
|
9
|
+
"imbrace workflow mcp delete <mcpId> --yes --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
mcpId: Args.string({ description: "MCP server ID", required: true }),
|
|
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(WorkflowMcpDelete);
|
|
20
|
+
if (!flags.yes && !flags.json) {
|
|
21
|
+
const ok = await confirm({ message: `Delete MCP server ${args.mcpId}?`, default: false });
|
|
22
|
+
if (!ok) {
|
|
23
|
+
this.log("Cancelled.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const res = await apiRequest(`/workflow/mcp/${args.mcpId}`, { method: "DELETE" });
|
|
29
|
+
if (flags.json) {
|
|
30
|
+
this.log(JSON.stringify(res, null, 2));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
this.error(`Failed: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowMcpGet extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
mcpId: 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,40 @@
|
|
|
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 WorkflowMcpGet extends BaseCommand {
|
|
6
|
+
static description = "Get details of a single MCP server (token is NOT shown — use rotate-token to get a new one)";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow mcp get <mcpId>",
|
|
9
|
+
"imbrace workflow mcp get <mcpId> --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
mcpId: Args.string({ description: "MCP server ID" }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args, flags } = await this.parse(WorkflowMcpGet);
|
|
19
|
+
const mcpId = args.mcpId ?? (flags.json ? this.error("MCP ID is required") : await input({ message: "MCP server ID:" }));
|
|
20
|
+
try {
|
|
21
|
+
const res = await apiRequest(`/workflow/mcp/${mcpId}`);
|
|
22
|
+
if (flags.json) {
|
|
23
|
+
this.log(JSON.stringify(res, null, 2));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const m = res.data || {};
|
|
27
|
+
this.log(`\n ID: ${m.id || ""}`);
|
|
28
|
+
this.log(` Name: ${m.name || ""}`);
|
|
29
|
+
this.log(` Project ID: ${m.projectId || ""}`);
|
|
30
|
+
this.log(` External ID: ${m.externalId || ""}`);
|
|
31
|
+
this.log(` Tools: ${(m.tools || []).length}`);
|
|
32
|
+
this.log(` Created: ${m.created || ""}`);
|
|
33
|
+
this.log(` Updated: ${m.updated || ""}`);
|
|
34
|
+
this.log("");
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.error(`Failed: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowMcpList 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 WorkflowMcpList extends BaseCommand {
|
|
5
|
+
static description = "List MCP (Model Context Protocol) servers for the project";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow mcp list",
|
|
8
|
+
"imbrace workflow mcp list --json",
|
|
9
|
+
];
|
|
10
|
+
static flags = {
|
|
11
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = await this.parse(WorkflowMcpList);
|
|
15
|
+
try {
|
|
16
|
+
const res = await apiRequest("/workflow/mcp/list");
|
|
17
|
+
if (flags.json) {
|
|
18
|
+
this.log(JSON.stringify(res, null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.log(`\n Found ${res.count} MCP server(s):\n`);
|
|
22
|
+
this.log(" ID NAME TOOLS");
|
|
23
|
+
this.log(" ──────────────────────────────────────────────────────────");
|
|
24
|
+
for (const m of res.data || []) {
|
|
25
|
+
const id = (m.id || "").padEnd(24);
|
|
26
|
+
const name = (m.name || "").padEnd(26);
|
|
27
|
+
const tools = (m.tools || []).length;
|
|
28
|
+
this.log(` ${id} ${name} ${tools}`);
|
|
29
|
+
}
|
|
30
|
+
this.log("");
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
this.error(`Failed: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowMcpRotateToken extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
mcpId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
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 WorkflowMcpRotateToken extends BaseCommand {
|
|
6
|
+
static description = "Rotate the access token of an MCP server. Old token stops working immediately.";
|
|
7
|
+
static examples = [
|
|
8
|
+
"imbrace workflow mcp rotate-token <mcpId> --yes",
|
|
9
|
+
"imbrace workflow mcp rotate-token <mcpId> --yes --json",
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
mcpId: Args.string({ description: "MCP server ID", required: true }),
|
|
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(WorkflowMcpRotateToken);
|
|
20
|
+
if (!flags.yes && !flags.json) {
|
|
21
|
+
const ok = await confirm({
|
|
22
|
+
message: `Rotate token for MCP ${args.mcpId}? Old token stops working immediately.`,
|
|
23
|
+
default: false,
|
|
24
|
+
});
|
|
25
|
+
if (!ok) {
|
|
26
|
+
this.log("Cancelled.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const res = await apiRequest(`/workflow/mcp/${args.mcpId}/rotate-token`, { method: "POST", body: {} });
|
|
32
|
+
if (flags.json) {
|
|
33
|
+
this.log(JSON.stringify(res, null, 2));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const m = res.data || {};
|
|
37
|
+
this.log(`\n✅ ${res.message}`);
|
|
38
|
+
this.log(` ID: ${m.id}`);
|
|
39
|
+
this.log(` New token: ${m.token}`);
|
|
40
|
+
this.log(`\n ⚠️ Update any clients using the old token.\n`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.error(`Failed: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowMove extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
"folder-id": import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../http.js";
|
|
4
|
+
export default class WorkflowMove extends BaseCommand {
|
|
5
|
+
static description = "Move a workflow into a folder (category). Pass --folder-id NULL to make it unfiled.";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow move <flowId> --folder-id <folderId>",
|
|
8
|
+
"imbrace workflow move <flowId> --folder-id NULL # remove from any folder",
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.string({ description: "Workflow ID", required: true }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
"folder-id": Flags.string({
|
|
15
|
+
description: "Target folder ID. Use 'NULL' to unfile. Use 'imbrace workflow folder list' to discover folder IDs.",
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { args, flags } = await this.parse(WorkflowMove);
|
|
22
|
+
const folderId = flags["folder-id"] === "NULL" ? null : flags["folder-id"];
|
|
23
|
+
try {
|
|
24
|
+
const res = await apiRequest(`/workflow/${encodeURIComponent(args.id)}/move`, { method: "POST", body: { folderId } });
|
|
25
|
+
if (flags.json) {
|
|
26
|
+
this.log(JSON.stringify(res, null, 2));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
this.error(`Failed: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
2
|
+
export default class WorkflowNodeAddRaw 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
|
+
"op-file": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
op: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { BaseCommand } from "../../../base-command.js";
|
|
4
|
+
import { apiRequest } from "../../../http.js";
|
|
5
|
+
export default class WorkflowNodeAddRaw extends BaseCommand {
|
|
6
|
+
static description = [
|
|
7
|
+
"Add or update a node using a raw Activepieces flow-operation payload.",
|
|
8
|
+
"Use this for advanced node types (BRANCH, ROUTER, LOOP_ON_ITEMS, CODE)",
|
|
9
|
+
"that 'node add' doesn't expose. Caller is responsible for the full",
|
|
10
|
+
"payload shape — no validation, no auto-defaults.",
|
|
11
|
+
].join(" ");
|
|
12
|
+
static examples = [
|
|
13
|
+
"imbrace workflow node add-raw <flowId> --op-file ./branch.json --json",
|
|
14
|
+
"imbrace workflow node add-raw <flowId> --op '{\"type\":\"ADD_ACTION\",\"request\":{...}}' --json",
|
|
15
|
+
"echo '{\"type\":\"ADD_ACTION\",...}' | imbrace workflow node add-raw <flowId> --stdin --json",
|
|
16
|
+
];
|
|
17
|
+
static args = {
|
|
18
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
"op-file": Flags.string({ description: "Path to JSON file containing { type, request }" }),
|
|
22
|
+
op: Flags.string({ description: "Inline JSON string of { type, request }" }),
|
|
23
|
+
stdin: Flags.boolean({ description: "Read operation JSON from stdin" }),
|
|
24
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
25
|
+
};
|
|
26
|
+
async run() {
|
|
27
|
+
const { args, flags } = await this.parse(WorkflowNodeAddRaw);
|
|
28
|
+
const sources = [flags["op-file"], flags.op, flags.stdin].filter(Boolean).length;
|
|
29
|
+
if (sources === 0)
|
|
30
|
+
this.error("Provide one of --op-file, --op, or --stdin");
|
|
31
|
+
if (sources > 1)
|
|
32
|
+
this.error("Use only one of --op-file, --op, --stdin");
|
|
33
|
+
let raw;
|
|
34
|
+
if (flags["op-file"]) {
|
|
35
|
+
try {
|
|
36
|
+
raw = readFileSync(flags["op-file"], "utf8");
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
this.error(`Cannot read --op-file: ${e.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (flags.op) {
|
|
43
|
+
raw = flags.op;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
raw = readFileSync(0, "utf8");
|
|
47
|
+
}
|
|
48
|
+
let body;
|
|
49
|
+
try {
|
|
50
|
+
body = JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
this.error(`Invalid JSON: ${e.message}`);
|
|
54
|
+
}
|
|
55
|
+
if (!body.type || !body.request) {
|
|
56
|
+
this.error("Operation JSON must have { type, request } — e.g. { type: \"ADD_ACTION\", request: { parentStep, action } }");
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const res = await apiRequest(`/workflow/${args.flowId}/nodes/raw`, { method: "POST", body });
|
|
60
|
+
if (flags.json) {
|
|
61
|
+
this.log(JSON.stringify(res, null, 2));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.log(`\n✅ ${res.message}\n`);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
this.error(`Failed: ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowPublish 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,30 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../http.js";
|
|
4
|
+
export default class WorkflowPublish extends BaseCommand {
|
|
5
|
+
static description = "Lock the current draft and publish it as the production version. Required before 'workflow enable'.";
|
|
6
|
+
static examples = [
|
|
7
|
+
"imbrace workflow publish <flowId>",
|
|
8
|
+
"imbrace workflow publish <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(WorkflowPublish);
|
|
18
|
+
try {
|
|
19
|
+
const res = await apiRequest(`/workflow/${args.flowId}/publish`, { method: "POST", body: {} });
|
|
20
|
+
if (flags.json) {
|
|
21
|
+
this.log(JSON.stringify(res, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
this.log(`\n✅ ${res.message}\n Run 'imbrace workflow enable ${args.flowId}' to start auto-triggering.\n`);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
this.error(`Failed: ${error.message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from "../../base-command.js";
|
|
2
|
+
export default class WorkflowRun 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
|
+
payload: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
sync: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../../base-command.js";
|
|
3
|
+
import { apiRequest } from "../../http.js";
|
|
4
|
+
export default class WorkflowRun extends BaseCommand {
|
|
5
|
+
static description = "Manually trigger a workflow with a payload. Use --sync to wait for completion.";
|
|
6
|
+
static examples = [
|
|
7
|
+
'imbrace workflow run <flowId> --payload \'{"text":"hello"}\' --json',
|
|
8
|
+
'imbrace workflow run <flowId> --payload \'{"text":"hello"}\' --sync --json',
|
|
9
|
+
'imbrace workflow run <flowId> # no payload (empty {})',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
flowId: Args.string({ description: "Workflow ID", required: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
payload: Flags.string({ description: "JSON payload (becomes trigger.body in flow). Default: {}" }),
|
|
16
|
+
sync: Flags.boolean({ description: "Wait for flow to finish (timeout ~60s). Without it, fire-and-forget." }),
|
|
17
|
+
json: Flags.boolean({ description: "Output as JSON" }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(WorkflowRun);
|
|
21
|
+
let payload = {};
|
|
22
|
+
if (flags.payload) {
|
|
23
|
+
try {
|
|
24
|
+
payload = JSON.parse(flags.payload);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
this.error(`--payload is not valid JSON: ${e.message}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const qs = flags.sync ? "?sync=true" : "";
|
|
31
|
+
try {
|
|
32
|
+
const res = await apiRequest(`/workflow/${args.flowId}/run${qs}`, { method: "POST", body: { payload } });
|
|
33
|
+
if (flags.json) {
|
|
34
|
+
this.log(JSON.stringify(res, null, 2));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.log(`\n✅ ${res.message}`);
|
|
38
|
+
if (flags.sync && res.data) {
|
|
39
|
+
this.log(`\n Result:\n${JSON.stringify(res.data, null, 2).split("\n").map(l => " " + l).join("\n")}`);
|
|
40
|
+
}
|
|
41
|
+
else if (!flags.sync) {
|
|
42
|
+
this.log(`\n (async — use 'imbrace workflow runs' to check execution status)`);
|
|
43
|
+
}
|
|
44
|
+
this.log("");
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.error(`Failed: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|