@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 +334 -114
- package/dist/bin/refly.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +12 -3
- package/skill/SKILL.md +37 -227
- package/skill/references/file.md +20 -0
- package/skill/references/node.md +46 -0
- package/skill/references/skill.md +119 -0
- package/skill/references/workflow.md +82 -0
- package/skill/registry.json +15 -0
- package/skill/references/api-errors.md +0 -120
- package/skill/references/node-types.md +0 -91
- package/skill/references/workflow-schema.md +0 -95
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,
|
|
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
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
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
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
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
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
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
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
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
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
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 (
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
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
|
|
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
|
|
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>",
|
|
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
|
-
|
|
11795
|
-
input =
|
|
11796
|
-
}
|
|
11797
|
-
|
|
11798
|
-
|
|
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
|
-
|
|
11805
|
-
input
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
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
|
|
11834
|
-
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:
|
|
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.
|
|
11844
|
-
|
|
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/
|
|
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/
|
|
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,
|