@nomad-e/bluma-cli 0.1.26 → 0.1.27

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 +307 -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,170 @@ ${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 memoryStore = [];
3432
+ var nextId2 = 1;
3433
+ var loaded = false;
3434
+ function getMemoryFilePath() {
3435
+ return path10.join(os4.homedir(), ".bluma", "coding_memory.json");
3436
+ }
3437
+ function getLegacyMemoryFilePath() {
3438
+ return path10.join(process.cwd(), ".bluma", "coding_memory.json");
3439
+ }
3440
+ function loadMemoryFromFile() {
3441
+ if (loaded) return;
3442
+ loaded = true;
3443
+ memoryStore = [];
3444
+ nextId2 = 1;
3445
+ try {
3446
+ const filePath = getMemoryFilePath();
3447
+ const legacy = getLegacyMemoryFilePath();
3448
+ const legacyDistinct = path10.resolve(legacy) !== path10.resolve(filePath);
3449
+ const readIntoStore = (p) => {
3450
+ const raw = fs8.readFileSync(p, "utf-8");
3451
+ const parsed = JSON.parse(raw);
3452
+ if (Array.isArray(parsed.entries)) {
3453
+ memoryStore = parsed.entries;
3454
+ nextId2 = typeof parsed.nextId === "number" ? parsed.nextId : memoryStore.length + 1;
3455
+ }
3456
+ };
3457
+ if (fs8.existsSync(filePath)) {
3458
+ readIntoStore(filePath);
3459
+ }
3460
+ if (memoryStore.length === 0 && legacyDistinct && fs8.existsSync(legacy)) {
3461
+ readIntoStore(legacy);
3462
+ if (memoryStore.length > 0) {
3463
+ saveMemoryToFile();
3464
+ }
3465
+ }
3466
+ } catch {
3467
+ memoryStore = [];
3468
+ nextId2 = 1;
3469
+ }
3470
+ }
3471
+ function saveMemoryToFile() {
3472
+ try {
3473
+ const filePath = getMemoryFilePath();
3474
+ const dir = path10.dirname(filePath);
3475
+ if (!fs8.existsSync(dir)) {
3476
+ fs8.mkdirSync(dir, { recursive: true });
3477
+ }
3478
+ const payload = {
3479
+ entries: memoryStore,
3480
+ nextId: nextId2,
3481
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3482
+ };
3483
+ fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2));
3484
+ } catch {
3485
+ }
3486
+ }
3487
+ function normalizeTags(tags) {
3488
+ if (!tags) return [];
3489
+ return tags.map((t) => typeof t === "string" ? t.trim() : "").filter((t) => t.length > 0).slice(0, 10);
3490
+ }
3491
+ function addNote(args) {
3492
+ loadMemoryFromFile();
3493
+ const note = (args.note || "").trim();
3494
+ if (!note) {
3495
+ return {
3496
+ success: false,
3497
+ message: "note is required for action=add",
3498
+ entries: memoryStore
3499
+ };
3500
+ }
3501
+ if (note.length > 4e3) {
3502
+ return {
3503
+ success: false,
3504
+ message: "note too long (max 4000 chars)",
3505
+ entries: memoryStore
3506
+ };
3507
+ }
3508
+ const entry = {
3509
+ id: nextId2++,
3510
+ note,
3511
+ tags: normalizeTags(args.tags),
3512
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3513
+ usageCount: 0
3514
+ };
3515
+ memoryStore.push(entry);
3516
+ saveMemoryToFile();
3517
+ return {
3518
+ success: true,
3519
+ message: "Memory entry added",
3520
+ entries: memoryStore
3521
+ };
3522
+ }
3523
+ function listNotes() {
3524
+ loadMemoryFromFile();
3525
+ return {
3526
+ success: true,
3527
+ message: memoryStore.length === 0 ? "No coding memory entries yet" : `Listing ${memoryStore.length} coding memory entries`,
3528
+ entries: memoryStore
3529
+ };
3530
+ }
3531
+ function searchNotes(args) {
3532
+ loadMemoryFromFile();
3533
+ const query = (args.query || "").trim();
3534
+ if (!query) {
3535
+ return {
3536
+ success: false,
3537
+ message: "query is required for action=search",
3538
+ entries: memoryStore,
3539
+ matched: []
3540
+ };
3541
+ }
3542
+ const lower = query.toLowerCase();
3543
+ const matches = memoryStore.filter((e) => {
3544
+ if (e.note.toLowerCase().includes(lower)) return true;
3545
+ return e.tags.some((t) => t.toLowerCase().includes(lower));
3546
+ });
3547
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3548
+ for (const entry of matches) {
3549
+ entry.lastUsedAt = nowIso;
3550
+ entry.usageCount = (entry.usageCount || 0) + 1;
3551
+ }
3552
+ saveMemoryToFile();
3553
+ return {
3554
+ success: true,
3555
+ message: matches.length === 0 ? "No matching coding memory entries" : `Found ${matches.length} matching entries`,
3556
+ entries: memoryStore,
3557
+ matched: matches
3558
+ };
3559
+ }
3560
+ function clearNotes() {
3561
+ loadMemoryFromFile();
3562
+ memoryStore = [];
3563
+ nextId2 = 1;
3564
+ saveMemoryToFile();
3565
+ return {
3566
+ success: true,
3567
+ message: "All coding memory entries cleared",
3568
+ entries: memoryStore
3569
+ };
3570
+ }
3571
+ async function coding_memory(args) {
3572
+ const action = args.action;
3573
+ switch (action) {
3574
+ case "add":
3575
+ return addNote(args);
3576
+ case "list":
3577
+ return listNotes();
3578
+ case "search":
3579
+ return searchNotes(args);
3580
+ case "clear":
3581
+ return clearNotes();
3582
+ default:
3583
+ return {
3584
+ success: false,
3585
+ message: `Unknown action: ${String(action)}`,
3586
+ entries: memoryStore
3587
+ };
3588
+ }
3589
+ }
3590
+
3427
3591
  // src/app/agent/tool_invoker.ts
