@powerformer/refly-cli 0.1.4 → 0.1.6

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/dist/bin/refly.js CHANGED
@@ -4040,30 +4040,15 @@ var OutputFormatter = class {
4040
4040
  }
4041
4041
  // === CLI Status Format (Phase 1: Charm-style cards) ===
4042
4042
  outputStatusPretty(payload) {
4043
- const { cli_version, api_endpoint, auth_status, auth_method, auth_details, user, skill } = payload;
4043
+ const { cli_version, api_endpoint, auth_status, user, skill } = payload;
4044
4044
  const sym = this.useUnicode ? Symbols : AsciiSymbol;
4045
4045
  console.log(`${sym.DIAMOND} ${UI.bold("Refly CLI")} v${cli_version || "?"}`);
4046
4046
  console.log();
4047
4047
  const authOk = auth_status === "valid";
4048
4048
  const userObj = user;
4049
- const authDetailsObj = auth_details;
4050
4049
  const authLines = [];
4051
4050
  if (authOk && userObj?.email) {
4052
4051
  authLines.push({ text: String(userObj.email) });
4053
- const provider = authDetailsObj?.provider || auth_method;
4054
- if (provider) {
4055
- const providerDisplay = String(provider).charAt(0).toUpperCase() + String(provider).slice(1);
4056
- const exp = userObj?.exp;
4057
- let expiryText = "";
4058
- if (exp) {
4059
- expiryText = ` \xB7 ${UI.timeRemaining(exp)}`;
4060
- }
4061
- authLines.push({
4062
- text: `via ${providerDisplay}${expiryText}`,
4063
- indent: true,
4064
- muted: true
4065
- });
4066
- }
4067
4052
  } else if (auth_status === "expired") {
4068
4053
  authLines.push({ text: "Token expired", muted: true });
4069
4054
  } else {
@@ -4377,6 +4362,9 @@ function configureOutput(options) {
4377
4362
  };
4378
4363
  initFormatter(outputConfig);
4379
4364
  }
4365
+ function isPrettyOutput() {
4366
+ return outputConfig.format !== "json";
4367
+ }
4380
4368
  function ok(type, payload) {
4381
4369
  const formatter = getFormatter();
4382
4370
  formatter.success(type, payload);
@@ -4436,6 +4424,7 @@ var ErrorCodes = {
4436
4424
  // Node
4437
4425
  INVALID_NODE_TYPE: "INVALID_NODE_TYPE",
4438
4426
  INVALID_NODE_INPUT: "INVALID_NODE_INPUT",
4427
+ EXECUTION_FAILED: "EXECUTION_FAILED",
4439
4428
  // Network
4440
4429
  NETWORK_ERROR: "NETWORK_ERROR",
4441
4430
  TIMEOUT: "TIMEOUT",
@@ -9655,7 +9644,40 @@ async function loginWithDeviceFlow() {
9655
9644
  },
9656
9645
  requireAuth: false
9657
9646
  });
9658
- const { deviceId, expiresAt } = initResponse;
9647
+ const { deviceId, expiresAt, userCode } = initResponse;
9648
+ const cleanup = async (deviceIdToCancel = deviceId) => {
9649
+ try {
9650
+ logger.debug("Cleaning up device session...");
9651
+ await apiRequest("/v1/auth/cli/device/cancel", {
9652
+ method: "POST",
9653
+ body: { device_id: deviceIdToCancel },
9654
+ requireAuth: false
9655
+ });
9656
+ logger.debug("Device session cancelled");
9657
+ } catch (error) {
9658
+ logger.debug("Failed to cancel device session during cleanup:", error);
9659
+ }
9660
+ };
9661
+ process.on("SIGINT", async () => {
9662
+ logger.debug("Received SIGINT, cleaning up...");
9663
+ await cleanup();
9664
+ process.exit(130);
9665
+ });
9666
+ process.on("SIGTERM", async () => {
9667
+ logger.debug("Received SIGTERM, cleaning up...");
9668
+ await cleanup();
9669
+ process.exit(143);
9670
+ });
9671
+ process.on("uncaughtException", async (error) => {
9672
+ logger.debug("Uncaught exception, cleaning up:", error);
9673
+ await cleanup();
9674
+ process.exit(1);
9675
+ });
9676
+ process.on("unhandledRejection", async (reason) => {
9677
+ logger.debug("Unhandled rejection, cleaning up:", reason);
9678
+ await cleanup();
9679
+ process.exit(1);
9680
+ });
9659
9681
  const webUrl = getWebUrl();
9660
9682
  const authUrl = `${webUrl}/cli/auth?device_id=${encodeURIComponent(deviceId)}&cli_version=${encodeURIComponent(CLI_VERSION)}&host=${encodeURIComponent(hostname2)}`;
9661
9683
  process.stderr.write("\n");
@@ -9664,6 +9686,10 @@ async function loginWithDeviceFlow() {
9664
9686
  process.stderr.write(` ${authUrl}
9665
9687
  `);
9666
9688
  process.stderr.write("\n");
9689
+ if (userCode) {
9690
+ process.stderr.write(`Verification Code: ${styled(userCode, Style.TEXT_HIGHLIGHT_BOLD)}
9691
+ `);
9692
+ }
9667
9693
  process.stderr.write(`Device ID: ${deviceId}
9668
9694
  `);
9669
9695
  process.stderr.write(`Expires: ${new Date(expiresAt).toLocaleTimeString()}
@@ -9678,55 +9704,67 @@ async function loginWithDeviceFlow() {
9678
9704
  }
9679
9705
  const pollInterval = 2e3;
9680
9706
  const maxAttempts = 150;
9681
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
9682
- await sleep(pollInterval);
9683
- const statusResponse = await apiRequest("/v1/auth/cli/device/status", {
9684
- method: "GET",
9685
- query: { device_id: deviceId },
9686
- requireAuth: false
9687
- });
9688
- switch (statusResponse.status) {
9689
- case "authorized":
9690
- if (statusResponse.accessToken && statusResponse.refreshToken) {
9691
- const userInfo = await getUserInfoFromToken(statusResponse.accessToken);
9692
- setOAuthTokens({
9693
- accessToken: statusResponse.accessToken,
9694
- refreshToken: statusResponse.refreshToken,
9695
- expiresAt: new Date(Date.now() + 36e5).toISOString(),
9696
- // 1 hour
9697
- provider: "google",
9698
- // Device flow doesn't specify provider, default to google
9699
- user: userInfo
9707
+ try {
9708
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
9709
+ await sleep(pollInterval);
9710
+ const statusResponse = await apiRequest(
9711
+ "/v1/auth/cli/device/status",
9712
+ {
9713
+ method: "GET",
9714
+ query: { device_id: deviceId },
9715
+ requireAuth: false
9716
+ }
9717
+ );
9718
+ switch (statusResponse.status) {
9719
+ case "authorized":
9720
+ if (statusResponse.accessToken && statusResponse.refreshToken) {
9721
+ const userInfo = await getUserInfoFromToken(statusResponse.accessToken);
9722
+ setOAuthTokens({
9723
+ accessToken: statusResponse.accessToken,
9724
+ refreshToken: statusResponse.refreshToken,
9725
+ expiresAt: new Date(Date.now() + 36e5).toISOString(),
9726
+ // 1 hour
9727
+ provider: "google",
9728
+ // Device flow doesn't specify provider, default to google
9729
+ user: userInfo
9730
+ });
9731
+ ok("login", {
9732
+ message: "Successfully authenticated via device authorization",
9733
+ user: userInfo,
9734
+ method: "device"
9735
+ });
9736
+ return true;
9737
+ }
9738
+ break;
9739
+ case "cancelled":
9740
+ printError(ErrorCodes.AUTH_REQUIRED, "Authorization was cancelled", {
9741
+ hint: "The authorization request was cancelled in the browser"
9700
9742
  });
9701
- ok("login", {
9702
- message: "Successfully authenticated via device authorization",
9703
- user: userInfo,
9704
- method: "device"
9743
+ return false;
9744
+ case "expired":
9745
+ printError(ErrorCodes.AUTH_REQUIRED, "Authorization request expired", {
9746
+ hint: "Run `refly login` again to start a new session"
9705
9747
  });
9706
- return true;
9707
- }
9708
- break;
9709
- case "cancelled":
9710
- printError(ErrorCodes.AUTH_REQUIRED, "Authorization was cancelled", {
9711
- hint: "The authorization request was cancelled in the browser"
9712
- });
9713
- return false;
9714
- case "expired":
9715
- printError(ErrorCodes.AUTH_REQUIRED, "Authorization request expired", {
9716
- hint: "Run `refly login` again to start a new session"
9717
- });
9718
- return false;
9719
- case "pending":
9720
- if (attempt % 5 === 0) {
9721
- process.stderr.write(".");
9722
- }
9723
- break;
9748
+ return false;
9749
+ case "pending":
9750
+ if (attempt % 5 === 0) {
9751
+ process.stderr.write(".");
9752
+ }
9753
+ break;
9754
+ }
9724
9755
  }
9756
+ logger.debug("Authorization timeout, updating device status...");
9757
+ await cleanup(deviceId);
9758
+ printError(ErrorCodes.TIMEOUT, "Authorization timeout", {
9759
+ hint: "Complete authorization in the browser within 5 minutes"
9760
+ });
9761
+ return false;
9762
+ } finally {
9763
+ process.removeAllListeners("SIGINT");
9764
+ process.removeAllListeners("SIGTERM");
9765
+ process.removeAllListeners("uncaughtException");
9766
+ process.removeAllListeners("unhandledRejection");
9725
9767
  }
9726
- printError(ErrorCodes.TIMEOUT, "Authorization timeout", {
9727
- hint: "Complete authorization in the browser within 5 minutes"
9728
- });
9729
- return false;
9730
9768
  }
9731
9769
  async function getUserInfoFromToken(accessToken) {
9732
9770
  try {
@@ -9759,15 +9797,66 @@ function sleep(ms) {
9759
9797
  return new Promise((resolve2) => setTimeout(resolve2, ms));
9760
9798
  }
9761
9799
 
9800
+ // src/utils/logo.ts
9801
+ init_cjs_shims();
9802
+ var REFLY_LOGO = `\u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588 \u2588 \u2588 \u2588\u2580\u2588 \u2588
9803
+ \u2588\u2580\u2584 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588 \u2588\u2584\u2588 \u2580 \u2588\u2580\u2588 \u2588
9804
+ \u2580 \u2580 \u2580\u2580\u2580 \u2580 \u2580\u2580\u2580 \u2580 \u2580 \u2580 \u2580`;
9805
+ function printLogo(options) {
9806
+ const useColor = options?.color ?? shouldUseColor();
9807
+ const tty = isTTY();
9808
+ if (!tty && !options?.force) {
9809
+ return;
9810
+ }
9811
+ if (useColor) {
9812
+ process.stderr.write(`${Style.TEXT_SUCCESS}${REFLY_LOGO}${Style.RESET}
9813
+ `);
9814
+ } else {
9815
+ process.stderr.write(`${REFLY_LOGO}
9816
+ `);
9817
+ }
9818
+ }
9819
+ function printSuccess(message) {
9820
+ process.stderr.write(`${UI.successMsg(message)}
9821
+ `);
9822
+ }
9823
+ function printError2(message) {
9824
+ process.stderr.write(`${UI.errorMsg(message)}
9825
+ `);
9826
+ }
9827
+ function printDim(message) {
9828
+ process.stderr.write(`${UI.dim(message)}
9829
+ `);
9830
+ }
9831
+ function println(message) {
9832
+ process.stderr.write(`${message}
9833
+ `);
9834
+ }
9835
+
9762
9836
  // src/commands/init.ts
9763
9837
  var DEFAULT_API_ENDPOINT2 = "https://refly-api.powerformer.net";
9764
9838
  var initCommand = new Command("init").description("Initialize Refly CLI, install skill files, and authenticate").option("--force", "Force reinstall even if already installed").option("--host <url>", "API server URL", DEFAULT_API_ENDPOINT2).option("--skip-login", "Skip automatic login after initialization").action(async (options) => {
9765
9839
  try {
9766
9840
  const { force, host, skipLogin } = options;
9767
9841
  const apiEndpoint = host || DEFAULT_API_ENDPOINT2;
9842
+ const pretty = isPrettyOutput();
9843
+ const tty = isTTY();
9844
+ const useColor = shouldUseColor();
9768
9845
  const skillStatus = isSkillInstalled();
9769
9846
  const isAuthenticated2 = !!(getAccessToken() || getApiKey());
9770
9847
  if (skillStatus.installed && skillStatus.upToDate && !force && isAuthenticated2) {
9848
+ if (pretty && tty) {
9849
+ printLogo({ color: useColor });
9850
+ println("");
9851
+ printSuccess("Already initialized and authenticated");
9852
+ const user = getAuthUser();
9853
+ if (user?.email) {
9854
+ printDim(` Logged in as ${user.email}`);
9855
+ }
9856
+ println("");
9857
+ printDim("Run `refly status` for details.");
9858
+ return;
9859
+ }
9771
9860
  return ok("init", {
9772
9861
  message: "Refly CLI already initialized and authenticated",
9773
9862
  configDir: getReflyDir(),
@@ -9777,34 +9866,92 @@ var initCommand = new Command("init").description("Initialize Refly CLI, install
9777
9866
  authenticated: true
9778
9867
  });
9779
9868
  }
9869
+ if (pretty && tty) {
9870
+ printLogo({ color: useColor });
9871
+ println("");
9872
+ println("Initializing Refly CLI...");
9873
+ println("");
9874
+ }
9780
9875
  const config = loadConfig();
9781
9876
  config.api = {
9782
9877
  endpoint: apiEndpoint
9783
9878
  };
9784
9879
  saveConfig(config);
9785
- const result = installSkill();
9786
- print("init", {
9787
- message: "Refly CLI initialized successfully",
9788
- configDir: getReflyDir(),
9789
- apiEndpoint,
9790
- skillInstalled: result.skillInstalled,
9791
- skillPath: result.skillPath,
9792
- commandsInstalled: result.commandsInstalled,
9793
- commandsPath: result.commandsPath,
9794
- version: result.version
9795
- });
9880
+ const installResult = installSkill();
9881
+ if (pretty && tty) {
9882
+ if (installResult.skillInstalled) {
9883
+ printSuccess("Skill files installed");
9884
+ } else {
9885
+ printError2("Skill files installation failed");
9886
+ }
9887
+ if (installResult.commandsInstalled) {
9888
+ printSuccess("Slash commands installed");
9889
+ } else {
9890
+ printError2("Slash commands installation failed");
9891
+ }
9892
+ println("");
9893
+ } else if (!pretty) {
9894
+ print("init", {
9895
+ message: "Refly CLI initialized successfully",
9896
+ configDir: getReflyDir(),
9897
+ apiEndpoint,
9898
+ skillInstalled: installResult.skillInstalled,
9899
+ skillPath: installResult.skillPath,
9900
+ commandsInstalled: installResult.commandsInstalled,
9901
+ commandsPath: installResult.commandsPath,
9902
+ version: installResult.version
9903
+ });
9904
+ }
9796
9905
  if (!skipLogin && !isAuthenticated2) {
9797
- process.stderr.write("\nStarting authentication...\n");
9798
- const loginSuccess = await loginWithDeviceFlow();
9799
- if (!loginSuccess) {
9800
- process.stderr.write(
9801
- "\nAuthentication was not completed. You can login later with `refly login`.\n"
9802
- );
9906
+ if (pretty && tty) {
9907
+ println("Starting authentication...");
9908
+ printDim("A browser window will open for login.");
9909
+ println("");
9910
+ }
9911
+ const loginResult = await loginWithDeviceFlow({ emitOutput: false });
9912
+ if (pretty && tty) {
9913
+ if (loginResult.ok) {
9914
+ printSuccess("Authentication successful");
9915
+ if (loginResult.user?.email) {
9916
+ printDim(` Welcome, ${loginResult.user.email}!`);
9917
+ }
9918
+ } else {
9919
+ printError2("Authentication was not completed");
9920
+ printDim(" Run `refly login` to authenticate later.");
9921
+ }
9922
+ println("");
9923
+ } else if (!pretty && loginResult.ok) {
9924
+ print("login", {
9925
+ message: "Successfully authenticated",
9926
+ user: loginResult.user
9927
+ });
9803
9928
  }
9804
- } else if (isAuthenticated2) {
9805
- process.stderr.write("\nAlready authenticated.\n");
9806
- } else {
9807
- process.stderr.write("\nSkipped login. Run `refly login` to authenticate later.\n");
9929
+ } else if (pretty && tty) {
9930
+ if (isAuthenticated2) {
9931
+ printSuccess("Already authenticated");
9932
+ const user = getAuthUser();
9933
+ if (user?.email) {
9934
+ printDim(` Logged in as ${user.email}`);
9935
+ }
9936
+ } else {
9937
+ printDim("Skipped login. Run `refly login` to authenticate later.");
9938
+ }
9939
+ println("");
9940
+ }
9941
+ if (pretty && tty) {
9942
+ println("Ready to use! Try `refly status` to verify.");
9943
+ return;
9944
+ }
9945
+ if (!pretty) {
9946
+ return ok("init", {
9947
+ message: "Refly CLI initialized successfully",
9948
+ configDir: getReflyDir(),
9949
+ apiEndpoint,
9950
+ skillInstalled: installResult.skillInstalled,
9951
+ commandsInstalled: installResult.commandsInstalled,
9952
+ version: installResult.version,
9953
+ authenticated: !!(getAccessToken() || getApiKey())
9954
+ });
9808
9955
  }
9809
9956
  } catch (error) {
9810
9957
  fail(
@@ -11465,7 +11612,7 @@ var workflowRunToolcallsCommand = new Command("toolcalls").description("Get all
11465
11612
  });
11466
11613
 
11467
11614
  // src/commands/workflow/run.ts
11468
- var workflowRunCommand = new Command("run").description("Run workflows and get execution results").argument("[workflowId]", "Workflow ID to run").option("--input <json>", "Input variables as JSON", "{}").action(async (workflowId, options) => {
11615
+ var workflowRunCommand = new Command("run").description("Run workflows and get execution results").argument("[workflowId]", "Workflow ID to run").option("--input <json>", "Input variables as JSON", "{}").option("--from-node <nodeId>", "Start workflow execution from a specific node (Run From Here)").action(async (workflowId, options) => {
11469
11616
  if (!workflowId) {
11470
11617
  workflowRunCommand.help();
11471
11618
  return;
@@ -11479,17 +11626,22 @@ var workflowRunCommand = new Command("run").description("Run workflows and get e
11479
11626
  hint: "Ensure the input is valid JSON"
11480
11627
  });
11481
11628
  }
11629
+ const body = { input };
11630
+ if (options.fromNode) {
11631
+ body.startNodes = [options.fromNode];
11632
+ }
11482
11633
  const result = await apiRequest(`/v1/cli/workflow/${workflowId}/run`, {
11483
11634
  method: "POST",
11484
- body: { input }
11635
+ body
11485
11636
  });
11486
11637
  ok("workflow.run", {
11487
- message: "Workflow run started",
11638
+ message: options.fromNode ? `Workflow run started from node ${options.fromNode}` : "Workflow run started",
11488
11639
  runId: result.runId,
11489
11640
  workflowId: result.workflowId,
11490
11641
  status: result.status,
11642
+ startNode: options.fromNode || void 0,
11491
11643
  createdAt: result.createdAt,
11492
- nextStep: `Check status with \`refly workflow run get ${result.runId}\``
11644
+ nextStep: `Check status with \`refly workflow status ${result.runId}\``
11493
11645
  });
11494
11646
  } catch (error) {
11495
11647
  if (error instanceof CLIError) {
@@ -11788,29 +11940,56 @@ async function fetchAndCache() {
11788
11940
 
11789
11941
  // src/commands/node/run.ts
11790
11942
  init_cjs_shims();
11791
- var nodeRunCommand = new Command("run").description("Run a single node for debugging").requiredOption("--type <nodeType>", "Node type to run").requiredOption("--input <json>", "Input data as JSON").action(async (options) => {
11943
+ var nodeRunCommand = new Command("run").description("Run a single node for debugging (currently supports skillResponse only)").requiredOption("--type <nodeType>", 'Node type to run (e.g., "skillResponse")').option("--query <query>", "Query text for skillResponse node").option("--input <json>", "Full input data as JSON (alternative to --query)").option("--config <json>", 'Node configuration as JSON (e.g., {"modelItemId": "..."})').action(async (options) => {
11792
11944
  try {
11793
- let input;
11794
- try {
11795
- input = JSON.parse(options.input);
11796
- } catch {
11797
- fail(ErrorCodes.INVALID_INPUT, "Invalid JSON in --input", {
11798
- hint: "Ensure the input is valid JSON"
11799
- });
11945
+ let input = {};
11946
+ if (options.query) {
11947
+ input = { query: options.query };
11948
+ } else if (options.input) {
11949
+ try {
11950
+ input = JSON.parse(options.input);
11951
+ } catch {
11952
+ fail(ErrorCodes.INVALID_INPUT, "Invalid JSON in --input", {
11953
+ hint: "Ensure the input is valid JSON"
11954
+ });
11955
+ return;
11956
+ }
11957
+ }
11958
+ let config = {};
11959
+ if (options.config) {
11960
+ try {
11961
+ config = JSON.parse(options.config);
11962
+ } catch {
11963
+ fail(ErrorCodes.INVALID_INPUT, "Invalid JSON in --config", {
11964
+ hint: "Ensure the config is valid JSON"
11965
+ });
11966
+ return;
11967
+ }
11800
11968
  }
11801
11969
  const result = await apiRequest("/v1/cli/node/run", {
11802
11970
  method: "POST",
11803
11971
  body: {
11804
- type: options.type,
11805
- input
11806
- }
11807
- });
11808
- ok("node.run", {
11809
- type: options.type,
11810
- result: result.result,
11811
- metrics: result.metrics,
11812
- logs: result.logs ?? []
11813
- });
11972
+ nodeType: options.type,
11973
+ input,
11974
+ config
11975
+ }
11976
+ });
11977
+ if (result.status === "completed") {
11978
+ ok("node.run", {
11979
+ nodeType: result.nodeType,
11980
+ status: result.status,
11981
+ output: result.output,
11982
+ duration: result.duration,
11983
+ tokenUsage: result.tokenUsage
11984
+ });
11985
+ } else {
11986
+ fail(ErrorCodes.EXECUTION_FAILED, result.error || "Node execution failed", {
11987
+ details: {
11988
+ nodeType: result.nodeType,
11989
+ output: result.output
11990
+ }
11991
+ });
11992
+ }
11814
11993
  } catch (error) {
11815
11994
  if (error instanceof CLIError) {
11816
11995
  fail(error.code, error.message, { details: error.details, hint: error.hint });
@@ -11827,24 +12006,65 @@ init_cjs_shims();
11827
12006
  var nodeResultCommand = new Command("result").description("Get node execution result").argument("<resultId>", "Node result ID").option("--include-steps", "Include detailed step information").option("--include-messages", "Include chat messages").option("--include-tool-calls", "Include tool call details").action(async (resultId, options) => {
11828
12007
  try {
11829
12008
  const result = await apiRequest(`/v1/cli/action/result?resultId=${resultId}`);
12009
+ let totalTokenUsage;
12010
+ if (result.steps?.length) {
12011
+ totalTokenUsage = { input: 0, output: 0, reasoning: 0 };
12012
+ for (const step of result.steps) {
12013
+ if (step.tokenUsage?.length) {
12014
+ for (const usage of step.tokenUsage) {
12015
+ totalTokenUsage.input += usage.inputTokens || 0;
12016
+ totalTokenUsage.output += usage.outputTokens || 0;
12017
+ totalTokenUsage.reasoning += usage.reasoningTokens || 0;
12018
+ }
12019
+ }
12020
+ }
12021
+ }
12022
+ const lastStep = result.steps?.[result.steps.length - 1];
12023
+ const content = lastStep?.content;
11830
12024
  const output = {
11831
12025
  resultId: result.resultId,
12026
+ version: result.version,
12027
+ title: result.title,
11832
12028
  status: result.status,
11833
- content: result.content,
11834
- tokenUsage: result.tokenUsage
12029
+ content,
12030
+ tokenUsage: totalTokenUsage,
12031
+ createdAt: result.createdAt,
12032
+ updatedAt: result.updatedAt
11835
12033
  };
11836
12034
  if (options.includeSteps && result.steps) {
11837
- output.steps = result.steps.map((step) => ({
11838
- stepIndex: step.stepIndex,
12035
+ output.steps = result.steps.map((step, index) => ({
12036
+ stepIndex: index,
12037
+ name: step.name,
11839
12038
  content: step.content,
12039
+ reasoningContent: step.reasoningContent,
11840
12040
  toolCallsCount: step.toolCalls?.length ?? 0
11841
12041
  }));
11842
12042
  }
11843
- if (options.includeToolCalls && result.toolCalls) {
11844
- output.toolCalls = result.toolCalls;
12043
+ if (options.includeToolCalls && result.steps) {
12044
+ const allToolCalls = [];
12045
+ for (const step of result.steps) {
12046
+ if (step.toolCalls?.length) {
12047
+ for (const tc of step.toolCalls) {
12048
+ allToolCalls.push({
12049
+ callId: tc.callId,
12050
+ toolName: tc.toolName,
12051
+ status: tc.status,
12052
+ error: tc.error
12053
+ });
12054
+ }
12055
+ }
12056
+ }
12057
+ output.toolCalls = allToolCalls;
11845
12058
  }
11846
12059
  if (options.includeMessages && result.messages) {
11847
- output.messages = result.messages;
12060
+ output.messages = result.messages.map((msg) => ({
12061
+ messageId: msg.messageId,
12062
+ type: msg.type,
12063
+ content: msg.content
12064
+ }));
12065
+ }
12066
+ if (result.errors?.length) {
12067
+ output.errors = result.errors;
11848
12068
  }
11849
12069
  ok("node.result", output);
11850
12070
  } catch (error) {
@@ -11872,7 +12092,7 @@ var toolCallsCommand = new Command("calls").description("Get tool execution resu
11872
12092
  if (options.version) {
11873
12093
  params.set("version", options.version);
11874
12094
  }
11875
- const result = await apiRequest(`/v1/cli/toolcall?${params}`);
12095
+ const result = await apiRequest(`/v1/cli/tool-call?${params}`);
11876
12096
  ok("tool.calls", {
11877
12097
  resultId: options.resultId,
11878
12098
  version: result.version,
@@ -11909,7 +12129,7 @@ var toolGetCommand = new Command("get").description("Get full details for a sing
11909
12129
  params.set("sanitizeForDisplay", "false");
11910
12130
  }
11911
12131
  const queryString = params.toString();
11912
- const url = `/v1/cli/toolcall/${callId}${queryString ? `?${queryString}` : ""}`;
12132
+ const url = `/v1/cli/tool-call/${callId}${queryString ? `?${queryString}` : ""}`;
11913
12133
  const result = await apiRequest(url);
11914
12134
  ok("tool.detail", {
11915
12135
  callId: result.callId,