@imbrace/cli 0.3.0 → 0.4.1

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.
Files changed (68) hide show
  1. package/dist/base-command.js +20 -18
  2. package/dist/commands/ai-agent/create.js +8 -7
  3. package/dist/commands/ai-agent/delete.js +6 -4
  4. package/dist/commands/ai-agent/get.js +5 -5
  5. package/dist/commands/ai-agent/list-files.js +7 -5
  6. package/dist/commands/ai-agent/list-folders.js +7 -6
  7. package/dist/commands/ai-agent/list-models.js +5 -5
  8. package/dist/commands/ai-agent/list-providers.js +5 -5
  9. package/dist/commands/ai-agent/list.js +7 -5
  10. package/dist/commands/ai-agent/update.js +5 -4
  11. package/dist/commands/data-board/create-field.js +6 -4
  12. package/dist/commands/data-board/create-item.js +10 -8
  13. package/dist/commands/data-board/create.js +8 -6
  14. package/dist/commands/data-board/delete-item.js +6 -4
  15. package/dist/commands/data-board/export-csv.js +3 -2
  16. package/dist/commands/data-board/list-items.js +9 -11
  17. package/dist/commands/data-board/list.js +7 -5
  18. package/dist/commands/data-board/update-item.js +8 -6
  19. package/dist/commands/login.d.ts +0 -1
  20. package/dist/commands/login.js +39 -55
  21. package/dist/commands/whoami.js +0 -2
  22. package/dist/commands/workflow/conn/create.js +33 -16
  23. package/dist/commands/workflow/conn/delete.js +6 -4
  24. package/dist/commands/workflow/conn/get.js +5 -4
  25. package/dist/commands/workflow/conn/list.js +7 -5
  26. package/dist/commands/workflow/create.js +16 -14
  27. package/dist/commands/workflow/delete.js +6 -4
  28. package/dist/commands/workflow/disable.js +9 -4
  29. package/dist/commands/workflow/enable.js +9 -4
  30. package/dist/commands/workflow/folder/create.js +11 -10
  31. package/dist/commands/workflow/folder/delete.js +6 -4
  32. package/dist/commands/workflow/folder/get.js +5 -4
  33. package/dist/commands/workflow/folder/list.js +7 -5
  34. package/dist/commands/workflow/folder/update.js +6 -4
  35. package/dist/commands/workflow/get.js +5 -4
  36. package/dist/commands/workflow/list.js +8 -6
  37. package/dist/commands/workflow/mcp/create.js +10 -9
  38. package/dist/commands/workflow/mcp/delete.js +6 -4
  39. package/dist/commands/workflow/mcp/get.js +5 -4
  40. package/dist/commands/workflow/mcp/list.js +9 -5
  41. package/dist/commands/workflow/mcp/rotate-token.js +7 -5
  42. package/dist/commands/workflow/move.js +10 -4
  43. package/dist/commands/workflow/node/add-raw.js +6 -4
  44. package/dist/commands/workflow/node/add.js +70 -21
  45. package/dist/commands/workflow/node/delete.js +12 -4
  46. package/dist/commands/workflow/node/list.js +8 -5
  47. package/dist/commands/workflow/node/update.js +44 -8
  48. package/dist/commands/workflow/piece/detail.js +5 -4
  49. package/dist/commands/workflow/piece/list.js +22 -6
  50. package/dist/commands/workflow/publish.js +9 -4
  51. package/dist/commands/workflow/run-detail.js +5 -4
  52. package/dist/commands/workflow/run.js +10 -7
  53. package/dist/commands/workflow/runs.js +7 -5
  54. package/dist/config.d.ts +5 -5
  55. package/dist/config.js +6 -12
  56. package/dist/lib/ai-agent.d.ts +40 -0
  57. package/dist/lib/ai-agent.js +150 -0
  58. package/dist/lib/client.d.ts +7 -0
  59. package/dist/lib/client.js +21 -0
  60. package/dist/lib/gateway.d.ts +3 -0
  61. package/dist/lib/gateway.js +31 -0
  62. package/dist/lib/workflow.d.ts +20 -0
  63. package/dist/lib/workflow.js +71 -0
  64. package/dist/select-board.js +4 -3
  65. package/llms.txt +1 -0
  66. package/package.json +2 -2
  67. package/dist/http.d.ts +0 -9
  68. package/dist/http.js +0 -40