3428
3592
  var ToolInvoker = class {
3429
3593
  // Mapa privado para associar nomes de ferramentas às suas funções de implementação.
@@ -3441,9 +3605,9 @@ var ToolInvoker = class {
3441
3605
  async initialize() {
3442
3606
  try {
3443
3607
  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");
3608
+ const __dirname2 = path11.dirname(__filename);
3609
+ const configPath = path11.resolve(__dirname2, "config", "native_tools.json");
3610
+ const fileContent = await fs9.readFile(configPath, "utf-8");
3447
3611
  const config2 = JSON.parse(fileContent);
3448
3612
  this.toolDefinitions = config2.nativeTools;
3449
3613
  } catch (error) {
@@ -3474,6 +3638,7 @@ var ToolInvoker = class {
3474
3638
  this.toolImplementations.set("read_artifact", readArtifact);
3475
3639
  this.toolImplementations.set("search_web", searchWeb);
3476
3640
  this.toolImplementations.set("load_skill", loadSkill);
3641
+ this.toolImplementations.set("coding_memory", coding_memory);
3477
3642
  }
3478
3643
  /**
3479
3644
  * Retorna a lista de definições de todas as ferramentas nativas carregadas.
@@ -3503,9 +3668,9 @@ var ToolInvoker = class {
3503
3668
  };
3504
3669
 
3505
3670
  // 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";
3671
+ import { promises as fs10 } from "fs";
3672
+ import path12 from "path";
3673
+ import os5 from "os";
3509
3674
  import { fileURLToPath as fileURLToPath2 } from "url";
3510
3675
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3511
3676
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
@@ -3532,9 +3697,9 @@ var MCPClient = class {
3532
3697
  });
3533
3698
  }
3534
3699
  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");
3700
+ const __dirname2 = path12.dirname(__filename);
3701
+ const defaultConfigPath = path12.resolve(__dirname2, "config", "bluma-mcp.json");
3702
+ const userConfigPath = path12.join(os5.homedir(), ".bluma", "bluma-mcp.json");
3538
3703
  const defaultConfig = await this.loadMcpConfig(defaultConfigPath, "Default");
3539
3704
  const userConfig = await this.loadMcpConfig(userConfigPath, "User");
3540
3705
  const mergedConfig = {
@@ -3568,7 +3733,7 @@ var MCPClient = class {
3568
3733
  }
3569
3734
  async loadMcpConfig(configPath, configType) {
3570
3735
  try {
3571
- const fileContent = await fs9.readFile(configPath, "utf-8");
3736
+ const fileContent = await fs10.readFile(configPath, "utf-8");
3572
3737
  const processedContent = this.replaceEnvPlaceholders(fileContent);
3573
3738
  return JSON.parse(processedContent);
3574
3739
  } catch (error) {
@@ -3587,7 +3752,7 @@ var MCPClient = class {
3587
3752
  async connectToStdioServer(serverName, config2) {
3588
3753
  let commandToExecute = config2.command;
3589
3754
  let argsToExecute = config2.args || [];
3590
- const isWindows = os4.platform() === "win32";
3755
+ const isWindows = os5.platform() === "win32";
3591
3756
  if (!isWindows && commandToExecute.toLowerCase() === "cmd") {
3592
3757
  if (argsToExecute.length >= 2 && argsToExecute[0].toLowerCase() === "/c") {
3593
3758
  commandToExecute = argsToExecute[1];
@@ -3703,13 +3868,13 @@ var AdvancedFeedbackSystem = class {
3703
3868
  };
3704
3869
 
3705
3870
  // src/app/agent/bluma/core/bluma.ts
3706
- import path15 from "path";
3871
+ import path16 from "path";
3707
3872
  import { v4 as uuidv43 } from "uuid";
3708
3873
 
3709
3874
  // 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";
3875
+ import path13 from "path";
3876
+ import os6 from "os";
3877
+ import { promises as fs11 } from "fs";
3713
3878
  var fileLocks = /* @__PURE__ */ new Map();
3714
3879
  async function withFileLock(file, fn) {
3715
3880
  const prev = fileLocks.get(file) || Promise.resolve();
@@ -3744,13 +3909,13 @@ function debouncedSave(sessionFile, history) {
3744
3909
  function expandHome(p) {
3745
3910
  if (!p) return p;
3746
3911
  if (p.startsWith("~")) {
3747
- return path12.join(os5.homedir(), p.slice(1));
3912
+ return path13.join(os6.homedir(), p.slice(1));
3748
3913
  }
3749
3914
  return p;
3750
3915
  }
3751
3916
  function getPreferredAppDir() {
3752
- const fixed = path12.join(os5.homedir(), ".bluma");
3753
- return path12.resolve(expandHome(fixed));
3917
+ const fixed = path13.join(os6.homedir(), ".bluma");
3918
+ return path13.resolve(expandHome(fixed));
3754
3919
  }
3755
3920
  async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3756
3921
  let attempt = 0;
@@ -3758,10 +3923,10 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3758
3923
  const isWin = process.platform === "win32";
3759
3924
  while (attempt <= maxRetries) {
3760
3925
  try {
3761
- const dir = path12.dirname(dest);
3762
- await fs10.mkdir(dir, { recursive: true }).catch(() => {
3926
+ const dir = path13.dirname(dest);
3927
+ await fs11.mkdir(dir, { recursive: true }).catch(() => {
3763
3928
  });
3764
- await fs10.rename(src, dest);
3929
+ await fs11.rename(src, dest);
3765
3930
  return;
3766
3931
  } catch (e) {
3767
3932
  lastErr = e;
@@ -3774,13 +3939,13 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3774
3939
  }
3775
3940
  }
3776
3941
  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(() => {
3942
+ await fs11.access(src);
3943
+ const data = await fs11.readFile(src);
3944
+ const dir = path13.dirname(dest);
3945
+ await fs11.mkdir(dir, { recursive: true }).catch(() => {
3781
3946
  });
3782
- await fs10.writeFile(dest, data);
3783
- await fs10.unlink(src).catch(() => {
3947
+ await fs11.writeFile(dest, data);
3948
+ await fs11.unlink(src).catch(() => {
3784
3949
  });
3785
3950
  return;
3786
3951
  } catch (fallbackErr) {
@@ -3793,16 +3958,16 @@ async function safeRenameWithRetry(src, dest, maxRetries = 6) {
3793
3958
  }
3794
3959
  async function ensureSessionDir() {
3795
3960
  const appDir = getPreferredAppDir();
3796
- const sessionDir = path12.join(appDir, "sessions");
3797
- await fs10.mkdir(sessionDir, { recursive: true });
3961
+ const sessionDir = path13.join(appDir, "sessions");
3962
+ await fs11.mkdir(sessionDir, { recursive: true });
3798
3963
  return sessionDir;
3799
3964
  }
3800
3965
  async function loadOrcreateSession(sessionId) {
3801
3966
  const sessionDir = await ensureSessionDir();
3802
- const sessionFile = path12.join(sessionDir, `${sessionId}.json`);
3967
+ const sessionFile = path13.join(sessionDir, `${sessionId}.json`);
3803
3968
  try {
3804
- await fs10.access(sessionFile);
3805
- const fileContent = await fs10.readFile(sessionFile, "utf-8");
3969
+ await fs11.access(sessionFile);
3970
+ const fileContent = await fs11.readFile(sessionFile, "utf-8");
3806
3971
  const sessionData = JSON.parse(fileContent);
3807
3972
  return [sessionFile, sessionData.conversation_history || [], []];
3808
3973
  } catch (error) {
@@ -3811,7 +3976,7 @@ async function loadOrcreateSession(sessionId) {
3811
3976
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
3812
3977
  conversation_history: []
3813
3978
  };
3814
- await fs10.writeFile(sessionFile, JSON.stringify(newSessionData, null, 2), "utf-8");
3979
+ await fs11.writeFile(sessionFile, JSON.stringify(newSessionData, null, 2), "utf-8");
3815
3980
  return [sessionFile, [], []];
3816
3981
  }
3817
3982
  }
@@ -3819,12 +3984,12 @@ async function doSaveSessionHistory(sessionFile, history) {
3819
3984
  await withFileLock(sessionFile, async () => {
3820
3985
  let sessionData;
3821
3986
  try {
3822
- const dir = path12.dirname(sessionFile);
3823
- await fs10.mkdir(dir, { recursive: true });
3987
+ const dir = path13.dirname(sessionFile);
3988
+ await fs11.mkdir(dir, { recursive: true });
3824
3989
  } catch {
3825
3990
  }
3826
3991
  try {
3827
- const fileContent = await fs10.readFile(sessionFile, "utf-8");
3992
+ const fileContent = await fs11.readFile(sessionFile, "utf-8");
3828
3993
  sessionData = JSON.parse(fileContent);
3829
3994
  } catch (error) {
3830
3995
  const code = error && error.code;
@@ -3835,14 +4000,14 @@ async function doSaveSessionHistory(sessionFile, history) {
3835
4000
  console.warn(`An unknown error occurred while reading ${sessionFile}. Re-initializing.`, error);
3836
4001
  }
3837
4002
  }
3838
- const sessionId = path12.basename(sessionFile, ".json");
4003
+ const sessionId = path13.basename(sessionFile, ".json");
3839
4004
  sessionData = {
3840
4005
  session_id: sessionId,
3841
4006
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
3842
4007
  conversation_history: []
3843
4008
  };
3844
4009
  try {
3845
- await fs10.writeFile(sessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
4010
+ await fs11.writeFile(sessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
3846
4011
  } catch {
3847
4012
  }
3848
4013
  }
@@ -3850,7 +4015,7 @@ async function doSaveSessionHistory(sessionFile, history) {
3850
4015
  sessionData.last_updated = (/* @__PURE__ */ new Date()).toISOString();
3851
4016
  const tempSessionFile = `${sessionFile}.${Date.now()}.tmp`;
3852
4017
  try {
3853
- await fs10.writeFile(tempSessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
4018
+ await fs11.writeFile(tempSessionFile, JSON.stringify(sessionData, null, 2), "utf-8");
3854
4019
  await safeRenameWithRetry(tempSessionFile, sessionFile);
3855
4020
  } catch (writeError) {
3856
4021
  if (writeError instanceof Error) {
@@ -3859,7 +4024,7 @@ async function doSaveSessionHistory(sessionFile, history) {
3859
4024
  console.error(`An unknown fatal error occurred while saving session to ${sessionFile}:`, writeError);
3860
4025
  }
3861
4026
  try {
3862
- await fs10.unlink(tempSessionFile);
4027
+ await fs11.unlink(tempSessionFile);
3863
4028
  } catch {
3864
4029
  }
3865
4030
  }
@@ -3876,15 +4041,15 @@ async function saveSessionHistory(sessionFile, history) {
3876
4041
  }
3877
4042
 
3878
4043
  // src/app/agent/core/prompt/prompt_builder.ts
3879
- import os7 from "os";
3880
- import fs12 from "fs";
3881
- import path14 from "path";
4044
+ import os8 from "os";
4045
+ import fs13 from "fs";
4046
+ import path15 from "path";
3882
4047
  import { execSync } from "child_process";
3883
4048
 
3884
4049
  // src/app/agent/skills/skill_loader.ts
3885
- import fs11 from "fs";
3886
- import path13 from "path";
3887
- import os6 from "os";
4050
+ import fs12 from "fs";
4051
+ import path14 from "path";
4052
+ import os7 from "os";
3888
4053
  import { fileURLToPath as fileURLToPath3 } from "url";
3889
4054
  var SkillLoader = class _SkillLoader {
3890
4055
  bundledSkillsDir;
@@ -3893,8 +4058,8 @@ var SkillLoader = class _SkillLoader {
3893
4058
  cache = /* @__PURE__ */ new Map();
3894
4059
  conflicts = [];
3895
4060
  constructor(projectRoot, bundledDir) {
3896
- this.projectSkillsDir = path13.join(projectRoot, ".bluma", "skills");
3897
- this.globalSkillsDir = path13.join(os6.homedir(), ".bluma", "skills");
4061
+ this.projectSkillsDir = path14.join(projectRoot, ".bluma", "skills");
4062
+ this.globalSkillsDir = path14.join(os7.homedir(), ".bluma", "skills");
3898
4063
  this.bundledSkillsDir = bundledDir || _SkillLoader.resolveBundledDir();
3899
4064
  }
3900
4065
  /**
@@ -3904,16 +4069,16 @@ var SkillLoader = class _SkillLoader {
3904
4069
  static resolveBundledDir() {
3905
4070
  if (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) {
3906
4071
  if (typeof __dirname !== "undefined") {
3907
- return path13.join(__dirname, "config", "skills");
4072
+ return path14.join(__dirname, "config", "skills");
3908
4073
  }
3909
- return path13.join(process.cwd(), "dist", "config", "skills");
4074
+ return path14.join(process.cwd(), "dist", "config", "skills");
3910
4075
  }
3911
4076
  try {
3912
4077
  const currentFile = fileURLToPath3(import.meta.url);
3913
- const distDir = path13.dirname(currentFile);
3914
- return path13.join(distDir, "config", "skills");
4078
+ const distDir = path14.dirname(currentFile);
4079
+ return path14.join(distDir, "config", "skills");
3915
4080
  } catch {
3916
- return path13.join(process.cwd(), "dist", "config", "skills");
4081
+ return path14.join(process.cwd(), "dist", "config", "skills");
3917
4082
  }
3918
4083
  }
3919
4084
  /**
@@ -3942,8 +4107,8 @@ var SkillLoader = class _SkillLoader {
3942
4107
  this.conflicts.push({
3943
4108
  name: skill.name,
3944
4109
  userSource: source,
3945
- userPath: path13.join(dir, skill.name, "SKILL.md"),
3946
- bundledPath: path13.join(this.bundledSkillsDir, skill.name, "SKILL.md")
4110
+ userPath: path14.join(dir, skill.name, "SKILL.md"),
4111
+ bundledPath: path14.join(this.bundledSkillsDir, skill.name, "SKILL.md")
3947
4112
  });
3948
4113
  continue;
3949
4114
  }
@@ -3951,20 +4116,20 @@ var SkillLoader = class _SkillLoader {
3951
4116
  }
3952
4117
  }
3953
4118
  listFromDir(dir, source) {
3954
- if (!fs11.existsSync(dir)) return [];
4119
+ if (!fs12.existsSync(dir)) return [];
3955
4120
  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);
4121
+ return fs12.readdirSync(dir).filter((d) => {
4122
+ const fullPath = path14.join(dir, d);
4123
+ return fs12.statSync(fullPath).isDirectory() && fs12.existsSync(path14.join(fullPath, "SKILL.md"));
4124
+ }).map((d) => this.loadMetadataFromPath(path14.join(dir, d, "SKILL.md"), d, source)).filter((m) => m !== null);
3960
4125
  } catch {
3961
4126
  return [];
3962
4127
  }
3963
4128
  }
3964
4129
  loadMetadataFromPath(skillPath, skillName, source) {
3965
- if (!fs11.existsSync(skillPath)) return null;
4130
+ if (!fs12.existsSync(skillPath)) return null;
3966
4131
  try {
3967
- const raw = fs11.readFileSync(skillPath, "utf-8");
4132
+ const raw = fs12.readFileSync(skillPath, "utf-8");
3968
4133
  const parsed = this.parseFrontmatter(raw);
3969
4134
  return {
3970
4135
  name: parsed.name || skillName,
@@ -3986,12 +4151,12 @@ var SkillLoader = class _SkillLoader {
3986
4151
  */
3987
4152
  load(name) {
3988
4153
  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);
4154
+ const bundledPath = path14.join(this.bundledSkillsDir, name, "SKILL.md");
4155
+ const projectPath = path14.join(this.projectSkillsDir, name, "SKILL.md");
4156
+ const globalPath = path14.join(this.globalSkillsDir, name, "SKILL.md");
4157
+ const existsBundled = fs12.existsSync(bundledPath);
4158
+ const existsProject = fs12.existsSync(projectPath);
4159
+ const existsGlobal = fs12.existsSync(globalPath);
3995
4160
  if (existsBundled && (existsProject || existsGlobal)) {
3996
4161
  const conflictSource = existsProject ? "project" : "global";
3997
4162
  const conflictPath = existsProject ? projectPath : globalPath;
@@ -4030,9 +4195,9 @@ var SkillLoader = class _SkillLoader {
4030
4195
  }
4031
4196
  loadFromPath(skillPath, name, source) {
4032
4197
  try {
4033
- const raw = fs11.readFileSync(skillPath, "utf-8");
4198
+ const raw = fs12.readFileSync(skillPath, "utf-8");
4034
4199
  const parsed = this.parseFrontmatter(raw);
4035
- const skillDir = path13.dirname(skillPath);
4200
+ const skillDir = path14.dirname(skillPath);
4036
4201
  return {
4037
4202
  name: parsed.name || name,
4038
4203
  description: parsed.description || "",
@@ -4041,22 +4206,22 @@ var SkillLoader = class _SkillLoader {
4041
4206
  version: parsed.version,
4042
4207
  author: parsed.author,
4043
4208
  license: parsed.license,
4044
- references: this.scanAssets(path13.join(skillDir, "references")),
4045
- scripts: this.scanAssets(path13.join(skillDir, "scripts"))
4209
+ references: this.scanAssets(path14.join(skillDir, "references")),
4210
+ scripts: this.scanAssets(path14.join(skillDir, "scripts"))
4046
4211
  };
4047
4212
  } catch {
4048
4213
  return null;
4049
4214
  }
4050
4215
  }
4051
4216
  scanAssets(dir) {
4052
- if (!fs11.existsSync(dir)) return [];
4217
+ if (!fs12.existsSync(dir)) return [];
4053
4218
  try {
4054
- return fs11.readdirSync(dir).filter((f) => {
4055
- const fp = path13.join(dir, f);
4056
- return fs11.statSync(fp).isFile();
4219
+ return fs12.readdirSync(dir).filter((f) => {
4220
+ const fp = path14.join(dir, f);
4221
+ return fs12.statSync(fp).isFile();
4057
4222
  }).map((f) => ({
4058
4223
  name: f,
4059
- path: path13.resolve(dir, f)
4224
+ path: path14.resolve(dir, f)
4060
4225
  }));
4061
4226
  } catch {
4062
4227
  return [];
@@ -4113,10 +4278,10 @@ var SkillLoader = class _SkillLoader {
4113
4278
  this.cache.clear();
4114
4279
  }
4115
4280
  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);
4281
+ const bundledPath = path14.join(this.bundledSkillsDir, name, "SKILL.md");
4282
+ const projectPath = path14.join(this.projectSkillsDir, name, "SKILL.md");
4283
+ const globalPath = path14.join(this.globalSkillsDir, name, "SKILL.md");
4284
+ return fs12.existsSync(bundledPath) || fs12.existsSync(projectPath) || fs12.existsSync(globalPath);
4120
4285
  }
4121
4286
  /**
4122
4287
  * Retorna conflitos detetados (skills do utilizador com mesmo nome de nativas).
@@ -4175,10 +4340,10 @@ function getGitBranch(dir) {
4175
4340
  }
4176
4341
  function getPackageManager(dir) {
4177
4342
  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";
4343
+ if (fs13.existsSync(path15.join(dir, "pnpm-lock.yaml"))) return "pnpm";
4344
+ if (fs13.existsSync(path15.join(dir, "yarn.lock"))) return "yarn";
4345
+ if (fs13.existsSync(path15.join(dir, "bun.lockb"))) return "bun";
4346
+ if (fs13.existsSync(path15.join(dir, "package-lock.json"))) return "npm";
4182
4347
  return "unknown";
4183
4348
  } catch {
4184
4349
  return "unknown";
@@ -4186,9 +4351,9 @@ function getPackageManager(dir) {
4186
4351
  }
4187
4352
  function getProjectType(dir) {
4188
4353
  try {
4189
- const files = fs12.readdirSync(dir);
4354
+ const files = fs13.readdirSync(dir);
4190
4355
  if (files.includes("package.json")) {
4191
- const pkg = JSON.parse(fs12.readFileSync(path14.join(dir, "package.json"), "utf-8"));
4356
+ const pkg = JSON.parse(fs13.readFileSync(path15.join(dir, "package.json"), "utf-8"));
4192
4357
  if (pkg.dependencies?.next || pkg.devDependencies?.next) return "Next.js";
4193
4358
  if (pkg.dependencies?.react || pkg.devDependencies?.react) return "React";
4194
4359
  if (pkg.dependencies?.express || pkg.devDependencies?.express) return "Express";
@@ -4207,9 +4372,9 @@ function getProjectType(dir) {
4207
4372
  }
4208
4373
  function getTestFramework(dir) {
4209
4374
  try {
4210
- const pkgPath = path14.join(dir, "package.json");
4211
- if (fs12.existsSync(pkgPath)) {
4212
- const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
4375
+ const pkgPath = path15.join(dir, "package.json");
4376
+ if (fs13.existsSync(pkgPath)) {
4377
+ const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf-8"));
4213
4378
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
4214
4379
  if (deps.jest) return "jest";
4215
4380
  if (deps.vitest) return "vitest";
@@ -4218,7 +4383,7 @@ function getTestFramework(dir) {
4218
4383
  if (deps["@playwright/test"]) return "playwright";
4219
4384
  if (deps.cypress) return "cypress";
4220
4385
  }
4221
- if (fs12.existsSync(path14.join(dir, "pytest.ini")) || fs12.existsSync(path14.join(dir, "conftest.py"))) return "pytest";
4386
+ if (fs13.existsSync(path15.join(dir, "pytest.ini")) || fs13.existsSync(path15.join(dir, "conftest.py"))) return "pytest";
4222
4387
  return "unknown";
4223
4388
  } catch {
4224
4389
  return "unknown";
@@ -4226,9 +4391,9 @@ function getTestFramework(dir) {
4226
4391
  }
4227
4392
  function getTestCommand(dir) {
4228
4393
  try {
4229
- const pkgPath = path14.join(dir, "package.json");
4230
- if (fs12.existsSync(pkgPath)) {
4231
- const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
4394
+ const pkgPath = path15.join(dir, "package.json");
4395
+ if (fs13.existsSync(pkgPath)) {
4396
+ const pkg = JSON.parse(fs13.readFileSync(pkgPath, "utf-8"));
4232
4397
  if (pkg.scripts?.test) return `npm test`;
4233
4398
  if (pkg.scripts?.["test:unit"]) return `npm run test:unit`;
4234
4399
  }
@@ -4664,12 +4829,12 @@ In sandbox mode you are a Python-focused, non-interactive, deterministic agent t
4664
4829
  function getUnifiedSystemPrompt(availableSkills) {
4665
4830
  const cwd = process.cwd();
4666
4831
  const env = {
4667
- os_type: os7.type(),
4668
- os_version: os7.release(),
4669
- architecture: os7.arch(),
4832
+ os_type: os8.type(),
4833
+ os_version: os8.release(),
4834
+ architecture: os8.arch(),
4670
4835
  workdir: cwd,
4671
4836
  shell_type: process.env.SHELL || process.env.COMSPEC || "unknown",
4672
- username: os7.userInfo().username,
4837
+ username: os8.userInfo().username,
4673
4838
  current_date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
4674
4839
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
4675
4840
  is_git_repo: isGitRepo(cwd) ? "yes" : "no",
@@ -4843,8 +5008,8 @@ User: "Publish the package"
4843
5008
  }
4844
5009
  function isGitRepo(dir) {
4845
5010
  try {
4846
- const gitPath = path14.join(dir, ".git");
4847
- return fs12.existsSync(gitPath) && fs12.lstatSync(gitPath).isDirectory();
5011
+ const gitPath = path15.join(dir, ".git");
5012
+ return fs13.existsSync(gitPath) && fs13.lstatSync(gitPath).isDirectory();
4848
5013
  } catch {
4849
5014
  return false;
4850
5015
  }
@@ -4915,7 +5080,7 @@ function createApiContextWindow(fullHistory, maxTurns) {
4915
5080
  }
4916
5081
 
4917
5082
  // src/app/agent/core/llm/llm.ts
4918
- import os8 from "os";
5083
+ import os9 from "os";
4919
5084
  import OpenAI from "openai";
4920
5085
  function defaultBlumaUserContextInput(sessionId, userMessage) {
4921
5086
  const msg = String(userMessage || "").slice(0, 300);
@@ -4932,7 +5097,7 @@ function defaultBlumaUserContextInput(sessionId, userMessage) {
4932
5097
  }
4933
5098
  function getPreferredMacAddress() {
4934
5099
  try {
4935
- const ifaces = os8.networkInterfaces();
5100
+ const ifaces = os9.networkInterfaces();
4936
5101
  for (const name of Object.keys(ifaces)) {
4937
5102
  const addrs = ifaces[name];
4938
5103
  if (!addrs) continue;
@@ -4947,7 +5112,7 @@ function getPreferredMacAddress() {
4947
5112
  } catch {
4948
5113
  }
4949
5114
  try {
4950
- return `host:${os8.hostname()}`;
5115
+ return `host:${os9.hostname()}`;
4951
5116
  } catch {
4952
5117
  return "unknown";
4953
5118
  }
@@ -4957,7 +5122,7 @@ function defaultInteractiveCliUserContextInput(sessionId, userMessage) {
4957
5122
  const machineId = getPreferredMacAddress();
4958
5123
  let userName = null;
4959
5124
  try {
4960
- userName = os8.userInfo().username || null;
5125
+ userName = os9.userInfo().username || null;
4961
5126
  } catch {
4962
5127
  userName = null;
4963
5128
  }
@@ -5532,7 +5697,7 @@ var BluMaAgent = class {
5532
5697
 
5533
5698
  ${editData.error.display}`;
5534
5699
  }
5535
- const filename = path15.basename(toolArgs.file_path);
5700
+ const filename = path16.basename(toolArgs.file_path);
5536
5701
  return createDiff(filename, editData.currentContent || "", editData.newContent);
5537
5702
  } catch (e) {
5538
5703
  return `An unexpected error occurred while generating the edit preview: ${e.message}`;
@@ -5770,7 +5935,7 @@ import { v4 as uuidv45 } from "uuid";
5770
5935
  import { v4 as uuidv44 } from "uuid";
5771
5936
 
5772
5937
  // src/app/agent/subagents/init/init_system_prompt.ts
5773
- import os9 from "os";
5938
+ import os10 from "os";
5774
5939
  var SYSTEM_PROMPT2 = `
5775
5940
 
5776
5941
  ### YOU ARE BluMa CLI \u2014 INIT SUBAGENT \u2014 AUTONOMOUS SENIOR SOFTWARE ENGINEER @ NOMADENGENUITY
@@ -5933,12 +6098,12 @@ Rule Summary:
5933
6098
  function getInitPrompt() {
5934
6099
  const now = /* @__PURE__ */ new Date();
5935
6100
  const collectedData = {
5936
- os_type: os9.type(),
5937
- os_version: os9.release(),
5938
- architecture: os9.arch(),
6101
+ os_type: os10.type(),
6102
+ os_version: os10.release(),
6103
+ architecture: os10.arch(),
5939
6104
  workdir: process.cwd(),
5940
6105
  shell_type: process.env.SHELL || process.env.COMSPEC || "Unknown",
5941
- username: os9.userInfo().username || "Unknown",
6106
+ username: os10.userInfo().username || "Unknown",
5942
6107
  current_date: now.toISOString().split("T")[0],
5943
6108
  // Formato YYYY-MM-DD
5944
6109
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "Unknown",
@@ -6219,14 +6384,14 @@ var RouteManager = class {
6219
6384
  this.subAgents = subAgents;
6220
6385
  this.core = core;
6221
6386
  }
6222
- registerRoute(path18, handler) {
6223
- this.routeHandlers.set(path18, handler);
6387
+ registerRoute(path19, handler) {
6388
+ this.routeHandlers.set(path19, handler);
6224
6389
  }
6225
6390
  async handleRoute(payload) {
6226
6391
  const inputText = String(payload.content || "").trim();
6227
6392
  const { userContext } = payload;
6228
- for (const [path18, handler] of this.routeHandlers) {
6229
- if (inputText === path18 || inputText.startsWith(`${path18} `)) {
6393
+ for (const [path19, handler] of this.routeHandlers) {
6394
+ if (inputText === path19 || inputText.startsWith(`${path19} `)) {
6230
6395
  return handler({ content: inputText, userContext });
6231
6396
  }
6232
6397
  }
@@ -6235,7 +6400,7 @@ var RouteManager = class {
6235
6400
  };
6236
6401
 
6237
6402
  // src/app/agent/agent.ts
6238
- var globalEnvPath = path16.join(os10.homedir(), ".bluma", ".env");
6403
+ var globalEnvPath = path17.join(os11.homedir(), ".bluma", ".env");
6239
6404
  dotenv.config({ path: globalEnvPath });
6240
6405
  var Agent = class {
6241
6406
  sessionId;
@@ -6462,12 +6627,12 @@ var renderShellCommand2 = ({ args }) => {
6462
6627
  };
6463
6628
  var renderLsTool2 = ({ args }) => {
6464
6629
  const parsed = parseArgs(args);
6465
- const path18 = parsed.directory_path || ".";
6630
+ const path19 = parsed.directory_path || ".";
6466
6631
  return /* @__PURE__ */ jsxs8(Box8, { paddingX: 1, children: [
6467
6632
  /* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "ls" }),
6468
6633
  /* @__PURE__ */ jsxs8(Text8, { children: [
6469
6634
  " ",
6470
- path18
6635
+ path19
6471
6636
  ] })
6472
6637
  ] });
6473
6638
  };
@@ -6598,7 +6763,7 @@ var renderFindByName = ({ args }) => {
6598
6763
  var renderGrepSearch = ({ args }) => {
6599
6764
  const parsed = parseArgs(args);
6600
6765
  const query = parsed.query || "";
6601
- const path18 = parsed.path || ".";
6766
+ const path19 = parsed.path || ".";
6602
6767
  return /* @__PURE__ */ jsxs8(Box8, { paddingX: 1, children: [
6603
6768
  /* @__PURE__ */ jsx8(Text8, { color: "white", bold: true, children: "grep" }),
6604
6769
  /* @__PURE__ */ jsxs8(Text8, { color: "white", children: [
@@ -6608,7 +6773,7 @@ var renderGrepSearch = ({ args }) => {
6608
6773
  ] }),
6609
6774
  /* @__PURE__ */ jsxs8(Text8, { children: [
6610
6775
  " ",
6611
- path18
6776
+ path19
6612
6777
  ] })
6613
6778
  ] });
6614
6779
  };
@@ -7226,16 +7391,16 @@ var SlashCommands_default = SlashCommands;
7226
7391
  // src/app/agent/utils/update_check.ts
7227
7392
  import updateNotifier from "update-notifier";
7228
7393
  import { fileURLToPath as fileURLToPath4 } from "url";
7229
- import path17 from "path";
7230
- import fs13 from "fs";
7394
+ import path18 from "path";
7395
+ import fs14 from "fs";
7231
7396
  var BLUMA_PACKAGE_NAME = "@nomad-e/bluma-cli";
7232
7397
  function findBlumaPackageJson(startDir) {
7233
7398
  let dir = startDir;
7234
7399
  for (let i = 0; i < 10; i++) {
7235
- const candidate = path17.join(dir, "package.json");
7236
- if (fs13.existsSync(candidate)) {
7400
+ const candidate = path18.join(dir, "package.json");
7401
+ if (fs14.existsSync(candidate)) {
7237
7402
  try {
7238
- const raw = fs13.readFileSync(candidate, "utf8");
7403
+ const raw = fs14.readFileSync(candidate, "utf8");
7239
7404
  const parsed = JSON.parse(raw);
7240
7405
  if (parsed?.name === BLUMA_PACKAGE_NAME && parsed?.version) {
7241
7406
  return { name: parsed.name, version: parsed.version };
@@ -7243,7 +7408,7 @@ function findBlumaPackageJson(startDir) {
7243
7408
  } catch {
7244
7409
  }
7245
7410
  }
7246
- const parent = path17.dirname(dir);
7411
+ const parent = path18.dirname(dir);
7247
7412
  if (parent === dir) break;
7248
7413
  dir = parent;
7249
7414
  }
@@ -7256,12 +7421,12 @@ async function checkForUpdates() {
7256
7421
  }
7257
7422
  const binPath = process.argv?.[1];
7258
7423
  let pkg = null;
7259
- if (binPath && fs13.existsSync(binPath)) {
7260
- pkg = findBlumaPackageJson(path17.dirname(binPath));
7424
+ if (binPath && fs14.existsSync(binPath)) {
7425
+ pkg = findBlumaPackageJson(path18.dirname(binPath));
7261
7426
  }
7262
7427
  if (!pkg) {
7263
7428
  const __filename = fileURLToPath4(import.meta.url);
7264
- const __dirname2 = path17.dirname(__filename);
7429
+ const __dirname2 = path18.dirname(__filename);
7265
7430
  pkg = findBlumaPackageJson(__dirname2);
7266
7431
  }
7267
7432
  if (!pkg) {
@@ -7733,7 +7898,7 @@ Please use command_status to check the result and report back to the user.`;
7733
7898
  }
7734
7899
  );
7735
7900
  } else if (parsed.type === "tool_call") {
7736
- const nextId2 = history.length;
7901
+ const nextId3 = history.length;
7737
7902
  newComponent = /* @__PURE__ */ jsx17(
7738
7903
  ToolCallDisplay,
7739
7904
  {
@@ -7926,9 +8091,9 @@ async function runAgentMode() {
7926
8091
  try {
7927
8092
  if (inputFileIndex !== -1 && args[inputFileIndex + 1]) {
7928
8093
  const filePath = args[inputFileIndex + 1];
7929
- rawPayload = fs14.readFileSync(filePath, "utf-8");
8094
+ rawPayload = fs15.readFileSync(filePath, "utf-8");
7930
8095
  } else {
7931
- rawPayload = fs14.readFileSync(0, "utf-8");
8096
+ rawPayload = fs15.readFileSync(0, "utf-8");
7932
8097
  }
7933
8098
  } catch (err) {
7934
8099
  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.27",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",