@kinqs/brainrouter-cli 0.3.4
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 +109 -0
- package/README.md +185 -0
- package/dist/agent/agent.d.ts +765 -0
- package/dist/agent/agent.js +1977 -0
- package/dist/cli/cliPrompt.d.ts +15 -0
- package/dist/cli/cliPrompt.js +62 -0
- package/dist/cli/commands/_context.d.ts +53 -0
- package/dist/cli/commands/_context.js +14 -0
- package/dist/cli/commands/_helpers.d.ts +45 -0
- package/dist/cli/commands/_helpers.js +140 -0
- package/dist/cli/commands/guard.d.ts +6 -0
- package/dist/cli/commands/guard.js +292 -0
- package/dist/cli/commands/memory.d.ts +12 -0
- package/dist/cli/commands/memory.js +263 -0
- package/dist/cli/commands/obs.d.ts +6 -0
- package/dist/cli/commands/obs.js +208 -0
- package/dist/cli/commands/orchestration.d.ts +6 -0
- package/dist/cli/commands/orchestration.js +218 -0
- package/dist/cli/commands/session.d.ts +6 -0
- package/dist/cli/commands/session.js +191 -0
- package/dist/cli/commands/ui.d.ts +6 -0
- package/dist/cli/commands/ui.js +477 -0
- package/dist/cli/commands/workflow.d.ts +6 -0
- package/dist/cli/commands/workflow.js +691 -0
- package/dist/cli/repl.d.ts +12 -0
- package/dist/cli/repl.js +894 -0
- package/dist/config/config.d.ts +22 -0
- package/dist/config/config.js +105 -0
- package/dist/config/workspace.d.ts +7 -0
- package/dist/config/workspace.js +62 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +610 -0
- package/dist/memory/briefing.d.ts +46 -0
- package/dist/memory/briefing.js +152 -0
- package/dist/memory/consolidation.d.ts +60 -0
- package/dist/memory/consolidation.js +208 -0
- package/dist/memory/formatters.d.ts +38 -0
- package/dist/memory/formatters.js +102 -0
- package/dist/memory/mentions.d.ts +10 -0
- package/dist/memory/mentions.js +72 -0
- package/dist/orchestration/orchestrator.d.ts +36 -0
- package/dist/orchestration/orchestrator.js +71 -0
- package/dist/orchestration/roles.d.ts +11 -0
- package/dist/orchestration/roles.js +117 -0
- package/dist/orchestration/tools.d.ts +244 -0
- package/dist/orchestration/tools.js +528 -0
- package/dist/prompt/breadthHint.d.ts +48 -0
- package/dist/prompt/breadthHint.js +93 -0
- package/dist/prompt/compactor.d.ts +31 -0
- package/dist/prompt/compactor.js +112 -0
- package/dist/prompt/initAgentMd.d.ts +13 -0
- package/dist/prompt/initAgentMd.js +194 -0
- package/dist/prompt/skillRunner.d.ts +34 -0
- package/dist/prompt/skillRunner.js +146 -0
- package/dist/prompt/systemPrompt.d.ts +10 -0
- package/dist/prompt/systemPrompt.js +171 -0
- package/dist/runtime/clipboard.d.ts +17 -0
- package/dist/runtime/clipboard.js +52 -0
- package/dist/runtime/llmSemaphore.d.ts +30 -0
- package/dist/runtime/llmSemaphore.js +67 -0
- package/dist/runtime/loopRunner.d.ts +25 -0
- package/dist/runtime/loopRunner.js +79 -0
- package/dist/runtime/mcpClient.d.ts +156 -0
- package/dist/runtime/mcpClient.js +234 -0
- package/dist/runtime/mcpUtils.d.ts +36 -0
- package/dist/runtime/mcpUtils.js +64 -0
- package/dist/runtime/sandbox.d.ts +48 -0
- package/dist/runtime/sandbox.js +156 -0
- package/dist/runtime/tracing.d.ts +25 -0
- package/dist/runtime/tracing.js +91 -0
- package/dist/state/cliState.d.ts +59 -0
- package/dist/state/cliState.js +311 -0
- package/dist/state/goalStore.d.ts +174 -0
- package/dist/state/goalStore.js +410 -0
- package/dist/state/hookifyStore.d.ts +80 -0
- package/dist/state/hookifyStore.js +237 -0
- package/dist/state/hooksStore.d.ts +42 -0
- package/dist/state/hooksStore.js +71 -0
- package/dist/state/preferencesStore.d.ts +41 -0
- package/dist/state/preferencesStore.js +25 -0
- package/dist/state/sessionStore.d.ts +42 -0
- package/dist/state/sessionStore.js +193 -0
- package/dist/state/taskStore.d.ts +23 -0
- package/dist/state/taskStore.js +80 -0
- package/dist/state/workflowArtifacts.d.ts +33 -0
- package/dist/state/workflowArtifacts.js +139 -0
- package/package.json +71 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ServerConfig {
|
|
2
|
+
type: 'stdio' | 'http';
|
|
3
|
+
command?: string;
|
|
4
|
+
args?: string[];
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
url?: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LLMConfig {
|
|
10
|
+
provider: 'openai';
|
|
11
|
+
apiKey: string;
|
|
12
|
+
model: string;
|
|
13
|
+
endpoint?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface Config {
|
|
16
|
+
activeServer: string;
|
|
17
|
+
servers: Record<string, ServerConfig>;
|
|
18
|
+
llm?: LLMConfig;
|
|
19
|
+
}
|
|
20
|
+
export declare function getConfigPath(): string;
|
|
21
|
+
export declare function loadConfig(): Config;
|
|
22
|
+
export declare function saveConfig(config: Config): void;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'brainrouter');
|
|
6
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
7
|
+
export function getConfigPath() {
|
|
8
|
+
return CONFIG_FILE;
|
|
9
|
+
}
|
|
10
|
+
export function loadConfig() {
|
|
11
|
+
let config;
|
|
12
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
13
|
+
config = createDefaultConfig();
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
try {
|
|
17
|
+
const raw = fs.readFileSync(CONFIG_FILE, 'utf8');
|
|
18
|
+
const parsed = JSON.parse(raw);
|
|
19
|
+
// Backfill standard properties if missing
|
|
20
|
+
if (!parsed.servers)
|
|
21
|
+
parsed.servers = {};
|
|
22
|
+
if (!parsed.activeServer)
|
|
23
|
+
parsed.activeServer = 'default';
|
|
24
|
+
config = parsed;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
console.error(`Warning: Failed to parse config file at ${CONFIG_FILE}. Using default config.`);
|
|
28
|
+
config = createDefaultConfig();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Auto-resolve placeholder API keys if possible
|
|
32
|
+
resolveDefaultApiKey(config);
|
|
33
|
+
// The default config writes `llm.apiKey: ''` so it never appears as a
|
|
34
|
+
// secret in the committed file. Backfill from the standard env vars at
|
|
35
|
+
// load time so every downstream consumer (callOpenAI, mcpClient env
|
|
36
|
+
// propagation, the cognitive extractor LLM runner) sees a real value
|
|
37
|
+
// instead of the empty string.
|
|
38
|
+
if (config.llm && !config.llm.apiKey.trim()) {
|
|
39
|
+
const envKey = process.env.OPENAI_API_KEY || process.env.BRAINROUTER_LLM_API_KEY;
|
|
40
|
+
if (envKey)
|
|
41
|
+
config.llm.apiKey = envKey;
|
|
42
|
+
}
|
|
43
|
+
return config;
|
|
44
|
+
}
|
|
45
|
+
export function saveConfig(config) {
|
|
46
|
+
try {
|
|
47
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
48
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error(`Error: Failed to save config to ${CONFIG_FILE}:`, error instanceof Error ? error.message : error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function createDefaultConfig() {
|
|
57
|
+
// Derive path to the default local MCP server dist relative to this module.
|
|
58
|
+
// After build: brainrouter-cli/dist/config/config.js → walk three levels up
|
|
59
|
+
// to the monorepo root, then into the sibling `brainrouter/` package
|
|
60
|
+
// (formerly `mcp/`) which is the MCP server.
|
|
61
|
+
const defaultMcpPath = path.resolve(import.meta.dirname, '..', '..', '..', 'brainrouter', 'dist', 'index.js');
|
|
62
|
+
const config = {
|
|
63
|
+
activeServer: 'default',
|
|
64
|
+
servers: {
|
|
65
|
+
default: {
|
|
66
|
+
type: 'stdio',
|
|
67
|
+
command: 'node',
|
|
68
|
+
args: [defaultMcpPath, '--root', './'],
|
|
69
|
+
env: {
|
|
70
|
+
BRAINROUTER_API_KEY: 'br_admin_key_placeholder'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
llm: {
|
|
75
|
+
provider: 'openai',
|
|
76
|
+
apiKey: '',
|
|
77
|
+
model: 'gpt-4o-mini',
|
|
78
|
+
endpoint: 'https://api.openai.com/v1'
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
saveConfig(config);
|
|
82
|
+
return config;
|
|
83
|
+
}
|
|
84
|
+
function resolveDefaultApiKey(config) {
|
|
85
|
+
const defaultServer = config.servers.default;
|
|
86
|
+
if (defaultServer &&
|
|
87
|
+
defaultServer.type === 'stdio' &&
|
|
88
|
+
defaultServer.env &&
|
|
89
|
+
defaultServer.env.BRAINROUTER_API_KEY === 'br_admin_key_placeholder') {
|
|
90
|
+
const dbPath = process.env.BRAINROUTER_MEMORY_DB || path.join(os.homedir(), '.brainrouter', 'memory.db');
|
|
91
|
+
if (fs.existsSync(dbPath)) {
|
|
92
|
+
try {
|
|
93
|
+
const db = new DatabaseSync(dbPath);
|
|
94
|
+
const row = db.prepare("SELECT api_key FROM users WHERE is_admin = 1 LIMIT 1").get();
|
|
95
|
+
if (row && row.api_key) {
|
|
96
|
+
defaultServer.env.BRAINROUTER_API_KEY = row.api_key;
|
|
97
|
+
saveConfig(config);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
// ignore errors
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const ROOT_MARKERS = ['AGENT.md', 'AGENTS.md', '.git'];
|
|
4
|
+
export function findWorkspaceRoot(startDir = process.cwd()) {
|
|
5
|
+
const launchCwd = fs.realpathSync(startDir);
|
|
6
|
+
const envRoot = process.env.BRAINROUTER_WORKSPACE;
|
|
7
|
+
if (envRoot) {
|
|
8
|
+
return {
|
|
9
|
+
launchCwd,
|
|
10
|
+
workspaceRoot: fs.realpathSync(path.resolve(envRoot)),
|
|
11
|
+
reason: 'BRAINROUTER_WORKSPACE',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const markerRoot = findNearestMarkerRoot(launchCwd);
|
|
15
|
+
if (markerRoot) {
|
|
16
|
+
const monorepoRoot = maybePromoteBrainRouterPackage(markerRoot);
|
|
17
|
+
return {
|
|
18
|
+
launchCwd,
|
|
19
|
+
workspaceRoot: monorepoRoot.root,
|
|
20
|
+
reason: monorepoRoot.reason,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
launchCwd,
|
|
25
|
+
workspaceRoot: launchCwd,
|
|
26
|
+
reason: 'cwd',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function applyWorkspaceRoot(workspaceRoot) {
|
|
30
|
+
process.chdir(workspaceRoot);
|
|
31
|
+
}
|
|
32
|
+
function findNearestMarkerRoot(startDir) {
|
|
33
|
+
let current = startDir;
|
|
34
|
+
while (true) {
|
|
35
|
+
if (ROOT_MARKERS.some(marker => fs.existsSync(path.join(current, marker)))) {
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
const parent = path.dirname(current);
|
|
39
|
+
if (parent === current)
|
|
40
|
+
return undefined;
|
|
41
|
+
current = parent;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function maybePromoteBrainRouterPackage(root) {
|
|
45
|
+
const parent = path.dirname(root);
|
|
46
|
+
const packageJsonPath = path.join(parent, 'package.json');
|
|
47
|
+
if (path.basename(root) === 'brainrouter-cli' &&
|
|
48
|
+
fs.existsSync(path.join(parent, 'AGENT.md')) &&
|
|
49
|
+
fs.existsSync(packageJsonPath)) {
|
|
50
|
+
try {
|
|
51
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
52
|
+
const workspaces = Array.isArray(packageJson.workspaces) ? packageJson.workspaces : [];
|
|
53
|
+
if (workspaces.includes('brainrouter-cli') || workspaces.includes('brainrouter-cli/*')) {
|
|
54
|
+
return { root: fs.realpathSync(parent), reason: 'parent monorepo workspace' };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Keep the original marker root if package.json is unreadable.
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { root, reason: 'nearest workspace marker' };
|
|
62
|
+
}
|
package/dist/index.d.ts
ADDED