@nomad-e/bluma-cli 0.20.0 → 0.21.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.
- package/dist/main.js +267 -213
- 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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
3920
|
-
const _ = slowLogging`fs.appendFileSync(${
|
|
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(
|
|
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(
|
|
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(
|
|
3941
|
-
const _ = slowLogging`fs.unlinkSync(${
|
|
3942
|
-
fs.unlinkSync(
|
|
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,
|
|
3949
|
-
const _ = slowLogging`fs.linkSync(${target} → ${
|
|
3950
|
-
fs.linkSync(target,
|
|
3948
|
+
linkSync(target, path59) {
|
|
3949
|
+
const _ = slowLogging`fs.linkSync(${target} → ${path59})`;
|
|
3950
|
+
fs.linkSync(target, path59);
|
|
3951
3951
|
},
|
|
3952
|
-
symlinkSync(target,
|
|
3953
|
-
const _ = slowLogging`fs.symlinkSync(${target} → ${
|
|
3954
|
-
fs.symlinkSync(target,
|
|
3952
|
+
symlinkSync(target, path59, type) {
|
|
3953
|
+
const _ = slowLogging`fs.symlinkSync(${target} → ${path59})`;
|
|
3954
|
+
fs.symlinkSync(target, path59, type);
|
|
3955
3955
|
},
|
|
3956
|
-
readlinkSync(
|
|
3957
|
-
const _ = slowLogging`fs.readlinkSync(${
|
|
3958
|
-
return fs.readlinkSync(
|
|
3956
|
+
readlinkSync(path59) {
|
|
3957
|
+
const _ = slowLogging`fs.readlinkSync(${path59})`;
|
|
3958
|
+
return fs.readlinkSync(path59);
|
|
3959
3959
|
},
|
|
3960
|
-
realpathSync(
|
|
3961
|
-
const _ = slowLogging`fs.realpathSync(${
|
|
3962
|
-
return fs.realpathSync(
|
|
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(
|
|
3996
|
-
const _ = slowLogging`fs.rmSync(${
|
|
3997
|
-
fs.rmSync(
|
|
3995
|
+
rmSync(path59, options) {
|
|
3996
|
+
const _ = slowLogging`fs.rmSync(${path59})`;
|
|
3997
|
+
fs.rmSync(path59, options);
|
|
3998
3998
|
},
|
|
3999
|
-
createWriteStream(
|
|
4000
|
-
return fs.createWriteStream(
|
|
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,
|
|
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(
|
|
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
|
|
4123
|
-
const dir = dirname(
|
|
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(
|
|
4133
|
+
getFsImplementation().appendFileSync(path59, content);
|
|
4134
4134
|
void updateLatestDebugLogSymlink();
|
|
4135
4135
|
return;
|
|
4136
4136
|
}
|
|
4137
|
-
pendingWrite = pendingWrite.then(appendAsync.bind(null, needMkdir, dir,
|
|
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 = (
|
|
10325
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
23895
|
+
const path59 = getSessionMemoryPath(sessionId, cwd2);
|
|
23896
23896
|
try {
|
|
23897
|
-
const content = await readFile3(
|
|
23897
|
+
const content = await readFile3(path59, "utf-8");
|
|
23898
23898
|
if (!content.trim()) return "";
|
|
23899
23899
|
return `<session_memory>
|
|
23900
|
-
Notes for this conversation (${
|
|
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
|
|
23910
|
+
const path59 = getSessionMemoryPath(sessionId, cwd2);
|
|
23911
23911
|
try {
|
|
23912
|
-
await readFile3(
|
|
23912
|
+
await readFile3(path59, "utf-8");
|
|
23913
23913
|
} catch {
|
|
23914
|
-
await writeFile2(
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
`|
|
|
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 (
|
|
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 (
|
|
24158
|
+
if (rt.severinoUrl && rt.factoraiBaseUrl && rt.severinoUrl !== rt.factoraiBaseUrl) {
|
|
24118
24159
|
lines.push("");
|
|
24119
|
-
lines.push("
|
|
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
|
|
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
|
|
24150
|
-
lines.push(userRequest.length >
|
|
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(
|
|
24188
|
-
if (fs37.existsSync(
|
|
24189
|
-
if (fs37.existsSync(
|
|
24190
|
-
if (fs37.existsSync(
|
|
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(
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
25718
|
-
const cwdR =
|
|
25719
|
-
const homeR =
|
|
25720
|
-
const tmpR =
|
|
25721
|
-
const underCwd = resolved === cwdR || resolved.startsWith(cwdR +
|
|
25722
|
-
const underHome = resolved === homeR || resolved.startsWith(homeR +
|
|
25723
|
-
const underTmp = resolved === tmpR || resolved.startsWith(tmpR +
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
26192
|
+
import * as path42 from "path";
|
|
26144
26193
|
import os26 from "os";
|
|
26145
26194
|
function memoryPath2() {
|
|
26146
|
-
return
|
|
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
|
|
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 =
|
|
26764
|
+
const dir = path43.join(appDir, "sessions", "archive", sessionId);
|
|
26716
26765
|
await fs40.mkdir(dir, { recursive: true });
|
|
26717
|
-
const archiveFile =
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
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 &&
|
|
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 &&
|
|
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(
|
|
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:
|
|
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 =
|
|
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
|
|
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 ||
|
|
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(
|
|
29701
|
-
this.routeHandlers.set(
|
|
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 [
|
|
29707
|
-
if (inputText ===
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
31648
|
+
import path50 from "node:path";
|
|
31600
31649
|
|
|
31601
31650
|
// src/app/ui/utils/pathDisplay.ts
|
|
31602
|
-
import
|
|
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 =
|
|
31611
|
-
const resolvedCwd =
|
|
31612
|
-
const rel =
|
|
31613
|
-
if (rel === "" || !rel.startsWith("..") && !
|
|
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 =
|
|
31617
|
-
if (abs === home || abs.startsWith(home +
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
38233
|
-
const entryRel = node.rel ?
|
|
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 =
|
|
38252
|
-
const label = relDir ?
|
|
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
|
|
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
|
-
|
|
38585
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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(
|
|
38814
|
-
const abs =
|
|
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 =
|
|
38835
|
-
const out =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
41330
|
-
this.archiveDir =
|
|
41331
|
-
this.indexPath =
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
41653
|
+
const oldPath = path53.join(this.archiveDir, `${threadId}.jsonl`);
|
|
41605
41654
|
const newPath = this.buildDatedThreadHistoryPath(threadId);
|
|
41606
|
-
await fs48.mkdir(
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 (
|
|
44262
|
+
if (path55.isAbsolute(argv1) && fs50.existsSync(argv1)) {
|
|
44214
44263
|
resolved = fs50.realpathSync(argv1);
|
|
44215
44264
|
} else {
|
|
44216
|
-
resolved =
|
|
44265
|
+
resolved = path55.resolve(process.cwd(), argv1);
|
|
44217
44266
|
}
|
|
44218
|
-
const fromArgv = tryFrom(
|
|
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
|
|
45087
|
+
import * as path56 from "path";
|
|
45039
45088
|
import { homedir as homedir4 } from "os";
|
|
45040
|
-
var SETTINGS_PATH =
|
|
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(
|
|
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
|
|
46390
|
+
import path57 from "path";
|
|
46339
46391
|
import { promises as fs52 } from "fs";
|
|
46340
46392
|
function getSessionsRoot() {
|
|
46341
|
-
return
|
|
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 ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
47034
|
-
const pkgPath =
|
|
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 {
|