@nomad-e/bluma-cli 0.6.2 β†’ 0.6.3

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/README.md CHANGED
@@ -13,6 +13,8 @@
13
13
 
14
14
  **BluMa** is an independent AI agent CLI for automation and advanced software engineering. It combines powerful tool orchestration, multi-agent coordination, and intelligent context management to help you build software faster and with higher quality.
15
15
 
16
+ **Latest Version:** v0.6.2 (2026-05-09) β€” Modular tool architecture, native clipboard, thread management, bidirectional mailbox IPC, enhanced multi-agent orchestration, and professional release engineering.
17
+
16
18
  ---
17
19
 
18
20
  ## πŸš€ Quick Start
@@ -75,18 +77,104 @@ Tools are now modularly structured in `src/app/agent/tools/` with separate UI co
75
77
  ### 🧠 **Multi-Agent Orchestration**
76
78
  - **Coordinator Mode**: Product Owner + Engineering Manager hybrid that delegates to specialist workers
77
79
  - **Parallel Execution**: Launch multiple workers concurrently for research, implementation, and verification
78
- - **Mailbox IPC**: Bidirectional communication between coordinator and workers via `send_message`, `list_mailbox_messages`, `poll_mailbox`, `signal_mailbox`
80
+ - **Mailbox IPC**: **Bidirectional file-based communication** between coordinator and workers
81
+ - **send_message**: Send follow-ups to running workers without re-spawning
82
+ - **list_mailbox_messages**: Read progress updates, permission requests, and results
83
+ - **poll_mailbox**: Poll for new messages from workers
84
+ - **signal_mailbox**: Send ack/nack/progress/heartbeat signals
85
+ - **File-based storage**: `~/.bluma/mailboxes/{session_id}.in/out/sig` (JSONL format)
79
86
  - **Worker Types**: Researchers, implementers, verifiers with specialized roles
80
87
  - **Session Registry**: Track and manage agent sessions with lifecycle events
88
+ - **Task Boundary Tracking**: Use `task_boundary` to track orchestration phases (PLANNING, EXECUTION, VERIFICATION)
81
89
 
82
90
  ### πŸ“ **Slash Commands** (80+ commands)
83
91
  Quick access to common operations across 5 categories:
84
92
 
