@nomad-e/bluma-cli 0.1.14 → 0.1.16
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 +160 -0
- package/dist/config/models_config.json +78 -0
- package/dist/config/native_tools.json +33 -0
- package/dist/main.js +291 -69
- package/dist/skills/git-conventional/LICENSE.txt +3 -0
- package/dist/skills/git-conventional/SKILL.md +83 -0
- package/dist/skills/skill-creator/SKILL.md +495 -0
- package/dist/skills/testing/LICENSE.txt +3 -0
- package/dist/skills/testing/SKILL.md +114 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ BluMa is a CLI-based model agent responsible for language-level code generation,
|
|
|
22
22
|
- [Screenshots](#screenshots)
|
|
23
23
|
- [Usage](#usage)
|
|
24
24
|
- [Examples](#-usage-examples)
|
|
25
|
+
- [Sandbox / Agent Mode](#sandbox-agent-mode)
|
|
25
26
|
- [Configuration and Environment Variables](#configuration-and-environment-variables)
|
|
26
27
|
- [Development and Build](#development-and-build)
|
|
27
28
|
- [Extensibility: Tools and Plugins](#extensibility-tools-and-plugins)
|
|
@@ -179,6 +180,165 @@ For full installation details, see [Installation](#installation).
|
|
|
179
180
|
|
|
180
181
|
---
|
|
181
182
|
|
|
183
|
+
## <a name="sandbox-agent-mode"></a>Sandbox / Agent Mode
|
|
184
|
+
|
|
185
|
+
BluMa was designed primarily as an **interactive CLI agent**, but it also exposes a **non-interactive “agent mode”** for integration with orchestrators such as AGIWeb Sandbox or other backends.
|
|
186
|
+
|
|
187
|
+
### Why Agent Mode Exists
|
|
188
|
+
|
|
189
|
+
- Allow external systems (e.g. a Sandbox API, another agent like Severino, CI pipelines) to:
|
|
190
|
+
- Send a **single JSON payload** describing a task (`action` + `context`).
|
|
191
|
+
- Receive **only structured JSON Lines (JSONL)** as output (no TUI).
|
|
192
|
+
- Orchestrate BluMa as a **sub-agent** inside a larger architecture.
|
|
193
|
+
- Guarantee:
|
|
194
|
+
- Deterministic, parseable logs.
|
|
195
|
+
- A single, well-defined `result` event per execution.
|
|
196
|
+
- No interactive prompts or confirmation flows when running in sandbox.
|
|
197
|
+
|
|
198
|
+
### How to Call BluMa in Agent Mode
|
|
199
|
+
|
|
200
|
+
Agent mode is activated by passing the `agent` subcommand and piping a JSON envelope to stdin:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
BLUMA_SANDBOX=true \
|
|
204
|
+
BLUMA_SANDBOX_NAME="sandbox-api" \
|
|
205
|
+
node dist/main.js agent --input - << 'EOF'
|
|
206
|
+
{
|
|
207
|
+
"message_id": "job-123",
|
|
208
|
+
"from_agent": "sandbox-api",
|
|
209
|
+
"to_agent": "bluma",
|
|
210
|
+
"action": "echo_test",
|
|
211
|
+
"context": {
|
|
212
|
+
"user_request": "Diz-me em uma frase o que é o bluma-cli."
|
|
213
|
+
},
|
|
214
|
+
"metadata": {
|
|
215
|
+
"sandbox": true
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
EOF
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
You can also use `--input-file` instead of stdin:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
BLUMA_SANDBOX=true BLUMA_SANDBOX_NAME="sandbox-api" \
|
|
225
|
+
node dist/main.js agent --input-file ./payload.json
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Input Envelope Contract
|
|
229
|
+
|
|
230
|
+
The JSON payload must follow this envelope:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"message_id": "job-123", // Optional but recommended
|
|
235
|
+
"from_agent": "sandbox-api", // Who is calling BluMa
|
|
236
|
+
"to_agent": "bluma", // Target agent (for routing)
|
|
237
|
+
"action": "generate_app", // High-level action label
|
|
238
|
+
"context": { // Arbitrary JSON with task details
|
|
239
|
+
"user_request": "Criar dashboard de vendas",
|
|
240
|
+
"erp_models": ["sale.order"],
|
|
241
|
+
"permissions": ["sales"]
|
|
242
|
+
},
|
|
243
|
+
"metadata": { // Free-form metadata for the orchestrator
|
|
244
|
+
"sandbox": true,
|
|
245
|
+
"caller": "agiweb"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Internally, BluMa will:
|
|
251
|
+
|
|
252
|
+
- Initialize the agent with a dedicated `eventBus`.
|
|
253
|
+
- Build a single user message containing this JSON.
|
|
254
|
+
- Run the normal reasoning + tool flow, but:
|
|
255
|
+
- **Without** rendering the Ink UI.
|
|
256
|
+
- **Without** asking for user confirmations when `BLUMA_SANDBOX=true`.
|
|
257
|
+
|
|
258
|
+
### Output: JSON Lines (JSONL)
|
|
259
|
+
|
|
260
|
+
In agent mode, BluMa writes **one JSON object per line** to stdout.
|
|
261
|
+
Typical events:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{"event_type":"log","level":"info","message":"Starting agent mode execution","timestamp":"...","data":{"message_id":"job-123","action":"echo_test","from_agent":"sandbox-api","to_agent":"bluma"}}
|
|
265
|
+
{"event_type":"action_status","timestamp":"...","payload":{"action":"Thinking"}}
|
|
266
|
+
{"event_type":"backend_message","backend_type":"tool_call","timestamp":"...","payload":{"type":"tool_call","tool_name":"read_file_lines","arguments":{...}}}
|
|
267
|
+
{"event_type":"backend_message","backend_type":"tool_result","timestamp":"...","payload":{"type":"tool_result","tool_name":"read_file_lines","result":"{ ... }"}}
|
|
268
|
+
...
|
|
269
|
+
{"event_type":"result","status":"success","timestamp":"...","data":{"message_id":"job-123","action":"echo_test","last_assistant_message":"...","reasoning":null}}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Key points:
|
|
273
|
+
|
|
274
|
+
- **`event_type: "backend_message"`** mirrors what the CLI UI would receive (`tool_call`, `tool_result`, `reasoning`, `done`, etc.).
|
|
275
|
+
- **`event_type: "action_status"`** surfaces high-level states (Thinking, Reading, Executing, Waiting, Responding).
|
|
276
|
+
- **`event_type: "result"`** appears **exactly once** per execution and contains:
|
|
277
|
+
- `message_id`: propagated from the input.
|
|
278
|
+
- `action`: propagated from the input.
|
|
279
|
+
- `last_assistant_message`: the final message BluMa would send to a human (content of the `message` tool).
|
|
280
|
+
- `reasoning`: concatenated reasoning text when available (can be `null`).
|
|
281
|
+
|
|
282
|
+
### Sandbox Behaviour and Permissions
|
|
283
|
+
|
|
284
|
+
When `BLUMA_SANDBOX=true`:
|
|
285
|
+
|
|
286
|
+
- The **system prompt** is augmented with sandbox-specific context, instructing the model that:
|
|
287
|
+
- It is running **inside a non-interactive sandbox**.
|
|
288
|
+
- All inputs come from JSON payloads, not from a human on a terminal.
|
|
289
|
+
- Outputs must be deterministic, concise and suitable for machine parsing.
|
|
290
|
+
- Tool execution:
|
|
291
|
+
- All tools are considered **auto-approved** in sandbox mode (no confirmation prompts from the user).
|
|
292
|
+
- This allows the orchestrator to let BluMa freely call `shell_command`, `command_status`, `coding_memory`, etc., while still observing every step through JSONL logs.
|
|
293
|
+
|
|
294
|
+
### Example: Asking for Python Version
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
BLUMA_SANDBOX=true BLUMA_SANDBOX_NAME="sandbox-api" \
|
|
298
|
+
node dist/main.js agent --input - << 'EOF'
|
|
299
|
+
{
|
|
300
|
+
"message_id": "job-python-version",
|
|
301
|
+
"from_agent": "sandbox-api",
|
|
302
|
+
"to_agent": "bluma",
|
|
303
|
+
"action": "python_version",
|
|
304
|
+
"context": {
|
|
305
|
+
"user_request": "Diz-me qual a versão do Python instalada neste ambiente."
|
|
306
|
+
},
|
|
307
|
+
"metadata": {
|
|
308
|
+
"sandbox": true
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
EOF
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
BluMa will typically:
|
|
315
|
+
|
|
316
|
+
- Call `shell_command` with `python3 --version`.
|
|
317
|
+
- Use `command_status` to wait for completion.
|
|
318
|
+
- Optionally probe `python --version`.
|
|
319
|
+
- Return a final `result` event like:
|
|
320
|
+
|
|
321
|
+
```json
|
|
322
|
+
{
|
|
323
|
+
"event_type": "result",
|
|
324
|
+
"status": "success",
|
|
325
|
+
"data": {
|
|
326
|
+
"message_id": "job-python-version",
|
|
327
|
+
"action": "python_version",
|
|
328
|
+
"last_assistant_message": "**Python 3.12.3** está instalado neste ambiente.\n\nO comando `python` não está disponível — apenas `python3`.",
|
|
329
|
+
"reasoning": null
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
This makes it straightforward for an API layer (AGIWeb Sandbox, Severino, etc.) to:
|
|
335
|
+
|
|
336
|
+
- Orchestrate BluMa as a sub-agent.
|
|
337
|
+
- Log all intermediate steps.
|
|
338
|
+
- Present only the final `last_assistant_message` (and optionally `reasoning`) to the end user.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
182
342
|
## Screenshots
|
|
183
343
|
|
|
184
344
|
Here's BluMa in action:
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"models": [
|
|
3
|
+
{
|
|
4
|
+
"id": "google/gemini-3.1-pro-preview-customtools",
|
|
5
|
+
"tier": "tools",
|
|
6
|
+
"task_type": "multi_tool",
|
|
7
|
+
"context_window": 1048576,
|
|
8
|
+
"pricing": {
|
|
9
|
+
"input_per_1m_tokens": "$2.00",
|
|
10
|
+
"output_per_1m_tokens": "$12.00"
|
|
11
|
+
},
|
|
12
|
+
"description": "Enhanced version of Gemini 3.1 Pro tuned specifically for reliable tool selection and function calling. Designed to avoid overusing generic shell tools when more targeted tools are available, making it ideal for complex coding agents and multi-tool workflows in the CLI.",
|
|
13
|
+
"best_for": [
|
|
14
|
+
"Workflows that involve many different tools (file operations, search, tests, shell) and require the model to pick the right one.",
|
|
15
|
+
"Coordinating multi-step coding tasks where safe and accurate tool use is more important than raw speed or cost.",
|
|
16
|
+
"Complex debugging or refactors that need mixing code edits, search, tests, and shell commands.",
|
|
17
|
+
"Agent-style tasks where tool misuse is risky and you want maximum reliability in tool choice."
|
|
18
|
+
],
|
|
19
|
+
"not_for": "Very simple edits, quick questions, or cheap one-off operations that qwen3.5-flash can handle more economically."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "qwen/qwen3-coder-next",
|
|
23
|
+
"tier": "coder",
|
|
24
|
+
"task_type": "multi_file",
|
|
25
|
+
"context_window": 262144,
|
|
26
|
+
"pricing": {
|
|
27
|
+
"input_per_1m_tokens": "$0.12",
|
|
28
|
+
"output_per_1m_tokens": "$0.75"
|
|
29
|
+
},
|
|
30
|
+
"description": "Coder-focused MoE model optimized for long-horizon coding agents and local development workflows. Handles large codebases, multi-file refactors, and recovery from execution failures while remaining cost-effective for always-on agents.",
|
|
31
|
+
"best_for": [
|
|
32
|
+
"Large refactors across many files where the agent must keep track of a global design.",
|
|
33
|
+
"Implementing new subsystems (features, services, modules) with tests and documentation.",
|
|
34
|
+
"Agentic coding loops that involve planning, executing edits, running commands/tests, and iterating.",
|
|
35
|
+
"Complex bug-hunting sessions where the model must reason over many files and past attempts."
|
|
36
|
+
],
|
|
37
|
+
"not_for": "Tiny edits, trivial Q&A, or ultra-simple tasks where qwen3.5-flash is cheaper and fast enough."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "deepseek/deepseek-chat-v3.1",
|
|
41
|
+
"tier": "reasoning",
|
|
42
|
+
"task_type": "reasoning",
|
|
43
|
+
"context_window": 32768,
|
|
44
|
+
"pricing": {
|
|
45
|
+
"input_per_1m_tokens": "$0.15",
|
|
46
|
+
"output_per_1m_tokens": "$0.75"
|
|
47
|
+
},
|
|
48
|
+
"description": "Hybrid reasoning model supporting both thinking and non-thinking modes with strong performance on coding, tool use, and long-context reasoning. Good choice when deep structured reasoning or complex analysis is needed in addition to code generation.",
|
|
49
|
+
"best_for": [
|
|
50
|
+
"Deep reasoning on tricky bugs, architecture decisions, or algorithm design.",
|
|
51
|
+
"Analyzing logs, traces, or large textual outputs to identify root causes.",
|
|
52
|
+
"Complex code reviews or design reviews where clear, structured justification is needed.",
|
|
53
|
+
"Cases where you explicitly want more deliberate reasoning rather than only fast responses."
|
|
54
|
+
],
|
|
55
|
+
"not_for": "Purely mechanical edits or very simple tasks where a cheaper, faster model is sufficient."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "anthropic/claude-haiku-4.5",
|
|
59
|
+
"tier": "heavy",
|
|
60
|
+
"task_type": "complex",
|
|
61
|
+
"context_window": 200000,
|
|
62
|
+
"pricing": {
|
|
63
|
+
"input_per_1m_tokens": "$1.00",
|
|
64
|
+
"output_per_1m_tokens": "$5.00"
|
|
65
|
+
},
|
|
66
|
+
"description": "High-end, high-speed frontier model with extended thinking and strong performance on coding, reasoning, and computer-use tasks. Best reserved for the most complex, high-stakes workflows where you need frontier-level capability and robustness.",
|
|
67
|
+
"best_for": [
|
|
68
|
+
"Very large, high-risk changes to critical production code where maximum reliability matters.",
|
|
69
|
+
"Long, multi-phase agentic tasks that must not fail (e.g. migrations, deep refactors, safety-sensitive changes).",
|
|
70
|
+
"Scenarios where you want frontier-level coding performance and can afford higher cost.",
|
|
71
|
+
"Coordinating many sub-agents or parallel tool workflows for large projects."
|
|
72
|
+
],
|
|
73
|
+
"not_for": "Routine day-to-day coding tasks, quick fixes, or low-impact work where cheaper models are perfectly adequate."
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"default_model": "qwen/qwen3-coder-next"
|
|
77
|
+
}
|
|
78
|
+
|
|
@@ -561,6 +561,39 @@
|
|
|
561
561
|
]
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"type": "function",
|
|
567
|
+
"function": {
|
|
568
|
+
"name": "coding_memory",
|
|
569
|
+
"description": "Persists and retrieves short notes about the codebase, decisions, and context that should be remembered across turns. Use this to store important insights (APIs, invariants, design decisions) and to search them later.",
|
|
570
|
+
"parameters": {
|
|
571
|
+
"type": "object",
|
|
572
|
+
"properties": {
|
|
573
|
+
"action": {
|
|
574
|
+
"type": "string",
|
|
575
|
+
"description": "Operation to perform: add a new note, list all notes, search by text/tags, or clear all entries.",
|
|
576
|
+
"enum": ["add", "list", "search", "clear"]
|
|
577
|
+
},
|
|
578
|
+
"note": {
|
|
579
|
+
"type": "string",
|
|
580
|
+
"description": "The note to store when action is 'add'. Should summarize something worth remembering about the code, architecture, or requirements."
|
|
581
|
+
},
|
|
582
|
+
"tags": {
|
|
583
|
+
"type": "array",
|
|
584
|
+
"items": {
|
|
585
|
+
"type": "string"
|
|
586
|
+
},
|
|
587
|
+
"description": "Optional tags to categorize the note (e.g. ['api', 'auth', 'performance'])."
|
|
588
|
+
},
|
|
589
|
+
"query": {
|
|
590
|
+
"type": "string",
|
|
591
|
+
"description": "Search text used when action is 'search'. Matches against note text and tags."
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
"required": ["action"]
|
|
595
|
+
}
|
|
596
|
+
}
|
|
564
597
|
}
|
|
565
598
|
]
|
|
566
599
|
}
|