import { describe, expect, it } from "vitest"; import { CODE_MODE_SHELL_SOURCE_ERROR, isShellLikeCodeModeSource, } from "./code-mode-shell-source.js"; describe("isShellLikeCodeModeSource", () => { it.each([ "ls", "ls -1", "ls -la /workspace/", "ls -la /workspace", "ls /var/log", "pwd", "pwd;", "pwd; // inspect the workspace", "# inspect the workspace\npwd", "# inspect the workspace\n# then report it\npwd", "#!/bin/sh\npwd", "#!/usr/bin/env bash\nset -euo pipefail\npwd", "pwd\nls -la /workspace", "pwd;ls -la /workspace", "pwd && ls /workspace", "pwd||ls /workspace", "echo hello", "cat /workspace/HEARTBEAT.md", "find /workspace -maxdepth 1 -type f | head -50", "echo listing; ls /workspace/ 2>&1 || echo failed", "ls /workspace/ > /tmp/wlist.txt 2>&1; cat /tmp/wlist.txt", "/bin/ls /workspace/", "/usr/bin/find /workspace", "/usr/local/bin/python3 script.py", "sh -c 'ls /workspace/'", "bash -lc 'pwd'", "export FOO=bar", "export PATH=/workspace/bin", "env FOO=bar node script.js", "NODE_ENV=test npm test", "NODE_ENV=test\nnpm test", "FOO=bar\r\n npm test", "FOO=bar ./gradlew test", "FOO=bar BAR=baz node --version", 'GREETING="hello world" npm test', "GREETING='hello world' ./gradlew test", "EMPTY= npm test", "// inspect the workspace\npwd", "/* inspect the workspace */ pwd;", "// use a clean environment\nNODE_ENV=test npm test", "git status", 'git status; const note = "git";', 'git status; const note = "function git";', "ls -1; const metadata = { ls: true };", "ls -1; const note = 'function ls';", "ls -1; let ls = 7;", "pwd; class/**/pwd {}", "npm test", "npx vitest run", "pnpm test src/agents/code-mode.test.ts", "rg code-mode src/agents", "sudo ls /workspace", "docker ps", "kubectl get pods", "make test", "set -euo pipefail", "exit", "logout", "if [ -d /workspace ]; then pwd; fi", "if [[ -d /workspace ]]; then pwd; fi", "while test -d /workspace; do pwd; done", 'for file in /workspace/*; do echo "$file"; done', 'for ((i=0; i<3; i++)); do echo "$i"; done', "function task { pwd; }", "source ./env", "command ls", "whoami", "date", "uname -a", "go test ./...", "cargo test", "sort /workspace/file", "wc -l file", "jq . file.json", "exec ls", "cut -d : file", "uniq -c file", "custom-tool --format=json", "some_cli /workspace/file", "ls > output", "ls>output", "ls >output", "ls >> output", "ls>>output", "ls 2> error", "ls < input", "cat { expect(isShellLikeCodeModeSource(source)).toBe(true); }); it.each([ "", " ", "true", "true;", "false", "false;", "null;", "42;", '"ls /workspace";', "return 7;", "return -1;", "return /foo/.test('foo');", "return true || false;", "Infinity -1; return 42;", "eval; return typeof eval;", "Date -1; return 7;", "if (true) { return -1; }", "while (false) { return 7; }", "for (let i = 0; i < 3; i++) { if (i === 2) { return i; } }", "function task() { return 7; } return task();", "const value = ;", "let value = ;", "value || fallback", "value && fallback", "value | mask", "value > limit", "/workspace/.test(value)", "/foo/.test('foo')", "ls('workspace')", "ls .call(null)", "ls ?.('workspace')", "ls = 7", "ls + count", "ls - count", "ls -1; function ls() {}", "ls -1; function/**/ls() {}", "ls -la /workspace; function ls() {}", "echo('hello')", "echo `hello`; function echo(parts) { return parts[0]; }", "pwd?.()", "pwd; function pwd() {}", "pwd\nfunction pwd() {}", "pwd; var { pwd } = { pwd: 7 }; return pwd;", "pwd; var [pwd] = [7]; return pwd;", "pwd; var { nested: { pwd } } = { nested: { pwd: 7 } }; return pwd;", "pwd; for (var pwd of [7]) {} return pwd;", "pwd; var other = 1, pwd = 7; return pwd;", "pwd; function* pwd() { yield 7; }", "pwd; function/**/pwd() {}", "pwd; function/**/\u002a/**/pwd() { yield 7; }", "pwd; var/**/{ pwd } = { pwd: 7 }; return pwd;", "node -version; function/**/node() {}; var version = 1;", "ls > limit; function ls() {} var limit = 1;", "test instanceof Function; function test() {}", "git instanceof Function; function git() {}", "export const answer = 7;", "export abstract class Example {}", "export import Alias = require('./module');", "export declare namespace Example {}", "export as namespace Example;", "export = Example;", "export async function read() {}", "export { answer };", "export * from './types';", "export interface Result { value: number }", "export enum Color { Red, Green }", 'const result = await tools.callValue("openclaw:core:exec", { command: "ls" }); return result;', 'return await tools.callValue("openclaw:core:read", { path: "/workspace" });', "console.log(await tools.callValue('openclaw:core:read', { path: '/workspace' }));", "// shell documentation: ls /workspace\nreturn 7;", "// shell documentation: ls /workspace\nconst answer = 7; return answer;", "/* typed module */ export interface Result { value: number }", ])("preserves the JavaScript or TypeScript source %j", (source) => { expect(isShellLikeCodeModeSource(source)).toBe(false); }); it.each([ { source: "node -1; var node: number = 7;", preparedSource: "node -1; var node = 7;", }, { source: "node --version; var node: number = 2, version = 1;", preparedSource: "node--; version; var node = 2, version = 1;", }, ])("preserves transpiled command-like TypeScript: $source", ({ source, preparedSource }) => { expect(isShellLikeCodeModeSource(source, preparedSource)).toBe(false); }); it("explains how to execute a real catalog tool without retrying shell source", () => { expect(CODE_MODE_SHELL_SOURCE_ERROR).toContain("JavaScript or TypeScript"); expect(CODE_MODE_SHELL_SOURCE_ERROR).toContain("not shell"); expect(CODE_MODE_SHELL_SOURCE_ERROR).toContain("tools.callValue"); expect(CODE_MODE_SHELL_SOURCE_ERROR).toContain("ALL_TOOLS"); expect(CODE_MODE_SHELL_SOURCE_ERROR).toContain("Do not retry"); }); });