Skip to content

Commit 822ee62

Browse files
committed
fix: tighten openshell exec preflight
1 parent aafed83 commit 822ee62

4 files changed

Lines changed: 10 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai
1515

1616
### Fixes
1717

18+
- OpenShell/SSH: reject malformed generated exec commands before sandbox/session setup so unresolved workflow placeholders fail fast instead of reaching the remote shell. Fixes #72373. Thanks @brokemac79.
1819
- Installer: make Alpine apk installs cover Git, verify the Node runtime floor, try `nodejs-current`, and report Alpine version guidance when repositories only provide older Node packages.
1920
- Agents/media: send direct fallback for generated media still missing after an active requester wake fails. (#85489) Thanks @fuller-stack-dev.
2021
- Agents: derive overflow compaction budgets from provider-reported and synthetic over-budget token counts so confirmed context overflows compact before retrying. (#70473) Thanks @fuller-stack-dev.

docs/plugins/sdk-subpaths.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ focused channel/runtime subpaths, `config-contracts`, `string-coerce-runtime`,
264264
| `plugin-sdk/tool-plugin` | Define a simple typed agent-tool plugin and expose static metadata for manifest generation |
265265
| `plugin-sdk/tool-payload` | Extract normalized payloads from tool result objects |
266266
| `plugin-sdk/tool-send` | Extract canonical send target fields from tool args |
267+
| `plugin-sdk/sandbox` | Sandbox backend types and SSH/OpenShell command helpers, including fail-fast exec command preflight |
267268
| `plugin-sdk/temp-path` | Shared temp-download path helpers and private secure temp workspaces |
268269
| `plugin-sdk/logging-core` | Subsystem logger and redaction helpers |
269270
| `plugin-sdk/markdown-table-runtime` | Markdown table mode and conversion helpers |

src/agents/sandbox/ssh.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ describe("sandbox ssh helpers", () => {
124124
it.each([
125125
["workflow install <name>", /unresolved placeholder token <name>/],
126126
["workflow run <workflow-id> --ref main", /unresolved placeholder token <workflow-id>/],
127+
["echo $(workflow run <workflow-id> --ref main)", /unresolved placeholder token <workflow-id>/],
128+
["WORKFLOW_ID=<workflow-id> workflow run", /unresolved placeholder token <workflow-id>/],
127129
['echo "unterminated', /unclosed double quote/],
128130
["printf '%s", /unclosed single quote/],
129131
["echo foo\\", /trailing backslash escape/],
@@ -148,6 +150,7 @@ describe("sandbox ssh helpers", () => {
148150
"cat < input.txt > output.txt",
149151
"cat <in>out",
150152
"cat <input> output",
153+
"cat = <input-file> output.txt",
151154
'cat <input-file> "output file"',
152155
"cat <<'EOF' > literal.txt",
153156
"<workflow-id>",

src/agents/sandbox/ssh.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ function readPlaceholderToken(command: string, index: number): string | null {
301301
if (!match) {
302302
return null;
303303
}
304+
if (command[index - 1] === "=") {
305+
return match[0];
306+
}
304307
if (isLikelyGeneratedWorkflowPlaceholder(command, index)) {
305308
return match[0];
306309
}
@@ -330,6 +333,8 @@ function isLikelyGeneratedWorkflowPlaceholder(command: string, index: number): b
330333
prefix.lastIndexOf(";"),
331334
prefix.lastIndexOf("&"),
332335
prefix.lastIndexOf("|"),
336+
prefix.lastIndexOf("("),
337+
prefix.lastIndexOf("`"),
333338
) + 1;
334339
const currentCommand = prefix.slice(segmentStart).trim();
335340
return /^workflow(?:\s+[A-Za-z0-9._/-]+)*$/.test(currentCommand);

0 commit comments

Comments
 (0)