85
- - **Session** (25+): `/clear`, `/sessions`, `/attach`, `/follow`, `/bridge`, `/status`, `/logs`, `/resume`, `/kill`, `/compact`, `/export`, `/summarize`, `/history`, `/share`, `/copy`, `/commit`, `/pr`, `/release`, `/snip`, `/collapse`, `/brief`, `/undo`, `/redo`, `/thread` (with subcommands: list/new/resume/fork/rename/archive/delete)
86
- - **Inspect** (30+): `/plugins`, `/plugin`, `/diagnostics`, `/permissions`, `/features`, `/hooks`, `/model`, `/effort`, `/style`, `/sandbox`, `/worktree`, `/statusline`, `/skills`, `/tools`, `/mcp`, `/debug-workers`, `/cost`, `/memory`, `/stats`, `/theme`, `/keybindings`, `/vim`, `/ctx`, `/dream`, `/diff`, `/editor`, `/config`, `/file`, `/search`, `/context`, `/token`, `/settings`, `/alias`, `/macro`, `/thread stats`
87
- - **Agent** (15+): `/agent`, `/agents`, `/img`, `/image`, `/init`, `/review`, `/explain`, `/fix`, `/debug`, `/bug`, `/test`, `/optimize`, `/refactor`, `/document`, `/chat`, `/code`, `/terminal`, `/template`
88
- - **Help**: `/help`
89
- - **Input**: `Ctrl+V`/`Cmd+V` (paste image/text/file), `Ctrl+Shift+I` (same as Ctrl+V)
93
+ **Session Commands** (25+):
94
+ - `/clear` - Clear current session
95
+ - `/sessions` - List all sessions
96
+ - `/attach` - Attach to existing session
97
+ - `/follow` - Follow session output
98
+ - `/bridge` - Bridge multiple sessions
99
+ - `/status` - Show session status
100
+ - `/logs` - View session logs
101
+ - `/resume` - Resume previous session
102
+ - `/kill` - Terminate session
103
+ - `/compact` - Compress context
104
+ - `/export` - Export session
105
+ - `/summarize` - Summarize conversation
106
+ - `/history` - Command history
107
+ - `/share` - Share session
108
+ - `/copy` - Copy output to clipboard
109
+ - `/commit` - Create git commit
110
+ - `/pr` - Create pull request
111
+ - `/release` - Professional release engineering
112
+ - `/snip` - Extract conversation snippets
113
+ - `/collapse` - Collapse context
114
+ - `/brief` - Generate brief
115
+ - `/undo` - Undo last action
116
+ - `/redo` - Redo undone action
117
+ - `/thread` - Thread management (list/new/resume/fork/rename/archive/delete)
118
+
119
+ **Inspect Commands** (30+):
120
+ - `/plugins` - List plugins
121
+ - `/plugin` - Plugin details
122
+ - `/diagnostics` - Run diagnostics
123
+ - `/permissions` - Show permissions
124
+ - `/features` - List features
125
+ - `/hooks` - Hook registry
126
+ - `/model` - Model info
127
+ - `/effort` - Effort estimation
128
+ - `/style` - Code style
129
+ - `/sandbox` - Sandbox status
130
+ - `/worktree` - Worktree info
131
+ - `/statusline` - Status line config
132
+ - `/skills` - List skills
133
+ - `/tools` - List tools
134
+ - `/mcp` - MCP resources
135
+ - `/debug-workers` - Worker debug
136
+ - `/cost` - Cost tracking
137
+ - `/memory` - Memory usage
138
+ - `/stats` - Session stats
139
+ - `/theme` - Theme config
140
+ - `/keybindings` - Key bindings
141
+ - `/vim` - Vim mode
142
+ - `/ctx` - Context inspector
143
+ - `/dream` - Dream engine status
144
+ - `/diff` - Show recent changes
145
+ - `/editor` - Open in editor
146
+ - `/config` - Runtime config
147
+ - `/file` - File operations
148
+ - `/search` - Search codebase
149
+ - `/context` - Context management
150
+ - `/token` - Token usage
151
+ - `/settings` - Runtime settings
152
+ - `/alias` - Manage aliases
153
+ - `/macro` - Execute macros
154
+ - `/thread stats` - Thread statistics
155
+
156
+ **Agent Commands** (15+):
157
+ - `/agent` - Agent info
158
+ - `/agents` - List agents
159
+ - `/img` / `/image` - Image handling
160
+ - `/init` - Initialize project
161
+ - `/review` - Code review
162
+ - `/explain` - Explain code
163
+ - `/fix` - Fix errors
164
+ - `/debug` - Debug issues
165
+ - `/bug` - Report bug
166
+ - `/test` - Run tests
167
+ - `/optimize` - Optimize code
168
+ - `/refactor` - Refactor code
169
+ - `/document` - Generate docs
170
+ - `/chat` - Chat mode
171
+ - `/code` - Code mode
172
+ - `/terminal` - Terminal placeholder
173
+ - `/template` - Create from template
174
+
175
+ **Input Methods**:
176
+ - `Ctrl+V` / `Cmd+V` - Paste image/text/file
177
+ - `Ctrl+Shift+I` - Same as Ctrl+V
90
178
 
91
179
  ### 🎯 **Intelligent Context Management**
92
180
  - **Auto Memory**: Persistent coding notes across sessions (`coding_memory`)
@@ -102,15 +190,29 @@ Structured problem-solving workflow with 3 phases:
102
190
  2. **EXECUTION**: Implementation
103
191
  3. **VERIFICATION**: Testing and validation
104
192
 
105
- ### πŸ”§ **Skills System**
106
- Extendable expertise modules with progressive disclosure:
193
+ ### πŸ”§ **Skills System** (6 skills)
194
+ Extendable expertise modules with **progressive disclosure** β€” load only when needed:
195
+
196
+ **Available Skills:**
107
197
  - **git-commit**: Conventional commits automation with BluMa watermark
108
- - **git-pr**: Pull request creation and management
109
- - **git-release**: Full release engineering workflow (version bumps, changelog, tags, npm publish)
198
+ - **git-pr**: Pull request creation and management (descriptions, reviewers, draft mode)
199
+ - **git-release**: Full release engineering (version bumps, changelog, tags, npm publish, GitHub releases)
110
200
  - **pdf**: PDF generation and manipulation (reports, merge, forms, OCR)
