feat(cli): flow-debug run-script — run a site script by name through the flow debugger
Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -32,6 +32,7 @@ public static class FlowDebugCommands
|
||||
var command = new Command("flow-debug") { Description = "Flow Debugger: trace an inbound API method or value-change flow end to end, or replay a past one" };
|
||||
|
||||
command.Add(BuildRunMethod(urlOption, formatOption, usernameOption, passwordOption));
|
||||
command.Add(BuildRunScript(urlOption, formatOption, usernameOption, passwordOption));
|
||||
command.Add(BuildRunValueChange(urlOption, formatOption, usernameOption, passwordOption));
|
||||
command.Add(BuildReplay(urlOption, formatOption, usernameOption, passwordOption));
|
||||
|
||||
@@ -82,13 +83,77 @@ public static class FlowDebugCommands
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildRunScript(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
||||
{
|
||||
var instanceIdOption = new Option<int>("--instance-id") { Description = "Instance ID", Required = true };
|
||||
var scriptOption = new Option<string>("--script")
|
||||
{
|
||||
Description = "Canonical script name, as shown by the Flow Debugger picker / the flattened configuration (e.g. Manual or Module.Script)",
|
||||
Required = true,
|
||||
};
|
||||
var paramsOption = new Option<string?>("--params") { Description = "Flat JSON object of parameters for a Call/Interval/Expression/no-trigger script (validated against the script's ParameterDefinitions)" };
|
||||
var valueOption = new Option<string?>("--value") { Description = "Value to write to the trigger attribute of a ValueChange/Conditional script (canonical string form)" };
|
||||
var waitOption = new Option<int>("--wait-seconds") { Description = "Write kinds: how long to wait for the triggered run before NO_TRIGGER_WITHIN_WINDOW", DefaultValueFactory = _ => 45 };
|
||||
var timeoutOption = new Option<int>("--timeout-seconds")
|
||||
{
|
||||
Description = "Client-side wait for the run; raise above the script's ExecutionTimeoutSeconds + 25 for a long script",
|
||||
DefaultValueFactory = _ => 120,
|
||||
};
|
||||
var cmd = new Command("run-script") { Description = "Run one site script with tracing — a ValueChange/Conditional script is fired by writing its trigger attribute (--value); any other script is called directly (--params)" };
|
||||
cmd.Add(instanceIdOption);
|
||||
cmd.Add(scriptOption);
|
||||
cmd.Add(paramsOption);
|
||||
cmd.Add(valueOption);
|
||||
cmd.Add(waitOption);
|
||||
cmd.Add(timeoutOption);
|
||||
cmd.SetAction(async (ParseResult result) =>
|
||||
{
|
||||
var waitSeconds = result.GetValue(waitOption);
|
||||
var timeoutSeconds = result.GetValue(timeoutOption);
|
||||
if (waitSeconds <= 0)
|
||||
{
|
||||
OutputFormatter.WriteError("--wait-seconds must be greater than zero.", "INVALID_ARGUMENT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (timeoutSeconds <= 0)
|
||||
{
|
||||
OutputFormatter.WriteError("--timeout-seconds must be greater than zero.", "INVALID_ARGUMENT");
|
||||
return 1;
|
||||
}
|
||||
|
||||
JsonElement? parameters;
|
||||
try
|
||||
{
|
||||
parameters = ParseParameters(result.GetValue(paramsOption));
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
OutputFormatter.WriteError($"--params is not valid JSON: {ex.Message}", "INVALID_PARAMS");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return await CommandHelpers.ExecuteCommandAsync(
|
||||
result, urlOption, formatOption, usernameOption, passwordOption,
|
||||
new FlowDebugRunScriptCommand(
|
||||
result.GetValue(instanceIdOption),
|
||||
result.GetValue(scriptOption)!,
|
||||
parameters,
|
||||
result.GetValue(valueOption),
|
||||
waitSeconds),
|
||||
timeout: TimeSpan.FromSeconds(Math.Max(timeoutSeconds, waitSeconds + ClientSlackSeconds)),
|
||||
tableProjector: FlowDebugTableProjection.ProjectEvents);
|
||||
});
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Command BuildRunValueChange(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
||||
{
|
||||
var instanceIdOption = new Option<int>("--instance-id") { Description = "Instance ID", Required = true };
|
||||
var attributeOption = new Option<string>("--attribute") { Description = "Canonical attribute name to write", Required = true };
|
||||
var valueOption = new Option<string>("--value") { Description = "Value to write (canonical string form)", Required = true };
|
||||
var waitOption = new Option<int>("--wait-seconds") { Description = "How long to wait for a triggered script run before reporting NO_TRIGGER_WITHIN_WINDOW", DefaultValueFactory = _ => 45 };
|
||||
var cmd = new Command("run-value-change") { Description = "Write an attribute through the traced path and capture the script run(s) the change triggers" };
|
||||
var cmd = new Command("run-value-change") { Description = "Write an attribute through the traced path and capture the script run(s) the change triggers — the attribute-level path (also fires Expression triggers); prefer run-script to run a named script" };
|
||||
cmd.Add(instanceIdOption);
|
||||
cmd.Add(attributeOption);
|
||||
cmd.Add(valueOption);
|
||||
|
||||
Reference in New Issue
Block a user