@@ -1,7 +1,8 @@
1
1
  import { Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { input } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
+ import { resolveProjectId } from "../../../lib/workflow.js";
5
6
  export default class WorkflowMcpCreate extends BaseCommand {
6
7
  static description = "Create a new MCP (Model Context Protocol) server. The token is shown once at creation — save it.";
7
8
  static examples = [
@@ -18,21 +19,21 @@ export default class WorkflowMcpCreate extends BaseCommand {
18
19
  const { flags } = await this.parse(WorkflowMcpCreate);
19
20
  const nonInteractive = flags.json || flags["id-only"];
20
21
  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
22
  try {
25
- const res = await apiRequest("/workflow/mcp/create", { method: "POST", body });
23
+ const client = getClient();
24
+ const projectId = flags["project-id"] || (await resolveProjectId(client));
25
+ const data = await client.workflows.createMcpServer({ name, projectId });
26
+ const message = `MCP server "${name}" created`;
26
27
  if (flags["id-only"]) {
27
- this.log(res.data?.id ?? "");
28
+ this.log(data?.id ?? "");
28
29
  return;
29
30
  }
30
31
  if (flags.json) {
31
- this.log(JSON.stringify(res, null, 2));
32
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
32
33
  return;
33
34
  }
34
- const m = res.data || {};
35
- this.log(`\n✅ ${res.message}`);
35
+ const m = data || {};
36
+ this.log(`\n✅ ${message}`);
36
37
  this.log(` ID: ${m.id}`);
37
38
  this.log(` Token: ${m.token}`);
38
39
  this.log(`\n ⚠️ Save the token now — it WON'T be shown again. Use 'mcp rotate-token <id>' to issue a new one.\n`);
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { confirm } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
5
  export default class WorkflowMcpDelete extends BaseCommand {
6
6
  static description = "Delete an MCP server. Any client using its token will lose access.";
7
7
  static examples = [
@@ -25,12 +25,14 @@ export default class WorkflowMcpDelete extends BaseCommand {
25
25
  }
26
26
  }
27
27
  try {
28
- const res = await apiRequest(`/workflow/mcp/${args.mcpId}`, { method: "DELETE" });
28
+ const client = getClient();
29
+ await client.workflows.deleteMcpServer(args.mcpId);
30
+ const message = "MCP server deleted";
29
31
  if (flags.json) {
30
- this.log(JSON.stringify(res, null, 2));
32
+ this.log(JSON.stringify({ ok: true, message }, null, 2));
31
33
  return;
32
34
  }
33
- this.log(`\n✅ ${res.message}\n`);
35
+ this.log(`\n✅ ${message}\n`);
34
36
  }
35
37
  catch (error) {
36
38
  this.error(`Failed: ${error.message}`);
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { input } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
5
  export default class WorkflowMcpGet extends BaseCommand {
6
6
  static description = "Get details of a single MCP server (token is NOT shown — use rotate-token to get a new one)";
7
7
  static examples = [
@@ -18,12 +18,13 @@ export default class WorkflowMcpGet extends BaseCommand {
18
18
  const { args, flags } = await this.parse(WorkflowMcpGet);
19
19
  const mcpId = args.mcpId ?? (flags.json ? this.error("MCP ID is required") : await input({ message: "MCP server ID:" }));
20
20
  try {
21
- const res = await apiRequest(`/workflow/mcp/${mcpId}`);
21
+ const client = getClient();
22
+ const data = await client.workflows.getMcpServer(mcpId);
22
23
  if (flags.json) {
23
- this.log(JSON.stringify(res, null, 2));
24
+ this.log(JSON.stringify({ ok: true, data }, null, 2));
24
25
  return;
25
26
  }
26
- const m = res.data || {};
27
+ const m = data || {};
27
28
  this.log(`\n ID: ${m.id || ""}`);
28
29
  this.log(` Name: ${m.name || ""}`);
29
30
  this.log(` Project ID: ${m.projectId || ""}`);
@@ -1,6 +1,7 @@
1
1
  import { Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
- import { apiRequest } from "../../../http.js";
3
+ import { getClient } from "../../../lib/client.js";
4
+ import { resolveProjectId } from "../../../lib/workflow.js";
4
5
  export default class WorkflowMcpList extends BaseCommand {
5
6
  static description = "List MCP (Model Context Protocol) servers for the project";
6
7
  static examples = [
@@ -13,15 +14,18 @@ export default class WorkflowMcpList extends BaseCommand {
13
14
  async run() {
14
15
  const { flags } = await this.parse(WorkflowMcpList);
15
16
  try {
16
- const res = await apiRequest("/workflow/mcp/list");
17
+ const client = getClient();
18
+ const projectId = await resolveProjectId(client);
19
+ const res = await client.workflows.listMcpServers(projectId);
20
+ const data = res?.data ?? [];
17
21
  if (flags.json) {
18
- this.log(JSON.stringify(res, null, 2));
22
+ this.log(JSON.stringify({ ok: true, count: data.length, data }, null, 2));
19
23
  return;
20
24
  }
21
- this.log(`\n Found ${res.count} MCP server(s):\n`);
25
+ this.log(`\n Found ${data.length} MCP server(s):\n`);
22
26
  this.log(" ID NAME TOOLS");
23
27
  this.log(" ──────────────────────────────────────────────────────────");
24
- for (const m of res.data || []) {
28
+ for (const m of data) {
25
29
  const id = (m.id || "").padEnd(24);
26
30
  const name = (m.name || "").padEnd(26);
27
31
  const tools = (m.tools || []).length;
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { confirm } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
5
  export default class WorkflowMcpRotateToken extends BaseCommand {
6
6
  static description = "Rotate the access token of an MCP server. Old token stops working immediately.";
7
7
  static examples = [
@@ -28,13 +28,15 @@ export default class WorkflowMcpRotateToken extends BaseCommand {
28
28
  }
29
29
  }
30
30
  try {
31
- const res = await apiRequest(`/workflow/mcp/${args.mcpId}/rotate-token`, { method: "POST", body: {} });
31
+ const client = getClient();
32
+ const data = await client.workflows.rotateMcpToken(args.mcpId);
33
+ const message = "MCP token rotated";
32
34
  if (flags.json) {
33
- this.log(JSON.stringify(res, null, 2));
35
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
34
36
  return;
35
37
  }
36
- const m = res.data || {};
37
- this.log(`\n✅ ${res.message}`);
38
+ const m = data || {};
39
+ this.log(`\n✅ ${message}`);
38
40
  this.log(` ID: ${m.id}`);
39
41
  this.log(` New token: ${m.token}`);
40
42
  this.log(`\n ⚠️ Update any clients using the old token.\n`);
@@ -1,6 +1,6 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../base-command.js";
3
- import { apiRequest } from "../../http.js";
3
+ import { getClient } from "../../lib/client.js";
4
4
  export default class WorkflowMove extends BaseCommand {
5
5
  static description = "Move a workflow into a folder (category). Pass --folder-id NULL to make it unfiled.";
6
6
  static examples = [
@@ -21,12 +21,18 @@ export default class WorkflowMove extends BaseCommand {
21
21
  const { args, flags } = await this.parse(WorkflowMove);
22
22
  const folderId = flags["folder-id"] === "NULL" ? null : flags["folder-id"];
23
23
  try {
24
- const res = await apiRequest(`/workflow/${encodeURIComponent(args.id)}/move`, { method: "POST", body: { folderId } });
24
+ const client = getClient();
25
+ const data = await client.workflows.applyFlowOperation(args.id, {
26
+ type: "CHANGE_FOLDER",
27
+ request: { folderId },
28
+ });
29
+ const target = folderId ?? "(unfiled)";
30
+ const message = `Workflow moved to ${target}`;
25
31
  if (flags.json) {
26
- this.log(JSON.stringify(res, null, 2));
32
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
27
33
  return;
28
34
  }
29
- this.log(`\n✅ ${res.message}\n`);
35
+ this.log(`\n✅ ${message}\n`);
30
36
  }
31
37
  catch (error) {
32
38
  this.error(`Failed: ${error.message}`);
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { BaseCommand } from "../../../base-command.js";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
5
  export default class WorkflowNodeAddRaw extends BaseCommand {
6
6
  static description = [
7
7
  "Add or update a node using a raw Activepieces flow-operation payload.",
@@ -56,12 +56,14 @@ export default class WorkflowNodeAddRaw extends BaseCommand {
56
56
  this.error("Operation JSON must have { type, request } — e.g. { type: \"ADD_ACTION\", request: { parentStep, action } }");
57
57
  }
58
58
  try {
59
- const res = await apiRequest(`/workflow/${args.flowId}/nodes/raw`, { method: "POST", body });
59
+ const client = getClient();
60
+ const data = await client.workflows.applyFlowOperation(args.flowId, body);
61
+ const message = `Operation "${body.type}" applied`;
60
62
  if (flags.json) {
61
- this.log(JSON.stringify(res, null, 2));
63
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
62
64
  return;
63
65
  }
64
- this.log(`\n✅ ${res.message}\n`);
66
+ this.log(`\n✅ ${message}\n`);
65
67
  }
66
68
  catch (error) {
67
69
  this.error(`Failed: ${error.message}`);
@@ -1,6 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
- import { apiRequest } from "../../../http.js";
3
+ import { getClient } from "../../../lib/client.js";
4
+ import { buildPropertySettings, fetchPieceMeta, flattenNodes, nextStepName, normalizePieceName, } from "../../../lib/workflow.js";
4
5
  export default class WorkflowNodeAdd extends BaseCommand {
5
6
  static description = "Add a trigger or action node to a workflow";
6
7
  static examples = [
@@ -39,30 +40,78 @@ export default class WorkflowNodeAdd extends BaseCommand {
39
40
  this.error(`--input is not valid JSON: ${e.message}`);
40
41
  }
41
42
  }
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
43
  try {
58
- const res = await apiRequest(`/workflow/${args.flowId}/nodes`, { method: "POST", body });
44
+ const client = getClient();
45
+ const pieceName = normalizePieceName(flags.piece);
46
+ const pieceVersion = (await fetchPieceMeta(pieceName)).version;
47
+ const propertySettings = buildPropertySettings(parsedInput);
48
+ if (flags.type === "trigger") {
49
+ const op = {
50
+ type: "UPDATE_TRIGGER",
51
+ request: {
52
+ name: "trigger",
53
+ type: "PIECE_TRIGGER",
54
+ displayName: flags["display-name"] || flags["trigger-name"],
55
+ settings: {
56
+ pieceName,
57
+ pieceVersion,
58
+ triggerName: flags["trigger-name"],
59
+ input: parsedInput,
60
+ propertySettings,
61
+ sampleData: {},
62
+ },
63
+ valid: true,
64
+ },
65
+ };
66
+ const data = await client.workflows.applyFlowOperation(args.flowId, op);
67
+ const message = "Trigger set";
68
+ if (flags.json) {
69
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
70
+ return;
71
+ }
72
+ this.log(`\n✅ ${message}\n`);
73
+ return;
74
+ }
75
+ // type === "action"
76
+ const flow = await client.workflows.getFlow(args.flowId);
77
+ const trigger = flow?.version?.trigger;
78
+ const parentStep = flags.after || (() => {
79
+ const nodes = flattenNodes(trigger);
80
+ return nodes.length > 0 ? nodes[nodes.length - 1].name : "trigger";
81
+ })();
82
+ const stepName = flags.name || nextStepName(trigger);
83
+ const op = {
84
+ type: "ADD_ACTION",
85
+ request: {
86
+ parentStep,
87
+ action: {
88
+ name: stepName,
89
+ type: "PIECE",
90
+ displayName: flags["display-name"] || flags["action-name"],
91
+ settings: {
92
+ pieceName,
93
+ pieceVersion,
94
+ actionName: flags["action-name"],
95
+ input: parsedInput,
96
+ propertySettings,
97
+ sampleData: {},
98
+ errorHandlingOptions: {
99
+ retryOnFailure: { value: false },
100
+ continueOnFailure: { value: false },
101
+ },
102
+ },
103
+ valid: true,
104
+ },
105
+ },
106
+ };
107
+ const data = await client.workflows.applyFlowOperation(args.flowId, op);
108
+ const message = `Action "${stepName}" added after ${parentStep}`;
59
109
  if (flags.json) {
60
- this.log(JSON.stringify(res, null, 2));
110
+ this.log(JSON.stringify({ ok: true, message, data: { stepName, parentStep, flow: data } }, null, 2));
61
111
  return;
62
112
  }
63
- this.log(`\n✅ ${res.message}`);
64
- if (res.data?.stepName)
65
- this.log(` Step: ${res.data.stepName} (after ${res.data.parentStep})`);
113
+ this.log(`\n✅ ${message}`);
114
+ this.log(` Step: ${stepName} (after ${parentStep})`);
66
115
  this.log("");
67
116
  }
68
117
  catch (error) {
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { confirm } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { getClient } from "../../../lib/client.js";
5
5
  export default class WorkflowNodeDelete extends BaseCommand {
6
6
  static description = "Delete an action node from a workflow (cannot delete trigger — replace it via `node add --type trigger`)";
7
7
  static examples = [
@@ -25,13 +25,21 @@ export default class WorkflowNodeDelete extends BaseCommand {
25
25
  return;
26
26
  }
27
27
  }
28
+ if (args.nodeName === "trigger") {
29
+ this.error("Cannot delete trigger node — replace it with `node add --type trigger ...` instead");
30
+ }
28
31
  try {
29
- const res = await apiRequest(`/workflow/${args.flowId}/nodes/${args.nodeName}`, { method: "DELETE" });
32
+ const client = getClient();
33
+ const data = await client.workflows.applyFlowOperation(args.flowId, {
34
+ type: "DELETE_ACTION",
35
+ request: { names: [args.nodeName] },
36
+ });
37
+ const message = `Node "${args.nodeName}" deleted`;
30
38
  if (flags.json) {
31
- this.log(JSON.stringify(res, null, 2));
39
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
32
40
  return;
33
41
  }
34
- this.log(`\n✅ ${res.message}\n`);
42
+ this.log(`\n✅ ${message}\n`);
35
43
  }
36
44
  catch (error) {
37
45
  this.error(`Failed: ${error.message}`);
@@ -1,6 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
- import { apiRequest } from "../../../http.js";
3
+ import { getClient } from "../../../lib/client.js";
4
+ import { flattenNodes } from "../../../lib/workflow.js";
4
5
  export default class WorkflowNodeList extends BaseCommand {
5
6
  static description = "List nodes (trigger + actions) of a workflow";
6
7
  static examples = [
@@ -16,15 +17,17 @@ export default class WorkflowNodeList extends BaseCommand {
16
17
  async run() {
17
18
  const { args, flags } = await this.parse(WorkflowNodeList);
18
19
  try {
19
- const res = await apiRequest(`/workflow/${args.flowId}/nodes`);
20
+ const client = getClient();
21
+ const flow = await client.workflows.getFlow(args.flowId);
22
+ const data = flattenNodes(flow?.version?.trigger);
20
23
  if (flags.json) {
21
- this.log(JSON.stringify(res, null, 2));
24
+ this.log(JSON.stringify({ ok: true, count: data.length, data }, null, 2));
22
25
  return;
23
26
  }
24
- this.log(`\n Found ${res.count} node(s):\n`);
27
+ this.log(`\n Found ${data.length} node(s):\n`);
25
28
  this.log(" NAME TYPE PIECE ACTION/TRIGGER");
26
29
  this.log(" ─────────────────────────────────────────────────────────────────────────────────");
27
- for (const n of res.data || []) {
30
+ for (const n of data) {
28
31
  const name = (n.name || "").padEnd(10);
29
32
  const type = (n.type || "").padEnd(16);
30
33
  const piece = (n.pieceName || "-").padEnd(38);
@@ -1,6 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
- import { apiRequest } from "../../../http.js";
3
+ import { getClient } from "../../../lib/client.js";
4
+ import { buildPropertySettings, fetchPieceMeta, flattenNodes } from "../../../lib/workflow.js";
4
5
  export default class WorkflowNodeUpdate extends BaseCommand {
5
6
  static description = "Update a node's input or display name (preserves piece + action/trigger)";
6
7
  static examples = [
@@ -21,24 +22,59 @@ export default class WorkflowNodeUpdate extends BaseCommand {
21
22
  if (!flags.input && !flags["display-name"]) {
22
23
  this.error("Provide at least --input or --display-name to update");
23
24
  }
24
- const body = {};
25
+ let parsedInput;
25
26
  if (flags.input) {
26
27
  try {
27
- body.input = JSON.parse(flags.input);
28
+ parsedInput = JSON.parse(flags.input);
28
29
  }
29
30
  catch (e) {
30
31
  this.error(`--input is not valid JSON: ${e.message}`);
31
32
  }
32
33
  }
33
- if (flags["display-name"])
34
- body.displayName = flags["display-name"];
35
34
  try {
36
- const res = await apiRequest(`/workflow/${args.flowId}/nodes/${args.nodeName}`, { method: "PUT", body });
35
+ const client = getClient();
36
+ const flow = await client.workflows.getFlow(args.flowId);
37
+ const nodes = flattenNodes(flow?.version?.trigger);
38
+ const cur = nodes.find((n) => n.name === args.nodeName);
39
+ if (!cur)
40
+ this.error(`Node "${args.nodeName}" not found`);
41
+ const isTrigger = args.nodeName === "trigger";
42
+ const opType = isTrigger ? "UPDATE_TRIGGER" : "UPDATE_ACTION";
43
+ const newInput = parsedInput ?? cur.input ?? {};
44
+ const pieceVersion = (await fetchPieceMeta(cur.pieceName)).version;
45
+ const baseSettings = {
46
+ pieceName: cur.pieceName,
47
+ pieceVersion,
48
+ input: newInput,
49
+ propertySettings: buildPropertySettings(newInput),
50
+ sampleData: {},
51
+ };
52
+ if (isTrigger)
53
+ baseSettings.triggerName = cur.triggerName;
54
+ else {
55
+ baseSettings.actionName = cur.actionName;
56
+ baseSettings.errorHandlingOptions = {
57
+ retryOnFailure: { value: false },
58
+ continueOnFailure: { value: false },
59
+ };
60
+ }
61
+ const op = {
62
+ type: opType,
63
+ request: {
64
+ name: args.nodeName,
65
+ type: cur.type,
66
+ displayName: flags["display-name"] ?? cur.displayName,
67
+ settings: baseSettings,
68
+ valid: true,
69
+ },
70
+ };
71
+ const data = await client.workflows.applyFlowOperation(args.flowId, op);
72
+ const message = `Node "${args.nodeName}" updated`;
37
73
  if (flags.json) {
38
- this.log(JSON.stringify(res, null, 2));
74
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
39
75
  return;
40
76
  }
41
- this.log(`\n✅ ${res.message}\n`);
77
+ this.log(`\n✅ ${message}\n`);
42
78
  }
43
79
  catch (error) {
44
80
  this.error(`Failed: ${error.message}`);
@@ -1,7 +1,8 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
3
  import { input } from "@inquirer/prompts";
4
- import { apiRequest } from "../../../http.js";
4
+ import { gatewayFetch } from "../../../lib/gateway.js";
5
+ import { normalizePieceName } from "../../../lib/workflow.js";
5
6
  export default class WorkflowPieceDetail extends BaseCommand {
6
7
  static description = "Get full piece schema (actions + triggers + input fields)";
7
8
  static examples = [
@@ -20,12 +21,12 @@ export default class WorkflowPieceDetail extends BaseCommand {
20
21
  const { args, flags } = await this.parse(WorkflowPieceDetail);
21
22
  const piece = args.piece ?? (flags.json ? this.error("piece is required") : await input({ message: "Piece name (e.g. slack):" }));
22
23
  try {
23
- const res = await apiRequest(`/workflow/piece/detail?name=${encodeURIComponent(piece)}`);
24
+ const data = await gatewayFetch(`/activepieces/v1/pieces/${normalizePieceName(piece)}`);
24
25
  if (flags.json) {
25
- this.log(JSON.stringify(res, null, 2));
26
+ this.log(JSON.stringify({ ok: true, data }, null, 2));
26
27
  return;
27
28
  }
28
- const d = res.data || {};
29
+ const d = data || {};
29
30
  this.log(`\n ${d.displayName} (${d.name})`);
30
31
  this.log(` ${d.description || ""}`);
31
32
  this.log(` Version: ${d.version} Categories: ${(d.categories || []).join(", ")}`);
@@ -1,6 +1,6 @@
1
1
  import { Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../../base-command.js";
3
- import { apiRequest } from "../../../http.js";
3
+ import { getClient } from "../../../lib/client.js";
4
4
  export default class WorkflowPieceList extends BaseCommand {
5
5
  static description = "List available integrations (pieces) for use in workflow nodes";
6
6
  static examples = [
@@ -14,17 +14,33 @@ export default class WorkflowPieceList extends BaseCommand {
14
14
  };
15
15
  async run() {
16
16
  const { flags } = await this.parse(WorkflowPieceList);
17
- const qs = flags.search ? `?search=${encodeURIComponent(flags.search)}` : "";
18
17
  try {
19
- const res = await apiRequest(`/workflow/piece/list${qs}`);
18
+ const client = getClient();
19
+ const res = await client.workflows.listPieces();
20
+ let arr = (Array.isArray(res) ? res : res?.data) || [];
21
+ if (flags.search) {
22
+ const q = flags.search.toLowerCase();
23
+ arr = arr.filter((p) => p.name?.toLowerCase().includes(q) ||
24
+ p.displayName?.toLowerCase().includes(q) ||
25
+ p.description?.toLowerCase().includes(q));
26
+ }
27
+ const data = arr.map((p) => ({
28
+ name: p.name,
29
+ displayName: p.displayName,
30
+ description: p.description,
31
+ categories: p.categories,
32
+ actions: p.actions,
33
+ triggers: p.triggers,
34
+ version: p.version,
35
+ }));
20
36
  if (flags.json) {
21
- this.log(JSON.stringify(res, null, 2));
37
+ this.log(JSON.stringify({ ok: true, count: data.length, data }, null, 2));
22
38
  return;
23
39
  }
24
- this.log(`\n Found ${res.count} piece(s)${flags.search ? ` matching "${flags.search}"` : ""}:\n`);
40
+ this.log(`\n Found ${data.length} piece(s)${flags.search ? ` matching "${flags.search}"` : ""}:\n`);
25
41
  this.log(" NAME DISPLAY A T");
26
42
  this.log(" ──────────────────────────────────────────────────────────────────────────────────");
27
- for (const p of res.data || []) {
43
+ for (const p of data) {
28
44
  const name = (p.name || "").padEnd(45);
29
45
  const display = (p.displayName || "").padEnd(32);
30
46
  const a = String(p.actions ?? 0).padStart(2);
@@ -1,6 +1,6 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../base-command.js";
3
- import { apiRequest } from "../../http.js";
3
+ import { getClient } from "../../lib/client.js";
4
4
  export default class WorkflowPublish extends BaseCommand {
5
5
  static description = "Lock the current draft and publish it as the production version. Required before 'workflow enable'.";
6
6
  static examples = [
@@ -16,12 +16,17 @@ export default class WorkflowPublish extends BaseCommand {
16
16
  async run() {
17
17
  const { args, flags } = await this.parse(WorkflowPublish);
18
18
  try {
19
- const res = await apiRequest(`/workflow/${args.flowId}/publish`, { method: "POST", body: {} });
19
+ const client = getClient();
20
+ const data = await client.workflows.applyFlowOperation(args.flowId, {
21
+ type: "LOCK_AND_PUBLISH",
22
+ request: {},
23
+ });
24
+ const message = "Workflow published";
20
25
  if (flags.json) {
21
- this.log(JSON.stringify(res, null, 2));
26
+ this.log(JSON.stringify({ ok: true, message, data }, null, 2));
22
27
  return;
23
28
  }
24
- this.log(`\n✅ ${res.message}\n Run 'imbrace workflow enable ${args.flowId}' to start auto-triggering.\n`);
29
+ this.log(`\n✅ ${message}\n Run 'imbrace workflow enable ${args.flowId}' to start auto-triggering.\n`);
25
30
  }
26
31
  catch (error) {
27
32
  this.error(`Failed: ${error.message}`);
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../base-command.js";
3
3
  import { input } from "@inquirer/prompts";
4
- import { apiRequest } from "../../http.js";
4
+ import { getClient } from "../../lib/client.js";
5
5
  export default class WorkflowRunDetail extends BaseCommand {
6
6
  static description = "Get details of a single workflow run (status, failed step, timing)";
7
7
  static examples = [
@@ -18,12 +18,13 @@ export default class WorkflowRunDetail extends BaseCommand {
18
18
  const { args, flags } = await this.parse(WorkflowRunDetail);
19
19
  const runId = args.runId ?? (flags.json ? this.error("Run ID is required") : await input({ message: "Run ID:" }));
20
20
  try {
21
- const res = await apiRequest(`/workflow/runs/${runId}`);
21
+ const client = getClient();
22
+ const data = await client.workflows.getRun(runId);
22
23
  if (flags.json) {
23
- this.log(JSON.stringify(res, null, 2));
24
+ this.log(JSON.stringify({ ok: true, data }, null, 2));
24
25
  return;
25
26
  }
26
- const r = res.data || {};
27
+ const r = data || {};
27
28
  const dur = r.startTime && r.finishTime
28
29
  ? `${((new Date(r.finishTime).getTime() - new Date(r.startTime).getTime()) / 1000).toFixed(2)}s`
29
30
  : "—";
@@ -1,6 +1,6 @@
1
1
  import { Args, Flags } from "@oclif/core";
2
2
  import { BaseCommand } from "../../base-command.js";
3
- import { apiRequest } from "../../http.js";
3
+ import { getClient } from "../../lib/client.js";
4
4
  export default class WorkflowRun extends BaseCommand {
5
5
  static description = "Manually trigger a workflow with a payload. Use --sync to wait for completion.";
6
6
  static examples = [
@@ -27,16 +27,19 @@ export default class WorkflowRun extends BaseCommand {
27
27
  this.error(`--payload is not valid JSON: ${e.message}`);
28
28
  }
29
29
  }
30
- const qs = flags.sync ? "?sync=true" : "";
31
30
  try {
32
- const res = await apiRequest(`/workflow/${args.flowId}/run${qs}`, { method: "POST", body: { payload } });
31
+ const client = getClient();
32
+ const data = flags.sync
33
+ ? await client.workflows.triggerFlowSync(args.flowId, payload)
34
+ : await client.workflows.triggerFlow(args.flowId, payload);
35
+ const message = flags.sync ? "Workflow run completed" : "Workflow run triggered";
33
36
  if (flags.json) {
34
- this.log(JSON.stringify(res, null, 2));
37
+ this.log(JSON.stringify({ ok: true, message, mode: flags.sync ? "sync" : "async", data }, null, 2));
35
38
  return;
36
39
  }
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
+ this.log(`\n✅ ${message}`);
41
+ if (flags.sync && data) {
42
+ this.log(`\n Result:\n${JSON.stringify(data, null, 2).split("\n").map(l => " " + l).join("\n")}`);
40
43
  }
41
44
  else if (!flags.sync) {
42
45
  this.log(`\n (async — use 'imbrace workflow runs' to check execution status)`);