@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.
Files changed (87) hide show
  1. package/.env.example +109 -0
  2. package/README.md +185 -0
  3. package/dist/agent/agent.d.ts +765 -0
  4. package/dist/agent/agent.js +1977 -0
  5. package/dist/cli/cliPrompt.d.ts +15 -0
  6. package/dist/cli/cliPrompt.js +62 -0
  7. package/dist/cli/commands/_context.d.ts +53 -0
  8. package/dist/cli/commands/_context.js +14 -0
  9. package/dist/cli/commands/_helpers.d.ts +45 -0
  10. package/dist/cli/commands/_helpers.js +140 -0
  11. package/dist/cli/commands/guard.d.ts +6 -0
  12. package/dist/cli/commands/guard.js +292 -0
  13. package/dist/cli/commands/memory.d.ts +12 -0
  14. package/dist/cli/commands/memory.js +263 -0
  15. package/dist/cli/commands/obs.d.ts +6 -0
  16. package/dist/cli/commands/obs.js +208 -0
  17. package/dist/cli/commands/orchestration.d.ts +6 -0
  18. package/dist/cli/commands/orchestration.js +218 -0
  19. package/dist/cli/commands/session.d.ts +6 -0
  20. package/dist/cli/commands/session.js +191 -0
  21. package/dist/cli/commands/ui.d.ts +6 -0
  22. package/dist/cli/commands/ui.js +477 -0
  23. package/dist/cli/commands/workflow.d.ts +6 -0
  24. package/dist/cli/commands/workflow.js +691 -0
  25. package/dist/cli/repl.d.ts +12 -0
  26. package/dist/cli/repl.js +894 -0
  27. package/dist/config/config.d.ts +22 -0
  28. package/dist/config/config.js +105 -0
  29. package/dist/config/workspace.d.ts +7 -0
  30. package/dist/config/workspace.js +62 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.js +610 -0
  33. package/dist/memory/briefing.d.ts +46 -0
  34. package/dist/memory/briefing.js +152 -0
  35. package/dist/memory/consolidation.d.ts +60 -0
  36. package/dist/memory/consolidation.js +208 -0
  37. package/dist/memory/formatters.d.ts +38 -0
  38. package/dist/memory/formatters.js +102 -0
  39. package/dist/memory/mentions.d.ts +10 -0
  40. package/dist/memory/mentions.js +72 -0
  41. package/dist/orchestration/orchestrator.d.ts +36 -0
  42. package/dist/orchestration/orchestrator.js +71 -0
  43. package/dist/orchestration/roles.d.ts +11 -0
  44. package/dist/orchestration/roles.js +117 -0
  45. package/dist/orchestration/tools.d.ts +244 -0
  46. package/dist/orchestration/tools.js +528 -0
  47. package/dist/prompt/breadthHint.d.ts +48 -0
  48. package/dist/prompt/breadthHint.js +93 -0
  49. package/dist/prompt/compactor.d.ts +31 -0
  50. package/dist/prompt/compactor.js +112 -0
  51. package/dist/prompt/initAgentMd.d.ts +13 -0
  52. package/dist/prompt/initAgentMd.js +194 -0
  53. package/dist/prompt/skillRunner.d.ts +34 -0
  54. package/dist/prompt/skillRunner.js +146 -0
  55. package/dist/prompt/systemPrompt.d.ts +10 -0
  56. package/dist/prompt/systemPrompt.js +171 -0
  57. package/dist/runtime/clipboard.d.ts +17 -0
  58. package/dist/runtime/clipboard.js +52 -0
  59. package/dist/runtime/llmSemaphore.d.ts +30 -0
  60. package/dist/runtime/llmSemaphore.js +67 -0
  61. package/dist/runtime/loopRunner.d.ts +25 -0
  62. package/dist/runtime/loopRunner.js +79 -0
  63. package/dist/runtime/mcpClient.d.ts +156 -0
  64. package/dist/runtime/mcpClient.js +234 -0
  65. package/dist/runtime/mcpUtils.d.ts +36 -0
  66. package/dist/runtime/mcpUtils.js +64 -0
  67. package/dist/runtime/sandbox.d.ts +48 -0
  68. package/dist/runtime/sandbox.js +156 -0
  69. package/dist/runtime/tracing.d.ts +25 -0
  70. package/dist/runtime/tracing.js +91 -0
  71. package/dist/state/cliState.d.ts +59 -0
  72. package/dist/state/cliState.js +311 -0
  73. package/dist/state/goalStore.d.ts +174 -0
  74. package/dist/state/goalStore.js +410 -0
  75. package/dist/state/hookifyStore.d.ts +80 -0
  76. package/dist/state/hookifyStore.js +237 -0
  77. package/dist/state/hooksStore.d.ts +42 -0
  78. package/dist/state/hooksStore.js +71 -0
  79. package/dist/state/preferencesStore.d.ts +41 -0
  80. package/dist/state/preferencesStore.js +25 -0
  81. package/dist/state/sessionStore.d.ts +42 -0
  82. package/dist/state/sessionStore.js +193 -0
  83. package/dist/state/taskStore.d.ts +23 -0
  84. package/dist/state/taskStore.js +80 -0
  85. package/dist/state/workflowArtifacts.d.ts +33 -0
  86. package/dist/state/workflowArtifacts.js +139 -0
  87. 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,7 @@
1
+ export interface WorkspaceInfo {
2
+ launchCwd: string;
3
+ workspaceRoot: string;
4
+ reason: string;
5
+ }
6
+ export declare function findWorkspaceRoot(startDir?: string): WorkspaceInfo;
7
+ export declare function applyWorkspaceRoot(workspaceRoot: string): void;
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};