fix: no env expansion in action parameters

Bun.spawn is not performing env expansion. Added a function in env_utils to perform expansion before Bun.spawn
diff --git a/ide/deploy/client.js b/ide/deploy/client.js
index 51930aa..307f7ed 100644
--- a/ide/deploy/client.js
+++ b/ide/deploy/client.js
@@ -19,7 +19,8 @@
 import {resolve} from 'path';
 import process from 'process';
 import {createInterface} from 'readline';
-import {globalWatcher} from "./watch";
+import {globalWatcher} from './watch';
+import {expandEnv} from './env_utils';
 const { parse } = await import('shell-quote');
 export let globalProc = undefined;
 
@@ -103,7 +104,8 @@
  * through `getOpenServerlessConfig` mechanism
  */
 export async function build() {
-    const deploy = await getOpenServerlessConfig('deploy', 'true');
+    let deploy = await getOpenServerlessConfig('deploy', 'true');
+    deploy = expandEnv(deploy);
 
     const deployArgs = parse(deploy).filter(arg => typeof arg === "string");
 
diff --git a/ide/deploy/deploy.js b/ide/deploy/deploy.js
index 50d629c..293ed50 100644
--- a/ide/deploy/deploy.js
+++ b/ide/deploy/deploy.js
@@ -16,6 +16,7 @@
 // under the License.
 
 import fs from 'fs/promises';
+import { expandEnv } from './env_utils';
 const { parse } = await import('shell-quote');
 
 const MAINS = ["__main__.py", "index.js", "index.php", "main.go"];
@@ -31,6 +32,7 @@
 
 async function exec(cmd) {
   console.log("$", cmd);
+  cmd = expandEnv(cmd);
   const cmdArgs = parse(cmd).filter(arg => typeof arg === "string");
   
   const proc = Bun.spawn(cmdArgs, {
diff --git a/ide/deploy/env_utils.js b/ide/deploy/env_utils.js
new file mode 100644
index 0000000..e793551
--- /dev/null
+++ b/ide/deploy/env_utils.js
@@ -0,0 +1,67 @@
+export function expandEnv(str, env = process.env) {
+  // Stato per sapere se siamo dentro apici singoli
+  let inSingleQuotes = false;
+  let result = "";
+  let i = 0;
+
+  while (i < str.length) {
+    const ch = str[i];
+
+    // Toggle apici singoli (niente espansione all'interno)
+    if (ch === "'") {
+      inSingleQuotes = !inSingleQuotes;
+      result += ch;
+      i++;
+      continue;
+    }
+
+    // Espansione variabile
+    if (ch === "$" && !inSingleQuotes) {
+      if (str[i + 1] === "{") {
+        // Forma ${...}
+        const end = str.indexOf("}", i + 2);
+        if (end === -1) {
+          result += ch; // niente chiusura, lasciamo così
+          i++;
+          continue;
+        }
+        const expr = str.slice(i + 2, end);
+        const match = expr.match(/^([A-Za-z_][A-Za-z0-9_]*)(?:(:-|:=)(.*))?$/);
+
+        if (match) {
+          const [, name, op, def] = match;
+          let val = env[name];
+          if ((op === ":-" && (!val || val === "")) || (op === ":=" && (!val || val === ""))) {
+            val = def ?? "";
+            if (op === ":=") env[name] = val; // assegna
+          }
+          result += val ?? "";
+        } else {
+          result += "${" + expr + "}";
+        }
+        i = end + 1;
+      } else {
+        // Forma $VAR o variabili speciali
+        const varMatch = str.slice(i + 1).match(/^([A-Za-z_][A-Za-z0-9_]*|[0-9@#?$*!-])/);
+        if (varMatch) {
+          const name = varMatch[1];
+          let val;
+          if (name === "$") val = process.pid;
+          else if (name === "?") val = "0"; // impossibile sapere senza contesto
+          else if (name === "#") val = "0";
+          else if (name === "!") val = "";
+          else val = env[name] ?? "";
+          result += val;
+          i += 1 + name.length;
+        } else {
+          result += ch;
+          i++;
+        }
+      }
+    } else {
+      result += ch;
+      i++;
+    }
+  }
+  return result;
+}