diff --git a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs
index 986f3fb..4c89ae7 100644
--- a/src/OpenClaw.Shared/Capabilities/SystemCapability.cs
+++ b/src/OpenClaw.Shared/Capabilities/SystemCapability.cs
@@ -161,46 +161,60 @@ private NodeInvokeResponse HandleWhich(NodeInvokeRequest request)
}
private static string FormatExecCommand(string[] argv) => ShellQuoting.FormatExecCommand(argv);
-
+
///
- /// Pre-flight for system.run: echoes back the execution plan without running anything.
- /// The gateway uses this to build its approval context before the actual run.
+ /// Parses the "command" field from a request's JSON args into an argv array.
+ /// Accepts either a JSON string array or a single string.
+ /// Returns true when at least one non-empty element was extracted.
///
- private NodeInvokeResponse HandleRunPrepare(NodeInvokeRequest request)
+ private static bool TryParseArgv(System.Text.Json.JsonElement args, out string[] argv)
{
- string? command = null;
- string[]? argv = null;
- string? rawCommand = null;
- string? cwd = null;
-
- if (request.Args.ValueKind != System.Text.Json.JsonValueKind.Undefined &&
- request.Args.TryGetProperty("command", out var cmdEl))
+ argv = [];
+ if (args.ValueKind == System.Text.Json.JsonValueKind.Undefined ||
+ !args.TryGetProperty("command", out var cmdEl))
{
- if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.Array)
+ return false;
+ }
+
+ if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.Array)
+ {
+ var list = new List();
+ foreach (var item in cmdEl.EnumerateArray())
{
- var list = new List();
- foreach (var item in cmdEl.EnumerateArray())
- {
- if (item.ValueKind == System.Text.Json.JsonValueKind.String)
- list.Add(item.GetString() ?? "");
- }
- argv = list.ToArray();
- command = argv.Length > 0 ? argv[0] : null;
+ if (item.ValueKind == System.Text.Json.JsonValueKind.String)
+ list.Add(item.GetString() ?? "");
}
- else if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.String)
+ argv = list.ToArray();
+ return argv.Length > 0;
+ }
+
+ if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.String)
+ {
+ var cmd = cmdEl.GetString();
+ if (!string.IsNullOrWhiteSpace(cmd))
{
- command = cmdEl.GetString();
- argv = command != null ? new[] { command } : null;
+ argv = [cmd];
+ return true;
}
}
-
- if (string.IsNullOrWhiteSpace(command) || argv == null || argv.Length == 0)
+
+ return false;
+ }
+
+ ///
+ /// Pre-flight for system.run: echoes back the execution plan without running anything.
+ /// The gateway uses this to build its approval context before the actual run.
+ ///
+ private NodeInvokeResponse HandleRunPrepare(NodeInvokeRequest request)
+ {
+ if (!TryParseArgv(request.Args, out var argv) || string.IsNullOrWhiteSpace(argv[0]))
{
return Error("Missing command parameter");
}
-
- rawCommand = GetStringArg(request.Args, "rawCommand");
- cwd = GetStringArg(request.Args, "cwd");
+
+ var command = argv[0];
+ var rawCommand = GetStringArg(request.Args, "rawCommand");
+ var cwd = GetStringArg(request.Args, "cwd");
var agentId = GetStringArg(request.Args, "agentId");
var sessionKey = GetStringArg(request.Args, "sessionKey");
@@ -226,52 +240,31 @@ private async Task HandleRunAsync(NodeInvokeRequest request)
{
return Error("Command execution not available");
}
-
+
// Per OpenClaw spec, "command" is an argv array (e.g. ["echo","Hello"]).
// Also accept a plain string for backward compatibility.
- string? command = null;
- string[]? args = null;
-
- if (request.Args.ValueKind != System.Text.Json.JsonValueKind.Undefined &&
- request.Args.TryGetProperty("command", out var cmdEl))
+ if (!TryParseArgv(request.Args, out var argv) || string.IsNullOrWhiteSpace(argv[0]))
{
- if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.Array)
- {
- var argv = new List();
- foreach (var item in cmdEl.EnumerateArray())
- {
- if (item.ValueKind == System.Text.Json.JsonValueKind.String)
- argv.Add(item.GetString() ?? "");
- }
- if (argv.Count > 0)
- {
- command = argv[0];
- args = argv.Count > 1 ? argv.Skip(1).ToArray() : null;
- }
- }
- else if (cmdEl.ValueKind == System.Text.Json.JsonValueKind.String)
- {
- command = cmdEl.GetString();
-
- // When command is a string, also check for separate "args" array
- if (request.Args.TryGetProperty("args", out var argsEl) &&
- argsEl.ValueKind == System.Text.Json.JsonValueKind.Array)
- {
- var list = new List();
- foreach (var item in argsEl.EnumerateArray())
- {
- if (item.ValueKind == System.Text.Json.JsonValueKind.String)
- list.Add(item.GetString() ?? "");
- }
- if (list.Count > 0)
- args = list.ToArray();
- }
- }
+ return Error("Missing command parameter");
}
-
- if (string.IsNullOrWhiteSpace(command))
+
+ var command = argv[0];
+ string[]? args = argv.Length > 1 ? argv[1..] : null;
+
+ // When command is a plain string (not an array), also check for a separate "args" array.
+ if (argv.Length == 1 &&
+ request.Args.ValueKind != System.Text.Json.JsonValueKind.Undefined &&
+ request.Args.TryGetProperty("args", out var argsEl) &&
+ argsEl.ValueKind == System.Text.Json.JsonValueKind.Array)
{
- return Error("Missing command parameter");
+ var list = new List();
+ foreach (var item in argsEl.EnumerateArray())
+ {
+ if (item.ValueKind == System.Text.Json.JsonValueKind.String)
+ list.Add(item.GetString() ?? "");
+ }
+ if (list.Count > 0)
+ args = list.ToArray();
}
var shell = GetStringArg(request.Args, "shell");
@@ -402,7 +395,7 @@ private NodeInvokeResponse HandleExecApprovalsSet(NodeInvokeRequest request)
if (ruleEl.TryGetProperty("description", out var descEl) && descEl.ValueKind == System.Text.Json.JsonValueKind.String)
rule.Description = descEl.GetString();
- if (ruleEl.TryGetProperty("enabled", out var enEl) && enEl.ValueKind == System.Text.Json.JsonValueKind.True || enEl.ValueKind == System.Text.Json.JsonValueKind.False)
+ if (ruleEl.TryGetProperty("enabled", out var enEl) && (enEl.ValueKind == System.Text.Json.JsonValueKind.True || enEl.ValueKind == System.Text.Json.JsonValueKind.False))
rule.Enabled = enEl.GetBoolean();
if (ruleEl.TryGetProperty("shells", out var shellsEl) && shellsEl.ValueKind == System.Text.Json.JsonValueKind.Array)