@nomad-e/bluma-cli 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +267 -213
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -3205,7 +3205,7 @@ __export(exportConversation_exports, {
3205
3205
  resolveExportOutputPath: () => resolveExportOutputPath
3206
3206
  });
3207
3207
  import { promises as fs49 } from "fs";
3208
- import path55 from "path";
3208
+ import path54 from "path";
3209
3209
  function extractTextParts2(content) {
3210
3210
  if (typeof content === "string") {
3211
3211
  const trimmed = content.trim();
@@ -3363,12 +3363,12 @@ function resolveExportOutputPath(sessionId, options) {
3363
3363
  const { outputPath, defaultExportDir } = options ?? {};
3364
3364
  if (outputPath?.trim()) {
3365
3365
  const raw = outputPath.trim();
3366
- return path55.isAbsolute(raw) ? raw : path55.resolve(process.cwd(), raw);
3366
+ return path54.isAbsolute(raw) ? raw : path54.resolve(process.cwd(), raw);
3367
3367
  }
3368
3368
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
3369
3369
  const safeId = sessionId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 48) || "session";
3370
3370
  const baseDir = defaultExportDir ?? getSandboxPolicy().workspaceRoot;
3371
- return path55.join(baseDir, `bluma-export-${safeId}-${stamp}.md`);
3371
+ return path54.join(baseDir, `bluma-export-${safeId}-${stamp}.md`);
3372
3372
  }
3373
3373
  async function resolveHistory(sessionId, fallbackHistory) {
3374
3374
  const loaded2 = await loadSession(sessionId);
@@ -3390,7 +3390,7 @@ async function exportConversationToFile(options) {
3390
3390
  }
3391
3391
  const markdown = formatConversationMarkdown(sessionId, history);
3392
3392
  const filePath = resolveExportOutputPath(sessionId, { outputPath, defaultExportDir });
3393
- await fs49.mkdir(path55.dirname(filePath), { recursive: true });
3393
+ await fs49.mkdir(path54.dirname(filePath), { recursive: true });
3394
3394
  await fs49.writeFile(filePath, markdown, "utf-8");
3395
3395
  return {
3396
3396
  success: true,
@@ -3916,11 +3916,11 @@ var NodeFsOperations = {
3916
3916
  if (fd) fs.closeSync(fd);
3917
3917
  }
3918
3918
  },
3919
- appendFileSync(path60, data, options) {
3920
- const _ = slowLogging`fs.appendFileSync(${path60}, ${data.length} chars)`;
3919
+ appendFileSync(path59, data, options) {
3920
+ const _ = slowLogging`fs.appendFileSync(${path59}, ${data.length} chars)`;
3921
3921
  if (options?.mode !== void 0) {
3922
3922
  try {
3923
- const fd = fs.openSync(path60, "ax", options.mode);
3923
+ const fd = fs.openSync(path59, "ax", options.mode);
3924
3924
  try {
3925
3925
  fs.appendFileSync(fd, data);
3926
3926
  } finally {
@@ -3931,35 +3931,35 @@ var NodeFsOperations = {
3931
3931
  if (getErrnoCode(e) !== "EEXIST") throw e;
3932
3932
  }
3933
3933
  }
3934
- fs.appendFileSync(path60, data);
3934
+ fs.appendFileSync(path59, data);
3935
3935
  },
3936
3936
  copyFileSync(src, dest) {
3937
3937
  const _ = slowLogging`fs.copyFileSync(${src} → ${dest})`;
3938
3938
  fs.copyFileSync(src, dest);
3939
3939
  },
3940
- unlinkSync(path60) {
3941
- const _ = slowLogging`fs.unlinkSync(${path60})`;
3942
- fs.unlinkSync(path60);
3940
+ unlinkSync(path59) {
3941
+ const _ = slowLogging`fs.unlinkSync(${path59})`;
3942
+ fs.unlinkSync(path59);
3943
3943
  },
3944
3944
  renameSync(oldPath, newPath) {
3945
3945
  const _ = slowLogging`fs.renameSync(${oldPath} → ${newPath})`;
3946
3946
  fs.renameSync(oldPath, newPath);
3947
3947
  },
3948
- linkSync(target, path60) {
3949
- const _ = slowLogging`fs.linkSync(${target} → ${path60})`;
3950
- fs.linkSync(target, path60);
3948
+ linkSync(target, path59) {
3949
+ const _ = slowLogging`fs.linkSync(${target} → ${path59})`;
3950
+ fs.linkSync(target, path59);
3951
3951
  },
3952
- symlinkSync(target, path60, type) {
3953
- const _ = slowLogging`fs.symlinkSync(${target} → ${path60})`;
3954
- fs.symlinkSync(target, path60, type);
3952
+ symlinkSync(target, path59, type) {
3953
+ const _ = slowLogging`fs.symlinkSync(${target} → ${path59})`;
3954
+ fs.symlinkSync(target, path59, type);
3955
3955
  },
3956
- readlinkSync(path60) {
3957
- const _ = slowLogging`fs.readlinkSync(${path60})`;
3958
- return fs.readlinkSync(path60);
3956
+ readlinkSync(path59) {
3957
+ const _ = slowLogging`fs.readlinkSync(${path59})`;
3958
+ return fs.readlinkSync(path59);
3959
3959
  },
3960
- realpathSync(path60) {
3961
- const _ = slowLogging`fs.realpathSync(${path60})`;
3962
- return fs.realpathSync(path60).normalize("NFC");
3960
+ realpathSync(path59) {
3961
+ const _ = slowLogging`fs.realpathSync(${path59})`;
3962
+ return fs.realpathSync(path59).normalize("NFC");
3963
3963
  },
3964
3964
  mkdirSync(dirPath, options) {
3965
3965
  const _ = slowLogging`fs.mkdirSync(${dirPath})`;
@@ -3992,12 +3992,12 @@ var NodeFsOperations = {
3992
3992
  const _ = slowLogging`fs.rmdirSync(${dirPath})`;
3993
3993
  fs.rmdirSync(dirPath);
3994
3994
  },
3995
- rmSync(path60, options) {
3996
- const _ = slowLogging`fs.rmSync(${path60})`;
3997
- fs.rmSync(path60, options);
3995
+ rmSync(path59, options) {
3996
+ const _ = slowLogging`fs.rmSync(${path59})`;
3997
+ fs.rmSync(path59, options);
3998
3998
  },
3999
- createWriteStream(path60) {
4000
- return fs.createWriteStream(path60);
3999
+ createWriteStream(path59) {
4000
+ return fs.createWriteStream(path59);
4001
4001
  },
4002
4002
  async readFileBytes(fsPath, maxBytes) {
4003
4003
  if (maxBytes === void 0) {
@@ -4104,12 +4104,12 @@ function shouldLogDebugMessage(message2) {
4104
4104
  var hasFormattedOutput = false;
4105
4105
  var debugWriter = null;
4106
4106
  var pendingWrite = Promise.resolve();
4107
- async function appendAsync(needMkdir, dir, path60, content) {
4107
+ async function appendAsync(needMkdir, dir, path59, content) {
4108
4108
  if (needMkdir) {
4109
4109
  await mkdir(dir, { recursive: true }).catch(() => {
4110
4110
  });
4111
4111
  }
4112
- await appendFile(path60, content);
4112
+ await appendFile(path59, content);
4113
4113
  void updateLatestDebugLogSymlink();
4114
4114
  }
4115
4115
  function noop() {
@@ -4119,8 +4119,8 @@ function getDebugWriter() {
4119
4119
  let ensuredDir = null;
4120
4120
  debugWriter = createBufferedWriter({
4121
4121
  writeFn: (content) => {
4122
- const path60 = getDebugLogPath();
4123
- const dir = dirname(path60);
4122
+ const path59 = getDebugLogPath();
4123
+ const dir = dirname(path59);
4124
4124
  const needMkdir = ensuredDir !== dir;
4125
4125
  ensuredDir = dir;
4126
4126
  if (isDebugMode()) {
@@ -4130,11 +4130,11 @@ function getDebugWriter() {
4130
4130
  } catch {
4131
4131
  }
4132
4132
  }
4133
- getFsImplementation().appendFileSync(path60, content);
4133
+ getFsImplementation().appendFileSync(path59, content);
4134
4134
  void updateLatestDebugLogSymlink();
4135
4135
  return;
4136
4136
  }
4137
- pendingWrite = pendingWrite.then(appendAsync.bind(null, needMkdir, dir, path60, content)).catch(noop);
4137
+ pendingWrite = pendingWrite.then(appendAsync.bind(null, needMkdir, dir, path59, content)).catch(noop);
4138
4138
  },
4139
4139
  flushIntervalMs: 1e3,
4140
4140
  maxBufferSize: 100,
@@ -10321,8 +10321,8 @@ import codeExcerpt from "code-excerpt";
10321
10321
  import { readFileSync as readFileSync2 } from "fs";
10322
10322
  import StackUtils from "stack-utils";
10323
10323
  import { jsx as jsx6, jsxs } from "react/jsx-runtime";
10324
- var cleanupPath = (path60) => {
10325
- return path60?.replace(`file://${process.cwd()}/`, "");
10324
+ var cleanupPath = (path59) => {
10325
+ return path59?.replace(`file://${process.cwd()}/`, "");
10326
10326
  };
10327
10327
  var stackUtils;
10328
10328
  function getStackUtils() {
@@ -14300,7 +14300,7 @@ var getInstance = (stdout, createInstance) => {
14300
14300
  // src/main.ts
14301
14301
  import { EventEmitter as EventEmitter7 } from "events";
14302
14302
  import fs53 from "fs";
14303
- import path59 from "path";
14303
+ import path58 from "path";
14304
14304
  import { fileURLToPath as fileURLToPath8 } from "url";
14305
14305
  import { spawn as spawn6 } from "child_process";
14306
14306
  import { v4 as uuidv412 } from "uuid";
@@ -14979,7 +14979,7 @@ function cancelSlashSubmenu() {
14979
14979
 
14980
14980
  // src/app/agent/agent.ts
14981
14981
  import * as dotenv from "dotenv";
14982
- import path49 from "path";
14982
+ import path48 from "path";
14983
14983
  import os30 from "os";
14984
14984
 
14985
14985
  // src/app/agent/tool_invoker.ts
@@ -22028,14 +22028,14 @@ PENALTY APPLIED: ${penalty.toFixed(1)} points deducted.
22028
22028
 
22029
22029
  // src/app/agent/bluma/core/bluma.ts
22030
22030
  init_session_manager();
22031
- import path46 from "path";
22031
+ import path45 from "path";
22032
22032
  import fs41 from "fs";
22033
22033
  import { v4 as uuidv48 } from "uuid";
22034
22034
 
22035
22035
  // src/app/agent/core/prompt/prompt_builder.ts
22036
22036
  import os23 from "os";
22037
22037
  import fs37 from "fs";
22038
- import path40 from "path";
22038
+ import path39 from "path";
22039
22039
  import { execSync as execSync3 } from "child_process";
22040
22040
 
22041
22041
  // src/app/agent/skills/skill_loader.ts
@@ -23892,12 +23892,12 @@ init_session_memory_paths();
23892
23892
  import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
23893
23893
  async function loadSessionMemoryForPrompt(sessionId, cwd2 = process.cwd()) {
23894
23894
  if (!sessionId?.trim()) return "";
23895
- const path60 = getSessionMemoryPath(sessionId, cwd2);
23895
+ const path59 = getSessionMemoryPath(sessionId, cwd2);
23896
23896
  try {
23897
- const content = await readFile3(path60, "utf-8");
23897
+ const content = await readFile3(path59, "utf-8");
23898
23898
  if (!content.trim()) return "";
23899
23899
  return `<session_memory>
23900
- Notes for this conversation (${path60}):
23900
+ Notes for this conversation (${path59}):
23901
23901
 
23902
23902
  ${content.trim()}
23903
23903
  </session_memory>`;
@@ -23907,11 +23907,11 @@ ${content.trim()}
23907
23907
  }
23908
23908
  async function initSessionMemoryFile(sessionId, cwd2 = process.cwd()) {
23909
23909
  await ensureSessionMemoryDir(sessionId, cwd2);
23910
- const path60 = getSessionMemoryPath(sessionId, cwd2);
23910
+ const path59 = getSessionMemoryPath(sessionId, cwd2);
23911
23911
  try {
23912
- await readFile3(path60, "utf-8");
23912
+ await readFile3(path59, "utf-8");
23913
23913
  } catch {
23914
- await writeFile2(path60, `${DEFAULT_SESSION_MEMORY_TEMPLATE}
23914
+ await writeFile2(path59, `${DEFAULT_SESSION_MEMORY_TEMPLATE}
23915
23915
  `, "utf-8");
23916
23916
  }
23917
23917
  }
@@ -24065,10 +24065,58 @@ No diret\xF3rio do projeto (ex. \`./my-app\`):
24065
24065
 
24066
24066
  // src/app/agent/runtime/sandbox_runtime_context.ts
24067
24067
  import fs36 from "fs";
24068
- import path39 from "path";
24069
24068
  function env2(key) {
24070
24069
  return String(process.env[key] ?? "").trim();
24071
24070
  }
24071
+ function pickRuntime(cwd2, injected) {
24072
+ const severinoUrl = injected?.severinoUrl || env2("SEVERINO_URL");
24073
+ const factoraiBaseUrl = injected?.factoraiBaseUrl || env2("FACTORAI_BASE_URL") || env2("FACTORAI_URL") || severinoUrl;
24074
+ return {
24075
+ sandboxName: injected?.sandboxName || env2("BLUMA_SANDBOX_NAME") || "sandbox-api",
24076
+ sessionId: injected?.sessionId || env2("BLUMA_SESSION_ID") || "unknown",
24077
+ workspaceRoot: injected?.workspaceRoot || cwd2,
24078
+ fromAgent: injected?.fromAgent || env2("BLUMA_FROM_AGENT") || "orchestrator",
24079
+ action: injected?.action || env2("BLUMA_ACTION") || "unknown",
24080
+ severinoUrl: severinoUrl || void 0,
24081
+ factoraiBaseUrl: factoraiBaseUrl || void 0,
24082
+ severinoApiKeyConfigured: injected?.severinoApiKeyConfigured ?? Boolean(env2("SEVERINO_API_KEY") || env2("SEVERINO_TOKEN")),
24083
+ factoraiApiKeyConfigured: injected?.factoraiApiKeyConfigured ?? Boolean(env2("FACTORAI_API_KEY") || env2("FACTORAI_TOKEN")),
24084
+ timeoutSeconds: injected?.timeoutSeconds,
24085
+ userRequest: injected?.userRequest || env2("BLUMA_USER_REQUEST") || void 0,
24086
+ operatorMode: injected?.operatorMode || "autonomous_worker",
24087
+ injectedAt: injected?.injectedAt
24088
+ };
24089
+ }
24090
+ function applySandboxRuntimeFromEnvelope(envelope) {
24091
+ const rt = envelope.sandbox_runtime;
24092
+ if (!rt || typeof rt !== "object") {
24093
+ return null;
24094
+ }
24095
+ process.env.BLUMA_SANDBOX = "true";
24096
+ if (rt.sandboxName) process.env.BLUMA_SANDBOX_NAME = rt.sandboxName;
24097
+ if (rt.sessionId) process.env.BLUMA_SESSION_ID = rt.sessionId;
24098
+ if (rt.fromAgent) process.env.BLUMA_FROM_AGENT = rt.fromAgent;
24099
+ if (rt.action) process.env.BLUMA_ACTION = rt.action;
24100
+ if (rt.severinoUrl) process.env.SEVERINO_URL = rt.severinoUrl.replace(/\/$/, "");
24101
+ if (rt.factoraiBaseUrl) {
24102
+ process.env.FACTORAI_BASE_URL = rt.factoraiBaseUrl.replace(/\/$/, "");
24103
+ } else if (rt.severinoUrl && !env2("FACTORAI_BASE_URL")) {
24104
+ process.env.FACTORAI_BASE_URL = rt.severinoUrl.replace(/\/$/, "");
24105
+ }
24106
+ if (rt.userRequest?.trim()) {
24107
+ process.env.BLUMA_USER_REQUEST = rt.userRequest.trim();
24108
+ }
24109
+ if (typeof rt.timeoutSeconds === "number" && rt.timeoutSeconds > 0) {
24110
+ process.env.BLUMA_JOB_TIMEOUT_SECONDS = String(rt.timeoutSeconds);
24111
+ }
24112
+ if (rt.workspaceRoot) {
24113
+ process.env.BLUMA_SANDBOX_WORKSPACE = rt.workspaceRoot;
24114
+ }
24115
+ if (envelope.metadata?.sandbox === true && !process.env.BLUMA_SANDBOX_NAME?.trim()) {
24116
+ process.env.BLUMA_SANDBOX_NAME = String(envelope.metadata.sandbox_name || "sandbox-api");
24117
+ }
24118
+ return rt;
24119
+ }
24072
24120
  function listWorkspaceTopLevel(cwd2, max = 24) {
24073
24121
  try {
24074
24122
  return fs36.readdirSync(cwd2, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")).slice(0, max).map((e) => e.isDirectory() ? `${e.name}/` : e.name);
@@ -24076,53 +24124,45 @@ function listWorkspaceTopLevel(cwd2, max = 24) {
24076
24124
  return [];
24077
24125
  }
24078
24126
  }
24079
- function buildSandboxRuntimeContextBlock(cwd2) {
24080
- const sessionId = env2("BLUMA_SESSION_ID") || "unknown";
24081
- const sandboxName = env2("BLUMA_SANDBOX_NAME") || "sandbox-api";
24082
- const fromAgent = env2("BLUMA_FROM_AGENT") || "orchestrator";
24083
- const action = env2("BLUMA_ACTION") || "unknown";
24084
- const severinoUrl = env2("SEVERINO_URL");
24085
- const factoraiUrl = env2("FACTORAI_BASE_URL") || env2("FACTORAI_URL") || severinoUrl;
24086
- const userRequest = env2("BLUMA_USER_REQUEST");
24127
+ function buildSandboxRuntimeContextBlock(cwd2, injected) {
24128
+ const rt = pickRuntime(cwd2, injected);
24087
24129
  const factoraiEnabled = isFactorAiShPromptEnabled();
24088
24130
  const top = listWorkspaceTopLevel(cwd2);
24089
24131
  const lines = [
24090
24132
  "<sandbox_runtime>",
24091
- "## Ambiente atual (factos reais \u2014 usa isto para te orientares)",
24133
+ "## Ambiente atual (injetado pelo orquestrador \u2014 factos autoritativos)",
24134
+ "",
24135
+ rt.injectedAt ? `_Atualizado: ${rt.injectedAt}_` : "_Dados do envelope stdin + env da sess\xE3o_",
24092
24136
  "",
24093
- "Operas como **agente aut\xF3nomo** (estilo Manus): n\xE3o h\xE1 utilizador no terminal a responder. O orquestrador (Severino / sandbox-api) envia o pedido, observa o teu progresso via `message(info)` e s\xF3 encerra o job com `message(result)`.",
24137
+ `Modo: **${rt.operatorMode || "autonomous_worker"}** (sem humano no terminal; progresso via \`message(info)\`, fim via \`message(result)\`).`,
24094
24138
  "",
24095
24139
  "| Campo | Valor |",
24096
24140
  "|-------|-------|",
24097
- `| sandbox | ${sandboxName} |`,
24098
- `| session_id | ${sessionId} |`,
24099
- `| workspace (cwd) | ${cwd2} |`,
24100
- `| delegado por | ${fromAgent} |`,
24101
- `| action | ${action} |`,
24141
+ `| sandbox | ${rt.sandboxName} |`,
24142
+ `| session_id | ${rt.sessionId} |`,
24143
+ `| workspace (cwd) | ${rt.workspaceRoot || cwd2} |`,
24144
+ `| delegado por | ${rt.fromAgent} |`,
24145
+ `| action | ${rt.action} |`,
24102
24146
  `| node | ${process.version} |`,
24103
- `| auto_approve_tools | sim (sandbox isolado) |`
24147
+ `| job_timeout_seconds | ${rt.timeoutSeconds ?? (env2("BLUMA_JOB_TIMEOUT_SECONDS") || "\u2014")} |`,
24148
+ `| auto_approve_tools | sim |`
24104
24149
  ];
24105
- if (severinoUrl) {
24106
- lines.push(`| SEVERINO_URL (deploy ZIP) | ${severinoUrl} |`);
24107
- }
24108
- if (factoraiUrl) {
24109
- lines.push(`| FACTORAI_BASE_URL (status/apply/redeploy) | ${factoraiUrl} |`);
24150
+ if (rt.severinoUrl) {
24151
+ lines.push(`| SEVERINO_URL (deploy ZIP) | ${rt.severinoUrl} |`);
24152
+ lines.push(`| SEVERINO_API_KEY | ${rt.severinoApiKeyConfigured ? "configurada" : "ausente"} |`);
24110
24153
  }
24111
- if (severinoUrl && factoraiUrl && severinoUrl !== factoraiUrl) {
24112
- lines.push("");
24113
- lines.push(
24114
- "\u26A0\uFE0F SEVERINO_URL e FACTORAI_BASE_URL diferem \u2014 confirma qual backend falhou se `get_app_status` der 404 ap\xF3s deploy."
24115
- );
24154
+ if (rt.factoraiBaseUrl) {
24155
+ lines.push(`| FACTORAI_BASE_URL | ${rt.factoraiBaseUrl} |`);
24156
+ lines.push(`| FACTORAI_API_KEY | ${rt.factoraiApiKeyConfigured ? "configurada" : "ausente"} |`);
24116
24157
  }
24117
- if (factoraiEnabled) {
24158
+ if (rt.severinoUrl && rt.factoraiBaseUrl && rt.severinoUrl !== rt.factoraiBaseUrl) {
24118
24159
  lines.push("");
24119
- lines.push("**FactorAI.sh:** ativo nesta sess\xE3o (`factorai.sh.*` tools dispon\xEDveis).");
24120
- } else {
24121
- lines.push("");
24122
- lines.push(
24123
- "**FactorAI.sh:** n\xE3o configurado (falta `FACTORAI_BASE_URL` ou `BLUMA_SANDBOX`). Hosting Next.js via factorai.sh indispon\xEDvel at\xE9 o orquestrador definir env."
24124
- );
24160
+ lines.push("\u26A0\uFE0F SEVERINO_URL \u2260 FACTORAI_BASE_URL \u2014 usa o host certo por tool.");
24125
24161
  }
24162
+ lines.push("");
24163
+ lines.push(
24164
+ factoraiEnabled ? "**FactorAI.sh:** ativo (`factorai.sh.*` dispon\xEDveis)." : "**FactorAI.sh:** inativo \u2014 orquestrador deve definir FACTORAI_BASE_URL + BLUMA_SANDBOX."
24165
+ );
24126
24166
  if (top.length > 0) {
24127
24167
  lines.push("");
24128
24168
  lines.push(`**Raiz do workspace:** ${top.join(", ")}`);
@@ -24130,30 +24170,39 @@ function buildSandboxRuntimeContextBlock(cwd2) {
24130
24170
  const manifest = readFactorAiWorkspaceManifest(cwd2);
24131
24171
  if (manifest) {
24132
24172
  const ctx = manifest.appContext;
24133
- const appId = ctx?.appId;
24134
24173
  const liveUrl = resolveFactorShAppLiveUrl(cwd2);
24135
24174
  lines.push("");
24136
- lines.push("**App FactorAI nesta sess\xE3o (factorai.sh.json):**");
24137
- if (appId) lines.push(`- appId: ${appId}`);
24175
+ lines.push("**App FactorAI (factorai.sh.json no workspace):**");
24176
+ if (ctx?.appId) lines.push(`- appId: ${ctx.appId}`);
24138
24177
  if (liveUrl) lines.push(`- appUrl: ${liveUrl}`);
24139
- const appDir = typeof manifest.app === "object" && manifest.app && typeof manifest.app.name === "string" ? manifest.app.name : null;
24140
- if (appDir) {
24141
- const projectPath = path39.join(cwd2, appDir);
24142
- if (fs36.existsSync(projectPath)) {
24143
- lines.push(`- project_dir: ${projectPath}`);
24144
- }
24145
- }
24146
24178
  }
24147
- if (userRequest) {
24179
+ if (rt.userRequest) {
24148
24180
  lines.push("");
24149
- lines.push("**Pedido deste turno (resumo):**");
24150
- lines.push(userRequest.length > 2500 ? `${userRequest.slice(0, 2500)}\u2026` : userRequest);
24181
+ lines.push("**Pedido deste job (user_request):**");
24182
+ lines.push(rt.userRequest.length > 4e3 ? `${rt.userRequest.slice(0, 4e3)}\u2026` : rt.userRequest);
24151
24183
  }
24152
24184
  lines.push("</sandbox_runtime>");
24153
24185
  return lines.join("\n");
24154
24186
  }
24187
+ function formatSandboxRuntimeUserTurnPrefix(rt) {
24188
+ const parts = [
24189
+ "<sandbox_runtime_injected>",
24190
+ `session=${rt.sessionId ?? "?"}`,
24191
+ `action=${rt.action ?? "?"}`,
24192
+ `from=${rt.fromAgent ?? "?"}`,
24193
+ rt.severinoUrl ? `SEVERINO_URL=${rt.severinoUrl}` : null,
24194
+ rt.factoraiBaseUrl ? `FACTORAI_BASE_URL=${rt.factoraiBaseUrl}` : null,
24195
+ typeof rt.timeoutSeconds === "number" ? `timeout_seconds=${rt.timeoutSeconds}` : null,
24196
+ "</sandbox_runtime_injected>"
24197
+ ].filter(Boolean);
24198
+ return parts.join("\n");
24199
+ }
24155
24200
 
24156
24201
  // src/app/agent/core/prompt/prompt_builder.ts
24202
+ var _injectedSandboxRuntime = null;
24203
+ function setInjectedSandboxRuntimeForPrompt(rt) {
24204
+ _injectedSandboxRuntime = rt;
24205
+ }
24157
24206
  function getNodeVersion() {
24158
24207
  return process.version;
24159
24208
  }
@@ -24184,17 +24233,17 @@ function getGitBranch(dir) {
24184
24233
  }
24185
24234
  }
24186
24235
  function getPackageManager(dir) {
24187
- if (fs37.existsSync(path40.join(dir, "pnpm-lock.yaml"))) return "pnpm";
24188
- if (fs37.existsSync(path40.join(dir, "yarn.lock"))) return "yarn";
24189
- if (fs37.existsSync(path40.join(dir, "bun.lockb"))) return "bun";
24190
- if (fs37.existsSync(path40.join(dir, "package-lock.json"))) return "npm";
24236
+ if (fs37.existsSync(path39.join(dir, "pnpm-lock.yaml"))) return "pnpm";
24237
+ if (fs37.existsSync(path39.join(dir, "yarn.lock"))) return "yarn";
24238
+ if (fs37.existsSync(path39.join(dir, "bun.lockb"))) return "bun";
24239
+ if (fs37.existsSync(path39.join(dir, "package-lock.json"))) return "npm";
24191
24240
  return "unknown";
24192
24241
  }
24193
24242
  function getProjectType(dir) {
24194
24243
  try {
24195
24244
  const files = fs37.readdirSync(dir);
24196
24245
  if (files.includes("package.json")) {
24197
- const pkg = JSON.parse(fs37.readFileSync(path40.join(dir, "package.json"), "utf-8"));
24246
+ const pkg = JSON.parse(fs37.readFileSync(path39.join(dir, "package.json"), "utf-8"));
24198
24247
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
24199
24248
  if (deps.next) return "Next.js";
24200
24249
  if (deps.react) return "React";
@@ -24214,7 +24263,7 @@ function getProjectType(dir) {
24214
24263
  }
24215
24264
  function getTestFramework(dir) {
24216
24265
  try {
24217
- const pkgPath = path40.join(dir, "package.json");
24266
+ const pkgPath = path39.join(dir, "package.json");
24218
24267
  if (fs37.existsSync(pkgPath)) {
24219
24268
  const pkg = JSON.parse(fs37.readFileSync(pkgPath, "utf-8"));
24220
24269
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
@@ -24225,7 +24274,7 @@ function getTestFramework(dir) {
24225
24274
  if (deps["@playwright/test"]) return "playwright";
24226
24275
  if (deps.cypress) return "cypress";
24227
24276
  }
24228
- if (fs37.existsSync(path40.join(dir, "pytest.ini")) || fs37.existsSync(path40.join(dir, "conftest.py"))) return "pytest";
24277
+ if (fs37.existsSync(path39.join(dir, "pytest.ini")) || fs37.existsSync(path39.join(dir, "conftest.py"))) return "pytest";
24229
24278
  return "unknown";
24230
24279
  } catch {
24231
24280
  return "unknown";
@@ -24233,7 +24282,7 @@ function getTestFramework(dir) {
24233
24282
  }
24234
24283
  function getTestCommand(dir) {
24235
24284
  try {
24236
- const pkgPath = path40.join(dir, "package.json");
24285
+ const pkgPath = path39.join(dir, "package.json");
24237
24286
  if (fs37.existsSync(pkgPath)) {
24238
24287
  const pkg = JSON.parse(fs37.readFileSync(pkgPath, "utf-8"));
24239
24288
  if (pkg.scripts?.test) return "npm test";
@@ -24250,7 +24299,7 @@ function getTestCommand(dir) {
24250
24299
  }
24251
24300
  function isGitRepo(dir) {
24252
24301
  try {
24253
- const p = path40.join(dir, ".git");
24302
+ const p = path39.join(dir, ".git");
24254
24303
  return fs37.existsSync(p) && fs37.lstatSync(p).isDirectory();
24255
24304
  } catch {
24256
24305
  return false;
@@ -24508,7 +24557,7 @@ async function getUnifiedSystemPrompt(availableSkills, options) {
24508
24557
  ${SUBJECT_MACHINE_MODEL_XML}`;
24509
24558
  prompt += `
24510
24559
 
24511
- ${buildSandboxRuntimeContextBlock(cwd2)}`;
24560
+ ${buildSandboxRuntimeContextBlock(cwd2, _injectedSandboxRuntime ?? void 0)}`;
24512
24561
  prompt += `
24513
24562
 
24514
24563
  ${SANDBOX_AUTONOMY_SECTION}`;
@@ -25693,7 +25742,7 @@ var LLMService = class {
25693
25742
  // src/app/agent/utils/user_message_images.ts
25694
25743
  import fs38 from "fs";
25695
25744
  import os25 from "os";
25696
- import path41 from "path";
25745
+ import path40 from "path";
25697
25746
  import { fileURLToPath as fileURLToPath5 } from "url";
25698
25747
  var IMAGE_EXT = /\.(png|jpe?g|gif|webp|bmp)$/i;
25699
25748
  var MAX_IMAGE_BYTES = 4 * 1024 * 1024;
@@ -25709,22 +25758,22 @@ var MIME = {
25709
25758
  function expandUserPath(p) {
25710
25759
  const t = p.trim();
25711
25760
  if (t.startsWith("~")) {
25712
- return path41.join(os25.homedir(), t.slice(1).replace(/^\//, ""));
25761
+ return path40.join(os25.homedir(), t.slice(1).replace(/^\//, ""));
25713
25762
  }
25714
25763
  return t;
25715
25764
  }
25716
25765
  function isPathAllowed(absResolved, cwd2) {
25717
- const resolved = path41.normalize(path41.resolve(absResolved));
25718
- const cwdR = path41.normalize(path41.resolve(cwd2));
25719
- const homeR = path41.normalize(path41.resolve(os25.homedir()));
25720
- const tmpR = path41.normalize(path41.resolve(os25.tmpdir()));
25721
- const underCwd = resolved === cwdR || resolved.startsWith(cwdR + path41.sep);
25722
- const underHome = resolved === homeR || resolved.startsWith(homeR + path41.sep);
25723
- const underTmp = resolved === tmpR || resolved.startsWith(tmpR + path41.sep);
25766
+ const resolved = path40.normalize(path40.resolve(absResolved));
25767
+ const cwdR = path40.normalize(path40.resolve(cwd2));
25768
+ const homeR = path40.normalize(path40.resolve(os25.homedir()));
25769
+ const tmpR = path40.normalize(path40.resolve(os25.tmpdir()));
25770
+ const underCwd = resolved === cwdR || resolved.startsWith(cwdR + path40.sep);
25771
+ const underHome = resolved === homeR || resolved.startsWith(homeR + path40.sep);
25772
+ const underTmp = resolved === tmpR || resolved.startsWith(tmpR + path40.sep);
25724
25773
  return underCwd || underHome || underTmp;
25725
25774
  }
25726
25775
  function mimeFor(abs) {
25727
- const ext = path41.extname(abs).toLowerCase();
25776
+ const ext = path40.extname(abs).toLowerCase();
25728
25777
  return MIME[ext] || "application/octet-stream";
25729
25778
  }
25730
25779
  var IMAGE_EXT_SRC = String.raw`(?:png|jpe?g|gif|webp|bmp)`;
@@ -25768,7 +25817,7 @@ function collectImagePathStrings(raw) {
25768
25817
  }
25769
25818
  function resolveImagePath(candidate, cwd2) {
25770
25819
  const expanded = expandUserPath(candidate);
25771
- const abs = path41.isAbsolute(expanded) ? path41.normalize(expanded) : path41.normalize(path41.resolve(cwd2, expanded));
25820
+ const abs = path40.isAbsolute(expanded) ? path40.normalize(expanded) : path40.normalize(path40.resolve(cwd2, expanded));
25772
25821
  if (!isPathAllowed(abs, cwd2)) return null;
25773
25822
  try {
25774
25823
  if (!fs38.existsSync(abs) || !fs38.statSync(abs).isFile()) return null;
@@ -25791,7 +25840,7 @@ function trySingleLineFileUriOrBareImagePath(line, cwd2) {
25791
25840
  if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
25792
25841
  s = s.slice(1, -1).trim();
25793
25842
  }
25794
- if (!IMAGE_EXT.test(path41.extname(s))) return null;
25843
+ if (!IMAGE_EXT.test(path40.extname(s))) return null;
25795
25844
  const abs = resolveImagePath(s, cwd2);
25796
25845
  if (!abs) return null;
25797
25846
  try {
@@ -25894,7 +25943,7 @@ function buildUserMessageContent(raw, cwd2) {
25894
25943
  init_sandbox_policy();
25895
25944
  init_runtime_config();
25896
25945
  init_permission_rules();
25897
- import path42 from "path";
25946
+ import path41 from "path";
25898
25947
  var LOCAL_EDIT_TOOL_NAMES = /* @__PURE__ */ new Set(["edit_tool", "file_write", "notebook_edit"]);
25899
25948
  function getToolPermissionLayer(metadata) {
25900
25949
  if (metadata.riskLevel === "safe") return "read";
@@ -25909,11 +25958,11 @@ function checkFilePermissionRules(toolName, filePath, policy) {
25909
25958
  if (!filePath) {
25910
25959
  return { allowed: false, reason: "No file path provided for permission check." };
25911
25960
  }
25912
- const resolvedPath = path42.resolve(filePath);
25961
+ const resolvedPath = path41.resolve(filePath);
25913
25962
  if (!isPathInsideWorkspace(resolvedPath, policy)) {
25914
25963
  return { allowed: false, reason: `File path "${filePath}" is outside workspace root.` };
25915
25964
  }
25916
- const relativePath = path42.relative(policy.workspaceRoot, resolvedPath);
25965
+ const relativePath = path41.relative(policy.workspaceRoot, resolvedPath);
25917
25966
  const toolPattern = `${toolName}(${relativePath})`;
25918
25967
  const ruleDecision = permissionRulesEngine.checkPermission(toolPattern, { filepath: filePath });
25919
25968
  if (ruleDecision === "deny") {
@@ -25922,7 +25971,7 @@ function checkFilePermissionRules(toolName, filePath, policy) {
25922
25971
  if (ruleDecision === "allow") {
25923
25972
  return { allowed: true, reason: `File "${filePath}" allowed by permission rules.` };
25924
25973
  }
25925
- const dirPath = path42.dirname(relativePath);
25974
+ const dirPath = path41.dirname(relativePath);
25926
25975
  const dirPattern = `${toolName}(${dirPath}/**)`;
25927
25976
  const dirRuleDecision = permissionRulesEngine.checkPermission(dirPattern, { filepath: filePath });
25928
25977
  if (dirRuleDecision === "allow") {
@@ -26140,10 +26189,10 @@ function effectiveToolAutoApprove(toolCall, sessionId, options) {
26140
26189
 
26141
26190
  // src/app/agent/tools/CodingMemoryTool/CodingMemoryConsolidate.ts
26142
26191
  import * as fs39 from "fs";
26143
- import * as path43 from "path";
26192
+ import * as path42 from "path";
26144
26193
  import os26 from "os";
26145
26194
  function memoryPath2() {
26146
- return path43.join(process.env.HOME || os26.homedir(), ".bluma", "coding_memory.json");
26195
+ return path42.join(process.env.HOME || os26.homedir(), ".bluma", "coding_memory.json");
26147
26196
  }
26148
26197
  function normalizeNote2(note) {
26149
26198
  return note.trim().toLowerCase().replace(/\s+/g, " ");
@@ -26705,16 +26754,16 @@ var BluMaToolRunner = class {
26705
26754
 
26706
26755
  // src/app/agent/session_manager/session_archive.ts
26707
26756
  init_bluma_app_dir();
26708
- import path44 from "path";
26757
+ import path43 from "path";
26709
26758
  import { promises as fs40 } from "fs";
26710
26759
  async function archivePrunedConversationMessages(sessionId, messages) {
26711
26760
  if (!sessionId || messages.length === 0) {
26712
26761
  return null;
26713
26762
  }
26714
26763
  const appDir = getPreferredAppDir();
26715
- const dir = path44.join(appDir, "sessions", "archive", sessionId);
26764
+ const dir = path43.join(appDir, "sessions", "archive", sessionId);
26716
26765
  await fs40.mkdir(dir, { recursive: true });
26717
- const archiveFile = path44.join(dir, `${Date.now()}.jsonl`);
26766
+ const archiveFile = path43.join(dir, `${Date.now()}.jsonl`);
26718
26767
  const lines = messages.map((m) => JSON.stringify(m)).join("\n") + "\n";
26719
26768
  await fs40.appendFile(archiveFile, lines, "utf-8");
26720
26769
  return archiveFile;
@@ -27577,7 +27626,7 @@ Update existing files instead of duplicating.` : "";
27577
27626
 
27578
27627
  // src/app/agent/memory/memory_tool_policy.ts
27579
27628
  init_paths();
27580
- import path45 from "path";
27629
+ import path44 from "path";
27581
27630
  var MEMORY_READ_TOOLS = /* @__PURE__ */ new Set([
27582
27631
  "read_file_lines",
27583
27632
  "grep_search",
@@ -27604,7 +27653,7 @@ function isReadOnlyShellCommand(command) {
27604
27653
  return READ_ONLY_SHELL.test(trimmed);
27605
27654
  }
27606
27655
  function createAutoMemToolGate(memoryDir) {
27607
- const memRoot = memoryDir.endsWith(path45.sep) ? memoryDir : memoryDir + path45.sep;
27656
+ const memRoot = memoryDir.endsWith(path44.sep) ? memoryDir : memoryDir + path44.sep;
27608
27657
  return (toolName, args) => {
27609
27658
  if (MEMORY_READ_TOOLS.has(toolName)) {
27610
27659
  return { allowed: true };
@@ -27617,7 +27666,7 @@ function createAutoMemToolGate(memoryDir) {
27617
27666
  }
27618
27667
  if (MEMORY_WRITE_TOOLS.has(toolName)) {
27619
27668
  const fp = extractFilePath(args);
27620
- if (fp && isAutoMemPath(path45.resolve(fp))) {
27669
+ if (fp && isAutoMemPath(path44.resolve(fp))) {
27621
27670
  return { allowed: true };
27622
27671
  }
27623
27672
  return { allowed: false, reason: `Writes must stay under ${memRoot}` };
@@ -27626,18 +27675,18 @@ function createAutoMemToolGate(memoryDir) {
27626
27675
  };
27627
27676
  }
27628
27677
  function createSessionMemoryToolGate(sessionMemoryPath) {
27629
- const resolvedTarget = path45.resolve(sessionMemoryPath);
27678
+ const resolvedTarget = path44.resolve(sessionMemoryPath);
27630
27679
  return (toolName, args) => {
27631
27680
  if (toolName === "read_file_lines") {
27632
27681
  const fp = extractFilePath(args);
27633
- if (fp && path45.resolve(fp) === resolvedTarget) {
27682
+ if (fp && path44.resolve(fp) === resolvedTarget) {
27634
27683
  return { allowed: true };
27635
27684
  }
27636
27685
  return { allowed: false, reason: "Session memory subagent may only read the session summary file" };
27637
27686
  }
27638
27687
  if (toolName === "edit_tool") {
27639
27688
  const fp = extractFilePath(args);
27640
- if (fp && path45.resolve(fp) === resolvedTarget) {
27689
+ if (fp && path44.resolve(fp) === resolvedTarget) {
27641
27690
  return { allowed: true };
27642
27691
  }
27643
27692
  return { allowed: false, reason: "Session memory subagent may only edit the session summary file" };
@@ -27664,7 +27713,7 @@ function hasAutoMemWritesSinceHistory(history, sinceIndex) {
27664
27713
  continue;
27665
27714
  }
27666
27715
  const fp = extractFilePath(args);
27667
- if (fp && isAutoMemPath(path45.resolve(fp))) {
27716
+ if (fp && isAutoMemPath(path44.resolve(fp))) {
27668
27717
  return true;
27669
27718
  }
27670
27719
  }
@@ -28132,7 +28181,7 @@ var BluMaAgent = class {
28132
28181
  if (!this.sessionFile) return;
28133
28182
  try {
28134
28183
  const sessionData = {
28135
- session_id: path46.basename(this.sessionFile, ".json"),
28184
+ session_id: path45.basename(this.sessionFile, ".json"),
28136
28185
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
28137
28186
  conversation_history: this.history,
28138
28187
  last_updated: (/* @__PURE__ */ new Date()).toISOString(),
@@ -28344,7 +28393,7 @@ var BluMaAgent = class {
28344
28393
 
28345
28394
  ${editData.error.display}`;
28346
28395
  }
28347
- const filename = path46.basename(toolArgs.file_path);
28396
+ const filename = path45.basename(toolArgs.file_path);
28348
28397
  return createDiff(filename, editData.currentContent || "", editData.newContent);
28349
28398
  } catch (e) {
28350
28399
  return `An unexpected error occurred while generating the edit preview: ${e.message}`;
@@ -29081,14 +29130,14 @@ async function fullCompact(messages, targetTokens, summarizer, llmClient) {
29081
29130
  // src/app/agent/core/memory/session_memory.ts
29082
29131
  import fs42 from "fs";
29083
29132
  import os29 from "os";
29084
- import path47 from "path";
29133
+ import path46 from "path";
29085
29134
  import { v4 as uuidv49 } from "uuid";
29086
29135
  var SessionMemoryExtractor = class {
29087
29136
  llmClient;
29088
29137
  memoryFile;
29089
29138
  constructor(options = {}) {
29090
29139
  this.llmClient = options.llmClient;
29091
- this.memoryFile = options.memoryFile || path47.join(os29.homedir(), ".bluma", "session_memory.json");
29140
+ this.memoryFile = options.memoryFile || path46.join(os29.homedir(), ".bluma", "session_memory.json");
29092
29141
  }
29093
29142
  /**
29094
29143
  * Extract memories from conversation using LLM
@@ -29697,14 +29746,14 @@ var RouteManager = class {
29697
29746
  this.subAgents = subAgents;
29698
29747
  this.core = core;
29699
29748
  }
29700
- registerRoute(path60, handler) {
29701
- this.routeHandlers.set(path60, handler);
29749
+ registerRoute(path59, handler) {
29750
+ this.routeHandlers.set(path59, handler);
29702
29751
  }
29703
29752
  async handleRoute(payload) {
29704
29753
  const inputText = String(payload.content || "").trim();
29705
29754
  const { userContext, options } = payload;
29706
- for (const [path60, handler] of this.routeHandlers) {
29707
- if (inputText === path60 || inputText.startsWith(`${path60} `)) {
29755
+ for (const [path59, handler] of this.routeHandlers) {
29756
+ if (inputText === path59 || inputText.startsWith(`${path59} `)) {
29708
29757
  return handler({ content: inputText, userContext });
29709
29758
  }
29710
29759
  }
@@ -29713,13 +29762,13 @@ var RouteManager = class {
29713
29762
  };
29714
29763
 
29715
29764
  // src/app/agent/runtime/plugin_runtime.ts
29716
- import path48 from "path";
29765
+ import path47 from "path";
29717
29766
  import { pathToFileURL as pathToFileURL2 } from "url";
29718
29767
  async function loadPluginsAtStartup() {
29719
29768
  for (const p of listPlugins()) {
29720
29769
  const entry = p.manifest.entry?.trim();
29721
29770
  if (!entry) continue;
29722
- const abs = path48.resolve(p.root, entry);
29771
+ const abs = path47.resolve(p.root, entry);
29723
29772
  try {
29724
29773
  const href = pathToFileURL2(abs).href;
29725
29774
  const mod = await import(href);
@@ -29740,7 +29789,7 @@ async function loadPluginsAtStartup() {
29740
29789
  }
29741
29790
 
29742
29791
  // src/app/agent/agent.ts
29743
- var globalEnvPath = path49.join(os30.homedir(), ".bluma", ".env");
29792
+ var globalEnvPath = path48.join(os30.homedir(), ".bluma", ".env");
29744
29793
  dotenv.config({ path: globalEnvPath });
29745
29794
  var Agent = class {
29746
29795
  sessionId;
@@ -31596,10 +31645,10 @@ function resolveToolPayload(result) {
31596
31645
 
31597
31646
  // src/app/ui/components/FilePathLink.tsx
31598
31647
  import { pathToFileURL as pathToFileURL3 } from "node:url";
31599
- import path51 from "node:path";
31648
+ import path50 from "node:path";
31600
31649
 
31601
31650
  // src/app/ui/utils/pathDisplay.ts
31602
- import path50 from "node:path";
31651
+ import path49 from "node:path";
31603
31652
  import os31 from "node:os";
31604
31653
  function formatPathForDisplay(pathInput, cwd2 = process.cwd()) {
31605
31654
  let s = String(pathInput ?? "").trim();
@@ -31607,17 +31656,17 @@ function formatPathForDisplay(pathInput, cwd2 = process.cwd()) {
31607
31656
  s = s.replace(/[/\\]+$/, "");
31608
31657
  }
31609
31658
  if (!s) return "";
31610
- const abs = path50.isAbsolute(s) ? path50.normalize(s) : path50.resolve(cwd2, s);
31611
- const resolvedCwd = path50.resolve(cwd2);
31612
- const rel = path50.relative(resolvedCwd, abs);
31613
- if (rel === "" || !rel.startsWith("..") && !path50.isAbsolute(rel)) {
31659
+ const abs = path49.isAbsolute(s) ? path49.normalize(s) : path49.resolve(cwd2, s);
31660
+ const resolvedCwd = path49.resolve(cwd2);
31661
+ const rel = path49.relative(resolvedCwd, abs);
31662
+ if (rel === "" || !rel.startsWith("..") && !path49.isAbsolute(rel)) {
31614
31663
  return rel === "" ? "." : rel;
31615
31664
  }
31616
- const home = path50.normalize(os31.homedir());
31617
- if (abs === home || abs.startsWith(home + path50.sep)) {
31665
+ const home = path49.normalize(os31.homedir());
31666
+ if (abs === home || abs.startsWith(home + path49.sep)) {
31618
31667
  return "~" + abs.slice(home.length);
31619
31668
  }
31620
- return path50.basename(abs);
31669
+ return path49.basename(abs);
31621
31670
  }
31622
31671
 
31623
31672
  // src/app/ui/components/FilePathLink.tsx
@@ -31627,7 +31676,7 @@ function FilePathLink({ filePath, children, cwd: cwd2 = process.cwd(), color })
31627
31676
  if (!raw) {
31628
31677
  return null;
31629
31678
  }
31630
- const abs = path51.isAbsolute(raw) ? path51.normalize(raw) : path51.resolve(cwd2, raw);
31679
+ const abs = path50.isAbsolute(raw) ? path50.normalize(raw) : path50.resolve(cwd2, raw);
31631
31680
  const href = pathToFileURL3(abs).href;
31632
31681
  const label = formatPathForDisplay(abs, cwd2);
31633
31682
  const text = typeof children === "string" ? children : label;
@@ -34262,13 +34311,13 @@ function EditToolDiffPanel({
34262
34311
  newString,
34263
34312
  replaceAll = false
34264
34313
  }) {
34265
- const path60 = filePath.trim() || "unknown file";
34314
+ const path59 = filePath.trim() || "unknown file";
34266
34315
  const hasPreviewArgs = oldString !== void 0 && newString !== void 0;
34267
34316
  const hasDiffText = diffText && diffText.trim().length > 0;
34268
34317
  return /* @__PURE__ */ jsx43(Box_default, { flexDirection: "column", children: hasPreviewArgs ? /* @__PURE__ */ jsx43(Box_default, { marginTop: 0, children: /* @__PURE__ */ jsx43(
34269
34318
  FileEditToolDiff,
34270
34319
  {
34271
- filePath: path60,
34320
+ filePath: path59,
34272
34321
  oldString,
34273
34322
  newString,
34274
34323
  replaceAll,
@@ -34306,7 +34355,7 @@ function renderToolUseMessage12({ args }) {
34306
34355
  return /* @__PURE__ */ jsx44(Text, { color: BLUMA_TERMINAL.blue, children: p });
34307
34356
  }
34308
34357
  function renderToolHeader12({ args }) {
34309
- const path60 = args?.file_path ?? ".";
34358
+ const path59 = args?.file_path ?? ".";
34310
34359
  const oldText = typeof args?.old_string === "string" ? args.old_string : "";
34311
34360
  const newText = typeof args?.new_string === "string" ? args.new_string : "";
34312
34361
  const counts = countLineDiff(oldText, newText);
@@ -34316,7 +34365,7 @@ function renderToolHeader12({ args }) {
34316
34365
  action,
34317
34366
  /* @__PURE__ */ jsxs27(Text, { dimColor: true, children: [
34318
34367
  " ",
34319
- /* @__PURE__ */ jsx44(FilePathLink, { filePath: path60, color: BLUMA_TERMINAL.dim })
34368
+ /* @__PURE__ */ jsx44(FilePathLink, { filePath: path59, color: BLUMA_TERMINAL.dim })
34320
34369
  ] })
34321
34370
  ] }),
34322
34371
  /* @__PURE__ */ jsxs27(Text, { dimColor: true, children: [
@@ -34708,11 +34757,11 @@ function userFacingName13() {
34708
34757
  }
34709
34758
  function renderToolUseMessage14({ args }) {
34710
34759
  const q = args?.query ? `"${args.query}"` : "...";
34711
- const path60 = args?.path || ".";
34760
+ const path59 = args?.path || ".";
34712
34761
  return /* @__PURE__ */ jsxs30(Box_default, { flexDirection: "row", flexWrap: "wrap", alignItems: "flex-end", children: [
34713
34762
  /* @__PURE__ */ jsx47(Text, { color: BLUMA_TERMINAL.blue, children: q }),
34714
34763
  /* @__PURE__ */ jsx47(Text, { color: BLUMA_TERMINAL.dim, children: " " }),
34715
- /* @__PURE__ */ jsx47(FilePathLink, { filePath: path60, color: BLUMA_TERMINAL.dim })
34764
+ /* @__PURE__ */ jsx47(FilePathLink, { filePath: path59, color: BLUMA_TERMINAL.dim })
34716
34765
  ] });
34717
34766
  }
34718
34767
  function renderToolHeader14({ args }) {
@@ -38192,7 +38241,7 @@ import {
38192
38241
  // src/app/ui/hooks/useAtCompletion.ts
38193
38242
  import { useEffect as useEffect11, useRef as useRef4, useState as useState13 } from "react";
38194
38243
  import fs45 from "fs";
38195
- import path52 from "path";
38244
+ import path51 from "path";
38196
38245
  var MAX_RESULTS3 = 50;
38197
38246
  var DEFAULT_RECURSIVE_DEPTH = 2;
38198
38247
  function listPathSuggestions(baseDir, pattern) {
@@ -38200,7 +38249,7 @@ function listPathSuggestions(baseDir, pattern) {
38200
38249
  const patternEndsWithSlash = raw.endsWith("/");
38201
38250
  const relDir = raw.replace(/^\/+|\/+$/g, "");
38202
38251
  const filterPrefix = patternEndsWithSlash ? "" : relDir.split("/").slice(-1)[0] || "";
38203
- const listDir = path52.resolve(baseDir, relDir || ".");
38252
+ const listDir = path51.resolve(baseDir, relDir || ".");
38204
38253
  const results = [];
38205
38254
  const IGNORED_DIRS = ["node_modules", ".git", ".venv", "dist", "build"];
38206
38255
  const IGNORED_EXTS = [".pyc", ".class", ".o", ".map", ".log", ".tmp"];
@@ -38217,7 +38266,7 @@ function listPathSuggestions(baseDir, pattern) {
38217
38266
  }
38218
38267
  function pushEntry(entryPath, label, isDir) {
38219
38268
  if (results.length >= MAX_RESULTS3) return;
38220
- const clean = label.split(path52.sep).join("/").replace(/[]+/g, "");
38269
+ const clean = label.split(path51.sep).join("/").replace(/[]+/g, "");
38221
38270
  results.push({ label: clean + (isDir ? "/" : ""), fullPath: entryPath, isDir });
38222
38271
  }
38223
38272
  try {
@@ -38229,8 +38278,8 @@ function listPathSuggestions(baseDir, pattern) {
38229
38278
  const entries = fs45.readdirSync(node.dir, { withFileTypes: true });
38230
38279
  for (const entry of entries) {
38231
38280
  if (isIgnoredName(entry.name)) continue;
38232
- const entryAbs = path52.join(node.dir, entry.name);
38233
- const entryRel = node.rel ? path52.posix.join(node.rel, entry.name) : entry.name;
38281
+ const entryAbs = path51.join(node.dir, entry.name);
38282
+ const entryRel = node.rel ? path51.posix.join(node.rel, entry.name) : entry.name;
38234
38283
  if (entryRel.split("/").includes("node_modules")) continue;
38235
38284
  if (!entry.isDirectory() && isIgnoredFile(entry.name)) continue;
38236
38285
  pushEntry(entryAbs, entryRel, entry.isDirectory());
@@ -38248,8 +38297,8 @@ function listPathSuggestions(baseDir, pattern) {
38248
38297
  if (filterPrefix && !entry.name.startsWith(filterPrefix)) continue;
38249
38298
  if (isIgnoredName(entry.name)) continue;
38250
38299
  if (!entry.isDirectory() && isIgnoredFile(entry.name)) continue;
38251
- const entryAbs = path52.join(listDir, entry.name);
38252
- const label = relDir ? path52.posix.join(relDir, entry.name) : entry.name;
38300
+ const entryAbs = path51.join(listDir, entry.name);
38301
+ const label = relDir ? path51.posix.join(relDir, entry.name) : entry.name;
38253
38302
  pushEntry(entryAbs, label, entry.isDirectory());
38254
38303
  if (results.length >= MAX_RESULTS3) break;
38255
38304
  }
@@ -38452,7 +38501,7 @@ var SlashSubmenuInline = memo15(SlashSubmenuInlineComponent);
38452
38501
  // src/app/ui/utils/clipboardImage.ts
38453
38502
  import fs46 from "fs";
38454
38503
  import os32 from "os";
38455
- import path53 from "path";
38504
+ import path52 from "path";
38456
38505
  import { spawn as spawn5, execFile as execFileCb, execSync as execSync4 } from "child_process";
38457
38506
  import { promisify as promisify2 } from "util";
38458
38507
 
@@ -38581,8 +38630,8 @@ function commandOnPath(cmd) {
38581
38630
  function unixClipboardHelperDirs() {
38582
38631
  const h = os32.homedir();
38583
38632
  return [
38584
- path53.join(h, ".local", "bin"),
38585
- path53.join(h, "bin"),
38633
+ path52.join(h, ".local", "bin"),
38634
+ path52.join(h, "bin"),
38586
38635
  "/usr/bin",
38587
38636
  "/usr/local/bin",
38588
38637
  "/bin",
@@ -38600,7 +38649,7 @@ function resolveHelperBinary(cmd) {
38600
38649
  return cmd;
38601
38650
  }
38602
38651
  for (const dir of unixClipboardHelperDirs()) {
38603
- const full = path53.join(dir, cmd);
38652
+ const full = path52.join(dir, cmd);
38604
38653
  try {
38605
38654
  fs46.accessSync(full, fs46.constants.X_OK);
38606
38655
  return full;
@@ -38608,7 +38657,7 @@ function resolveHelperBinary(cmd) {
38608
38657
  }
38609
38658
  }
38610
38659
  for (const dir of unixClipboardHelperDirs()) {
38611
- const full = path53.join(dir, cmd);
38660
+ const full = path52.join(dir, cmd);
38612
38661
  if (fs46.existsSync(full)) {
38613
38662
  return full;
38614
38663
  }
@@ -38650,7 +38699,7 @@ function writeBufferIfImage(baseDir, buf) {
38650
38699
  if (!ext) {
38651
38700
  return null;
38652
38701
  }
38653
- const out = path53.join(
38702
+ const out = path52.join(
38654
38703
  baseDir,
38655
38704
  `clip-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`
38656
38705
  );
@@ -38689,9 +38738,9 @@ async function tryDarwinClipboardy(baseDir) {
38689
38738
  if (st.size < 80 || st.size > CLIPBOARD_MAX_BYTES) {
38690
38739
  continue;
38691
38740
  }
38692
- const ext = path53.extname(src).toLowerCase();
38741
+ const ext = path52.extname(src).toLowerCase();
38693
38742
  const safeExt = ext && /^\.(png|jpe?g|gif|webp)$/i.test(ext) ? ext : ".png";
38694
- const out = path53.join(
38743
+ const out = path52.join(
38695
38744
  baseDir,
38696
38745
  `clip-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${safeExt}`
38697
38746
  );
@@ -38709,7 +38758,7 @@ async function tryDarwinClipboardy(baseDir) {
38709
38758
  return null;
38710
38759
  }
38711
38760
  async function tryWindowsPowerShell(outFile) {
38712
- const ps = process.env.SystemRoot != null ? path53.join(
38761
+ const ps = process.env.SystemRoot != null ? path52.join(
38713
38762
  process.env.SystemRoot,
38714
38763
  "System32",
38715
38764
  "WindowsPowerShell",
@@ -38810,8 +38859,8 @@ function parseClipboardTextAsImagePath(raw) {
38810
38859
  s = s.slice(1, -1);
38811
38860
  }
38812
38861
  s = s.trim();
38813
- if (!CLIPBOARD_PATH_IMAGE_EXT.test(path53.extname(s))) return null;
38814
- const abs = path53.isAbsolute(s) ? path53.normalize(s) : path53.resolve(process.cwd(), s);
38862
+ if (!CLIPBOARD_PATH_IMAGE_EXT.test(path52.extname(s))) return null;
38863
+ const abs = path52.isAbsolute(s) ? path52.normalize(s) : path52.resolve(process.cwd(), s);
38815
38864
  return abs;
38816
38865
  }
38817
38866
  async function tryClipboardTextAsImageFile(baseDir) {
@@ -38831,8 +38880,8 @@ async function tryClipboardTextAsImageFile(baseDir) {
38831
38880
  } catch {
38832
38881
  return null;
38833
38882
  }
38834
- const ext = path53.extname(abs).toLowerCase();
38835
- const out = path53.join(
38883
+ const ext = path52.extname(abs).toLowerCase();
38884
+ const out = path52.join(
38836
38885
  baseDir,
38837
38886
  `clip-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`
38838
38887
  );
@@ -38847,7 +38896,7 @@ async function tryLinuxShellPipelineSave(baseDir) {
38847
38896
  if (process.platform !== "linux" && process.platform !== "freebsd") {
38848
38897
  return null;
38849
38898
  }
38850
- const outPath = path53.join(
38899
+ const outPath = path52.join(
38851
38900
  baseDir,
38852
38901
  `clip-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.tmp`
38853
38902
  );
@@ -38905,7 +38954,7 @@ async function tryNativeClipboardImage() {
38905
38954
  return null;
38906
38955
  }
38907
38956
  async function readClipboardImageToTempFile() {
38908
- const baseDir = path53.join(os32.homedir(), ".cache", "bluma", "clipboard");
38957
+ const baseDir = path52.join(os32.homedir(), ".cache", "bluma", "clipboard");
38909
38958
  fs46.mkdirSync(baseDir, { recursive: true });
38910
38959
  const nativeResult = await tryNativeClipboardImage();
38911
38960
  if (nativeResult) {
@@ -38924,7 +38973,7 @@ async function readClipboardImageToTempFile() {
38924
38973
  }
38925
38974
  }
38926
38975
  if (process.platform === "win32") {
38927
- const outFile = path53.join(
38976
+ const outFile = path52.join(
38928
38977
  baseDir,
38929
38978
  `clip-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.png`
38930
38979
  );
@@ -41300,7 +41349,7 @@ var renderSettingsEditUsage = () => {
41300
41349
 
41301
41350
  // src/app/agent/core/thread/thread_store.ts
41302
41351
  init_bluma_app_dir();
41303
- import path54 from "path";
41352
+ import path53 from "path";
41304
41353
  import { promises as fs48 } from "fs";
41305
41354
  import { randomUUID as randomUUID2 } from "crypto";
41306
41355
  var INDEX_VERSION = 1;
@@ -41326,9 +41375,9 @@ var ThreadStore = class {
41326
41375
  packageVersion;
41327
41376
  constructor() {
41328
41377
  const appDir = getPreferredAppDir();
41329
- this.threadsDir = path54.join(appDir, "threads");
41330
- this.archiveDir = path54.join(this.threadsDir, "archive");
41331
- this.indexPath = path54.join(this.threadsDir, "index.json");
41378
+ this.threadsDir = path53.join(appDir, "threads");
41379
+ this.archiveDir = path53.join(this.threadsDir, "archive");
41380
+ this.indexPath = path53.join(this.threadsDir, "index.json");
41332
41381
  this.packageVersion = process.env.npm_package_version || "0.0.0";
41333
41382
  }
41334
41383
  // ==================== Inicialização ====================
@@ -41450,7 +41499,7 @@ var ThreadStore = class {
41450
41499
  messages: params.initialMessages || []
41451
41500
  };
41452
41501
  const historyPath = this.buildDatedThreadHistoryPath(threadId);
41453
- await fs48.mkdir(path54.dirname(historyPath), { recursive: true });
41502
+ await fs48.mkdir(path53.dirname(historyPath), { recursive: true });
41454
41503
  await this.saveHistoryAtPath(historyPath, history);
41455
41504
  const index = await this.loadIndex();
41456
41505
  index.threads.unshift({
@@ -41505,7 +41554,7 @@ var ThreadStore = class {
41505
41554
  compressedSliceCount: source.history.compressedSliceCount
41506
41555
  };
41507
41556
  const historyPath = this.buildDatedThreadHistoryPath(newThreadId);
41508
- await fs48.mkdir(path54.dirname(historyPath), { recursive: true });
41557
+ await fs48.mkdir(path53.dirname(historyPath), { recursive: true });
41509
41558
  await this.saveHistoryAtPath(historyPath, history);
41510
41559
  const index = await this.loadIndex();
41511
41560
  index.threads.unshift({
@@ -41578,7 +41627,7 @@ var ThreadStore = class {
41578
41627
  const entry = index.threads[entryIndex];
41579
41628
  if (entry.status === "archived") return true;
41580
41629
  const oldPath = entry.historyPath || this.getLegacyHistoryPath(threadId);
41581
- const newPath = path54.join(this.archiveDir, `${threadId}.jsonl`);
41630
+ const newPath = path53.join(this.archiveDir, `${threadId}.jsonl`);
41582
41631
  try {
41583
41632
  await fs48.rename(oldPath, newPath);
41584
41633
  } catch (e) {
@@ -41601,9 +41650,9 @@ var ThreadStore = class {
41601
41650
  if (entryIndex === -1) return false;
41602
41651
  const entry = index.threads[entryIndex];
41603
41652
  if (entry.status === "active") return true;
41604
- const oldPath = path54.join(this.archiveDir, `${threadId}.jsonl`);
41653
+ const oldPath = path53.join(this.archiveDir, `${threadId}.jsonl`);
41605
41654
  const newPath = this.buildDatedThreadHistoryPath(threadId);
41606
- await fs48.mkdir(path54.dirname(newPath), { recursive: true });
41655
+ await fs48.mkdir(path53.dirname(newPath), { recursive: true });
41607
41656
  try {
41608
41657
  await fs48.rename(oldPath, newPath);
41609
41658
  } catch (e) {
@@ -41636,14 +41685,14 @@ var ThreadStore = class {
41636
41685
  }
41637
41686
  // ==================== Histórico ====================
41638
41687
  getLegacyHistoryPath(threadId) {
41639
- return path54.join(this.threadsDir, `${threadId}.jsonl`);
41688
+ return path53.join(this.threadsDir, `${threadId}.jsonl`);
41640
41689
  }
41641
41690
  /** ~/.bluma/threads/YYYY/MM/DD/<threadId>.jsonl (data local de criação). */
41642
41691
  buildDatedThreadHistoryPath(threadId, at = /* @__PURE__ */ new Date()) {
41643
41692
  const y = String(at.getFullYear());
41644
41693
  const mo = String(at.getMonth() + 1).padStart(2, "0");
41645
41694
  const d = String(at.getDate()).padStart(2, "0");
41646
- return path54.join(this.threadsDir, y, mo, d, `${threadId}.jsonl`);
41695
+ return path53.join(this.threadsDir, y, mo, d, `${threadId}.jsonl`);
41647
41696
  }
41648
41697
  async resolveHistoryPath(threadId) {
41649
41698
  const index = await this.loadIndex();
@@ -41674,7 +41723,7 @@ var ThreadStore = class {
41674
41723
  for (const msg of history.messages) {
41675
41724
  lines.push(JSON.stringify({ type: "message", ...msg }));
41676
41725
  }
41677
- await fs48.mkdir(path54.dirname(historyPath), { recursive: true }).catch(() => {
41726
+ await fs48.mkdir(path53.dirname(historyPath), { recursive: true }).catch(() => {
41678
41727
  });
41679
41728
  await fs48.writeFile(historyPath, lines.join("\n") + "\n", "utf-8");
41680
41729
  }
@@ -44170,13 +44219,13 @@ import latestVersion from "latest-version";
44170
44219
  import semverGt from "semver/functions/gt.js";
44171
44220
  import semverValid from "semver/functions/valid.js";
44172
44221
  import { fileURLToPath as fileURLToPath7 } from "url";
44173
- import path56 from "path";
44222
+ import path55 from "path";
44174
44223
  import fs50 from "fs";
44175
44224
  var BLUMA_PACKAGE_NAME = "@nomad-e/bluma-cli";
44176
44225
  function findBlumaPackageJson(startDir) {
44177
44226
  let dir = startDir;
44178
44227
  for (let i = 0; i < 12; i++) {
44179
- const candidate = path56.join(dir, "package.json");
44228
+ const candidate = path55.join(dir, "package.json");
44180
44229
  if (fs50.existsSync(candidate)) {
44181
44230
  try {
44182
44231
  const raw = fs50.readFileSync(candidate, "utf8");
@@ -44187,7 +44236,7 @@ function findBlumaPackageJson(startDir) {
44187
44236
  } catch {
44188
44237
  }
44189
44238
  }
44190
- const parent = path56.dirname(dir);
44239
+ const parent = path55.dirname(dir);
44191
44240
  if (parent === dir) break;
44192
44241
  dir = parent;
44193
44242
  }
@@ -44196,13 +44245,13 @@ function findBlumaPackageJson(startDir) {
44196
44245
  function resolveInstalledBlumaPackage() {
44197
44246
  const tried = /* @__PURE__ */ new Set();
44198
44247
  const tryFrom = (dir) => {
44199
- const abs = path56.resolve(dir);
44248
+ const abs = path55.resolve(dir);
44200
44249
  if (tried.has(abs)) return null;
44201
44250
  tried.add(abs);
44202
44251
  return findBlumaPackageJson(abs);
44203
44252
  };
44204
44253
  try {
44205
- const fromBundle = tryFrom(path56.dirname(fileURLToPath7(import.meta.url)));
44254
+ const fromBundle = tryFrom(path55.dirname(fileURLToPath7(import.meta.url)));
44206
44255
  if (fromBundle) return fromBundle;
44207
44256
  } catch {
44208
44257
  }
@@ -44210,12 +44259,12 @@ function resolveInstalledBlumaPackage() {
44210
44259
  if (argv1 && !argv1.startsWith("-")) {
44211
44260
  try {
44212
44261
  let resolved = argv1;
44213
- if (path56.isAbsolute(argv1) && fs50.existsSync(argv1)) {
44262
+ if (path55.isAbsolute(argv1) && fs50.existsSync(argv1)) {
44214
44263
  resolved = fs50.realpathSync(argv1);
44215
44264
  } else {
44216
- resolved = path56.resolve(process.cwd(), argv1);
44265
+ resolved = path55.resolve(process.cwd(), argv1);
44217
44266
  }
44218
- const fromArgv = tryFrom(path56.dirname(resolved));
44267
+ const fromArgv = tryFrom(path55.dirname(resolved));
44219
44268
  if (fromArgv) return fromArgv;
44220
44269
  } catch {
44221
44270
  }
@@ -45035,9 +45084,9 @@ function usePlanMode() {
45035
45084
  // src/app/hooks/useAgentMode.ts
45036
45085
  import { useState as useState22, useEffect as useEffect21, useCallback as useCallback9 } from "react";
45037
45086
  import * as fs51 from "fs";
45038
- import * as path57 from "path";
45087
+ import * as path56 from "path";
45039
45088
  import { homedir as homedir4 } from "os";
45040
- var SETTINGS_PATH = path57.join(homedir4(), ".bluma", "settings.json");
45089
+ var SETTINGS_PATH = path56.join(homedir4(), ".bluma", "settings.json");
45041
45090
  function readAgentModeFromFile() {
45042
45091
  try {
45043
45092
  if (!fs51.existsSync(SETTINGS_PATH)) {
@@ -45063,7 +45112,7 @@ function useAgentMode() {
45063
45112
  const updateAgentMode = useCallback9((mode) => {
45064
45113
  try {
45065
45114
  if (!fs51.existsSync(SETTINGS_PATH)) {
45066
- fs51.mkdirSync(path57.dirname(SETTINGS_PATH), { recursive: true });
45115
+ fs51.mkdirSync(path56.dirname(SETTINGS_PATH), { recursive: true });
45067
45116
  }
45068
45117
  let settings = {};
45069
45118
  if (fs51.existsSync(SETTINGS_PATH)) {
@@ -46288,7 +46337,7 @@ Dados do utilizador final / pedido \u2014 n\xE3o confundir com o sandbox onde o
46288
46337
  ${JSON.stringify(extra, null, 2)}
46289
46338
  </${label}>`;
46290
46339
  }
46291
- function buildAgentTurnUserContent(context) {
46340
+ function buildAgentTurnUserContent(context, sandboxRuntime) {
46292
46341
  if (context == null) return "";
46293
46342
  if (typeof context === "string") {
46294
46343
  return enrichSandboxUserTurn(context.trim());
@@ -46307,6 +46356,9 @@ function buildAgentTurnUserContent(context) {
46307
46356
  const extra = extractExtraContextFields(ctx);
46308
46357
  const hasMachineSpecs = looksLikeMachineSpecs(extra.machine_specs) || looksLikeMachineSpecs(extra.machineSpecs) || looksLikeMachineSpecs(extra.client_machine) || looksLikeMachineSpecs(extra.target_machine) || looksLikeMachineSpecs(extra.hardware) || Object.values(extra).some(looksLikeMachineSpecs);
46309
46358
  const parts = [];
46359
+ if (sandboxRuntime && typeof sandboxRuntime === "object") {
46360
+ parts.push(formatSandboxRuntimeUserTurnPrefix(sandboxRuntime));
46361
+ }
46310
46362
  if (userRequest) parts.push(userRequest);
46311
46363
  if (coordinatorText) {
46312
46364
  parts.push(`<contexto_adicional>
@@ -46335,10 +46387,10 @@ import { memo as memo26, useCallback as useCallback11, useEffect as useEffect23,
46335
46387
 
46336
46388
  // src/app/agent/session_manager/session_resume_browser.ts
46337
46389
  init_bluma_app_dir();
46338
- import path58 from "path";
46390
+ import path57 from "path";
46339
46391
  import { promises as fs52 } from "fs";
46340
46392
  function getSessionsRoot() {
46341
- return path58.join(getPreferredAppDir(), "sessions");
46393
+ return path57.join(getPreferredAppDir(), "sessions");
46342
46394
  }
46343
46395
  function normalizeSessionsCwd(cwd2) {
46344
46396
  return cwd2.replace(/\\/g, "/").split("/").filter((p) => p && p !== "." && p !== "..").join("/");
@@ -46389,7 +46441,7 @@ function compareDirNames(a, b) {
46389
46441
  async function listSessionBrowserEntries(cwdRel) {
46390
46442
  const cwd2 = normalizeSessionsCwd(cwdRel);
46391
46443
  const root = getSessionsRoot();
46392
- const absDir = cwd2 ? path58.join(root, ...cwd2.split("/")) : root;
46444
+ const absDir = cwd2 ? path57.join(root, ...cwd2.split("/")) : root;
46393
46445
  const out = [];
46394
46446
  if (cwd2) {
46395
46447
  out.push({ kind: "up", label: ".." });
@@ -46406,7 +46458,7 @@ async function listSessionBrowserEntries(cwdRel) {
46406
46458
  for (const e of dirents) {
46407
46459
  const name = String(e.name);
46408
46460
  if (name.startsWith(".")) continue;
46409
- const full = path58.join(absDir, name);
46461
+ const full = path57.join(absDir, name);
46410
46462
  if (e.isDirectory()) {
46411
46463
  dirNames.push(name);
46412
46464
  } else if (e.isFile() && name.endsWith(".json") && !name.includes(".tmp")) {
@@ -46416,7 +46468,7 @@ async function listSessionBrowserEntries(cwdRel) {
46416
46468
  dirNames.sort(compareDirNames);
46417
46469
  const sessions = [];
46418
46470
  for (const { name, full } of sessionFiles) {
46419
- const sessionId = path58.basename(name, ".json");
46471
+ const sessionId = path57.basename(name, ".json");
46420
46472
  sessions.push(await sessionEntryFromFile(full, sessionId));
46421
46473
  }
46422
46474
  sessions.sort((a, b) => {
@@ -46841,6 +46893,8 @@ async function runAgentMode() {
46841
46893
  if (envelope.action?.trim()) {
46842
46894
  process.env.BLUMA_ACTION = envelope.action.trim();
46843
46895
  }
46896
+ const injectedRuntime = applySandboxRuntimeFromEnvelope(envelope);
46897
+ setInjectedSandboxRuntimeForPrompt(injectedRuntime);
46844
46898
  const eventBus = new EventEmitter7();
46845
46899
  const sessionId = registrySessionId || envelope.session_id || envelope.message_id || uuidv412();
46846
46900
  process.env.BLUMA_SESSION_ID = sessionId;
@@ -46983,7 +47037,7 @@ async function runAgentMode() {
46983
47037
  const agent = new Agent(sessionId, eventBus);
46984
47038
  agentRef = agent;
46985
47039
  await agent.initialize();
46986
- const userContent = buildAgentTurnUserContent(envelope.context) || JSON.stringify({
47040
+ const userContent = buildAgentTurnUserContent(envelope.context, injectedRuntime) || JSON.stringify({
46987
47041
  message_id: envelope.message_id || sessionId,
46988
47042
  from_agent: envelope.from_agent || "unknown",
46989
47043
  to_agent: envelope.to_agent || "bluma",
@@ -47030,8 +47084,8 @@ async function runAgentMode() {
47030
47084
  }
47031
47085
  function readCliPackageVersion() {
47032
47086
  try {
47033
- const base = path59.dirname(fileURLToPath8(import.meta.url));
47034
- const pkgPath = path59.join(base, "..", "package.json");
47087
+ const base = path58.dirname(fileURLToPath8(import.meta.url));
47088
+ const pkgPath = path58.join(base, "..", "package.json");
47035
47089
  const j = JSON.parse(fs53.readFileSync(pkgPath, "utf8"));
47036
47090
  return String(j.version || "0.0.0");
47037
47091
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",