111
201
  - **xlsx**: Spreadsheet processing (create, edit, formulas, charting, cleaning)
112
202
  - **skill-creator**: Create custom skills
113
203
 
204
+ **How Skills Work:**
205
+ 1. **Discovery**: Skills loaded from `dist/config/skills/`, `{cwd}/.bluma/skills/`, `~/.bluma/skills/`
206
+ 2. **Progressive Disclosure**:
207
+ - Level 1: One-line description (always visible)
208
+ - Level 2: Full instructions (loaded on activation)
209
+ - Level 3: References and scripts (loaded on demand)
210
+ 3. **Triggering**: Agent auto-detects when to load skills based on task context
211
+ 4. **Priority**: Native > Project > Global (native skills cannot be overridden)
212
+
213
+ **Create Custom Skills:**
214
+ See [docs/SKILLS.md](docs/SKILLS.md) for complete guide on authoring skills.
215
+
114
216
  ### 🎨 **Modern UI**
115
217
  - Built with **Ink** (React for CLI)
116
218
  - **Shimmer effects** for working states (WorkingShimmerText, Spinner with ShimmerChar/FlashingChar)
@@ -132,6 +234,17 @@ Extendable expertise modules with progressive disclosure:
132
234
  - **ES Modules**: Modern module system with bundler resolution
133
235
  - **React 19**: Latest React with concurrent features
134
236
  - **Optimized rendering**: Memoized message blocks, offscreen freeze, expandable previews
237
+ - **Parallel tests**: Up to 8 workers for faster test execution
238
+ - **Native modules**: Rust-based clipboard and layout engine for critical paths
239
+
240
+ ### πŸ”Œ **Hooks & Plugins**
241
+ Extensible architecture with hook registry and plugin system:
242
+
243
+ - **Hook Registry**: Execute custom scripts on events (pre-commit, post-build, etc.)
244
+ - **Plugin System**: Extend BluMa with custom plugins
245
+ - **Event-driven**: Hooks triggered by tool execution, session events, and lifecycle hooks
246
+
247
+ See [docs/BLUMA_DEVELOPER_GUIDE.md](docs/BLUMA_DEVELOPER_GUIDE.md) for plugin development.
135
248
 
136
249
  ### πŸ”Œ **MCP Support**
137
250
  - **Model Context Protocol**: Connect to external MCP servers
@@ -143,6 +256,28 @@ Extendable expertise modules with progressive disclosure:
143
256
  - **Thread stats**: View thread metadata and statistics
144
257
  - **Codex-style interface**: Familiar thread management commands
145
258
 
259
+ ### πŸ¦€ **Native Modules** (Rust)
260
+ High-performance native extensions for critical operations:
261
+
262
+ - **bluma-clipboard**: Cross-platform clipboard with image support
263
+ - Built with Rust (arboard crate)
264
+ - No dependencies on wl-paste/xclip
265
+ - Native image reading for terminal paste
266
+ - **yoga-layout**: High-performance layout engine for Ink
267
+ - Facebook's Yoga layout library
268
+ - Optimized for terminal UI rendering
269
+
270
+ ### πŸ“¦ **VS Code Extension**
271
+ Full BluMa capabilities integrated into VS Code:
272
+
273
+ - **Chat Panel**: Interactive chat interface with full BluMa capabilities
274
+ - **Session Sync**: Real-time synchronization with terminal sessions
275
+ - **Image Support**: Paste and view images directly in VS Code
276
+ - **File Integration**: Open and edit files from within the chat
277
+ - **Streaming**: Real-time response streaming with markdown rendering
278
+
279
+ See [vscode-extension/README.md](vscode-extension/README.md) for setup instructions.
280
+
146
281
  ---
147
282
 
148
283
  ## πŸ—οΈ Architecture
@@ -207,7 +342,12 @@ This modular design enables:
207
342
  - **`src/ink/`**: Ink renderer shims and compatibility layer
208
343
  - **`src/shims/`**: Build-time shims for react-compiler-runtime and bidi-js
