@kinqs/brainrouter-cli 0.3.5 → 0.3.7
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 +29 -52
- package/agents/architect.json +18 -0
- package/agents/explorer.json +18 -0
- package/agents/reviewer.json +18 -0
- package/agents/verifier.json +18 -0
- package/agents/worker.json +18 -0
- package/bin/cli.cjs +71 -0
- package/dist/agent/agent.d.ts +224 -3
- package/dist/agent/agent.js +561 -55
- package/dist/cli/banner.d.ts +80 -0
- package/dist/cli/banner.js +232 -0
- package/dist/cli/cliPrompt.d.ts +106 -0
- package/dist/cli/cliPrompt.js +314 -0
- package/dist/cli/commands/_context.d.ts +3 -1
- package/dist/cli/commands/_helpers.d.ts +1 -1
- package/dist/cli/commands/_helpers.js +6 -6
- package/dist/cli/commands/config.d.ts +46 -0
- package/dist/cli/commands/config.js +1042 -0
- package/dist/cli/commands/guard.js +75 -10
- package/dist/cli/commands/init.d.ts +20 -0
- package/dist/cli/commands/init.js +64 -0
- package/dist/cli/commands/login.d.ts +13 -0
- package/dist/cli/commands/login.js +179 -0
- package/dist/cli/commands/mcp.d.ts +19 -0
- package/dist/cli/commands/mcp.js +286 -0
- package/dist/cli/commands/memory.js +2 -2
- package/dist/cli/commands/obs.js +22 -22
- package/dist/cli/commands/orchestration.js +18 -0
- package/dist/cli/commands/session.js +13 -5
- package/dist/cli/commands/ui.js +202 -91
- package/dist/cli/commands/workflow.d.ts +20 -0
- package/dist/cli/commands/workflow.js +368 -51
- package/dist/cli/ink/ChatApp.d.ts +206 -0
- package/dist/cli/ink/ChatApp.js +493 -0
- package/dist/cli/ink/Frame.d.ts +26 -0
- package/dist/cli/ink/Frame.js +5 -0
- package/dist/cli/ink/Picker.d.ts +65 -0
- package/dist/cli/ink/Picker.js +133 -0
- package/dist/cli/ink/SlashPalette.d.ts +51 -0
- package/dist/cli/ink/SlashPalette.js +136 -0
- package/dist/cli/ink/TextField.d.ts +34 -0
- package/dist/cli/ink/TextField.js +47 -0
- package/dist/cli/ink/WizardApp.d.ts +7 -0
- package/dist/cli/ink/WizardApp.js +422 -0
- package/dist/cli/ink/ambientChat.d.ts +34 -0
- package/dist/cli/ink/ambientChat.js +7 -0
- package/dist/cli/ink/consoleCapture.d.ts +11 -0
- package/dist/cli/ink/consoleCapture.js +33 -0
- package/dist/cli/ink/markdownRender.d.ts +41 -0
- package/dist/cli/ink/markdownRender.js +278 -0
- package/dist/cli/ink/renderWithResizeClear.d.ts +14 -0
- package/dist/cli/ink/renderWithResizeClear.js +33 -0
- package/dist/cli/ink/runChat.d.ts +34 -0
- package/dist/cli/ink/runChat.js +571 -0
- package/dist/cli/ink/runPicker.d.ts +31 -0
- package/dist/cli/ink/runPicker.js +139 -0
- package/dist/cli/ink/runSlashPalette.d.ts +23 -0
- package/dist/cli/ink/runSlashPalette.js +33 -0
- package/dist/cli/ink/runWizard.d.ts +22 -0
- package/dist/cli/ink/runWizard.js +133 -0
- package/dist/cli/ink/stdinHandoff.d.ts +51 -0
- package/dist/cli/ink/stdinHandoff.js +78 -0
- package/dist/cli/ink/toolFormat.d.ts +73 -0
- package/dist/cli/ink/toolFormat.js +180 -0
- package/dist/cli/ink/useTerminalSize.d.ts +35 -0
- package/dist/cli/ink/useTerminalSize.js +26 -0
- package/dist/cli/repl.d.ts +25 -3
- package/dist/cli/repl.js +64 -646
- package/dist/cli/slashSuggest.d.ts +32 -0
- package/dist/cli/slashSuggest.js +146 -0
- 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/cli/wizard/modelsApi.d.ts +72 -0
- package/dist/cli/wizard/modelsApi.js +166 -0
- package/dist/cli/wizard/picker.d.ts +202 -0
- package/dist/cli/wizard/picker.js +547 -0
- package/dist/cli/wizard/providers.d.ts +86 -0
- package/dist/cli/wizard/providers.js +190 -0
- package/dist/cli/wizard/runner.d.ts +13 -0
- package/dist/cli/wizard/runner.js +488 -0
- package/dist/cli/wizard/types.d.ts +122 -0
- package/dist/cli/wizard/types.js +109 -0
- package/dist/config/config.d.ts +52 -0
- package/dist/config/config.js +89 -75
- package/dist/index.js +215 -206
- package/dist/memory/briefing.d.ts +11 -1
- package/dist/memory/briefing.js +69 -1
- package/dist/memory/consolidation.d.ts +1 -1
- package/dist/orchestration/agentRegistry.d.ts +36 -0
- package/dist/orchestration/agentRegistry.js +64 -0
- package/dist/orchestration/orchestrator.d.ts +7 -0
- package/dist/orchestration/orchestrator.js +2 -0
- package/dist/orchestration/tools.d.ts +10 -1
- package/dist/orchestration/tools.js +48 -4
- package/dist/prompt/breadthHint.d.ts +5 -0
- package/dist/prompt/breadthHint.js +44 -0
- package/dist/prompt/skillCatalog.d.ts +11 -0
- package/dist/prompt/skillCatalog.js +134 -0
- package/dist/prompt/skillRunner.d.ts +2 -2
- package/dist/prompt/skillRunner.js +2 -31
- package/dist/prompt/systemPrompt.d.ts +34 -0
- package/dist/prompt/systemPrompt.js +128 -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 +104 -13
- package/dist/runtime/mcpPool.d.ts +162 -0
- package/dist/runtime/mcpPool.js +423 -0
- package/dist/runtime/mcpUtils.d.ts +3 -1
- 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 +12 -5
- package/.env.example +0 -109
package/README.md
CHANGED
|
@@ -6,8 +6,6 @@ recall, skills, and capture.
|
|
|
6
6
|
|
|
7
7
|
Ships the `brainrouter` binary.
|
|
8
8
|
|
|
9
|
-
---
|
|
10
|
-
|
|
11
9
|
## Install
|
|
12
10
|
|
|
13
11
|
```bash
|
|
@@ -23,52 +21,44 @@ command not found`.
|
|
|
23
21
|
|
|
24
22
|
| How Node is installed | Use `sudo`? |
|
|
25
23
|
|---|---|
|
|
26
|
-
| Homebrew (`brew install node`) |
|
|
27
|
-
| nvm / asdf / fnm |
|
|
28
|
-
| System Node on macOS / Linux |
|
|
29
|
-
|
|
30
|
-
Check yours:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm config get prefix
|
|
34
|
-
```
|
|
24
|
+
| Homebrew (`brew install node`) | No — global prefix is user-writable |
|
|
25
|
+
| nvm / asdf / fnm | No — same reason |
|
|
26
|
+
| System Node on macOS / Linux | Yes — global prefix is `/usr/local/...` |
|
|
35
27
|
|
|
36
|
-
If the path is under `/Users/...`,
|
|
37
|
-
|
|
28
|
+
Check yours: `npm config get prefix`. If the path is under `/Users/...`,
|
|
29
|
+
`/opt/homebrew/...`, or your home dir — no sudo. If it's `/usr/local/...` — use sudo.
|
|
38
30
|
|
|
39
31
|
Verify the install:
|
|
40
32
|
|
|
41
33
|
```bash
|
|
42
34
|
which brainrouter # prints the path to the binary
|
|
43
|
-
brainrouter --version # prints 0.3.
|
|
35
|
+
brainrouter --version # prints 0.3.7
|
|
44
36
|
```
|
|
45
37
|
|
|
46
|
-
---
|
|
47
|
-
|
|
48
38
|
## Configure
|
|
49
39
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
### 1. The chat LLM and MCP server profile
|
|
40
|
+
Run `brainrouter` for the first time and the **setup wizard** starts
|
|
41
|
+
automatically:
|
|
53
42
|
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
brainrouter login # interactive — set MCP server URL + API key
|
|
43
|
+
```
|
|
44
|
+
Welcome → Theme → Provider → API key → Model → MCP → AGENT.md → Done
|
|
57
45
|
```
|
|
58
46
|
|
|
59
|
-
|
|
47
|
+
It writes everything to `~/.config/brainrouter/config.json` — no manual
|
|
48
|
+
file editing needed.
|
|
60
49
|
|
|
61
|
-
|
|
62
|
-
`http://localhost:1234/v1/chat/completions` or `http://localhost:11434/v1/chat/completions`.
|
|
50
|
+
To re-run the wizard later: type `/init` inside the REPL.
|
|
63
51
|
|
|
64
|
-
|
|
52
|
+
To change a single setting: use `/config <key> <value>` or the `/config`
|
|
53
|
+
home panel. To re-configure the MCP server connection: use `/login`.
|
|
65
54
|
|
|
66
|
-
|
|
67
|
-
or
|
|
68
|
-
this package for the full list. LLM credentials do **not** go here — they
|
|
69
|
-
live in `config.json`.
|
|
55
|
+
For local-model setups (LM Studio / Ollama), point the LLM endpoint at
|
|
56
|
+
`http://localhost:1234/v1/chat/completions` or `http://localhost:11434/v1/chat/completions`.
|
|
70
57
|
|
|
71
|
-
|
|
58
|
+
**Runtime knobs** (sandbox, trace log, web-search backend, tool-loop limits)
|
|
59
|
+
are set as shell environment variables. See
|
|
60
|
+
[`brainrouter-docs/configuration.md`](https://github.com/kinqsradiollc/BrainRouter/blob/main/brainrouter-docs/configuration.md)
|
|
61
|
+
for the full list.
|
|
72
62
|
|
|
73
63
|
## Run
|
|
74
64
|
|
|
@@ -83,22 +73,15 @@ Inside the REPL, type `/help` for the full slash-command list (60+
|
|
|
83
73
|
commands across session / memory / workflow / orchestration / observability
|
|
84
74
|
surfaces).
|
|
85
75
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
76
|
+
**Offline mode** — if the MCP server isn't reachable, the CLI still boots
|
|
77
|
+
with only local tools (file edits, shell, web fetch, `spawn_agent`). Memory
|
|
78
|
+
recall, capture, and skills are disabled until the server is back. The
|
|
79
|
+
startup banner shows `offline` when this happens. Pass `--strict-mcp` to
|
|
92
80
|
make the CLI exit instead of degrading.
|
|
93
81
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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.
|
|
100
|
-
|
|
101
|
-
---
|
|
82
|
+
**Stdio mode** — to have the CLI spawn the MCP server as a child process
|
|
83
|
+
instead of running it separately: open `/config`, go to MCP settings, and
|
|
84
|
+
pick the bundled `stdio` profile. The CLI manages the server's lifecycle.
|
|
102
85
|
|
|
103
86
|
## Workspace detection
|
|
104
87
|
|
|
@@ -113,8 +96,6 @@ BRAINROUTER_WORKSPACE=/absolute/path/to/project brainrouter
|
|
|
113
96
|
|
|
114
97
|
Inside the REPL, run `/workspace` to confirm the active root and session key.
|
|
115
98
|
|
|
116
|
-
---
|
|
117
|
-
|
|
118
99
|
## What you also probably want
|
|
119
100
|
|
|
120
101
|
A BrainRouter MCP server for the cognitive memory. The CLI works without
|
|
@@ -127,9 +108,7 @@ $EDITOR ~/.config/brainrouter/server.env # set BRAINROUTER_LLM_API_KEY,
|
|
|
127
108
|
brainrouter-mcp --http --port 3747 # in a separate terminal
|
|
128
109
|
```
|
|
129
110
|
|
|
130
|
-
Then
|
|
131
|
-
|
|
132
|
-
---
|
|
111
|
+
Then run `/login` inside the REPL and point at `http://localhost:3747/mcp`.
|
|
133
112
|
|
|
134
113
|
## Docs
|
|
135
114
|
|
|
@@ -138,8 +117,6 @@ Then `brainrouter login` and point at `http://localhost:3747/mcp`.
|
|
|
138
117
|
- **Maintainer runbook**: [SETUP.md](https://github.com/kinqsradiollc/BrainRouter/blob/main/SETUP.md)
|
|
139
118
|
- **Bugs / requests**: <https://github.com/kinqsradiollc/BrainRouter/issues>
|
|
140
119
|
|
|
141
|
-
---
|
|
142
|
-
|
|
143
120
|
## License
|
|
144
121
|
|
|
145
122
|
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "architect",
|
|
3
|
+
"displayName": "Architect",
|
|
4
|
+
"whenToUse": "Design alternatives and tradeoffs for a feature or system change. No file writes.",
|
|
5
|
+
"prompt": "## Role: Architect\nYou design solutions; you do not write production code.\n\n### Memory-first opening (mandatory)\n- `memory_search` and `memory_graph_query` for the feature/domain — past architecture decisions often constrain new ones.\n- `memory_contradictions` (action: list) — if prior designs contradict the proposed change, flag it.\n- Cite any architecture_decision records you find with their recordId.\n\nAlways present at least two design alternatives with explicit tradeoffs (complexity, blast radius, reversibility, test cost).\nEnd with a clear recommendation and the smallest first vertical slice.",
|
|
6
|
+
"model": null,
|
|
7
|
+
"effort": null,
|
|
8
|
+
"defaultAccess": "read",
|
|
9
|
+
"toolScope": { "local": ["*"], "mcp": ["memory_*"] },
|
|
10
|
+
"disallowedTools": [],
|
|
11
|
+
"maxIterations": 30,
|
|
12
|
+
"timeoutMs": 120000,
|
|
13
|
+
"maxResultChars": 8000,
|
|
14
|
+
"subagents": [],
|
|
15
|
+
"delegateName": "delegate_architect",
|
|
16
|
+
"tier": "reasoning",
|
|
17
|
+
"outputContract": null
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "explorer",
|
|
3
|
+
"displayName": "Explorer",
|
|
4
|
+
"whenToUse": "Read-only codebase investigation. Returns concrete file paths, line ranges, and a short list of facts.",
|
|
5
|
+
"prompt": "## Role: Explorer\nYou are a read-only investigator. Do not edit files or run shell commands.\nGoal: map the relevant code, return concrete file paths with line ranges, and surface the few facts the parent needs to decide.\n\n### Memory-first opening (mandatory)\n- Step 1: `memory_search` for the topic of investigation. Past explorers may have mapped this already — do not re-discover what BrainRouter already knows.\n- Step 2: `memory_graph_query` with the dominant feature/entity name to surface related memories across 2 hops.\n- Step 3: `memory_file_history` for any file the parent specifically mentions.\n- Cite every recordId you build on. Your output begins with a `### Memory consulted` block listing the record IDs and what they told you.\n\nOutput structure: 1) Memory consulted, 2) Summary (3-5 bullets), 3) Key files with line ranges, 4) Open questions, 5) Suggested next probe.\nNever claim work is complete without naming actual files you read AND showing the memory you consulted.",
|
|
6
|
+
"model": null,
|
|
7
|
+
"effort": null,
|
|
8
|
+
"defaultAccess": "read",
|
|
9
|
+
"toolScope": { "local": ["*"], "mcp": ["memory_*"] },
|
|
10
|
+
"disallowedTools": [],
|
|
11
|
+
"maxIterations": 30,
|
|
12
|
+
"timeoutMs": 120000,
|
|
13
|
+
"maxResultChars": 8000,
|
|
14
|
+
"subagents": [],
|
|
15
|
+
"delegateName": "delegate_explorer",
|
|
16
|
+
"tier": "reasoning",
|
|
17
|
+
"outputContract": null
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "reviewer",
|
|
3
|
+
"displayName": "Reviewer",
|
|
4
|
+
"whenToUse": "Code review stance; findings first, severity-ordered. Read-only.",
|
|
5
|
+
"prompt": "## Role: Reviewer\nYou review changes critically. Findings first; severity-ordered (blocker, major, minor, nit).\n\n### Memory-first opening (mandatory)\n- `memory_search` for prior reviews on the same files or feature — never re-flag an issue another reviewer already decided is acceptable.\n- `memory_file_history` for each file in the diff — known regressions and prior bug fixes inform your verdict.\n- Cite related recordIds inline in each finding so the parent can see the precedent.\n\nFor each finding: file:line, what is wrong, why it matters, suggested fix.\nDo not make edits. The parent will decide what to apply.",
|
|
6
|
+
"model": null,
|
|
7
|
+
"effort": null,
|
|
8
|
+
"defaultAccess": "read",
|
|
9
|
+
"toolScope": { "local": ["*"], "mcp": ["memory_*"] },
|
|
10
|
+
"disallowedTools": [],
|
|
11
|
+
"maxIterations": 30,
|
|
12
|
+
"timeoutMs": 120000,
|
|
13
|
+
"maxResultChars": 8000,
|
|
14
|
+
"subagents": [],
|
|
15
|
+
"delegateName": "delegate_reviewer",
|
|
16
|
+
"tier": "reasoning",
|
|
17
|
+
"outputContract": null
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "verifier",
|
|
3
|
+
"displayName": "Verifier",
|
|
4
|
+
"whenToUse": "Runs tests and checks; reports pass/fail with evidence.",
|
|
5
|
+
"prompt": "## Role: Verifier\nYou verify that recent changes work. Run the smallest useful set of tests/typechecks.\n\n### Memory-first opening (mandatory)\n- `memory_search` for prior failure modes on these tests — flaky tests, environment caveats, and known-bad commands live in memory.\n- `memory_file_history` for any test file involved — past fixes for the same suite are highly relevant.\n\nReport: which command(s) you ran, exit codes, failing output (trimmed), and a clear PASS/FAIL verdict.\nNever claim PASS without actually executing a check. On failure, call `memory_task_update` with the blocker so the next worker can pick it up.",
|
|
6
|
+
"model": null,
|
|
7
|
+
"effort": null,
|
|
8
|
+
"defaultAccess": "shell",
|
|
9
|
+
"toolScope": { "local": ["*"], "mcp": ["memory_*"] },
|
|
10
|
+
"disallowedTools": [],
|
|
11
|
+
"maxIterations": 30,
|
|
12
|
+
"timeoutMs": 120000,
|
|
13
|
+
"maxResultChars": 8000,
|
|
14
|
+
"subagents": [],
|
|
15
|
+
"delegateName": "delegate_verifier",
|
|
16
|
+
"tier": "worker",
|
|
17
|
+
"outputContract": null
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "worker",
|
|
3
|
+
"displayName": "Worker",
|
|
4
|
+
"whenToUse": "Implementation-focused. May edit files when granted write access.",
|
|
5
|
+
"prompt": "## Role: Worker\nYou implement a single bounded task. Keep edits minimal and scoped.\n\n### Memory-first opening (mandatory)\n- `memory_recall` for the task topic — past instructions, conventions, and tool_preference records often dictate HOW to implement.\n- `memory_file_history` for the files you intend to touch — known fragility lives there.\n- If the parent gave you `seedRecordIds`, treat those as authoritative context.\n- `memory_task_state` if this looks like a continuation — pick up where prior work left off.\n\nRead before editing. Prefer edit_file over write_file when possible. Prefer apply_patch for multi-file edits.\nOn completion call `memory_task_update` with the outcome, then report exactly which files you changed and any follow-ups the verifier should run.",
|
|
6
|
+
"model": null,
|
|
7
|
+
"effort": null,
|
|
8
|
+
"defaultAccess": "write",
|
|
9
|
+
"toolScope": { "local": ["*"], "mcp": ["memory_*"] },
|
|
10
|
+
"disallowedTools": [],
|
|
11
|
+
"maxIterations": 30,
|
|
12
|
+
"timeoutMs": 120000,
|
|
13
|
+
"maxResultChars": 8000,
|
|
14
|
+
"subagents": [],
|
|
15
|
+
"delegateName": "delegate_worker",
|
|
16
|
+
"tier": "worker",
|
|
17
|
+
"outputContract": null
|
|
18
|
+
}
|
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
|
+
});
|