@nomad-e/bluma-cli 0.1.30 → 0.1.31

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
@@ -8,7 +8,7 @@
8
8
  <img src="https://pharmaseedevsa.blob.core.windows.net/pharmassee-dev-storage/bluma.png" alt="Screenshot BluMa CLI" width="1000"/>
9
9
  </p>
10
10
 
11
- BluMa is a CLI-based model agent responsible for language-level code generation, refactoring and semantic transformations in the Factor AI stack. The project is a conversational assistant that interacts via terminal (CLI), built with React/Ink, supporting smart agents (LLM via OpenRouter), tool execution, persistent history, session management, and extensibility through external plugins/tools.
11
+ BluMa is a CLI-based model agent responsible for language-level code generation, refactoring and semantic transformations in the Factor AI stack. The project is a conversational assistant that interacts via terminal (CLI), built with React/Ink, supporting smart agents (LLM via FactorRouter), tool execution, persistent history, session management, coding memory, and extensibility through external plugins/tools and skills.
12
12
 
13
13
  ---
14
14
 
@@ -25,8 +25,9 @@ BluMa is a CLI-based model agent responsible for language-level code generation,
25
25
  - [Sandbox / Agent Mode](#sandbox-agent-mode)
26
26
  - [Configuration and Environment Variables](#configuration-and-environment-variables)
27
27
  - [Development and Build](#development-and-build)
28
- - [Extensibility: Tools and Plugins](#extensibility-tools-and-plugins)
28
+ - [Extensibility: Tools, Skills and Plugins](#extensibility-tools-and-plugins)
29
29
  - [Tests](#tests)
30
+ - [Coding Memory](#coding-memory)
30
31
  - [Limitations / Next Steps](#️-limitations--next-steps)
31
32
  - [Security Notes](#-security-notes)
32
33
  - [Tech Stack Overview](#stack)
@@ -56,19 +57,21 @@ Choose BluMa for intelligent, efficient, and collaborative software engineering
56
57
  ## <a name="key-features"></a>Key Features
57
58
  - **Rich CLI interface** using React/Ink 5, with interactive prompts and custom components.
58
59
  - **Session management:** automatic persistence of conversation and tool history via files.
59
- - **Central agent (LLM):** orchestrated by OpenRouter, enabling natural language-driven automation.
60
+ - **Central agent (LLM):** orchestrated by FactorRouter, enabling natural language-driven automation.
60
61
  - **Tool invocation:** native and via MCP SDK for running commands, code manipulation, file management, and more.
61
62
  - **Dynamic prompts:** builds live conversational context, behavioral rules, and technical history.
62
63
  - **Smart feedback component** with technical suggestions and checks.
63
64
  - **ConfirmPrompt & Workflow Decision:** confirmations for sensitive operations, edit/code previews, always-accepted tool whitelists.
64
- - **Extensible:** easily add new tools or integrate external SDK/plugins.
65
+ - **Coding Memory:** persistent notes about the codebase, decisions, and context that survive across sessions.
66
+ - **Skills System:** pluggable knowledge modules for domain-specific expertise (git, testing, docker, etc.).
67
+ - **Extensible:** easily add new tools, skills, or integrate external SDK/plugins.
65
68
 
66
69
  ---
67
70
 
68
71
  ## <a name="requirements"></a>Requirements
69
72
  - Node.js >= 18
70
73
  - npm >= 9
71
- - OpenRouter API key (get one at [openrouter.ai](https://openrouter.ai))
74
+ - FactorRouter API key (get one from your FactorRouter admin)
72
75
 
73
76
  ---
74
77
 
@@ -98,17 +101,19 @@ If you get permission errors, EXAMPLES:
98
101
  > Only use sudo to install, never to run the CLI.
99
102
 
100
103
  ### Setting Up Environment Variables
101
- For BluMa CLI to operate, set the following environment variable globally in your system.
104
+ For BluMa CLI to operate, set the following environment variables globally in your system.
102
105
 
103
106
  **Required:**
104
- - `OPENROUTER_API_KEY` (get your key at [openrouter.ai](https://openrouter.ai))
107
+ - `FACTOR_ROUTER_KEY` API key from your FactorRouter admin (e.g., `sk-fai-...`)
108
+ - `FACTOR_ROUTER_URL` — FactorRouter gateway base URL (e.g., `http://host:8003/router-api`)
105
109
 
106
110
  #### How to set environment variables globally:
107
111
 
108
112
  **Linux/macOS:**
109
113
  Add to your `~/.bashrc`, `~/.zshrc`, or equivalent:
110
114
  ```sh
111
- export OPENROUTER_API_KEY="your_openrouter_key"
115
+ export FACTOR_ROUTER_KEY="your_factor_router_key"
116
+ export FACTOR_ROUTER_URL="http://host:8003/router-api"
112
117
  ```
113
118
  Then run:
114
119
  ```sh
@@ -117,13 +122,15 @@ source ~/.bashrc # or whichever file you edited
117
122
 
118
123
  **Windows (CMD):**
119
124
  ```cmd
120
- setx OPENROUTER_API_KEY "your_openrouter_key"
125
+ setx FACTOR_ROUTER_KEY "your_factor_router_key"
126
+ setx FACTOR_ROUTER_URL "http://host:8003/router-api"
121
127
  ```
122
128
  (Only needs to be run once per variable. Restart the terminal after.)
123
129
 
124
130
  **Windows (PowerShell):**
125
131
  ```powershell
126
- [Environment]::SetEnvironmentVariable("OPENROUTER_API_KEY", "your_openrouter_key", "Machine")
132
+ [Environment]::SetEnvironmentVariable("FACTOR_ROUTER_KEY", "your_factor_router_key", "Machine")
133
+ [Environment]::SetEnvironmentVariable("FACTOR_ROUTER_URL", "http://host:8003/router-api", "Machine")
127
134
  ```
128
135
 
129
136
  ### ℹ️ Global Installation of npm Packages in PowerShell (Windows)
@@ -166,7 +173,7 @@ Get up and running with BluMa in minutes:
166
173
  ```
167
174
 
168
175
  2. **Configure Environment:**
169
- Set your OpenRouter API key (see [Configuration](#configuration-and-environment-variables)).
176
+ Set your FactorRouter API key and URL (see [Configuration](#configuration-and-environment-variables)).
170
177
 
171
178
  3. **Launch BluMa:**
172
179
  ```bash
@@ -412,15 +419,34 @@ Here's BluMa in action:
412
419
 
413
420
  ## <a name="project-structure"></a>Project Structure
414
421
  ```
415
- bluma-engineer/
422
+ bluma-cli/
416
423
  ├── package.json # npm/project config
417
424
  ├── tsconfig.json # TypeScript config
418
- ├── scripts/build.js # Build script using esbuild
425
+ ├── scripts/
426
+ │ └── build.js # Build script using esbuild
419
427
  ├── src/
420
- │ ├── main.ts # Entry point (Ink renderer)
421
- └── app/
422
- ├── agent/ # Agent core (session mgmt, tools, MCP, prompt, feedback)
423
- ├── ui/ # Ink/React CLI interface components
428
+ │ ├── main.tsx # Entry point (Ink renderer)
429
+ ├── App.tsx # Main React/Ink UI component
430
+ ├── app/
431
+ ├── agent/ # Agent core
432
+ │ │ │ ├── Agent.ts # Main orchestrator
433
+ │ │ │ ├── BluMaAgent.ts # Core agent loop & state
434
+ │ │ │ ├── config/ # Configuration files
435
+ │ │ │ ├── mcp/ # MCP client integration
436
+ │ │ │ ├── prompts/ # System prompts
437
+ │ │ │ ├── skills/ # Pluggable skills system
438
+ │ │ │ ├── subagents/ # Sub-agent implementations
439
+ │ │ │ └── tools/ # Tool definitions
440
+ │ │ │ ├── natives/ # Native tools (shell, file ops, etc.)
441
+ │ │ │ └── types.ts # Tool type definitions
442
+ │ │ └── ui/ # Ink/React CLI interface components
443
+ │ ├── lib/ # Shared utilities
444
+ │ └── types/ # TypeScript type definitions
445
+ ├── tests/ # Test files
446
+ ├── artifacts/ # Generated deliverables (runtime)
447
+ └── .bluma/ # User config & sessions (runtime)
448
+ ├── sessions/ # Persistent session history
449
+ └── skills/ # Installed skills
424
450
  ```
425
451
  ---
426
452
 
@@ -439,10 +465,26 @@ npm run dev # (If configured, hot-reload/TS watch)
439
465
 
440
466
  ---
441
467
 
442
- ## <a name="extensibility-tools-and-plugins"></a>Extensibility: Tools and Plugins
443
- - Add native tools in `src/app/agent/tools/natives/`
444
- - Use the MCP SDK for advanced plugins integrating with external APIs
445
- - Create custom Ink components to expand the interface
468
+ ## <a name="extensibility-tools-and-plugins"></a>Extensibility: Tools, Skills and Plugins
469
+
470
+ ### Native Tools
471
+ Add native tools in `src/app/agent/tools/natives/` for file operations, shell commands, code search, and more.
472
+
473
+ ### Skills System
474
+ BluMa features a **pluggable skills system** that loads domain-specific knowledge modules:
475
+
476
+ - Skills are stored in `.bluma/skills/` (user) or `src/app/agent/skills/` (built-in)
477
+ - Each skill is a directory with a `SKILL.md` file containing workflows and best practices
478
+ - Skills can include `references/` (extra docs) and `scripts/` (executable helpers)
479
+ - Load a skill with `load_skill({ skill_name: "git-commit" })`
480
+
481
+ Available skills include: `git-commit`, `git-pr`, `testing`, `docker`, `pdf`, `xlsx`, and more.
482
+
483
+ ### MCP Integration
484
+ Use the MCP SDK for advanced plugins integrating with external APIs and services.
485
+
486
+ ### Custom UI Components
487
+ Create custom Ink components in `src/app/ui/` to expand the interface.
446
488
 
447
489
  ---
448
490
 
@@ -661,7 +703,7 @@ stateDiagram-v2
661
703
  ```mermaid
662
704
  graph TD
663
705
  CLI["CLI (BluMa)"] --> LocalFS[("Local File System")]
664
- CLI --> OpenRouter[("OpenRouter API")]
706
+ CLI --> FactorRouter[("FactorRouter API")]
665
707
  CLI --> OtherAPIs[("Other External APIs")]
666
708
  CLI --> MCPServer[("MCP Server / Plugins")]
667
709
  ```
@@ -745,15 +787,47 @@ We welcome contributions! For full details, read [CONTRIBUTING.md](CONTRIBUTING.
745
787
 
746
788
  ---
747
789
 
790
+ ## Coding memory
791
+
792
+ BluMa includes a **persistent coding memory** system that stores notes about the codebase, decisions, and context that survive across sessions:
793
+
794
+ - Memory is stored in `~/.bluma/coding_memory.json`
795
+ - Use the `coding_memory` tool to **add**, **list**, **search**, **update** (by id), or **remove** (one id at a time). There is **no** bulk “clear all” action.
796
+ - Notes can be tagged for easy categorization (e.g., `['api', 'auth', 'performance']`)
797
+ - Memory is loaded at session start and can be searched during tasks
798
+
799
+ ### When to use Coding Memory:
800
+ - After learning stable facts about architecture or conventions
801
+ - To store important URLs, API endpoints, or design decisions
802
+ - To remember user preferences that should persist across sessions
803
+ - To document invariants or critical system behaviors
804
+
805
+ ### Example:
806
+ ```json
807
+ {
808
+ "action": "add",
809
+ "note": "Project uses FactorRouter for LLM routing with model auto-selection",
810
+ "tags": ["llm", "architecture"]
811
+ }
812
+ ```
813
+
814
+ ---
815
+
748
816
  ## ⚠️ Limitations / Next Steps
749
- - Current LLM integration uses OpenRouter; add more providers.
750
817
  - Logging verbosity could be made configurable.
751
818
  - Potential for richer plugin lifecycle (install/remove at runtime).
752
819
  - Improve error reporting in subagents.
820
+ - Expand skill library with more domain-specific modules.
753
821
 
754
822
  ---
755
823
 
756
824
  ## 🔒 Security Notes
825
+ - **API Keys:** Never commit `.env` files or hardcode API keys in source code.
826
+ - **File Operations:** `edit_tool` can modify files — always review previews before accepting changes.
827
+ - **Sandbox Mode:** When `BLUMA_SANDBOX=true`, BluMa is forbidden from exposing environment variables, API keys, or infrastructure details.
828
+ - **Permissions:** Use restricted permissions for API tokens wherever possible (principle of least privilege).
829
+ - **Shared Systems:** If using on shared systems, ensure `.bluma` config directory is private (`chmod 700 ~/.bluma`).
830
+ - **Input Validation:** All user inputs are validated and sanitized to prevent prompt injection attacks.
757
831
 
758
832
  ---
759
833
 
@@ -824,7 +898,3 @@ BluMa handles different classes of errors gracefully:
824
898
  - Add unit tests for all business logic.
825
899
 
826
900
  ---
827
- - Protect your API keys: never commit `.env` files.
828
- - `edit_tool` can modify files — review previews before accepting.
829
- - Use restricted permissions for API tokens wherever possible.
830
- - If using on shared systems, ensure `.bluma` config is private.
@@ -40,7 +40,7 @@
40
40
  "type": "function",
41
41
  "function": {
42
42
  "name": "edit_tool",
43
- "description": "Safely and precisely replaces text in a file, or creates a new file. The tool is resilient to common formatting issues but performs best with precise input.\n\n**Best Practices for Success:**\n1. **Use a read tool first:** Always read the file to get the exact content before generating the `old_string`.\n2. **Provide Context:** For `old_string`, provide a unique, multi-line segment of the file. Including 3+ lines of context around the target change is highly recommended to ensure precision.\n3. **Create New Files:** To create a new file, provide the full `file_path` and an empty string for `old_string`.",
43
+ "description": "Replaces exact text in a file or creates a new file. Prefer **one** well-scoped edit over many tiny edits.\n\n**Critical avoid line-by-line surgery:**\n- Do **not** change the same file in a dozen sequential calls with one line each; that drifts, breaks whitespace, and often fails.\n- After `read_file_lines`, copy a **single contiguous block** (whole function, whole component, or 5–20 lines with unique context) into `old_string`, then replace with your revised block in `new_string`.\n- If the tool reports no match or ambiguous match, **widen** `old_string` (more surrounding lines) or fix indentation to match the file **exactly** — do not blindly retry a one-line fragment.\n\n**CLI note:** The user may press Ctrl+O to see more lines of a **truncated** read/shell preview in the terminal. That view is UI-only and may still omit lines; always trust `read_file_lines` for exact text and whitespace before calling `edit_tool`.\n\n**Checklist:**\n1. Read the file first; use literal newlines in `old_string`/`new_string` (not the two-character sequence backslash-n).\n2. `expected_replacements` must match how many times `old_string` appears (default 1).\n3. New file: `old_string` empty, `new_string` full content.",
44
44
  "parameters": {
45
45
  "type": "object",
46
46
  "properties": {
@@ -573,29 +573,33 @@
573
573
  "type": "function",
574
574
  "function": {
575
575
  "name": "coding_memory",
576
- "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.",
576
+ "description": "CRUD for durable coding notes on disk (~/.bluma/coding_memory.json), separate from chat. There is **no** action to wipe all entries: delete only one id at a time with `remove`.",
577
577
  "parameters": {
578
578
  "type": "object",
579
579
  "properties": {
580
580
  "action": {
581
581
  "type": "string",
582
- "description": "Operation to perform: add a new note, list all notes, search by text/tags, or clear all entries.",
583
- "enum": ["add", "list", "search", "clear"]
582
+ "description": "add=new note | list=all entries with ids | search=filter by query | remove=delete one entry by id | update=change note and/or tags for one id",
583
+ "enum": ["add", "list", "search", "remove", "update"]
584
+ },
585
+ "id": {
586
+ "type": "integer",
587
+ "description": "Required for remove and update. Obtain from list, search, or the id shown in the system prompt snapshot."
584
588
  },
585
589
  "note": {
586
590
  "type": "string",
587
- "description": "The note to store when action is 'add'. Should summarize something worth remembering about the code, architecture, or requirements."
591
+ "description": "For add: full note text. For update: new note text (non-empty); omit if only changing tags."
588
592
  },
589
593
  "tags": {
590
594
  "type": "array",
591
595
  "items": {
592
596
  "type": "string"
593
597
  },
594
- "description": "Optional tags to categorize the note (e.g. ['api', 'auth', 'performance'])."
598
+ "description": "For add: optional tags. For update: optional new tag list (replaces tags when provided)."
595
599
  },
596
600
  "query": {
597
601
  "type": "string",
598
- "description": "Search text used when action is 'search'. Matches against note text and tags."
602
+ "description": "Required for search. Matches note text and tags."
599
603
  }
600
604
  },
601
605
  "required": ["action"]