209
344
  - **`native/`**: Rust-based native modules (clipboard, yoga-layout)
345
+ - **bluma-clipboard**: Cross-platform clipboard with image support
346
+ - **yoga-layout**: High-performance layout engine for Ink
210
347
  - **`vscode-extension/`**: VS Code extension for chat integration
348
+ - Chat panel with full BluMa capabilities
349
+ - Real-time session sync
350
+ - Image and file support
211
351
 
212
352
  ---
213
353
 
@@ -352,6 +492,24 @@ bluma
352
492
  /pr "feat: add new authentication" # Create PR with conventional commit
353
493
  ```
354
494
 
495
+ ### 5. **Web Integration**
496
+ ```bash
497
+ # Use the embeddable React chat widget
498
+ import { useChatWidget } from '@nomad-e/bluma-cli/chat-widget';
499
+
500
+ // Embed BluMa capabilities in your web app
501
+ const { messages, streamResponse } = useChatWidget();
502
+ ```
503
+
504
+ ### 6. **VS Code Integration**
505
+ ```bash
506
+ # Install the VS Code extension
507
+ # Access full BluMa capabilities from within VS Code
508
+ - Chat panel with session sync
509
+ - Image and file support
510
+ - Real-time streaming
511
+ ```
512
+
355
513
  ---
356
514
 
357
515
  ## πŸ“„ License
@@ -366,4 +524,30 @@ Apache 2.0 β€” see [LICENSE](LICENSE) for details.
366
524
 
367
525
  ---
368
526
 
369
- *BluMa CLI v0.3.1 β€” Built with TypeScript, React/Ink, and ES modules.*
527
+ ## πŸ“° Changelog
528
+
529
+ See [CHANGELOG.md](CHANGELOG.md) for detailed release notes.
530
+
531
+ ### What's New in v0.6.2 (2026-05-09)
532
+
533
+ **Major Features:**
534
+ - **Modular Tool Architecture**: All 45+ tools now have dedicated directories with separate logic, UI, and types
535
+ - **Native Clipboard Support**: Rust-based clipboard implementation for cross-platform image handling
536
+ - **Thread Management**: Full thread lifecycle with create, resume, fork, rename, archive, delete operations
537
+ - **Enhanced Multi-Agent Orchestration**: Improved coordinator-worker communication with bidirectional mailbox IPC
538
+ - **Chat Widget**: Embeddable React chat component for web integration
539
+
540
+ **Improvements:**
541
+ - 27 new slash commands for session management, inspection, and agent control
542
+ - Performance optimizations in UI rendering and context management
543
+ - Enhanced sandbox security with improved policy enforcement
544
+ - Better error handling and user-friendly error messages
545
+
546
+ **Fixes:**
547
+ - Resolved circular dependency in tool metadata
548
+ - Fixed worker registration for UI visibility
549
+ - Improved session persistence on LLM errors
550
+
551
+ ---
552
+
553
+ *BluMa CLI v0.6.2 β€” Built with TypeScript, React 19, Ink, and ES modules.*
@@ -570,13 +570,14 @@
570
570
  "type": "function",
571
571
  "function": {
572
572
  "name": "task_boundary",
573
- "description": "Indicate the start of a task or make an update to the current task. Use this to organize complex work into phases (PLANNING, EXECUTION, VERIFICATION). The UI will show this as a structured task view with progress tracking.",
573
+ "description": "Indicate the start of a task or make an update to the current task. Use this to organize complex work into phases (PLANNING, EXECUTION, VERIFICATION). The UI will show this as a structured task view with progress tracking. **IMPORTANT: All 4 fields are required and must not be empty.**",
574
574
  "parameters": {
575
575
  "type": "object",
576
576
  "properties": {
577
577
  "task_name": {
578
578
  "type": "string",
579
- "description": "Name of the task, e.g. 'Implementing Authentication'. Use the same name to update an existing task."
579
+ "minLength": 1,
580
+ "description": "Name of the task, e.g. 'Implementing Authentication'. Use the same name to update an existing task. **REQUIRED: Must not be empty.**"
580
581
  },
581
582
  "mode": {
582
583
  "type": "string",
@@ -585,15 +586,17 @@
585
586
  "EXECUTION",
586
587
  "VERIFICATION"
587
588
  ],
588
- "description": "Current mode: PLANNING (research/design), EXECUTION (implementing), VERIFICATION (testing)."
589
+ "description": "Current mode: PLANNING (research/design), EXECUTION (implementing), VERIFICATION (testing). **REQUIRED.**"
589
590
  },
590
591
  "task_status": {
591
592
  "type": "string",
592
- "description": "Current activity, e.g. 'Creating authentication middleware'. Describes what you are about to do."
593
+ "minLength": 1,
594
+ "description": "Current activity, e.g. 'Creating authentication middleware'. Describes what you are about to do. **REQUIRED: Must not be empty.**"
593
595
  },
594
596
  "task_summary": {
595
597
  "type": "string",
596
- "description": "Summary of what has been accomplished so far. Should be concise but comprehensive."
598
+ "minLength": 1,
599
+ "description": "Summary of what has been accomplished so far. Should be concise but comprehensive. **REQUIRED: Must not be empty.**"
597
600
  }
598
601
  },
599
602
  "required": [
package/dist/main.js CHANGED
@@ -16617,31 +16617,26 @@ async function updateTaskFile(task) {
16617
16617
  async function taskBoundary(args) {
16618
16618
  try {
16619
16619
  const { task_name, mode, task_status, task_summary } = args;
16620
+ const missingFields = [];
16620
16621
  if (!task_name || typeof task_name !== "string") {
16621
- return {
16622
- success: false,
16623
- task_name: "",
16624
- mode: "EXECUTION",
16625
- status: "",
16626
- message: "task_name is required"
16627
- };
16622
+ missingFields.push("task_name");
16628
16623
  }
16629
- if (!["PLANNING", "EXECUTION", "VERIFICATION"].includes(mode)) {
16630
- return {
16631
- success: false,
16632
- task_name,
16633
- mode: "EXECUTION",
16634
- status: "",
16635
- message: `Invalid mode: ${mode}. Must be PLANNING, EXECUTION, or VERIFICATION`
16636
- };
16624
+ if (!mode || !["PLANNING", "EXECUTION", "VERIFICATION"].includes(mode)) {
16625
+ missingFields.push("mode");
16637
16626
  }
16638
16627
  if (!task_status || typeof task_status !== "string") {
16628
+ missingFields.push("task_status");
16629
+ }
16630
+ if (!task_summary || typeof task_summary !== "string") {
16631
+ missingFields.push("task_summary");
16632
+ }
16633
+ if (missingFields.length > 0) {
16639
16634
  return {
16640
16635
  success: false,
16641
- task_name,
16642
- mode,
16643
- status: "",
16644
- message: "task_status is required"
16636
+ task_name: task_name || "",
16637
+ mode: mode || "EXECUTION",
16638
+ status: task_status || "",
16639
+ message: `Missing required fields: ${missingFields.join(", ")}. All 4 fields are required: task_name, mode, task_status, task_summary`
16645
16640
  };
16646
16641
  }
16647
16642
  const now2 = Date.now();
@@ -23542,53 +23537,6 @@ function disableCoordinatorMode() {
23542
23537
  delete process.env.BLUMA_COORDINATOR_MODE;
23543
23538
  }
23544
23539
 
23545
- // src/app/agent/core/prompt/tool_guidance.ts
23546
- var TOOL_GUIDANCE_RULES = [
23547
- {
23548
- toolName: "read_file_lines",
23549
- guidance: "To read files use `read_file_lines` instead of cat, head, tail, or sed"
23550
- },
23551
- {
23552
- toolName: "edit_tool",
23553
- guidance: "To edit files use `edit_tool` instead of sed or awk"
23554
- },
23555
- {
23556
- toolName: "file_write",
23557
- guidance: "To create files use `file_write` instead of cat with heredoc or echo redirection"
23558
- },
23559
- {
23560
- toolName: "grep_search",
23561
- guidance: "To search file content use `grep_search` instead of grep or rg"
23562
- },
23563
- {
23564
- toolName: "find_by_name",
23565
- guidance: "To search for files use `find_by_name` instead of find or ls"
23566
- },
23567
- {
23568
- toolName: "view_file_outline",
23569
- guidance: "To understand file structure use `view_file_outline` instead of opening the whole file"
23570
- }
23571
- ];
23572
- var ALWAYS_INCLUDED = [
23573
- "Reserve using `shell_command` exclusively for system commands and terminal operations that require shell execution. If you are unsure and there is a relevant dedicated tool, default to using the dedicated tool.",
23574
- "You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency.",
23575
- "Do NOT use `shell_command` to run commands when a relevant dedicated tool is provided. Using dedicated tools allows the user to better understand and review your work."
23576
- ];
23577
- function buildToolGuidanceSection(availableTools) {
23578
- const toolSet = new Set(availableTools);
23579
- const activeRules = TOOL_GUIDANCE_RULES.filter((rule) => toolSet.has(rule.toolName)).map((rule) => rule.guidance);
23580
- if (activeRules.length === 0) {
23581
- return "";
23582
- }
23583
- const lines = [
23584
- "# Using your tools",
23585
- "",
23586
- ...activeRules.map((r) => `- ${r}`),
23587
- ...ALWAYS_INCLUDED.map((r) => `- ${r}`)
23588
- ];
23589
- return lines.join("\n");
23590
- }
23591
-
23592
23540
  // src/app/agent/core/prompt/model_info.ts
23593
23541
  var KNOWLEDGE_CUTOFFS = [
23594
23542
  { match: "claude-sonnet-4-6", cutoff: "August 2025" },
@@ -23811,16 +23759,6 @@ function isAutoMemoryEnabled() {
23811
23759
  }
23812
23760
 
23813
23761
  // src/app/agent/core/prompt/prompt_builder.ts
23814
- var INTERNAL_TOOLS = /* @__PURE__ */ new Set([
23815
- "spawn_agent",
23816
- "wait_agent",
23817
- "list_agents",
23818
- "send_message",
23819
- "list_mailbox_messages",
23820
- "poll_mailbox",
23821
- "signal_mailbox",
23822
- "kill_agent"
23823
- ]);
23824
23762
  function getNodeVersion() {
23825
23763
  return process.version;
23826
23764
  }
@@ -24167,14 +24105,6 @@ ${formatFactorAiAppContextSummary(appContext)}
24167
24105
  if (modelInfo) prompt += `
