@nomad-e/bluma-cli 0.1.26 → 0.1.28

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 +386 -142
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -178,16 +178,16 @@ async function commandStatus(args) {
178
178
  }
179
179
  const maxWait = Math.min(wait_seconds, 15);
180
180
  if (maxWait > 0 && entry.status === "running") {
181
- await new Promise((resolve) => {
181
+ await new Promise((resolve2) => {
182
182
  const checkInterval = setInterval(() => {
183
183
  if (entry.status !== "running") {
184
184
  clearInterval(checkInterval);
185
- resolve();
185
+ resolve2();
186
186
  }
187
187
  }, 100);
188
188
  setTimeout(() => {
189
189
  clearInterval(checkInterval);
190
- resolve();
190
+ resolve2();
191
191
  }, maxWait * 1e3);
192
192
  });
193
193
  }
@@ -331,7 +331,7 @@ var init_async_command = __esm({
331
331
  import React11 from "react";
332
332
  import { render } from "ink";
333
333
  import { EventEmitter as EventEmitter2 } from "events";
334
- import fs14 from "fs";
334
+ import fs15 from "fs";
335
335
  import { v4 as uuidv46 } from "uuid";
336
336
 
337
337
  // src/app/ui/App.tsx
@@ -1484,12 +1484,12 @@ var ConfirmationPrompt = memo4(ConfirmationPromptComponent);
1484
1484
 
1485
1485
  // src/app/agent/agent.ts
1486
1486
  import * as dotenv from "dotenv";
1487
- import path16 from "path";
1488
- import os10 from "os";
1487
+ import path17 from "path";
1488
+ import os11 from "os";
1489
1489
 
1490
1490
  // src/app/agent/tool_invoker.ts
1491
- import { promises as fs8 } from "fs";
1492
- import path10 from "path";
1491
+ import { promises as fs9 } from "fs";
1492
+ import path11 from "path";
1493
1493
  import { fileURLToPath } from "url";
1494
1494
 
1495
1495
  // src/app/agent/tools/natives/edit.ts
@@ -3077,7 +3077,7 @@ var MAX_RESULTS_DEFAULT = 5;
3077
3077
  var REQUEST_TIMEOUT = 15e3;
3078
3078
  var MAX_CONTENT_LENGTH = 4e3;
3079
3079
  function httpGet(url, customHeaders) {
3080
- return new Promise((resolve, reject) => {
3080
+ return new Promise((resolve2, reject) => {
3081
3081
  const protocol = url.startsWith("https") ? https : http;
3082
3082
  const defaultHeaders = {
3083
3083
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
@@ -3093,14 +3093,14 @@ function httpGet(url, customHeaders) {
3093
3093
  timeout: REQUEST_TIMEOUT
3094
3094
  }, (res) => {
3095
3095
  if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
3096
- httpGet(res.headers.location, customHeaders).then(resolve).catch(reject);
3096
+ httpGet(res.headers.location, customHeaders).then(resolve2).catch(reject);
3097
3097
  return;
3098
3098
  }
3099
3099
  let data = "";
3100
3100
  res.on("data", (chunk) => data += chunk);
3101
3101
  res.on("end", () => {
3102
3102
  if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
3103
- resolve(data);
3103
+ resolve2(data);
3104
3104
  } else {
3105
3105
  reject(new Error(`HTTP ${res.statusCode}: ${data.substring(0, 200)}`));
3106
3106
  }
@@ -3424,6 +3424,218 @@ ${skill.content}`;
3424
3424
  };
3425
3425
  }
3426
3426
 
3427
+ // src/app/agent/tools/natives/coding_memory.ts
3428
+ import * as fs8 from "fs";
3429
+ import * as path10 from "path";
3430
+ import os4 from "os";
3431
+ var PROMPT_DEFAULT_MAX_TOTAL = 1e4;
3432
+ var PROMPT_DEFAULT_MAX_NOTES = 25;
3433
+ var PROMPT_DEFAULT_PREVIEW = 500;
3434
+ function readCodingMemoryForPrompt(options) {
3435
+ const maxTotal = options?.maxTotalChars ?? PROMPT_DEFAULT_MAX_TOTAL;
3436
+ const maxNotes = options?.maxNotes ?? PROMPT_DEFAULT_MAX_NOTES;
3437
+ const preview = options?.previewCharsPerNote ?? PROMPT_DEFAULT_PREVIEW;
3438
+ const globalPath = path10.join(os4.homedir(), ".bluma", "coding_memory.json");
3439
+ const legacyPath = path10.join(process.cwd(), ".bluma", "coding_memory.json");
3440
+ let raw = null;
3441
+ try {
3442
+ if (fs8.existsSync(globalPath)) {
3443
+ raw = fs8.readFileSync(globalPath, "utf-8");
3444
+ } else if (path10.resolve(globalPath) !== path10.resolve(legacyPath) && fs8.existsSync(legacyPath)) {
3445
+ raw = fs8.readFileSync(legacyPath, "utf-8");
3446
+ }
3447
+ } catch {
3448
+ return "";
3449
+ }
3450
+ if (!raw) return "";
3451
+ let data;
3452
+ try {
3453
+ data = JSON.parse(raw);
3454
+ } catch {
3455
+ return "";
3456
+ }
3457
+ const entries = Array.isArray(data.entries) ? [...data.entries] : [];
3458
+ if (entries.length === 0) return "";
3459
+ entries.sort((a, b) => (b.id ?? 0) - (a.id ?? 0));
3460
+ const parts = [];
3461
+ let used = 0;
3462
+ for (let i = 0; i < entries.length && i < maxNotes; i++) {
3463
+ const e = entries[i];
3464
+ const full = e.note || "";
3465
+ const body = full.length > preview ? `${full.slice(0, preview)}\u2026` : full;
3466
+ const block = `### id ${e.id} \xB7 tags: ${(e.tags || []).join(", ") || "(none)"}
3467
+ ${body}`;
3468
+ const piece = parts.length > 0 ? `
3469
+
3470
+ ---
3471
+
3472
+ ${block}` : block;
3473
+ if (used + piece.length > maxTotal) break;
3474
+ parts.push(piece);
3475
+ used += piece.length;
3476
+ }
3477
+ return parts.join("");
3478
+ }
3479
+ var memoryStore = [];
3480
+ var nextId2 = 1;
3481
+ var loaded = false;
3482
+ function getMemoryFilePath() {
3483
+ return path10.join(os4.homedir(), ".bluma", "coding_memory.json");
3484
+ }
3485
+ function getLegacyMemoryFilePath() {
3486
+ return path10.join(process.cwd(), ".bluma", "coding_memory.json");
3487
+ }
3488
+ function loadMemoryFromFile() {
3489
+ if (loaded) return;
3490
+ loaded = true;
3491
+ memoryStore = [];
3492
+ nextId2 = 1;
3493
+ try {
3494
+ const filePath = getMemoryFilePath();
3495
+ const legacy = getLegacyMemoryFilePath();
3496
+ const legacyDistinct = path10.resolve(legacy) !== path10.resolve(filePath);
3497
+ const readIntoStore = (p) => {
3498
+ const raw = fs8.readFileSync(p, "utf-8");
3499
+ const parsed = JSON.parse(raw);
3500
+ if (Array.isArray(parsed.entries)) {
3501
+ memoryStore = parsed.entries;
3502
+ nextId2 = typeof parsed.nextId === "number" ? parsed.nextId : memoryStore.length + 1;
3503
+ }
3504
+ };
3505
+ if (fs8.existsSync(filePath)) {
3506
+ readIntoStore(filePath);
3507
+ }
3508
+ if (memoryStore.length === 0 && legacyDistinct && fs8.existsSync(legacy)) {
3509
+ readIntoStore(legacy);
3510
+ if (memoryStore.length > 0) {
3511
+ saveMemoryToFile();
3512
+ }
3513
+ }
3514
+ } catch {
3515
+ memoryStore = [];
3516
+ nextId2 = 1;
3517
+ }
3518
+ }
3519
+ function saveMemoryToFile() {
3520
+ try {
3521
+ const filePath = getMemoryFilePath();
3522
+ const dir = path10.dirname(filePath);
3523
+ if (!fs8.existsSync(dir)) {
3524
+ fs8.mkdirSync(dir, { recursive: true });
3525
+ }
3526
+ const payload = {
3527
+ entries: memoryStore,
3528
+ nextId: nextId2,
3529
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3530
+ };
3531
+ fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2));
3532
+ } catch {
3533
+ }
3534
+ }
3535
+ function normalizeTags(tags) {
3536
+ if (!tags) return [];
3537
+ return tags.map((t) => typeof t === "string" ? t.trim() : "").filter((t) => t.length > 0).slice(0, 10);
3538
+ }
3539
+ function addNote(args) {
3540
+ loadMemoryFromFile();
3541
+ const note = (args.note || "").trim();
3542
+ if (!note) {
3543
+ return {
3544
+ success: false,
3545
+ message: "note is required for action=add",
3546
+ entries: memoryStore
3547
+ };
3548
+ }
3549
+ if (note.length > 4e3) {
3550
+ return {
3551
+ success: false,
3552
+ message: "note too long (max 4000 chars)",
3553
+ entries: memoryStore
3554
+ };
3555
+ }
3556
+ const entry = {
3557
+ id: nextId2++,
3558
+ note,
3559
+ tags: normalizeTags(args.tags),
3560
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3561
+ usageCount: 0
3562
+ };
3563
+ memoryStore.push(entry);
3564
+ saveMemoryToFile();
3565
+ return {
3566
+ success: true,
3567
+ message: "Memory entry added",
3568
+ entries: memoryStore
3569
+ };
3570
+ }
3571
+ function listNotes() {
3572
+ loadMemoryFromFile();
3573
+ return {
3574
+ success: true,
3575
+ message: memoryStore.length === 0 ? "No coding memory entries yet" : `Listing ${memoryStore.length} coding memory entries`,
3576
+ entries: memoryStore
3577
+ };
3578
+ }
3579
+ function searchNotes(args) {
3580
+ loadMemoryFromFile();
3581
+ const query = (args.query || "").trim();
3582
+ if (!query) {
3583
+ return {
3584
+ success: false,
3585
+ message: "query is required for action=search",
3586
+ entries: memoryStore,
3587
+ matched: []
3588
+ };
3589
+ }
3590
+ const lower = query.toLowerCase();
3591
+ const matches = memoryStore.filter((e) => {
3592
+ if (e.note.toLowerCase().includes(lower)) return true;
3593
+ return e.tags.some((t) => t.toLowerCase().includes(lower));
3594
+ });
3595
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3596
+ for (const entry of matches) {
3597
+ entry.lastUsedAt = nowIso;
3598
+ entry.usageCount = (entry.usageCount || 0) + 1;
3599
+ }
3600
+ saveMemoryToFile();
3601
+ return {
3602
+ success: true,
3603
+ message: matches.length === 0 ? "No matching coding memory entries" : `Found ${matches.length} matching entries`,
3604
+ entries: memoryStore,
3605
+ matched: matches
3606
+ };
3607
+ }
3608
+ function clearNotes() {
3609
+ loadMemoryFromFile();
3610
+ memoryStore = [];
3611
+ nextId2 = 1;
3612
+ saveMemoryToFile();
3613
+ return {
3614
+ success: true,
3615
+ message: "All coding memory entries cleared",
3616
+ entries: memoryStore
3617
+ };
3618
+ }
3619
+ async function coding_memory(args) {
3620
+ const action = args.action;
3621
+ switch (action) {
3622
+ case "add":
3623
+ return addNote(args);
3624
+ case "list":
3625
+ return listNotes();
3626
+ case "search":
3627
+ return searchNotes(args);
3628
+ case "clear":
3629
+ return clearNotes();
3630
+ default:
3631
+ return {
3632
+ success: false,
3633
+ message: `Unknown action: ${String(action)}`,
3634
+ entries: memoryStore
3635
+ };
3636
+ }
3637
+ }
3638
+
3427
3639
  // src/app/agent/tool_invoker.ts
3428
3640
  var ToolInvoker = class {
3429
3641
  // Mapa privado para associar nomes de ferramentas às suas funções de implementação.
@@ -3441,9 +3653,9 @@ var ToolInvoker = class {
3441
3653
  async initialize() {
3442
3654
  try {
3443
3655
  const __filename = fileURLToPath(import.meta.url);
3444
- const __dirname2 = path10.dirname(__filename);
3445
- const configPath = path10.resolve(__dirname2, "config", "native_tools.json");
3446
- const fileContent = await fs8.readFile(configPath, "utf-8");
3656
+ const __dirname2 = path11.dirname(__filename);
3657
+ const configPath = path11.resolve(__dirname2, "config", "native_tools.json");
3658
+ const fileContent = await fs9.readFile(configPath, "utf-8");
3447
3659
  const config2 = JSON.parse(fileContent);
3448
3660
  this.toolDefinitions = config2.nativeTools;
3449
3661
  } catch (error) {
@@ -3474,6 +3686,7 @@ var ToolInvoker = class {
3474
3686
  this.toolImplementations.set("read_artifact", readArtifact);
3475
3687
  this.toolImplementations.set("search_web", searchWeb);
3476
3688
  this.toolImplementations.set("load_skill", loadSkill);
3689
+ this.toolImplementations.set("coding_memory", coding_memory);
3477
3690
  }
3478
3691
  /**
3479
3692
  * Retorna a lista de definições de todas as ferramentas nativas carregadas.
@@ -3503,9 +3716,9 @@ var ToolInvoker = class {
3503
3716
  };
3504
3717
 
3505
3718
  // src/app/agent/tools/mcp/mcp_client.ts
3506
- import { promises as fs9 } from "fs";
3507
- import path11 from "path";
3508
- import os4 from "os";
3719
+ import { promises as fs10 } from "fs";
3720
+ import path12 from "path";
3721
+ import os5 from "os";
3509
3722
  import { fileURLToPath as fileURLToPath2 } from "url";
3510
3723
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3511
3724
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
@@ -3532,9 +3745,9 @@ var MCPClient = class {
3532
3745
  });
3533
3746
  }
3534
3747
  const __filename = fileURLToPath2(import.meta.url);
3535
- const __dirname2 = path11.dirname(__filename);
3536
- const defaultConfigPath = path11.resolve(__dirname2, "config", "bluma-mcp.json");
3537
- const userConfigPath = path11.join(os4.homedir(), ".bluma", "bluma-mcp.json");
3748
+ const __dirname2 = path12.dirname(__filename);
3749
+ const defaultConfigPath = path12.resolve(__dirname2, "config", "bluma-mcp.json");
3750
+ const userConfigPath = path12.join(os5.homedir(), ".bluma", "bluma-mcp.json");
3538
3751
  const defaultConfig = await this.loadMcpConfig(defaultConfigPath, "Default");
3539
3752
  const userConfig = await this.loadMcpConfig(userConfigPath, "User");
3540
3753
  const mergedConfig = {
@@ -3568,7 +3781,7 @@ var MCPClient = class {
3568
3781
  }
3569
3782
  async loadMcpConfig(configPath, configType) {
3570
3783
  try {
3571
- const fileContent = await fs9.readFile(configPath, "utf-8");
3784
+ const fileContent = await fs10.readFile(configPath, "utf-8");
3572
3785
  const processedContent = this.replaceEnvPlaceholders(fileContent);
3573
3786
  return JSON.parse(processedContent);
3574
3787
  } catch (error) {
@@ -3587,7 +3800,7 @@ var MCPClient = class {
3587
3800
  async connectToStdioServer(serverName, config2) {
3588
3801
  let commandToExecute = config2.command;
3589
3802
  let argsToExecute = config2.args || [];
3590
- const isWindows = os4.platform() === "win32";
3803
+ const isWindows = os5.platform() === "win32";
3591
3804
  if (!isWindows && commandToExecute.toLowerCase() === "cmd") {
3592
3805
  if (argsToExecute.length >= 2 && argsToExecute[0].toLowerCase() === "/c") {
3593
3806
  commandToExecute = argsToExecute[1];
@@ -3703,13 +3916,13 @@ var AdvancedFeedbackSystem = class {
3703
3916
  };
3704
3917
 
3705
3918
  // src/app/agent/bluma/core/bluma.ts
3706
- import path15 from "path";
3919
+ import path16 from "path";
3707
3920
  import { v4 as uuidv43 } from "uuid";
3708
3921
 
3709
3922
  // src/app/agent/session_manager/session_manager.ts
3710
- import path12 from "path";
3711
- import os5 from "os";
3712
- import { promises as fs10 } from "fs";
3923
+ import path13 from "path";
3924
+ import os6 from "os";
3925
+ import { promises as fs11 } from "fs";
3713
3926
  var fileLocks = /* @__PURE__ */ new Map();
3714
3927
  async function withFileLock(file, fn) {
3715
3928
  const prev = fileLocks.get(file) || Promise.resolve();
@@ -3744,13 +3957,13 @@ function debouncedSave(sessionFile, history) {
3744
3957
  function expandHome(p) {
3745
3958
  if (!p) return p;
3746
3959
  if (p.startsWith("~")) {
3747
- return path12.join(os5.homedir(), p.slice(1));
3960
+ return path13.join(os6.homedir(), p.slice(1));
3748
3961
  }
3749
3962
  return p;
3750
3963
  }
3751
3964
  function getPreferredAppDir() {
3752
- const fixed = path12.join(os5.homedir(), ".bluma");
3753
- return path12.resolve(expandHome(fixed));
3965
+ const fixed = path13.join(os6.homedir(), ".bluma");
3966
+ return path13.resolve(expandHome(fixed));
3754
3967
  }
3755
3968
  async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3756
3969
  let attempt = 0;
@@ -3758,10 +3971,10 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3758
3971
  const isWin = process.platform === "win32";
3759
3972
  while (attempt <= maxRetries) {
3760
3973
  try {
3761
- const dir = path12.dirname(dest);
3762
- await fs10.mkdir(dir, { recursive: true }).catch(() => {
3974
+ const dir = path13.dirname(dest);
3975
+ await fs11.mkdir(dir, { recursive: true }).catch(() => {
3763
3976
  });
3764
- await fs10.rename(src, dest);
3977
+ await fs11.rename(src, dest);
3765
3978
  return;
3766
3979
  } catch (e) {
3767
3980
  lastErr = e;
@@ -3774,13 +3987,13 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3774
3987
  }
3775
3988
  }
3776
3989
  try {
3777
- await fs10.access(src);
3778
- const data = await fs10.readFile(src);
3779
- const dir = path12.dirname(dest);
3780
- await fs10.mkdir(dir, { recursive: true }).catch(() => {
3990
+ await fs11.access(src);
3991
+ const data = await fs11.readFile(src);
3992
+ const dir = path13.dirname(dest);
3993
+ await fs11.mkdir(dir, { recursive: true }).catch(() => {
3781
3994
  });
3782
- await fs10.writeFile(dest, data);
3783
- await fs10.unlink(src).catch(() => {
3995
+ await fs11.writeFile(dest, data);
3996
+ await fs11.unlink(src).catch(() => {
3784
3997
  });
3785
3998
  return;
3786
3999
  } catch (fallbackErr) {
@@ -3793,16 +4006,16 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3793
4006
  }
3794
4007
  async function ensureSessionDir() {
3795
4008
  const appDir = getPreferredAppDir();
3796
- const sessionDir = path12.join(appDir, "sessions");
3797
- await fs10.mkdir(sessionDir, { recursive: true });
4009
+ const sessionDir = path13.join(appDir, "sessions");
4010
+ await fs11.mkdir(sessionDir, { recursive: true });
3798
4011
  return sessionDir;
3799
4012
  }
3800
4013
  async function loadOrcreateSession(sessionId) {
3801
4014
  const sessionDir = await ensureSessionDir();
3802
- const sessionFile = path12.join(sessionDir, `${sessionId}.json`);
4015
+ const sessionFile = path13.join(sessionDir, `${sessionId}.json`);
3803
4016
  try {
3804
- await fs10.access(sessionFile);
3805
- const fileContent = await fs10.readFile(sessionFile, "utf-8");
4017
+ await fs11.access(sessionFile);
4018
+ const fileContent = await fs11.readFile(sessionFile, "utf-8");
3806
4019
  const sessionData = JSON.parse(fileContent);
3807
4020
  return [sessionFile, sessionData.conversation_history || [], []];
3808
4021
  } catch (error) {
@@ -3811,7 +4024,7 @@ async function loadOrcreateSession(sessionId) {
3811
4024
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
3812
4025
  conversation_history: []
3813
4026
  };
3814
- await fs10.writeFile(sessionFile, JSON.stringify(newSessionData, null, 2), "utf-8");
4027
+ await fs11.writeFile(sessionFile, JSON.stringify(newSessionData, null, 2), "utf-8");
3815
4028
  return [sessionFile, [], []];
3816
4029
  }
3817
4030
  }
@@ -3819,12 +4032,12 @@ async function doSaveSessionHistory(sessionFile, history) {
3819
4032
  await withFileLock(sessionFile, async () => {
3820
4033
  let sessionData;
3821
4034
  try {
3822
- const dir = path12.dirname(sessionFile);
3823
- await fs10.mkdir(dir, { recursive: true });
4035
+ const dir = path13.dirname(sessionFile);
4036
+ await fs11.mkdir(dir, { recursive: true });
3824
4037
  } catch {
3825
4038
  }
3826
4039
  try {
3827
- const fileContent = await fs10.readFile(sessionFile, "utf-8");
4040
+ const fileContent = await fs11.readFile(sessionFile, "utf-8");
3828
4041
  sessionData = JSON.parse(fileContent);
3829
4042
  } catch (error) {
3830
4043
  const code = error && error.code;
@@ -3835,14 +4048,14 @@ async function doSaveSessionHistory(sessionFile, history) {
3835
4048
  console.warn(`An unknown error occurred while reading ${sessionFile}. Re-initializing.`, error);
3836
4049
  }
3837
4050
  }
3838
- const sessionId = path12.basename(sessionFile, ".json");
4051
+ const sessionId = path13.basename(sessionFile, ".json");
3839
4052
  sessionData = {
3840
4053
  session_id: sessionId,
3841
4054
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
3842
4055
  conversation_history: []
3843
4056
  };
3844
4057
  try {
3845
- await fs10.writeFile(sessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
4058
+ await fs11.writeFile(sessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
3846
4059
  } catch {
3847
4060
  }
3848
4061
  }
@@ -3850,7 +4063,7 @@ async function doSaveSessionHistory(sessionFile, history) {
3850
4063
  sessionData.last_updated = (/* @__PURE__ */ new Date()).toISOString();
3851
4064
  const tempSessionFile = `${sessionFile}.${Date.now()}.tmp`;
3852
4065
  try {
3853
- await fs10.writeFile(tempSessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
4066
+ await fs11.writeFile(tempSessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
3854
4067
  await safeRenameWithRetry(tempSessionFile, sessionFile);
3855
4068
  } catch (writeError) {
3856
4069
  if (writeError instanceof Error) {
@@ -3859,7 +4072,7 @@ async function doSaveSessionHistory(sessionFile, history) {
3859
4072
  console.error(`An unknown fatal error occurred while saving session to ${sessionFile}:`, writeError);
3860
4073
  }
3861
4074
  try {
3862
- await fs10.unlink(tempSessionFile);
4075
+ await fs11.unlink(tempSessionFile);
3863
4076
  } catch {
3864
4077
  }
3865
4078
  }
@@ -3876,15 +4089,15 @@ async function saveSessionHistory(sessionFile, history) {
3876
4089
  }
3877
4090
 
3878
4091
  // src/app/agent/core/prompt/prompt_builder.ts
3879
- import os7 from "os";
3880
- import fs12 from "fs";
3881
- import path14 from "path";
4092
+ import os8 from "os";
4093
+ import fs13 from "fs";
4094
+ import path15 from "path";
3882
4095
  import { execSync } from "child_process";
3883
4096
 
3884
4097
  // src/app/agent/skills/skill_loader.ts
3885
- import fs11 from "fs";
3886
- import path13 from "path";
3887
- import os6 from "os";
4098
+ import fs12 from "fs";
4099
+ import path14 from "path";
4100
+ import os7 from "os";
3888
4101
  import { fileURLToPath as fileURLToPath3 } from "url";
3889
4102
  var SkillLoader = class _SkillLoader {
3890
4103
  bundledSkillsDir;
@@ -3893,8 +4106,8 @@ var SkillLoader = class _SkillLoader {
3893
4106
  cache = /* @__PURE__ */ new Map();
3894
4107
  conflicts = [];
3895
4108
  constructor(projectRoot, bundledDir) {
3896
- this.projectSkillsDir = path13.join(projectRoot, ".bluma", "skills");
3897
- this.globalSkillsDir = path13.join(os6.homedir(), ".bluma", "skills");
4109
+ this.projectSkillsDir = path14.join(projectRoot, ".bluma", "skills");
4110
+ this.globalSkillsDir = path14.join(os7.homedir(), ".bluma", "skills");
3898
4111
  this.bundledSkillsDir = bundledDir || _SkillLoader.resolveBundledDir();
3899
4112
  }
3900
4113
  /**
@@ -3904,16 +4117,16 @@ var SkillLoader = class _SkillLoader {
3904
4117
  static resolveBundledDir() {
3905
4118
  if (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) {
3906
4119
  if (typeof __dirname !== "undefined") {
3907
- return path13.join(__dirname, "config", "skills");
4120
+ return path14.join(__dirname, "config", "skills");
3908
4121
  }
3909
- return path13.join(process.cwd(), "dist", "config", "skills");
4122
+ return path14.join(process.cwd(), "dist", "config", "skills");
3910
4123
  }
3911
4124
  try {
3912
4125
  const currentFile = fileURLToPath3(import.meta.url);
3913
- const distDir = path13.dirname(currentFile);
3914
- return path13.join(distDir, "config", "skills");
4126
+ const distDir = path14.dirname(currentFile);
4127
+ return path14.join(distDir, "config", "skills");
3915
4128
  } catch {
3916
- return path13.join(process.cwd(), "dist", "config", "skills");
4129
+ return path14.join(process.cwd(), "dist", "config", "skills");
3917
4130
  }
3918
4131
  }
3919
4132
  /**
@@ -3942,8 +4155,8 @@ var SkillLoader = class _SkillLoader {
3942
4155
  this.conflicts.push({
3943
4156
  name: skill.name,
3944
4157
  userSource: source,
3945
- userPath: path13.join(dir, skill.name, "SKILL.md"),
3946
- bundledPath: path13.join(this.bundledSkillsDir, skill.name, "SKILL.md")
4158
+ userPath: path14.join(dir, skill.name, "SKILL.md"),
4159
+ bundledPath: path14.join(this.bundledSkillsDir, skill.name, "SKILL.md")
3947
4160
  });
3948
4161
  continue;
3949
4162
  }
@@ -3951,20 +4164,20 @@ var SkillLoader = class _SkillLoader {
3951
4164
  }
3952
4165
  }
3953
4166
  listFromDir(dir, source) {
3954
- if (!fs11.existsSync(dir)) return [];
4167
+ if (!fs12.existsSync(dir)) return [];
3955
4168
  try {
3956
- return fs11.readdirSync(dir).filter((d) => {
3957
- const fullPath = path13.join(dir, d);
3958
- return fs11.statSync(fullPath).isDirectory() && fs11.existsSync(path13.join(fullPath, "SKILL.md"));
3959
- }).map((d) => this.loadMetadataFromPath(path13.join(dir, d, "SKILL.md"), d, source)).filter((m) => m !== null);
4169
+ return fs12.readdirSync(dir).filter((d) => {
4170
+ const fullPath = path14.join(dir, d);
4171
+ return fs12.statSync(fullPath).isDirectory() && fs12.existsSync(path14.join(fullPath, "SKILL.md"));
4172
+ }).map((d) => this.loadMetadataFromPath(path14.join(dir, d, "SKILL.md"), d, source)).filter((m) => m !== null);
3960
4173
  } catch {
3961
4174
  return [];
3962
4175
  }
3963
4176
  }
3964
4177
  loadMetadataFromPath(skillPath, skillName, source) {
3965
- if (!fs11.existsSync(skillPath)) return null;
4178
+ if (!fs12.existsSync(skillPath)) return null;
3966
4179
  try {
3967
- const raw = fs11.readFileSync(skillPath, "utf-8");
4180
+ const raw = fs12.readFileSync(skillPath, "utf-8");
3968
4181
  const parsed = this.parseFrontmatter(raw);
3969
4182
  return {
3970
4183
  name: parsed.name || skillName,
@@ -3986,12 +4199,12 @@ var SkillLoader = class _SkillLoader {
3986
4199
  */
3987
4200
  load(name) {
3988
4201
  if (this.cache.has(name)) return this.cache.get(name);
3989
- const bundledPath = path13.join(this.bundledSkillsDir, name, "SKILL.md");
3990
- const projectPath = path13.join(this.projectSkillsDir, name, "SKILL.md");
3991
- const globalPath = path13.join(this.globalSkillsDir, name, "SKILL.md");
3992
- const existsBundled = fs11.existsSync(bundledPath);
3993
- const existsProject = fs11.existsSync(projectPath);
3994
- const existsGlobal = fs11.existsSync(globalPath);
4202
+ const bundledPath = path14.join(this.bundledSkillsDir, name, "SKILL.md");
4203
+ const projectPath = path14.join(this.projectSkillsDir, name, "SKILL.md");
4204
+ const globalPath = path14.join(this.globalSkillsDir, name, "SKILL.md");
4205
+ const existsBundled = fs12.existsSync(bundledPath);
4206
+ const existsProject = fs12.existsSync(projectPath);
4207
+ const existsGlobal = fs12.existsSync(globalPath);
3995
4208
  if (existsBundled && (existsProject || existsGlobal)) {
3996
4209
  const conflictSource = existsProject ? "project" : "global";
3997
4210
  const conflictPath = existsProject ? projectPath : globalPath;
@@ -4030,9 +4243,9 @@ var SkillLoader = class _SkillLoader {
4030
4243
  }
4031
4244
  loadFromPath(skillPath, name, source) {
4032
4245
  try {
4033
- const raw = fs11.readFileSync(skillPath, "utf-8");
4246
+ const raw = fs12.readFileSync(skillPath, "utf-8");
4034
4247
  const parsed = this.parseFrontmatter(raw);
4035
- const skillDir = path13.dirname(skillPath);
4248
+ const skillDir = path14.dirname(skillPath);
4036
4249
  return {
4037
4250
  name: parsed.name || name,
4038
4251
  description: parsed.description || "",
@@ -4041,22 +4254,22 @@ var SkillLoader = class _SkillLoader {
4041
4254
  version: parsed.version,
4042
4255
  author: parsed.author,
4043
4256
  license: parsed.license,
4044
- references: this.scanAssets(path13.join(skillDir, "references")),
4045
- scripts: this.scanAssets(path13.join(skillDir, "scripts"))
4257
+ references: this.scanAssets(path14.join(skillDir, "references")),
4258
+ scripts: this.scanAssets(path14.join(skillDir, "scripts"))
4046
4259
  };
4047
4260
  } catch {
4048
4261
  return null;
4049
4262
  }
4050
4263
  }
4051
4264
  scanAssets(dir) {
4052
- if (!fs11.existsSync(dir)) return [];
4265
+ if (!fs12.existsSync(dir)) return [];
4053
4266
  try {
4054
- return fs11.readdirSync(dir).filter((f) => {
4055
- const fp = path13.join(dir, f);
4056
- return fs11.statSync(fp).isFile();
4267
+ return fs12.readdirSync(dir).filter((f) => {
4268
+ const fp = path14.join(dir, f);
4269
+ return fs12.statSync(fp).isFile();
4057
4270
  }).map((f) => ({
4058
4271
  name: f,
4059
- path: path13.resolve(dir, f)
4272
+ path: path14.resolve(dir, f)
4060
4273
  }));
4061
4274
  } catch {
4062
4275
  return [];
@@ -4113,10 +4326,10 @@ var SkillLoader = class _SkillLoader {
4113
4326
  this.cache.clear();
4114
4327
  }
4115
4328
  exists(name) {
4116
- const bundledPath = path13.join(this.bundledSkillsDir, name, "SKILL.md");
4117
- const projectPath = path13.join(this.projectSkillsDir, name, "SKILL.md");
4118
- const globalPath = path13.join(this.globalSkillsDir, name, "SKILL.md");
4119
- return fs11.existsSync(bundledPath) || fs11.existsSync(projectPath) || fs11.existsSync(globalPath);
4329
+ const bundledPath = path14.join(this.bundledSkillsDir, name, "SKILL.md");
4330
+ const projectPath = path14.join(this.projectSkillsDir, name, "SKILL.md");
4331
+ const globalPath = path14.join(this.globalSkillsDir, name, "SKILL.md");
4332
+ return fs12.existsSync(bundledPath) || fs12.existsSync(projectPath) || fs12.existsSync(globalPath);
4120
4333
  }
4121
4334
  /**
4122
4335
  * Retorna conflitos detetados (skills do utilizador com mesmo nome de nativas).
@@ -4175,10 +4388,10 @@ function getGitBranch(dir) {
4175
4388
  }
4176
4389
  function getPackageManager(dir) {
4177
4390
  try {
4178
- if (fs12.existsSync(path14.join(dir, "pnpm-lock.yaml"))) return "pnpm";
4179
- if (fs12.existsSync(path14.join(dir, "yarn.lock"))) return "yarn";
4180
- if (fs12.existsSync(path14.join(dir, "bun.lockb"))) return "bun";
4181
- if (fs12.existsSync(path14.join(dir, "package-lock.json"))) return "npm";
4391
+ if (fs13.existsSync(path15.join(dir, "pnpm-lock.yaml"))) return "pnpm";
4392
+ if (fs13.existsSync(path15.join(dir, "yarn.lock"))) return "yarn";
4393
+ if (fs13.existsSync(path15.join(dir, "bun.lockb"))) return "bun";
4394
+ if (fs13.existsSync(path15.join(dir, "package-lock.json"))) return "npm";
4182
4395
  return "unknown";
4183
4396
  } catch {
4184
4397
  return "unknown";
@@ -4186,9 +4399,9 @@ function getPackageManager(dir) {
4186
4399
  }
4187
4400
  function getProjectType(dir) {
4188
4401
  try {
4189
- const files = fs12.readdirSync(dir);
4402
+ const files = fs13.readdirSync(dir);
4190
4403
  if (files.includes("package.json")) {
4191
- const pkg = JSON.parse(fs12.readFileSync(path14.join(dir, "package.json"), "utf-8"));
4404
+ const pkg = JSON.parse(fs13.readFileSync(path15.join(dir, "package.json"), "utf-8"));
4192
4405
  if (pkg.dependencies?.next || pkg.devDependencies?.next) return "Next.js";
4193
4406
  if (pkg.dependencies?.react || pkg.devDependencies?.react) return "React";
4194
4407
  if (pkg.dependencies?.express || pkg.devDependencies?.express) return "Express";
@@ -4207,9 +4420,9 @@ function getProjectType(dir) {
4207
4420
  }
4208
4421
  function getTestFramework(dir) {
4209
4422
  try {
4210
- const pkgPath = path14.join(dir, "package.json");
4211
- if (fs12.existsSync(pkgPath)) {
4212
- const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
4423
+ const pkgPath = path15.join(dir, "package.json");
4424
+ if (fs13.existsSync(pkgPath)) {
4425
+ const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf-8"));
4213
4426
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
4214
4427
  if (deps.jest) return "jest";
4215
4428
  if (deps.vitest) return "vitest";
@@ -4218,7 +4431,7 @@ function getTestFramework(dir) {
4218
4431
  if (deps["@playwright/test"]) return "playwright";
4219
4432
  if (deps.cypress) return "cypress";
4220
4433
  }
4221
- if (fs12.existsSync(path14.join(dir, "pytest.ini")) || fs12.existsSync(path14.join(dir, "conftest.py"))) return "pytest";
4434
+ if (fs13.existsSync(path15.join(dir, "pytest.ini")) || fs13.existsSync(path15.join(dir, "conftest.py"))) return "pytest";
4222
4435
  return "unknown";
4223
4436
  } catch {
4224
4437
  return "unknown";
@@ -4226,9 +4439,9 @@ function getTestFramework(dir) {
4226
4439
  }
4227
4440
  function getTestCommand(dir) {
4228
4441
  try {
4229
- const pkgPath = path14.join(dir, "package.json");
4230
- if (fs12.existsSync(pkgPath)) {
4231
- const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
4442
+ const pkgPath = path15.join(dir, "package.json");
4443
+ if (fs13.existsSync(pkgPath)) {
4444
+ const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf-8"));
4232
4445
  if (pkg.scripts?.test) return `npm test`;
4233
4446
  if (pkg.scripts?.["test:unit"]) return `npm run test:unit`;
4234
4447
  }
@@ -4337,6 +4550,26 @@ You MUST adapt all commands to this environment. Use the correct package manager
4337
4550
 
4338
4551
  ---
4339
4552
 
4553
+ <coding_memory>
4554
+ ## Persistent coding memory (tool: \`coding_memory\`)
4555
+
4556
+ You have **durable notes** on disk (typically \`~/.bluma/coding_memory.json\`), separate from chat history. They **survive new sessions**.
4557
+
4558
+ ### Baseline vs live refresh
4559
+ - The **<coding_memory_snapshot>** block (appended after this prompt) is loaded **once at session start** from disk. It can become stale if memory changes later or if the topic was never saved.
4560
+ - Act like a teammate who **checks their notes**: before relying on "what we agreed" or project-specific lore, use \`coding_memory\` with \`action: "search"\` and a short \`query\` \u2014 especially when the user asks if you remember something, or when switching back to a topic after a long stretch of work.
4561
+
4562
+ ### When to write
4563
+ - After you learn **stable** facts (architecture, conventions, important URLs, decisions, repeated user preferences), call \`coding_memory\` with \`action: "add"\`, a concise \`note\`, and \`tags\` for later search.
4564
+ - When something **changes**, add an updated note (and do not treat outdated snapshot text as truth without searching).
4565
+
4566
+ ### Habits (continuity)
4567
+ - Prefer **search** or **list** over guessing when answering "remember / last time / what we did".
4568
+ - Long specs belong in the repo or artifacts; use \`coding_memory\` for **short** reminders and pointers.
4569
+ </coding_memory>
4570
+
4571
+ ---
4572
+
4340
4573
  <workflow>
4341
4574
  ## How You Work
4342
4575
 
@@ -4664,12 +4897,12 @@ In sandbox mode you are a Python-focused, non-interactive, deterministic agent t
4664
4897
  function getUnifiedSystemPrompt(availableSkills) {
4665
4898
  const cwd = process.cwd();
4666
4899
  const env = {
4667
- os_type: os7.type(),
4668
- os_version: os7.release(),
4669
- architecture: os7.arch(),
4900
+ os_type: os8.type(),
4901
+ os_version: os8.release(),
4902
+ architecture: os8.arch(),
4670
4903
  workdir: cwd,
4671
4904
  shell_type: process.env.SHELL || process.env.COMSPEC || "unknown",
4672
- username: os7.userInfo().username,
4905
+ username: os8.userInfo().username,
4673
4906
  current_date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
4674
4907
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
4675
4908
  is_git_repo: isGitRepo(cwd) ? "yes" : "no",
@@ -4839,12 +5072,23 @@ User: "Publish the package"
4839
5072
  </available_skills>
4840
5073
  `;
4841
5074
  }
5075
+ const memorySnapshot = readCodingMemoryForPrompt();
5076
+ prompt += `
5077
+
5078
+ ---
5079
+
5080
+ <coding_memory_snapshot>
5081
+ ## Persistent notes (loaded at session start from disk)
5082
+
5083
+ ${memorySnapshot.trim().length > 0 ? memorySnapshot : "(No entries yet. Use coding_memory with action add or search to build continuity across sessions.)"}
5084
+ </coding_memory_snapshot>
5085
+ `;
4842
5086
  return prompt;
4843
5087
  }
4844
5088
  function isGitRepo(dir) {
4845
5089
  try {
4846
- const gitPath = path14.join(dir, ".git");
4847
- return fs12.existsSync(gitPath) && fs12.lstatSync(gitPath).isDirectory();
5090
+ const gitPath = path15.join(dir, ".git");
5091
+ return fs13.existsSync(gitPath) && fs13.lstatSync(gitPath).isDirectory();
4848
5092
  } catch {
4849
5093
  return false;
4850
5094
  }
@@ -4915,7 +5159,7 @@ function createApiContextWindow(fullHistory, maxTurns) {
4915
5159
  }
4916
5160
 
4917
5161
  // src/app/agent/core/llm/llm.ts
4918
- import os8 from "os";
5162
+ import os9 from "os";
4919
5163
  import OpenAI from "openai";
4920
5164
  function defaultBlumaUserContextInput(sessionId, userMessage) {
4921
5165
  const msg = String(userMessage || "").slice(0, 300);
@@ -4932,7 +5176,7 @@ function defaultBlumaUserContextInput(sessionId, userMessage) {
4932
5176
  }
4933
5177
  function getPreferredMacAddress() {
4934
5178
  try {
4935
- const ifaces = os8.networkInterfaces();
5179
+ const ifaces = os9.networkInterfaces();
4936
5180
  for (const name of Object.keys(ifaces)) {
4937
5181
  const addrs = ifaces[name];
4938
5182
  if (!addrs) continue;
@@ -4947,7 +5191,7 @@ function getPreferredMacAddress() {
4947
5191
  } catch {
4948
5192
  }
4949
5193
  try {
4950
- return `host:${os8.hostname()}`;
5194
+ return `host:${os9.hostname()}`;
4951
5195
  } catch {
4952
5196
  return "unknown";
4953
5197
  }
@@ -4957,7 +5201,7 @@ function defaultInteractiveCliUserContextInput(sessionId, userMessage) {
4957
5201
  const machineId = getPreferredMacAddress();
4958
5202
  let userName = null;
4959
5203
  try {
4960
- userName = os8.userInfo().username || null;
5204
+ userName = os9.userInfo().username || null;
4961
5205
  } catch {
4962
5206
  userName = null;
4963
5207
  }
@@ -5532,7 +5776,7 @@ var BluMaAgent = class {
5532
5776
 
5533
5777
  ${editData.error.display}`;
5534
5778
  }
5535
- const filename = path15.basename(toolArgs.file_path);
5779
+ const filename = path16.basename(toolArgs.file_path);
5536
5780
  return createDiff(filename, editData.currentContent || "", editData.newContent);
5537
5781
  } catch (e) {
5538
5782
  return `An unexpected error occurred while generating the edit preview: ${e.message}`;
@@ -5770,7 +6014,7 @@ import { v4 as uuidv45 } from "uuid";
5770
6014
  import { v4 as uuidv44 } from "uuid";
5771
6015
 
5772
6016
  // src/app/agent/subagents/init/init_system_prompt.ts
5773
- import os9 from "os";
6017
+ import os10 from "os";
5774
6018
  var SYSTEM_PROMPT2 = `
5775
6019
 
5776
6020
  ### YOU ARE BluMa CLI \u2014 INIT SUBAGENT \u2014 AUTONOMOUS SENIOR SOFTWARE ENGINEER @ NOMADENGENUITY
@@ -5933,12 +6177,12 @@ Rule Summary:
5933
6177
  function getInitPrompt() {
5934
6178
  const now = /* @__PURE__ */ new Date();
5935
6179
  const collectedData = {
5936
- os_type: os9.type(),
5937
- os_version: os9.release(),
5938
- architecture: os9.arch(),
6180
+ os_type: os10.type(),
6181
+ os_version: os10.release(),
6182
+ architecture: os10.arch(),
5939
6183
  workdir: process.cwd(),
5940
6184
  shell_type: process.env.SHELL || process.env.COMSPEC || "Unknown",
5941
- username: os9.userInfo().username || "Unknown",
6185
+ username: os10.userInfo().username || "Unknown",
5942
6186
  current_date: now.toISOString().split("T")[0],
5943
6187
  // Formato YYYY-MM-DD
5944
6188
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "Unknown",
@@ -6219,14 +6463,14 @@ var RouteManager = class {
6219
6463
  this.subAgents = subAgents;
6220
6464
  this.core = core;
6221
6465
  }
6222
- registerRoute(path18, handler) {
6223
- this.routeHandlers.set(path18, handler);
6466
+ registerRoute(path19, handler) {
6467
+ this.routeHandlers.set(path19, handler);
6224
6468
  }
6225
6469
  async handleRoute(payload) {
6226
6470
  const inputText = String(payload.content || "").trim();
6227
6471
  const { userContext } = payload;
6228
- for (const [path18, handler] of this.routeHandlers) {
6229
- if (inputText === path18 || inputText.startsWith(`${path18} `)) {
6472
+ for (const [path19, handler] of this.routeHandlers) {
6473
+ if (inputText === path19 || inputText.startsWith(`${path19} `)) {
6230
6474
  return handler({ content: inputText, userContext });
6231
6475
  }
6232
6476
  }
@@ -6235,7 +6479,7 @@ var RouteManager = class {
6235
6479
  };
6236
6480
 
6237
6481
  // src/app/agent/agent.ts
6238
- var globalEnvPath = path16.join(os10.homedir(), ".bluma", ".env");
6482
+ var globalEnvPath = path17.join(os11.homedir(), ".bluma", ".env");
6239
6483
  dotenv.config({ path: globalEnvPath });
6240
6484
  var Agent = class {
6241
6485
  sessionId;
@@ -6462,12 +6706,12 @@ var renderShellCommand2 = ({ args }) => {
6462
6706
  };
6463
6707
  var renderLsTool2 = ({ args }) => {
6464
6708
  const parsed = parseArgs(args);
6465
- const path18 = parsed.directory_path || ".";
6709
+ const path19 = parsed.directory_path || ".";
6466
6710
  return /* @__PURE__ */ jsxs8(Box8, { paddingX: 1, children: [
6467
6711
  /* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "ls" }),
6468
6712
  /* @__PURE__ */ jsxs8(Text8, { children: [
6469
6713
  " ",
6470
- path18
6714
+ path19
6471
6715
  ] })
6472
6716
  ] });
6473
6717
  };
@@ -6598,7 +6842,7 @@ var renderFindByName = ({ args }) => {
6598
6842
  var renderGrepSearch = ({ args }) => {
6599
6843
  const parsed = parseArgs(args);
6600
6844
  const query = parsed.query || "";
6601
- const path18 = parsed.path || ".";
6845
+ const path19 = parsed.path || ".";
6602
6846
  return /* @__PURE__ */ jsxs8(Box8, { paddingX: 1, children: [
6603
6847
  /* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "grep" }),
6604
6848
  /* @__PURE__ */ jsxs8(Text8, { color: "white", children: [
@@ -6608,7 +6852,7 @@ var renderGrepSearch = ({ args }) => {
6608
6852
  ] }),
6609
6853
  /* @__PURE__ */ jsxs8(Text8, { children: [
6610
6854
  " ",
6611
- path18
6855
+ path19
6612
6856
  ] })
6613
6857
  ] });
6614
6858
  };
@@ -7226,16 +7470,16 @@ var SlashCommands_default = SlashCommands;
7226
7470
  // src/app/agent/utils/update_check.ts
7227
7471
  import updateNotifier from "update-notifier";
7228
7472
  import { fileURLToPath as fileURLToPath4 } from "url";
7229
- import path17 from "path";
7230
- import fs13 from "fs";
7473
+ import path18 from "path";
7474
+ import fs14 from "fs";
7231
7475
  var BLUMA_PACKAGE_NAME = "@nomad-e/bluma-cli";
7232
7476
  function findBlumaPackageJson(startDir) {
7233
7477
  let dir = startDir;
7234
7478
  for (let i = 0; i < 10; i++) {
7235
- const candidate = path17.join(dir, "package.json");
7236
- if (fs13.existsSync(candidate)) {
7479
+ const candidate = path18.join(dir, "package.json");
7480
+ if (fs14.existsSync(candidate)) {
7237
7481
  try {
7238
- const raw = fs13.readFileSync(candidate, "utf8");
7482
+ const raw = fs14.readFileSync(candidate, "utf8");
7239
7483
  const parsed = JSON.parse(raw);
7240
7484
  if (parsed?.name === BLUMA_PACKAGE_NAME && parsed?.version) {
7241
7485
  return { name: parsed.name, version: parsed.version };
@@ -7243,7 +7487,7 @@ function findBlumaPackageJson(startDir) {
7243
7487
  } catch {
7244
7488
  }
7245
7489
  }
7246
- const parent = path17.dirname(dir);
7490
+ const parent = path18.dirname(dir);
7247
7491
  if (parent === dir) break;
7248
7492
  dir = parent;
7249
7493
  }
@@ -7256,12 +7500,12 @@ async function checkForUpdates() {
7256
7500
  }
7257
7501
  const binPath = process.argv?.[1];
7258
7502
  let pkg = null;
7259
- if (binPath && fs13.existsSync(binPath)) {
7260
- pkg = findBlumaPackageJson(path17.dirname(binPath));
7503
+ if (binPath && fs14.existsSync(binPath)) {
7504
+ pkg = findBlumaPackageJson(path18.dirname(binPath));
7261
7505
  }
7262
7506
  if (!pkg) {
7263
7507
  const __filename = fileURLToPath4(import.meta.url);
7264
- const __dirname2 = path17.dirname(__filename);
7508
+ const __dirname2 = path18.dirname(__filename);
7265
7509
  pkg = findBlumaPackageJson(__dirname2);
7266
7510
  }
7267
7511
  if (!pkg) {
@@ -7733,7 +7977,7 @@ Please use command_status to check the result and report back to the user.`;
7733
7977
  }
7734
7978
  );
7735
7979
  } else if (parsed.type === "tool_call") {
7736
- const nextId2 = history.length;
7980
+ const nextId3 = history.length;
7737
7981
  newComponent = /* @__PURE__ */ jsx17(
7738
7982
  ToolCallDisplay,
7739
7983
  {
@@ -7926,9 +8170,9 @@ async function runAgentMode() {
7926
8170
  try {
7927
8171
  if (inputFileIndex !== -1 && args[inputFileIndex + 1]) {
7928
8172
  const filePath = args[inputFileIndex + 1];
7929
- rawPayload = fs14.readFileSync(filePath, "utf-8");
8173
+ rawPayload = fs15.readFileSync(filePath, "utf-8");
7930
8174
  } else {
7931
- rawPayload = fs14.readFileSync(0, "utf-8");
8175
+ rawPayload = fs15.readFileSync(0, "utf-8");
7932
8176
  }
7933
8177
  } catch (err) {
7934
8178
  writeJsonl({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",