src / utils.ts
export { tool } from "@lmstudio/sdk";
export { z } from "zod";
import { exec } from "child_process"
import { config } from "dotenv";
import { promisify } from "util";
import stripAnsi from "strip-ansi";
config()
const execAsync = promisify(exec)
// Detect commands that use 'cd' (case-insensitive)
// Matches: 'cd', 'cd /path', 'cd /path && cmd', 'cmd; cd /path', etc.
const cdPattern = /(?:^|[;&|]|\|\||&&)\s*cd(?:\s|$|;|&|\|)/i
export function isCdCommand(command: string): boolean {
return cdPattern.test(command)
}
export async function run(command: string, cwd?: string) {
try {
const { stdout, stderr } = await execAsync(command, { env: process.env, cwd })
const output = `${stripAnsi(stdout) + '\n' + stripAnsi(stderr)}`.trim()
return output || 'Command executed successfully (no output)'
} catch (error: any) {
const stdout = error.stdout ? stripAnsi(error.stdout) : ''
const stderr = error.stderr ? stripAnsi(error.stderr) : ''
const exitCode = error.code ?? 'unknown'
const output = `${stdout}\n${stderr}`.trim()
if (output) return output
return `Command failed with exit code ${exitCode}: ${command}\n${error.message}`
}
}