24168
24106
 
24169
24107
  ${modelInfo}`;
24170
- const allToolNames = options?.availableToolNames ?? [];
24171
- if (allToolNames.length > 0) {
24172
- const visibleTools = isSandbox ? allToolNames : allToolNames.filter((n) => !INTERNAL_TOOLS.has(n));
24173
- const guidance = buildToolGuidanceSection(visibleTools);
24174
- if (guidance) prompt += `
24175
-
24176
- ${guidance}`;
24177
- }
24178
24108
  prompt += `
24179
24109
 
24180
24110
  ${buildSystemRemindersSection()}`;
@@ -25279,6 +25209,9 @@ var ToolCallNormalizer = class {
25279
25209
  }
25280
25210
  /**
25281
25211
  * Valida se um tool call normalizado Γ© vΓ‘lido
25212
+ * ValidaΓ§Γ£o dupla:
25213
+ * 1. JSON dos argumentos Γ© vΓ‘lido
25214
+ * 2. A ferramenta existe no catΓ‘logo de ferramentas nativas
25282
25215
  */
25283
25216
  static isValidToolCall(call) {
25284
25217
  if (!(call.id && call.type === "function" && call.function?.name && typeof call.function.arguments === "string")) {
@@ -25286,10 +25219,14 @@ var ToolCallNormalizer = class {
25286
25219
  }
25287
25220
  try {
25288
25221
  JSON.parse(call.function.arguments);
25289
- return true;
25290
25222
  } catch {
25291
25223
  return false;
25292
25224
  }
25225
+ const toolMetadata = getNativeToolMetadata(call.function.name);
25226
+ if (!toolMetadata) {
25227
+ return false;
25228
+ }
25229
+ return true;
25293
25230
  }
25294
25231
  };
25295
25232
 
@@ -25336,7 +25273,7 @@ function checkFilePermissionRules(toolName, filePath, policy) {
25336
25273
  }
25337
25274
  return { allowed: false, reason: `No permission rule found for file "${filePath}".` };
25338
25275
  }
25339
- function decideToolExecution(toolName, args) {
25276
+ function decideToolExecution(toolName, args, sessionId) {
25340
25277
  const policy = getSandboxPolicy();
25341
25278
  const metadata = getNativeToolMetadata(toolName);
25342
25279
  if (!metadata) {
@@ -25347,6 +25284,15 @@ function decideToolExecution(toolName, args) {
25347
25284
  reason: "Unknown tool metadata; require confirmation by default."
25348
25285
  };
25349
25286
  }
25287
+ if (sessionId && getEffectivePermissionMode(sessionId) === "full") {
25288
+ return {
25289
+ toolName,
25290
+ metadata,
25291
+ autoApprove: true,
25292
+ requiresConfirmation: false,
25293
+ reason: "Full permission mode: ALL tools auto-approved. User explicitly enabled unrestricted mode."
25294
+ };
25295
+ }
25350
25296
  const ruleDecision = permissionRulesEngine.checkPermission(toolName, args);
25351
25297
  if (ruleDecision === "deny") {
25352
25298
  return {
@@ -25619,10 +25565,10 @@ var PARALLEL_SAFE_TOOL_NAMES = /* @__PURE__ */ new Set([
25619
25565
  "read_mcp_resource",
25620
25566
  "todo"
25621
25567
  ]);
25622
- function toolEligibleForParallelRead(toolName) {
25568
+ function toolEligibleForParallelRead(toolName, sessionId) {
25623
25569
  const name = String(toolName || "").trim();
25624
25570
  if (!name || !PARALLEL_SAFE_TOOL_NAMES.has(name)) return false;
25625
- if (!decideToolExecution(name).autoApprove) return false;
25571
+ if (!decideToolExecution(name, void 0, sessionId).autoApprove) return false;
25626
25572
  const meta = getNativeToolMetadata(name);
25627
25573
  return meta?.riskLevel === "safe";
25628
25574
  }
@@ -25928,7 +25874,7 @@ var BluMaAgent = class _BluMaAgent {
25928
25874
  }
25929
25875
  /** PolΓ­tica mostrada na UI: combina metadata base com auto-approve efectivo (incl. permission_ml). */
25930
25876
  buildToolPolicyForUi(toolName, toolArgs) {
25931
- const base = decideToolExecution(toolName);
25877
+ const base = decideToolExecution(toolName, void 0, this.sessionId);
25932
25878
  const argsStr = typeof toolArgs === "string" ? toolArgs : JSON.stringify(toolArgs ?? {});
25933
25879
  const synthetic = { function: { name: toolName, arguments: argsStr } };
25934
25880
  const auto = effectiveToolAutoApprove(synthetic, this.sessionId, { logClassifier: false });
@@ -25988,10 +25934,6 @@ var BluMaAgent = class _BluMaAgent {
25988
25934
  role: "system",
25989
25935
  content: `[SYSTEM] Tool "${toolName}" is not found in the agent's available tools. Please use only tools that are listed in your tool catalog.`
