@kinqs/brainrouter-cli 0.3.4 → 0.3.6
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/.env.example +55 -48
- package/README.md +102 -142
- package/bin/cli.cjs +71 -0
- package/dist/agent/agent.d.ts +212 -2
- package/dist/agent/agent.js +430 -40
- package/dist/cli/banner.d.ts +60 -0
- package/dist/cli/banner.js +199 -0
- package/dist/cli/cliPrompt.d.ts +69 -0
- package/dist/cli/cliPrompt.js +287 -0
- package/dist/cli/commands/_helpers.js +6 -6
- package/dist/cli/commands/guard.js +75 -10
- package/dist/cli/commands/mcp.d.ts +17 -0
- package/dist/cli/commands/mcp.js +121 -0
- package/dist/cli/commands/memory.js +2 -2
- package/dist/cli/commands/obs.js +22 -22
- package/dist/cli/commands/session.js +13 -5
- package/dist/cli/commands/ui.js +97 -45
- package/dist/cli/commands/workflow.d.ts +18 -0
- package/dist/cli/commands/workflow.js +314 -43
- package/dist/cli/repl.js +219 -132
- package/dist/cli/spinner.d.ts +34 -0
- package/dist/cli/spinner.js +36 -0
- package/dist/cli/statusline.d.ts +67 -0
- package/dist/cli/statusline.js +204 -0
- package/dist/cli/theme.d.ts +79 -0
- package/dist/cli/theme.js +106 -0
- package/dist/cli/whereView.d.ts +81 -0
- package/dist/cli/whereView.js +245 -0
- package/dist/config/config.d.ts +40 -0
- package/dist/config/config.js +45 -73
- package/dist/index.js +81 -14
- package/dist/memory/briefing.d.ts +10 -0
- package/dist/memory/briefing.js +69 -1
- package/dist/prompt/breadthHint.d.ts +5 -0
- package/dist/prompt/breadthHint.js +44 -0
- package/dist/prompt/systemPrompt.d.ts +34 -0
- package/dist/prompt/systemPrompt.js +124 -108
- package/dist/runtime/dangerousCommand.d.ts +53 -0
- package/dist/runtime/dangerousCommand.js +105 -0
- package/dist/runtime/mcpClient.d.ts +38 -1
- package/dist/runtime/mcpClient.js +91 -3
- package/dist/state/goalStore.d.ts +98 -17
- package/dist/state/goalStore.js +132 -42
- package/dist/state/preferencesStore.d.ts +67 -3
- package/dist/state/preferencesStore.js +84 -1
- package/dist/state/workflowArtifacts.d.ts +63 -2
- package/dist/state/workflowArtifacts.js +120 -8
- package/dist/tests/_helpers.d.ts +31 -0
- package/dist/tests/_helpers.js +91 -0
- package/package.json +5 -4
package/.env.example
CHANGED
|
@@ -1,77 +1,81 @@
|
|
|
1
|
-
# BrainRouter CLI agent — environment
|
|
1
|
+
# BrainRouter CLI agent — environment template
|
|
2
2
|
#
|
|
3
|
-
# Copy to brainrouter-cli/.env
|
|
3
|
+
# Copy to `brainrouter-cli/.env`. Loaded by the CLI at startup.
|
|
4
4
|
#
|
|
5
5
|
# This file is for CLI-AGENT concerns only:
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# - workspace override
|
|
6
|
+
# 1. Chat LLM (the model the terminal agent talks to)
|
|
7
|
+
# 2. Tool runtime (loop limit, result clamp, MCP timeout, auto-compact)
|
|
8
|
+
# 3. Sandbox (run_command wrapping)
|
|
9
|
+
# 4. Workspace (root override + shared state root)
|
|
10
|
+
# 5. Web search (custom backend for the web_search tool)
|
|
11
|
+
# 6. Observability (trace log path)
|
|
13
12
|
#
|
|
14
|
-
# MCP-server concerns (cognitive extraction, embeddings, reranker,
|
|
15
|
-
# engine knobs, server auth) live in brainrouter/.env.example
|
|
13
|
+
# MCP-server concerns (cognitive extraction, embeddings, reranker, judge,
|
|
14
|
+
# memory engine knobs, server auth) live in `brainrouter/.env.example`.
|
|
16
15
|
#
|
|
17
16
|
# Why split: the MCP and the CLI are separate processes with different
|
|
18
17
|
# concerns. The CLI's chat LLM can be a smart cloud model while the MCP's
|
|
19
18
|
# cognitive extractor is a cheap local one. Their concurrency caps differ
|
|
20
19
|
# too (CLI default 4, MCP default 2). Keep them independent.
|
|
20
|
+
#
|
|
21
|
+
# All values in this template are blank placeholders. Fill in only what
|
|
22
|
+
# you actually need — most settings have sensible defaults.
|
|
23
|
+
|
|
21
24
|
|
|
22
|
-
#
|
|
23
|
-
# Chat LLM (for the agent's own conversation)
|
|
24
|
-
#
|
|
25
|
+
# =============================================================================
|
|
26
|
+
# 1. Chat LLM (for the agent's own conversation)
|
|
27
|
+
# =============================================================================
|
|
25
28
|
# Same var names as the MCP, but a separate process — set them here for the
|
|
26
29
|
# CLI's chat model. Falls back to OPENAI_API_KEY.
|
|
27
30
|
#
|
|
28
31
|
# If you don't set BRAINROUTER_LLM_API_KEY here, the CLI also reads it from
|
|
29
|
-
# brainrouter/.env as a transitional fallback. Setting it here makes the
|
|
32
|
+
# `brainrouter/.env` as a transitional fallback. Setting it here makes the
|
|
30
33
|
# CLI's choice explicit and lets you use a different chat model than the
|
|
31
34
|
# MCP's extractor (e.g. gpt-4o for chat, gpt-4o-mini for extraction).
|
|
32
|
-
BRAINROUTER_LLM_API_KEY=
|
|
35
|
+
BRAINROUTER_LLM_API_KEY=
|
|
33
36
|
|
|
34
37
|
# OpenAI-compatible chat-completions endpoint.
|
|
35
38
|
# Examples:
|
|
36
|
-
# OpenAI:
|
|
37
|
-
# OpenRouter:
|
|
38
|
-
# Anthropic via OpenRouter: anthropic/claude-sonnet-4
|
|
39
|
-
# LM Studio:
|
|
39
|
+
# OpenAI: https://api.openai.com/v1/chat/completions
|
|
40
|
+
# OpenRouter: https://openrouter.ai/api/v1/chat/completions
|
|
41
|
+
# Anthropic via OpenRouter: model id "anthropic/claude-sonnet-4"
|
|
42
|
+
# LM Studio: http://localhost:1234/v1/chat/completions
|
|
40
43
|
BRAINROUTER_LLM_ENDPOINT=https://api.openai.com/v1/chat/completions
|
|
41
|
-
|
|
42
44
|
BRAINROUTER_LLM_MODEL=gpt-4o-mini
|
|
43
45
|
|
|
44
|
-
# Per-call timeout for the CLI's chat LLM. Default
|
|
46
|
+
# Per-call timeout for the CLI's chat LLM. Default 120000 (2 min).
|
|
45
47
|
# BRAINROUTER_LLM_TIMEOUT_MS=120000
|
|
46
48
|
|
|
47
49
|
# Cap on concurrent in-flight chat LLM calls FROM THE CLI PROCESS.
|
|
48
|
-
# Default
|
|
49
|
-
# local backends;
|
|
50
|
+
# Default 4 (separate from the MCP's own cap). Set to 1 for consumer-grade
|
|
51
|
+
# local backends; raise to 16+ for cloud APIs.
|
|
50
52
|
# BRAINROUTER_LLM_MAX_CONCURRENT=4
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
54
|
+
|
|
55
|
+
# =============================================================================
|
|
56
|
+
# 2. Tool runtime
|
|
57
|
+
# =============================================================================
|
|
58
|
+
# Per-tool timeout for CLI → MCP requests. Default 60000.
|
|
56
59
|
# BRAINROUTER_MCP_TIMEOUT_MS=60000
|
|
57
60
|
|
|
58
61
|
# LLM-visible clamp on a single tool-result body (full text still recorded
|
|
59
|
-
# in the transcript on disk). Default
|
|
62
|
+
# in the transcript on disk). Default 8000.
|
|
60
63
|
# BRAINROUTER_MAX_TOOL_RESULT_CHARS=8000
|
|
61
64
|
|
|
62
|
-
# Hard ceiling on tool-call iterations per turn. Default
|
|
65
|
+
# Hard ceiling on tool-call iterations per turn. Default 60.
|
|
63
66
|
# BRAINROUTER_MAX_TOOL_LOOPS=60
|
|
64
67
|
|
|
65
|
-
# Estimated history-size trigger for auto-`/compact`. Default
|
|
68
|
+
# Estimated history-size trigger for auto-`/compact`. Default 80000 tokens.
|
|
66
69
|
# BRAINROUTER_AUTO_COMPACT_TOKENS=80000
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
+
|
|
72
|
+
# =============================================================================
|
|
73
|
+
# 3. Sandbox (run_command)
|
|
74
|
+
# =============================================================================
|
|
71
75
|
# Wrap shell commands in the platform sandbox:
|
|
72
76
|
# macOS: sandbox-exec
|
|
73
77
|
# Linux: bwrap (preferred) or firejail
|
|
74
|
-
# Set
|
|
78
|
+
# Set `on` to enable. Off by default.
|
|
75
79
|
# BRAINROUTER_SANDBOX=on
|
|
76
80
|
|
|
77
81
|
# Allow outbound network from sandboxed commands. Off by default.
|
|
@@ -81,29 +85,32 @@ BRAINROUTER_LLM_MODEL=gpt-4o-mini
|
|
|
81
85
|
# BRAINROUTER_SANDBOX_READ_PATHS=/usr/local:/opt
|
|
82
86
|
# BRAINROUTER_SANDBOX_WRITE_PATHS=/tmp
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
88
|
+
|
|
89
|
+
# =============================================================================
|
|
90
|
+
# 4. Workspace
|
|
91
|
+
# =============================================================================
|
|
92
|
+
# Override the workspace root the CLI uses for file tools + session key.
|
|
93
|
+
# Most users let the CLI auto-detect via git / closest package.json.
|
|
89
94
|
# BRAINROUTER_WORKSPACE=/path/to/project
|
|
90
95
|
|
|
91
96
|
# Override per-user state root. Default: ~/.brainrouter.
|
|
92
97
|
# Both the CLI and MCP honor this — set it once and both processes use it.
|
|
93
98
|
# BRAINROUTER_HOME=/path/to/state
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
#
|
|
100
|
+
|
|
101
|
+
# =============================================================================
|
|
102
|
+
# 5. Web search
|
|
103
|
+
# =============================================================================
|
|
98
104
|
# Custom search backend for the web_search tool. Must accept
|
|
99
|
-
# POST { query, maxResults } → { results: [{ title, url, snippet }] }
|
|
105
|
+
# POST { query, maxResults } → { results: [{ title, url, snippet }] }
|
|
100
106
|
# Falls back to DuckDuckGo's Instant Answer API when unset.
|
|
101
|
-
# Compatible with Brave Search API wrappers, Tavily, SerpAPI proxies.
|
|
107
|
+
# Compatible with Brave Search API wrappers, Tavily, SerpAPI proxies, etc.
|
|
102
108
|
# BRAINROUTER_WEB_SEARCH_ENDPOINT=https://your-search-proxy.example.com/search
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
#
|
|
106
|
-
#
|
|
110
|
+
|
|
111
|
+
# =============================================================================
|
|
112
|
+
# 6. Observability
|
|
113
|
+
# =============================================================================
|
|
107
114
|
# Path for OTEL-style JSONL turn traces. One line per turn/tool span.
|
|
108
115
|
# Toggle at runtime with /trace on|off.
|
|
109
116
|
# BRAINROUTER_TRACE_LOG=/path/to/trace.jsonl
|
package/README.md
CHANGED
|
@@ -1,185 +1,145 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@kinqs/brainrouter-cli`
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A memory-native terminal agent. Edits files, runs shell commands,
|
|
4
|
+
spawns child agents, and talks to a BrainRouter MCP server for long-term
|
|
5
|
+
recall, skills, and capture.
|
|
6
|
+
|
|
7
|
+
Ships the `brainrouter` binary.
|
|
4
8
|
|
|
5
9
|
---
|
|
6
10
|
|
|
7
|
-
##
|
|
8
|
-
- **Dual-Tier Connection**: Connects to local MCP servers via standard I/O (stdio) or hosted multi-tenant servers over Streamable HTTP/SSE.
|
|
9
|
-
- **Double-Tier Memory Architecture**:
|
|
10
|
-
- **System 1 (Heuristic Recall)**: Automatically retrieves active focus scenes, codebase facts, and skills *before* each LLM reasoning cycle.
|
|
11
|
-
- **System 2 (Memory Consolidation)**: Autonomously extracts learning points, updates facts, and saves evidence via turn-by-turn memory capture.
|
|
12
|
-
- **Local Execution Harness**: Autonomous execution of files editing, directory listing, regex/string grep, and terminal command invocation (safely prompted for user verification).
|
|
13
|
-
- **Obsidian Dark / Midnight Ledger Aesthetics**: High-end command line styling, loader animations, and formatted terminal markdown output.
|
|
11
|
+
## Install
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @kinqs/brainrouter-cli
|
|
15
|
+
```
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install
|
|
23
|
-
npm run build
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
2. **Configure Provider and Server Profiles**:
|
|
27
|
-
Run the interactive configurator to set up your LLM settings (OpenAI, local endpoints like Ollama/LM Studio) and active server profile.
|
|
28
|
-
From the repository root:
|
|
29
|
-
```bash
|
|
30
|
-
npm run cli config
|
|
31
|
-
```
|
|
32
|
-
Or from the `brainrouter` package subdirectory:
|
|
33
|
-
```bash
|
|
34
|
-
node dist/index.js config
|
|
35
|
-
```
|
|
36
|
-
This generates and modifies settings stored in `~/.config/brainrouter/config.json`.
|
|
17
|
+
**The `-g` flag is critical.** Without it, npm installs into the current
|
|
18
|
+
directory's `node_modules/` and the `brainrouter` binary ends up at
|
|
19
|
+
`./node_modules/.bin/brainrouter` — not on `$PATH`. Symptom: `brainrouter:
|
|
20
|
+
command not found`.
|
|
37
21
|
|
|
38
|
-
|
|
22
|
+
**Sudo caveat.** Whether you need `sudo` depends on your Node install:
|
|
23
|
+
|
|
24
|
+
| How Node is installed | Use `sudo`? |
|
|
25
|
+
|---|---|
|
|
26
|
+
| Homebrew (`brew install node`) | ❌ No — global prefix is user-writable |
|
|
27
|
+
| nvm / asdf / fnm | ❌ No — same reason |
|
|
28
|
+
| System Node on macOS / Linux | ✅ Yes — global prefix is `/usr/local/...` |
|
|
29
|
+
|
|
30
|
+
Check yours:
|
|
39
31
|
|
|
40
|
-
## CLI Usage
|
|
41
|
-
|
|
42
|
-
### Start Interactive Agent Session (REPL)
|
|
43
|
-
Starts the agent loop. It will automatically load the active server connection and prime the agent with active codebase memories.
|
|
44
|
-
From the repository root:
|
|
45
|
-
```bash
|
|
46
|
-
npm run cli
|
|
47
|
-
```
|
|
48
|
-
Or to run a specific command:
|
|
49
|
-
```bash
|
|
50
|
-
npm run cli chat
|
|
51
|
-
```
|
|
52
|
-
Or from the `brainrouter` package subdirectory:
|
|
53
|
-
```bash
|
|
54
|
-
node dist/index.js chat
|
|
55
|
-
```
|
|
56
|
-
*Tip: You can override the active LLM model via `--model <name>` or profile via `--profile <name>`.*
|
|
57
|
-
|
|
58
|
-
Workspace detection:
|
|
59
|
-
- By default, BrainRouter uses the nearest project root with `AGENT.md`, `AGENTS.md`, or `.git`.
|
|
60
|
-
- If you run from this package directory during BrainRouter development, the CLI promotes the workspace to the monorepo root so tools see the whole project, not only `brainrouter/`.
|
|
61
|
-
- Override manually with `--workspace /absolute/path/to/project` or `BRAINROUTER_WORKSPACE=/absolute/path/to/project`.
|
|
62
|
-
- In the REPL, run `/workspace` to confirm the active root and session key.
|
|
63
|
-
|
|
64
|
-
### Host Login / Setup Connection
|
|
65
|
-
Interactively log in to a hosted HTTP/SSE BrainRouter deployment and test latency/connectivity:
|
|
66
|
-
From the repository root:
|
|
67
32
|
```bash
|
|
68
|
-
npm
|
|
33
|
+
npm config get prefix
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If the path is under `/Users/...`, `/opt/homebrew/...`, or your home dir
|
|
37
|
+
→ no sudo. If it's `/usr/local/...` → use sudo.
|
|
38
|
+
|
|
39
|
+
Verify the install:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
which brainrouter # prints the path to the binary
|
|
43
|
+
brainrouter --version # prints 0.3.5
|
|
69
44
|
```
|
|
70
45
|
|
|
71
46
|
---
|
|
72
47
|
|
|
73
|
-
##
|
|
48
|
+
## Configure
|
|
49
|
+
|
|
50
|
+
Two configuration surfaces, both one-time:
|
|
74
51
|
|
|
75
|
-
|
|
76
|
-
- `/help` — List all available directive commands.
|
|
77
|
-
- `/status` — Display active server profile details, LLM model, server latency check, and database size stats.
|
|
78
|
-
- `/workspace` — Show active workspace root, launch directory, and BrainRouter session key.
|
|
79
|
-
- `/tools` — Show local workspace tools and MCP tools exposed to the LLM.
|
|
80
|
-
- `/doctor` — Check active profile, MCP connectivity, plan + session store health, and orchestration tool availability.
|
|
81
|
-
- `/skills` — Visualize all loaded BrainRouter skills and categories.
|
|
82
|
-
- `/plan` — Show the durable CLI task plan persisted under `.brainrouter/cli/tasks.json`.
|
|
83
|
-
- `/transcript [main|sessionKey]` — Show recent persisted transcript entries.
|
|
84
|
-
- `/roles` — List built-in agent roles (`explorer`, `architect`, `reviewer`, `worker`, `verifier`) with default access modes.
|
|
85
|
-
- `/agents` — List child agent sessions with status, role, label, and elapsed time.
|
|
86
|
-
- `/agent <id>` — Show child detail, prompt, final output, and recent transcript.
|
|
87
|
-
- `/spawn <role> <prompt>` — Spawn a child agent (parent narrates via the LLM tool call).
|
|
88
|
-
- `/wait <id> [timeoutMs]` — Wait for a child agent to finish.
|
|
89
|
-
- `/spec <title>` — Runs the **spec-driven-skill** and writes a full `spec.md` to `<workspace>/.brainrouter/cli/workflows/<slug>/spec.md`. Stops for approval before generating tasks.
|
|
90
|
-
- `/approve [slug]` — Approves the current (or named) workflow and kicks off the worker + verifier implementation phase, one task at a time, appending to `walkthrough.md`.
|
|
91
|
-
- `/workflows` — List durable workflow folders with per-artifact status (`spec.md`, `tasks.md`, `walkthrough.md`).
|
|
92
|
-
- `/feature-dev <feature>` — Runs the catalogued **agentic-engineering-workflow** skill with explorer + architect orchestration. Writes `spec.md` and `tasks.md` to the workflow folder, then stops for user approval before worker implementation.
|
|
93
|
-
- `/review [scope]` — Runs the catalogued **code-review-and-quality** skill with 3 parallel reviewer agents (correctness, maintainability, conventions).
|
|
94
|
-
- `/implement-plan` — Runs the catalogued **incremental-skill** with a worker + verifier loop on the next pending plan item.
|
|
95
|
-
- `/skill <name> [input]` — Generic invoker for any skill in your `skills/` catalogue. The CLI fetches the skill body via the MCP `get_skill` tool, falls back to filesystem (`skills/**/SKILL.md`), and hands the agent a structured prompt that embeds the skill instructions plus orchestration affordances (`spawn_agent`, `update_plan`).
|
|
52
|
+
### 1. The chat LLM and MCP server profile
|
|
96
53
|
|
|
97
|
-
|
|
54
|
+
```bash
|
|
55
|
+
brainrouter config # interactive — set LLM provider, model, key, endpoint
|
|
56
|
+
brainrouter login # interactive — set MCP server URL + API key
|
|
57
|
+
```
|
|
98
58
|
|
|
99
|
-
|
|
59
|
+
Both write to `~/.config/brainrouter/config.json`.
|
|
100
60
|
|
|
101
|
-
|
|
61
|
+
For local-model setups (LM Studio / Ollama), point the LLM endpoint at
|
|
62
|
+
`http://localhost:1234/v1/chat/completions` or `http://localhost:11434/v1/chat/completions`.
|
|
102
63
|
|
|
103
|
-
|
|
64
|
+
### 2. (Optional) Runtime knobs — `~/.config/brainrouter/cli.env` or `./brainrouter-cli.env`
|
|
104
65
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- The installed `@kinqs/brainrouter-mcp-server` package directory (resolved via `require.resolve`). This works because the MCP package bundles the canonical catalogue at publish time (see below).
|
|
110
|
-
3. Otherwise the CLI hands the agent a benign placeholder and asks it to use general judgement.
|
|
66
|
+
Only needed if you want to tune sandbox, tool-loop limits, trace logging,
|
|
67
|
+
or web-search backend. See the [`.env.example`](.env.example) bundled with
|
|
68
|
+
this package for the full list. LLM credentials do **not** go here — they
|
|
69
|
+
live in `config.json`.
|
|
111
70
|
|
|
112
|
-
|
|
71
|
+
---
|
|
113
72
|
|
|
114
|
-
|
|
73
|
+
## Run
|
|
115
74
|
|
|
116
|
-
|
|
75
|
+
```bash
|
|
76
|
+
brainrouter # starts the interactive REPL
|
|
77
|
+
brainrouter chat # same — `chat` is the default subcommand
|
|
78
|
+
brainrouter run "summarize the changes in src/" # one-shot non-interactive
|
|
79
|
+
brainrouter agents # list child agent sessions in this workspace
|
|
80
|
+
```
|
|
117
81
|
|
|
118
|
-
|
|
119
|
-
|
|
82
|
+
Inside the REPL, type `/help` for the full slash-command list (60+
|
|
83
|
+
commands across session / memory / workflow / orchestration / observability
|
|
84
|
+
surfaces).
|
|
120
85
|
|
|
121
|
-
|
|
86
|
+
### Offline mode
|
|
122
87
|
|
|
123
|
-
|
|
88
|
+
If the MCP server isn't reachable, the CLI still boots — but only local
|
|
89
|
+
tools (file edits, shell, web fetch, `spawn_agent`) work. Memory recall,
|
|
90
|
+
capture, and skills are disabled until the server is back. The startup
|
|
91
|
+
banner shows `⚠️ OFFLINE MODE` when this happens. Pass `--strict-mcp` to
|
|
92
|
+
make the CLI exit instead of degrading.
|
|
124
93
|
|
|
125
|
-
|
|
94
|
+
### Stdio mode
|
|
126
95
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
tasks.md # produced by /feature-dev phase 3
|
|
132
|
-
walkthrough.md # appended by /implement-plan as items ship
|
|
133
|
-
review.md # produced by /review
|
|
134
|
-
```
|
|
96
|
+
If you'd rather have the CLI spawn the MCP server as a child process
|
|
97
|
+
instead of running it separately, use `brainrouter config` → "Set Active
|
|
98
|
+
Server Profile" → `default` (the bundled stdio profile). You don't need
|
|
99
|
+
to run anything else — the CLI manages the server's lifecycle.
|
|
135
100
|
|
|
136
|
-
|
|
101
|
+
---
|
|
137
102
|
|
|
138
|
-
|
|
103
|
+
## Workspace detection
|
|
139
104
|
|
|
140
|
-
|
|
105
|
+
By default, the CLI uses the nearest project root with `AGENT.md`,
|
|
106
|
+
`AGENTS.md`, or `.git`. Override with:
|
|
141
107
|
|
|
142
|
-
|
|
108
|
+
```bash
|
|
109
|
+
brainrouter --workspace /absolute/path/to/project
|
|
110
|
+
# or
|
|
111
|
+
BRAINROUTER_WORKSPACE=/absolute/path/to/project brainrouter
|
|
112
|
+
```
|
|
143
113
|
|
|
144
|
-
|
|
145
|
-
2. **`memory_working_context`** — current working canvas, so resumed sessions don't reset.
|
|
146
|
-
3. **`memory_task_state`** — open tasks / handover notes for this workspace.
|
|
114
|
+
Inside the REPL, run `/workspace` to confirm the active root and session key.
|
|
147
115
|
|
|
148
|
-
|
|
116
|
+
---
|
|
149
117
|
|
|
150
|
-
|
|
118
|
+
## What you also probably want
|
|
151
119
|
|
|
152
|
-
|
|
120
|
+
A BrainRouter MCP server for the cognitive memory. The CLI works without
|
|
121
|
+
it (offline mode) but you lose recall, capture, and skills:
|
|
153
122
|
|
|
154
|
-
|
|
123
|
+
```bash
|
|
124
|
+
npm install -g @kinqs/brainrouter-mcp-server
|
|
125
|
+
brainrouter-mcp init # one-time: scaffold ~/.config/brainrouter/server.env
|
|
126
|
+
$EDITOR ~/.config/brainrouter/server.env # set BRAINROUTER_LLM_API_KEY, embeddings, etc.
|
|
127
|
+
brainrouter-mcp --http --port 3747 # in a separate terminal
|
|
128
|
+
```
|
|
155
129
|
|
|
156
|
-
|
|
157
|
-
- `/recall <query>` — explicit `memory_recall`, no LLM turn.
|
|
158
|
-
- `/briefing` — what was recalled before the most recent turn.
|
|
159
|
-
- `/scenes` — list active focus scenes.
|
|
160
|
-
- `/working` — current working-memory canvas.
|
|
161
|
-
- `/forget <recordId>` — archive an obsolete memory.
|
|
130
|
+
Then `brainrouter login` and point at `http://localhost:3747/mcp`.
|
|
162
131
|
|
|
163
|
-
|
|
132
|
+
---
|
|
164
133
|
|
|
165
|
-
|
|
134
|
+
## Docs
|
|
166
135
|
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
- `/exit` — Close connections and exit.
|
|
136
|
+
- **Repo**: <https://github.com/kinqsradiollc/BrainRouter>
|
|
137
|
+
- **Memory engine deep-dive**: [BRAINROUTER.md](https://github.com/kinqsradiollc/BrainRouter/blob/main/BRAINROUTER.md)
|
|
138
|
+
- **Maintainer runbook**: [SETUP.md](https://github.com/kinqsradiollc/BrainRouter/blob/main/SETUP.md)
|
|
139
|
+
- **Bugs / requests**: <https://github.com/kinqsradiollc/BrainRouter/issues>
|
|
172
140
|
|
|
173
141
|
---
|
|
174
142
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
1. **BrainRouter Memory Tools** (loaded dynamically via the MCP connection): `memory_recall`, `memory_capture_turn`, `list_skills`, etc.
|
|
179
|
-
2. **Local Workspace Tools**:
|
|
180
|
-
- `read_file` — Reads content of a workspace file.
|
|
181
|
-
- `write_file` — Overwrites or writes a new file.
|
|
182
|
-
- `edit_file` — Performs safe single-match string search-and-replace.
|
|
183
|
-
- `list_dir` — Lists directory paths.
|
|
184
|
-
- `grep_search` — Platform-independent recursive search of code patterns.
|
|
185
|
-
- `run_command` — Runs a shell command on your host (always requests manual confirmation first for safety).
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT
|
package/bin/cli.cjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Thin CommonJS shim that runs BEFORE the real ESM CLI entrypoint.
|
|
5
|
+
*
|
|
6
|
+
* Why CJS for the bin: ESM hoists all `import` statements above any
|
|
7
|
+
* top-level code in the module that owns them. The CLI imports
|
|
8
|
+
* `node:sqlite` transitively via `config/config.ts`, which triggers
|
|
9
|
+
* Node's `ExperimentalWarning` the FIRST time the module is touched —
|
|
10
|
+
* and that happens during import resolution, before any line of code
|
|
11
|
+
* in `src/index.ts` runs. So a warning filter installed inside that
|
|
12
|
+
* file always fires too late.
|
|
13
|
+
*
|
|
14
|
+
* This shim does three things synchronously, with zero ESM imports
|
|
15
|
+
* blocking it, and only then hands off:
|
|
16
|
+
*
|
|
17
|
+
* 1. Remove Node's default "warning" printer.
|
|
18
|
+
* 2. Install a filtered listener that drops `ExperimentalWarning`
|
|
19
|
+
* (sqlite, ESM in older Node) and dotenv self-promotion lines.
|
|
20
|
+
* 3. Override `process.emitWarning` so future direct callers also
|
|
21
|
+
* route through the same filter.
|
|
22
|
+
*
|
|
23
|
+
* Anything BrainRouter itself emits via `process.emitWarning('…',
|
|
24
|
+
* 'BrainRouterWarning')` (or any non-suppressible type) flows through
|
|
25
|
+
* unchanged. NODE_NO_WARNINGS=1 would silence those too, which is why
|
|
26
|
+
* we don't just set that env.
|
|
27
|
+
*
|
|
28
|
+
* The shim then dynamically imports the ESM entry. Dynamic `import()`
|
|
29
|
+
* is the only way to load ESM from CJS; it returns a promise we await
|
|
30
|
+
* so an unhandled rejection during boot still surfaces as an error.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
function isSuppressibleWarning(message, type) {
|
|
34
|
+
const looksExperimental =
|
|
35
|
+
type === 'ExperimentalWarning' ||
|
|
36
|
+
/experimental feature|SQLite is an experimental/i.test(message);
|
|
37
|
+
const looksDotenvNoise = /dotenv@\d|dotenvx|dotenv\.org/i.test(message);
|
|
38
|
+
return looksExperimental || looksDotenvNoise;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const listener of process.listeners('warning')) {
|
|
42
|
+
process.removeListener('warning', listener);
|
|
43
|
+
}
|
|
44
|
+
process.on('warning', (warning) => {
|
|
45
|
+
const message = (warning && warning.message) || '';
|
|
46
|
+
const type = (warning && warning.name) || '';
|
|
47
|
+
if (isSuppressibleWarning(message, type)) return;
|
|
48
|
+
process.stderr.write(`(node:${process.pid}) ${type || 'Warning'}: ${message || warning}\n`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const originalEmitWarning = process.emitWarning.bind(process);
|
|
52
|
+
process.emitWarning = function emitWarning(warning, ...rest) {
|
|
53
|
+
const message = typeof warning === 'string' ? warning : (warning && warning.message) || '';
|
|
54
|
+
const type =
|
|
55
|
+
typeof rest[0] === 'string' ? rest[0] :
|
|
56
|
+
(rest[0] && typeof rest[0] === 'object' && 'type' in rest[0]) ? rest[0].type :
|
|
57
|
+
(warning && warning.name) || '';
|
|
58
|
+
if (isSuppressibleWarning(message, type)) return;
|
|
59
|
+
return originalEmitWarning(warning, ...rest);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Path to the compiled ESM entry, resolved relative to this shim.
|
|
63
|
+
const path = require('node:path');
|
|
64
|
+
const url = require('node:url');
|
|
65
|
+
const entry = path.resolve(__dirname, '..', 'dist', 'index.js');
|
|
66
|
+
import(url.pathToFileURL(entry).href).catch((err) => {
|
|
67
|
+
// Surface boot-time errors verbatim — a silent exit would just look like
|
|
68
|
+
// the CLI never started.
|
|
69
|
+
process.stderr.write(`brainrouter: failed to load CLI entrypoint: ${(err && err.stack) || err}\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
});
|