25990
25936
  });
25991
- this.eventBus.emit("backend_message", {
25992
- type: "error",
25993
- message: `Tool "${toolName}" does not exist in the agent catalog.`
25994
- });
25995
25937
  this.persistSession();
25996
25938
  return true;
25997
25939
  }
@@ -26178,10 +26120,6 @@ var BluMaAgent = class _BluMaAgent {
26178
26120
  role: "system",
26179
26121
  content: `[SYSTEM] Tool "${toolName}" is not found in the agent's available tools. Please use only tools that are listed in your tool catalog.`
26180
26122
  });
26181
- this.eventBus.emit("backend_message", {
26182
- type: "error",
26183
- message: `Tool "${toolName}" does not exist in the agent catalog.`
26184
- });
26185
26123
  this.persistSession();
26186
26124
  return true;
26187
26125
  }
@@ -26330,13 +26268,13 @@ var BluMaAgent = class _BluMaAgent {
26330
26268
  let i = 0;
26331
26269
  while (i < calls.length && shouldContinue && !this.isInterrupted) {
26332
26270
  const name = calls[i].function.name;
26333
- if (!toolEligibleForParallelRead(name)) {
26271
+ if (!toolEligibleForParallelRead(name, this.sessionId)) {
26334
26272
  shouldContinue = await this.executeApprovedToolInvocation(calls[i], decisionData);
26335
26273
  i += 1;
26336
26274
  continue;
26337
26275
  }
26338
26276
  let j = i;
26339
- while (j < calls.length && toolEligibleForParallelRead(calls[j].function.name)) {
26277
+ while (j < calls.length && toolEligibleForParallelRead(calls[j].function.name, this.sessionId)) {
26340
26278
  j += 1;
26341
26279
  }
26342
26280
  const slice = calls.slice(i, j);
@@ -26624,7 +26562,7 @@ ${editData.error.display}`;
26624
26562
  }
26625
26563
  if (confirmationToolCalls.length > 0) {
26626
26564
  const toolToCall = confirmationToolCalls[0];
26627
- const decision = decideToolExecution(toolToCall.function.name);
26565
+ const decision = decideToolExecution(toolToCall.function.name, void 0, this.sessionId);
26628
26566
  const toolName = toolToCall.function.name;
26629
26567
  let previewContent;
26630
26568
  if (toolName === "edit_tool") {
@@ -26699,7 +26637,7 @@ ${editData.error.display}`;
26699
26637
  }
26700
26638
  if (confirmationToolCalls.length > 0) {
26701
26639
  const toolToCall = confirmationToolCalls[0];
26702
- const decision = decideToolExecution(toolToCall.function.name);
26640
+ const decision = decideToolExecution(toolToCall.function.name, void 0, this.sessionId);
26703
26641
  const toolName = toolToCall.function.name;
26704
26642
  let previewContent;
26705
26643
  if (toolName === "edit_tool") {
@@ -27647,7 +27585,7 @@ var BaseLLMSubAgent = class {
27647
27585
  break;
27648
27586
  }
27649
27587
  if (message2.tool_calls) {
27650
- const decision = decideToolExecution(message2.tool_calls[0].function.name);
27588
+ const decision = decideToolExecution(message2.tool_calls[0].function.name, void 0, `${this.id}`);
27651
27589
  if (!decision.autoApprove) {
27652
27590
  this.emitEvent("error", {
27653
27591
  message: `Subagent tool "${message2.tool_calls[0].function.name}" requires confirmation outside sandbox mode.`
@@ -27771,7 +27709,7 @@ ${editData.error.display}`;
27771
27709
  }
27772
27710
  }
27773
27711
  if (message2.tool_calls) {
27774
- const decision = decideToolExecution(message2.tool_calls[0].function.name);
27712
+ const decision = decideToolExecution(message2.tool_calls[0].function.name, void 0, `${this.id}`);
27775
27713
  if (!decision.autoApprove) {
27776
27714
  this.emitEvent("error", {
27777
27715
  message: `Subagent tool "${message2.tool_calls[0].function.name}" requires confirmation outside sandbox mode.`
@@ -27821,7 +27759,7 @@ ${editData.error.display}`;
27821
27759
  tool_name: toolName,
27822
27760
  arguments: toolArgs,
27823
27761
  preview: previewContent,
27824
- tool_policy: decideToolExecution(toolName)
27762
+ tool_policy: decideToolExecution(toolName, void 0, `${this.id}`)
27825
27763
  });
27826
27764
  try {
27827
27765
  if (this.isInterrupted) {
@@ -36484,10 +36422,10 @@ var runWorktreeSet = (_agentRef, _path, _setIsProcessing, _markTurnStarted) => {
36484
36422
  var runPermissionSet = (_agentRef, mode, _setIsProcessing, _markTurnStarted, sessionId) => {
36485
36423
  if (mode === "full") {
36486
36424
  if (sessionId) {
36487
- setSessionPermissionMode(sessionId, "accept_edits");
36425
+ setSessionPermissionMode(sessionId, "full");
36488
36426
  return usageBox("Permission", "Set to full");
36489
36427
  } else {
36490
- setRuntimeConfig({ permissionMode: "accept_edits", sandboxEnabled: false });
36428
+ setRuntimeConfig({ permissionMode: "full", sandboxEnabled: false });
36491
36429
  return usageBox("Permission", "Set to full (global)");
36492
36430
  }
36493
36431
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",