byterover-cli 1.1.0 → 1.2.0
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 +8 -4
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.js +61 -0
- package/dist/core/domain/cipher/agent-events/types.d.ts +44 -1
- package/dist/core/domain/entities/agent.js +72 -18
- package/dist/core/domain/entities/connector-type.d.ts +2 -1
- package/dist/core/domain/entities/connector-type.js +2 -1
- package/dist/core/interfaces/connectors/connector-types.d.ts +13 -0
- package/dist/core/interfaces/i-mcp-config-writer.d.ts +40 -0
- package/dist/core/interfaces/i-mcp-config-writer.js +1 -0
- package/dist/core/interfaces/i-rule-template-service.d.ts +4 -2
- package/dist/core/interfaces/transport/i-transport-client.d.ts +7 -0
- package/dist/infra/cipher/agent/cipher-agent.d.ts +8 -0
- package/dist/infra/cipher/agent/cipher-agent.js +16 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +8 -0
- package/dist/infra/cipher/llm/context/context-manager.js +16 -0
- package/dist/infra/cipher/llm/internal-llm-service.d.ts +4 -0
- package/dist/infra/cipher/llm/internal-llm-service.js +38 -10
- package/dist/infra/cipher/session/chat-session.d.ts +3 -0
- package/dist/infra/cipher/session/chat-session.js +7 -1
- package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +1 -8
- package/dist/infra/cipher/tools/implementations/curate-tool.js +360 -22
- package/dist/infra/connectors/connector-manager.js +2 -0
- package/dist/infra/connectors/mcp/index.d.ts +4 -0
- package/dist/infra/connectors/mcp/index.js +4 -0
- package/dist/infra/connectors/mcp/json-mcp-config-writer.d.ts +26 -0
- package/dist/infra/connectors/mcp/json-mcp-config-writer.js +71 -0
- package/dist/infra/connectors/mcp/mcp-connector-config.d.ts +229 -0
- package/dist/infra/connectors/mcp/mcp-connector-config.js +173 -0
- package/dist/infra/connectors/mcp/mcp-connector.d.ts +80 -0
- package/dist/infra/connectors/mcp/mcp-connector.js +324 -0
- package/dist/infra/connectors/mcp/toml-mcp-config-writer.d.ts +45 -0
- package/dist/infra/connectors/mcp/toml-mcp-config-writer.js +134 -0
- package/dist/infra/connectors/rules/rules-connector.d.ts +1 -8
- package/dist/infra/connectors/rules/rules-connector.js +20 -85
- package/dist/infra/connectors/shared/rule-file-manager.d.ts +72 -0
- package/dist/infra/connectors/shared/rule-file-manager.js +119 -0
- package/dist/infra/connectors/shared/template-service.d.ts +10 -1
- package/dist/infra/connectors/shared/template-service.js +53 -16
- package/dist/infra/mcp/index.d.ts +2 -0
- package/dist/infra/mcp/index.js +2 -0
- package/dist/infra/mcp/mcp-server.d.ts +58 -0
- package/dist/infra/mcp/mcp-server.js +178 -0
- package/dist/infra/mcp/tools/brv-curate-tool.d.ts +23 -0
- package/dist/infra/mcp/tools/brv-curate-tool.js +68 -0
- package/dist/infra/mcp/tools/brv-query-tool.d.ts +17 -0
- package/dist/infra/mcp/tools/brv-query-tool.js +68 -0
- package/dist/infra/mcp/tools/index.d.ts +3 -0
- package/dist/infra/mcp/tools/index.js +3 -0
- package/dist/infra/mcp/tools/task-result-waiter.d.ts +30 -0
- package/dist/infra/mcp/tools/task-result-waiter.js +56 -0
- package/dist/infra/process/agent-worker.js +37 -0
- package/dist/infra/repl/commands/curate-command.js +2 -2
- package/dist/infra/transport/socket-io-transport-client.d.ts +7 -0
- package/dist/infra/transport/socket-io-transport-client.js +25 -0
- package/dist/infra/transport/socket-io-transport-server.js +4 -0
- package/dist/infra/usecase/connectors-use-case.d.ts +4 -0
- package/dist/infra/usecase/connectors-use-case.js +29 -10
- package/dist/infra/usecase/init-use-case.js +2 -3
- package/dist/infra/usecase/status-use-case.d.ts +10 -0
- package/dist/infra/usecase/status-use-case.js +53 -0
- package/dist/resources/prompts/curate.yml +107 -4
- package/dist/templates/mcp-base.md +1 -0
- package/dist/templates/sections/mcp-workflow.md +13 -0
- package/dist/tui/app.js +4 -1
- package/dist/tui/components/command-details.js +1 -1
- package/dist/tui/components/execution/execution-changes.d.ts +2 -0
- package/dist/tui/components/execution/execution-changes.js +5 -1
- package/dist/tui/components/execution/execution-content.d.ts +2 -0
- package/dist/tui/components/execution/execution-content.js +8 -18
- package/dist/tui/components/execution/execution-input.d.ts +2 -0
- package/dist/tui/components/execution/execution-input.js +6 -4
- package/dist/tui/components/execution/execution-progress.d.ts +2 -0
- package/dist/tui/components/execution/execution-progress.js +6 -2
- package/dist/tui/components/execution/expanded-log-view.d.ts +20 -0
- package/dist/tui/components/execution/expanded-log-view.js +75 -0
- package/dist/tui/components/execution/expanded-message-view.d.ts +24 -0
- package/dist/tui/components/execution/expanded-message-view.js +68 -0
- package/dist/tui/components/execution/index.d.ts +2 -0
- package/dist/tui/components/execution/index.js +2 -0
- package/dist/tui/components/execution/log-item.d.ts +4 -0
- package/dist/tui/components/execution/log-item.js +2 -2
- package/dist/tui/components/footer.js +1 -1
- package/dist/tui/components/index.d.ts +2 -1
- package/dist/tui/components/index.js +2 -1
- package/dist/tui/components/init.js +2 -9
- package/dist/tui/components/logo.js +4 -3
- package/dist/tui/components/markdown.d.ts +13 -0
- package/dist/tui/components/markdown.js +88 -0
- package/dist/tui/components/message-item.js +1 -1
- package/dist/tui/components/onboarding/onboarding-flow.js +1 -1
- package/dist/tui/components/suggestions.js +3 -3
- package/dist/tui/contexts/mode-context.js +6 -2
- package/dist/tui/hooks/index.d.ts +1 -0
- package/dist/tui/hooks/index.js +1 -0
- package/dist/tui/hooks/use-is-latest-version.d.ts +6 -0
- package/dist/tui/hooks/use-is-latest-version.js +22 -0
- package/dist/tui/views/command-view.d.ts +1 -1
- package/dist/tui/views/command-view.js +83 -98
- package/dist/tui/views/logs-view.d.ts +8 -0
- package/dist/tui/views/logs-view.js +55 -27
- package/oclif.manifest.json +26 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@ Command-line interface for ByteRover, featuring an interactive REPL with a moder
|
|
|
31
31
|
- Debian/Ubuntu: `sudo apt-get install libsecret-1-dev`
|
|
32
32
|
- Red Hat-based: `sudo yum install libsecret-devel`
|
|
33
33
|
- Arch Linux: `sudo pacman -S libsecret`
|
|
34
|
+
- **WSL (Windows Subsystem for Linux)**: Supported with automatic file-based token storage fallback when keychain is unavailable
|
|
34
35
|
|
|
35
36
|
### Install globally via npm
|
|
36
37
|
|
|
@@ -99,7 +100,9 @@ The terminal UI includes:
|
|
|
99
100
|
- **Command Completion**: Type `/` to see available commands with auto-completion
|
|
100
101
|
- **Activity Log**: Real-time task status and execution progress
|
|
101
102
|
- **Streaming Output**: Live responses from AI-powered operations
|
|
102
|
-
- **File References**: Type `@` in curate mode to browse and attach files
|
|
103
|
+
- **File References**: Type `@` in curate mode to browse and attach files (supports PDF)
|
|
104
|
+
- **Dynamic Domains**: Automatically creates new knowledge domains as your context tree grows
|
|
105
|
+
- **Session Persistence**: Sessions auto-resume after restart
|
|
103
106
|
|
|
104
107
|
### Using Commands
|
|
105
108
|
|
|
@@ -141,9 +144,10 @@ Use `/connectors` to manage integrations with your AI coding agents:
|
|
|
141
144
|
/connectors
|
|
142
145
|
```
|
|
143
146
|
|
|
144
|
-
ByteRover supports
|
|
147
|
+
ByteRover supports three connector types:
|
|
145
148
|
- **Hook integration** (Claude Code): Direct injection via IDE settings for seamless integration
|
|
146
149
|
- **Rules-based** (all agents): Generates agent-specific rule files (e.g., `CLAUDE.md`, `.cursorrules`) that instruct the agent how to read from and contribute to your context tree
|
|
150
|
+
- **MCP integration** (Model Context Protocol): Exposes `brv-query` and `brv-curate` as MCP tools that AI agents can call directly
|
|
147
151
|
|
|
148
152
|
## Slash Commands Reference
|
|
149
153
|
|
|
@@ -159,7 +163,7 @@ ByteRover supports two connector types:
|
|
|
159
163
|
```
|
|
160
164
|
/curate # Interactive mode
|
|
161
165
|
/curate "Auth uses JWT tokens" # Autonomous mode with text
|
|
162
|
-
/curate "API docs" @src/api.ts @README.md # With file references (max 5)
|
|
166
|
+
/curate "API docs" @src/api.ts @README.md # With file references (max 5, supports PDF)
|
|
163
167
|
```
|
|
164
168
|
|
|
165
169
|
**Query example:**
|
|
@@ -219,7 +223,7 @@ ByteRover supports two connector types:
|
|
|
219
223
|
**Options:**
|
|
220
224
|
- `-y, --yes`: Skip confirmation prompt
|
|
221
225
|
|
|
222
|
-
**Note:**
|
|
226
|
+
**Note:** Sessions are stateful and auto-resume after restart. Use `/new` to start fresh—this clears conversation history but does NOT affect the context tree.
|
|
223
227
|
|
|
224
228
|
### Project Setup
|
|
225
229
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* MCP command - starts the MCP server for coding agent integration.
|
|
4
|
+
*
|
|
5
|
+
* This command is spawned by coding agents (Claude Code, Cursor, Windsurf)
|
|
6
|
+
* and connects to a running brv instance via Socket.IO.
|
|
7
|
+
*/
|
|
8
|
+
export default class Mcp extends Command {
|
|
9
|
+
static description: string;
|
|
10
|
+
static examples: string[];
|
|
11
|
+
static hidden: boolean;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { NoInstanceRunningError } from '../core/domain/errors/connection-error.js';
|
|
3
|
+
import { ByteRoverMcpServer } from '../infra/mcp/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* MCP command - starts the MCP server for coding agent integration.
|
|
6
|
+
*
|
|
7
|
+
* This command is spawned by coding agents (Claude Code, Cursor, Windsurf)
|
|
8
|
+
* and connects to a running brv instance via Socket.IO.
|
|
9
|
+
*/
|
|
10
|
+
export default class Mcp extends Command {
|
|
11
|
+
static description = `Start MCP server for coding agent integration
|
|
12
|
+
|
|
13
|
+
Connects to a running brv instance via Socket.IO.
|
|
14
|
+
Requires: brv running in another terminal.
|
|
15
|
+
|
|
16
|
+
Exposes tools:
|
|
17
|
+
- brv-query: Query the context tree
|
|
18
|
+
- brv-curate: Curate context to the tree`;
|
|
19
|
+
static examples = [
|
|
20
|
+
'# Start MCP server (typically called by coding agents)',
|
|
21
|
+
'<%= config.bin %> <%= command.id %>',
|
|
22
|
+
];
|
|
23
|
+
static hidden = true; // Called by agents, not users directly
|
|
24
|
+
async run() {
|
|
25
|
+
try {
|
|
26
|
+
const server = new ByteRoverMcpServer({
|
|
27
|
+
version: this.config.version,
|
|
28
|
+
workingDirectory: process.cwd(),
|
|
29
|
+
});
|
|
30
|
+
// Graceful shutdown
|
|
31
|
+
const cleanup = async () => {
|
|
32
|
+
await server.stop();
|
|
33
|
+
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit
|
|
34
|
+
process.exit(0);
|
|
35
|
+
};
|
|
36
|
+
process.on('SIGTERM', cleanup);
|
|
37
|
+
process.on('SIGINT', cleanup);
|
|
38
|
+
await server.start();
|
|
39
|
+
// Keep the process alive - MCP server runs on stdio
|
|
40
|
+
// The process will be terminated by SIGTERM/SIGINT or when the parent process closes stdin
|
|
41
|
+
await new Promise((resolve) => {
|
|
42
|
+
process.stdin.on('close', () => {
|
|
43
|
+
resolve();
|
|
44
|
+
});
|
|
45
|
+
process.stdin.on('end', () => {
|
|
46
|
+
resolve();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
await server.stop();
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof NoInstanceRunningError) {
|
|
53
|
+
this.logToStderr('Error: No ByteRover instance running.');
|
|
54
|
+
this.logToStderr('Start one with: brv');
|
|
55
|
+
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -497,11 +497,13 @@ export interface SessionEventMap {
|
|
|
497
497
|
* Emitted when a chunk of content is received (streaming).
|
|
498
498
|
* @property {string} content - Content of the chunk
|
|
499
499
|
* @property {boolean} [isComplete] - Whether this is the final chunk
|
|
500
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
500
501
|
* @property {'reasoning' | 'text'} type - Type of chunk (text or reasoning)
|
|
501
502
|
*/
|
|
502
503
|
'llmservice:chunk': {
|
|
503
504
|
content: string;
|
|
504
505
|
isComplete?: boolean;
|
|
506
|
+
taskId?: string;
|
|
505
507
|
type: 'reasoning' | 'text';
|
|
506
508
|
};
|
|
507
509
|
/**
|
|
@@ -509,32 +511,38 @@ export interface SessionEventMap {
|
|
|
509
511
|
* @property {number} compressedTokens - Token count after compression
|
|
510
512
|
* @property {number} originalTokens - Token count before compression
|
|
511
513
|
* @property {'middle_removal' | 'oldest_removal' | 'summary'} strategy - Compression strategy used
|
|
514
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
512
515
|
*/
|
|
513
516
|
'llmservice:contextCompressed': {
|
|
514
517
|
compressedTokens: number;
|
|
515
518
|
originalTokens: number;
|
|
516
519
|
strategy: 'middle_removal' | 'oldest_removal' | 'summary';
|
|
520
|
+
taskId?: string;
|
|
517
521
|
};
|
|
518
522
|
/**
|
|
519
523
|
* Emitted when context is approaching the token limit.
|
|
520
524
|
* @property {number} currentTokens - Current token count
|
|
521
525
|
* @property {number} maxTokens - Maximum allowed tokens
|
|
526
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
522
527
|
* @property {number} utilizationPercent - Percentage of context used (0-100)
|
|
523
528
|
*/
|
|
524
529
|
'llmservice:contextOverflow': {
|
|
525
530
|
currentTokens: number;
|
|
526
531
|
maxTokens: number;
|
|
532
|
+
taskId?: string;
|
|
527
533
|
utilizationPercent: number;
|
|
528
534
|
};
|
|
529
535
|
/**
|
|
530
536
|
* Emitted when old tool outputs are pruned to save context space.
|
|
531
537
|
* @property {number} pruneCount - Number of tool outputs pruned
|
|
532
538
|
* @property {'manual' | 'overflow'} reason - Why pruning was triggered
|
|
539
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
533
540
|
* @property {number} tokensSaved - Estimated tokens saved
|
|
534
541
|
*/
|
|
535
542
|
'llmservice:contextPruned': {
|
|
536
543
|
pruneCount: number;
|
|
537
544
|
reason: 'manual' | 'overflow';
|
|
545
|
+
taskId?: string;
|
|
538
546
|
tokensSaved: number;
|
|
539
547
|
};
|
|
540
548
|
/**
|
|
@@ -543,32 +551,38 @@ export interface SessionEventMap {
|
|
|
543
551
|
* @property {Record<string, unknown>} args - Arguments that were repeated
|
|
544
552
|
* @property {'exact_repeat' | 'oscillation'} loopType - Type of loop detected
|
|
545
553
|
* @property {number} repeatCount - Number of times the pattern repeated
|
|
554
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
546
555
|
* @property {string} toolName - Name of the tool involved in the loop
|
|
547
556
|
*/
|
|
548
557
|
'llmservice:doomLoopDetected': {
|
|
549
558
|
args: Record<string, unknown>;
|
|
550
559
|
loopType: 'exact_repeat' | 'oscillation';
|
|
551
560
|
repeatCount: number;
|
|
561
|
+
taskId?: string;
|
|
552
562
|
toolName: string;
|
|
553
563
|
};
|
|
554
564
|
/**
|
|
555
565
|
* Emitted when an error occurs during LLM service operation.
|
|
556
566
|
* @property {string} [code] - Error code (optional)
|
|
557
567
|
* @property {string} error - Error message
|
|
568
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
558
569
|
*/
|
|
559
570
|
'llmservice:error': {
|
|
560
571
|
code?: string;
|
|
561
572
|
error: string;
|
|
573
|
+
taskId?: string;
|
|
562
574
|
};
|
|
563
575
|
/**
|
|
564
576
|
* Emitted when tool output is truncated due to size.
|
|
565
577
|
* @property {number} originalLength - Original output length before truncation
|
|
566
578
|
* @property {string} savedToFile - Path to file where full output was saved
|
|
579
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
567
580
|
* @property {string} toolName - Name of the tool that produced the output
|
|
568
581
|
*/
|
|
569
582
|
'llmservice:outputTruncated': {
|
|
570
583
|
originalLength: number;
|
|
571
584
|
savedToFile: string;
|
|
585
|
+
taskId?: string;
|
|
572
586
|
toolName: string;
|
|
573
587
|
};
|
|
574
588
|
/**
|
|
@@ -578,6 +592,7 @@ export interface SessionEventMap {
|
|
|
578
592
|
* @property {boolean} [partial] - Whether this is a partial response (e.g., max iterations reached)
|
|
579
593
|
* @property {string} [provider] - LLM provider name
|
|
580
594
|
* @property {string} [reasoning] - Internal reasoning (if available)
|
|
595
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
581
596
|
* @property {TokenUsage} [tokenUsage] - Token usage statistics
|
|
582
597
|
*/
|
|
583
598
|
'llmservice:response': {
|
|
@@ -586,30 +601,38 @@ export interface SessionEventMap {
|
|
|
586
601
|
partial?: boolean;
|
|
587
602
|
provider?: string;
|
|
588
603
|
reasoning?: string;
|
|
604
|
+
taskId?: string;
|
|
589
605
|
tokenUsage?: TokenUsage;
|
|
590
606
|
};
|
|
591
607
|
/**
|
|
592
608
|
* Emitted when LLM service starts thinking/processing.
|
|
609
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
593
610
|
*/
|
|
594
|
-
'llmservice:thinking': void
|
|
611
|
+
'llmservice:thinking': void | {
|
|
612
|
+
taskId?: string;
|
|
613
|
+
};
|
|
595
614
|
/**
|
|
596
615
|
* Emitted when LLM generates a thought (Gemini models only).
|
|
597
616
|
* @property {string} description - Detailed thought description
|
|
598
617
|
* @property {string} subject - Brief thought subject
|
|
618
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
599
619
|
*/
|
|
600
620
|
'llmservice:thought': {
|
|
601
621
|
description: string;
|
|
602
622
|
subject: string;
|
|
623
|
+
taskId?: string;
|
|
603
624
|
};
|
|
604
625
|
/**
|
|
605
626
|
* Emitted when LLM requests a tool call.
|
|
606
627
|
* @property {Record<string, unknown>} args - Arguments for the tool
|
|
607
628
|
* @property {string} [callId] - Unique identifier for this tool call
|
|
629
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
608
630
|
* @property {string} toolName - Name of the tool to execute
|
|
609
631
|
*/
|
|
610
632
|
'llmservice:toolCall': {
|
|
611
633
|
args: Record<string, unknown>;
|
|
612
634
|
callId?: string;
|
|
635
|
+
taskId?: string;
|
|
613
636
|
toolName: string;
|
|
614
637
|
};
|
|
615
638
|
/**
|
|
@@ -617,11 +640,13 @@ export interface SessionEventMap {
|
|
|
617
640
|
* Allows tools to push real-time updates (e.g., bash output streaming).
|
|
618
641
|
* @property {string} callId - Tool call identifier
|
|
619
642
|
* @property {Record<string, unknown>} metadata - The metadata update
|
|
643
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
620
644
|
* @property {string} toolName - Name of the tool streaming metadata
|
|
621
645
|
*/
|
|
622
646
|
'llmservice:toolMetadata': {
|
|
623
647
|
callId: string;
|
|
624
648
|
metadata: Record<string, unknown>;
|
|
649
|
+
taskId?: string;
|
|
625
650
|
toolName: string;
|
|
626
651
|
};
|
|
627
652
|
/**
|
|
@@ -632,6 +657,7 @@ export interface SessionEventMap {
|
|
|
632
657
|
* @property {Record<string, unknown>} [metadata] - Execution metadata (duration, tokens, etc.)
|
|
633
658
|
* @property {unknown} [result] - Tool execution result
|
|
634
659
|
* @property {boolean} success - Whether execution succeeded
|
|
660
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
635
661
|
* @property {string} toolName - Name of the executed tool
|
|
636
662
|
*/
|
|
637
663
|
'llmservice:toolResult': {
|
|
@@ -641,32 +667,39 @@ export interface SessionEventMap {
|
|
|
641
667
|
metadata?: Record<string, unknown>;
|
|
642
668
|
result?: unknown;
|
|
643
669
|
success: boolean;
|
|
670
|
+
taskId?: string;
|
|
644
671
|
toolName: string;
|
|
645
672
|
};
|
|
646
673
|
/**
|
|
647
674
|
* Emitted when LLM receives unsupported input.
|
|
648
675
|
* @property {string} reason - Reason why input is unsupported
|
|
676
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
649
677
|
*/
|
|
650
678
|
'llmservice:unsupportedInput': {
|
|
651
679
|
reason: string;
|
|
680
|
+
taskId?: string;
|
|
652
681
|
};
|
|
653
682
|
/**
|
|
654
683
|
* Emitted when LLM service encounters a warning (e.g., max iterations reached).
|
|
655
684
|
* @property {string} message - Warning message
|
|
656
685
|
* @property {string} [model] - Model identifier
|
|
657
686
|
* @property {string} [provider] - LLM provider name
|
|
687
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
658
688
|
*/
|
|
659
689
|
'llmservice:warning': {
|
|
660
690
|
message: string;
|
|
661
691
|
model?: string;
|
|
662
692
|
provider?: string;
|
|
693
|
+
taskId?: string;
|
|
663
694
|
};
|
|
664
695
|
/**
|
|
665
696
|
* Emitted when queued messages are dequeued for processing.
|
|
666
697
|
* @property {number} count - Number of messages that were dequeued
|
|
698
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
667
699
|
*/
|
|
668
700
|
'message:dequeued': {
|
|
669
701
|
count: number;
|
|
702
|
+
taskId?: string;
|
|
670
703
|
};
|
|
671
704
|
/**
|
|
672
705
|
* Emitted when a message is queued because session is busy.
|
|
@@ -675,6 +708,7 @@ export interface SessionEventMap {
|
|
|
675
708
|
* @property {string} message.content - Message text content
|
|
676
709
|
* @property {number} message.queuedAt - Timestamp when queued
|
|
677
710
|
* @property {number} position - Position in the queue (1-based)
|
|
711
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
678
712
|
*/
|
|
679
713
|
'message:queued': {
|
|
680
714
|
message: {
|
|
@@ -683,6 +717,7 @@ export interface SessionEventMap {
|
|
|
683
717
|
queuedAt: number;
|
|
684
718
|
};
|
|
685
719
|
position: number;
|
|
720
|
+
taskId?: string;
|
|
686
721
|
};
|
|
687
722
|
/**
|
|
688
723
|
* Emitted when a session run completes (streaming API lifecycle event).
|
|
@@ -690,20 +725,24 @@ export interface SessionEventMap {
|
|
|
690
725
|
* @property {Error} [error] - Error if terminated due to error
|
|
691
726
|
* @property {'cancelled' | 'error' | 'max-iterations' | 'stop' | 'timeout'} finishReason - Why execution terminated
|
|
692
727
|
* @property {number} stepCount - Number of agentic steps completed
|
|
728
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
693
729
|
*/
|
|
694
730
|
'run:complete': {
|
|
695
731
|
durationMs: number;
|
|
696
732
|
error?: Error;
|
|
697
733
|
finishReason: 'cancelled' | 'error' | 'max-iterations' | 'stop' | 'timeout';
|
|
698
734
|
stepCount: number;
|
|
735
|
+
taskId?: string;
|
|
699
736
|
};
|
|
700
737
|
/**
|
|
701
738
|
* Emitted when session status changes.
|
|
702
739
|
* Tracks the lifecycle state of a session (idle, busy, retry, waiting).
|
|
703
740
|
* @property {SessionStatusType} status - The new session status
|
|
741
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
704
742
|
*/
|
|
705
743
|
'session:statusChanged': {
|
|
706
744
|
status: SessionStatusType;
|
|
745
|
+
taskId?: string;
|
|
707
746
|
};
|
|
708
747
|
/**
|
|
709
748
|
* Emitted when an execution step finishes.
|
|
@@ -711,20 +750,24 @@ export interface SessionEventMap {
|
|
|
711
750
|
* @property {number} cost - Cost in dollars for this step
|
|
712
751
|
* @property {'max_tokens' | 'stop' | 'tool_calls'} finishReason - Why step finished
|
|
713
752
|
* @property {number} stepIndex - Step index (0-based)
|
|
753
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
714
754
|
* @property {StepTokenUsage} tokens - Token usage for this step
|
|
715
755
|
*/
|
|
716
756
|
'step:finished': {
|
|
717
757
|
cost: number;
|
|
718
758
|
finishReason: 'max_tokens' | 'stop' | 'tool_calls';
|
|
719
759
|
stepIndex: number;
|
|
760
|
+
taskId?: string;
|
|
720
761
|
tokens: StepTokenUsage;
|
|
721
762
|
};
|
|
722
763
|
/**
|
|
723
764
|
* Emitted when an execution step starts.
|
|
724
765
|
* @property {number} stepIndex - Step index (0-based)
|
|
766
|
+
* @property {string} [taskId] - Optional task ID for concurrent task isolation
|
|
725
767
|
*/
|
|
726
768
|
'step:started': {
|
|
727
769
|
stepIndex: number;
|
|
770
|
+
taskId?: string;
|
|
728
771
|
};
|
|
729
772
|
}
|
|
730
773
|
/**
|
|
@@ -26,22 +26,76 @@ export const AGENT_VALUES = [
|
|
|
26
26
|
* Defines which connectors each agent supports and which is the default.
|
|
27
27
|
*/
|
|
28
28
|
export const AGENT_CONNECTOR_CONFIG = {
|
|
29
|
-
Amp: {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
Amp: {
|
|
30
|
+
default: 'mcp',
|
|
31
|
+
supported: ['rules', 'mcp'],
|
|
32
|
+
},
|
|
33
|
+
'Augment Code': {
|
|
34
|
+
default: 'mcp',
|
|
35
|
+
supported: ['rules', 'mcp'],
|
|
36
|
+
},
|
|
37
|
+
'Claude Code': {
|
|
38
|
+
default: 'hook',
|
|
39
|
+
supported: ['rules', 'hook', 'mcp'],
|
|
40
|
+
},
|
|
41
|
+
Cline: {
|
|
42
|
+
default: 'mcp',
|
|
43
|
+
supported: ['rules', 'mcp'],
|
|
44
|
+
},
|
|
45
|
+
Codex: {
|
|
46
|
+
default: 'mcp',
|
|
47
|
+
supported: ['rules', 'mcp'],
|
|
48
|
+
},
|
|
49
|
+
Cursor: {
|
|
50
|
+
default: 'mcp',
|
|
51
|
+
supported: ['rules', 'mcp'],
|
|
52
|
+
},
|
|
53
|
+
'Gemini CLI': {
|
|
54
|
+
default: 'mcp',
|
|
55
|
+
supported: ['rules', 'mcp'],
|
|
56
|
+
},
|
|
57
|
+
'Github Copilot': {
|
|
58
|
+
default: 'mcp',
|
|
59
|
+
supported: ['rules', 'mcp'],
|
|
60
|
+
},
|
|
61
|
+
Junie: {
|
|
62
|
+
default: 'mcp',
|
|
63
|
+
supported: ['rules', 'mcp'],
|
|
64
|
+
},
|
|
65
|
+
'Kilo Code': {
|
|
66
|
+
default: 'mcp',
|
|
67
|
+
supported: ['rules', 'mcp'],
|
|
68
|
+
},
|
|
69
|
+
Kiro: {
|
|
70
|
+
default: 'mcp',
|
|
71
|
+
supported: ['rules', 'mcp'],
|
|
72
|
+
},
|
|
73
|
+
Qoder: {
|
|
74
|
+
default: 'mcp',
|
|
75
|
+
supported: ['rules', 'mcp'],
|
|
76
|
+
},
|
|
77
|
+
'Qwen Code': {
|
|
78
|
+
default: 'mcp',
|
|
79
|
+
supported: ['rules', 'mcp'],
|
|
80
|
+
},
|
|
81
|
+
'Roo Code': {
|
|
82
|
+
default: 'mcp',
|
|
83
|
+
supported: ['rules', 'mcp'],
|
|
84
|
+
},
|
|
85
|
+
'Trae.ai': {
|
|
86
|
+
default: 'mcp',
|
|
87
|
+
supported: ['rules', 'mcp'],
|
|
88
|
+
},
|
|
89
|
+
Warp: {
|
|
90
|
+
default: 'mcp',
|
|
91
|
+
supported: ['rules', 'mcp'],
|
|
92
|
+
},
|
|
93
|
+
Windsurf: {
|
|
94
|
+
default: 'mcp',
|
|
95
|
+
supported: ['rules', 'mcp'],
|
|
96
|
+
},
|
|
97
|
+
Zed: {
|
|
98
|
+
default: 'mcp',
|
|
99
|
+
supported: ['rules', 'mcp'],
|
|
100
|
+
},
|
|
47
101
|
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - 'rules': Agent reads instructions from a rule file (e.g., CLAUDE.md)
|
|
6
6
|
* - 'hook': Instructions are injected on each prompt via agent hooks
|
|
7
|
+
* - 'mcp': Agent uses mcp tools to interact with brv
|
|
7
8
|
*/
|
|
8
|
-
export declare const CONNECTOR_TYPES: readonly ["rules", "hook"];
|
|
9
|
+
export declare const CONNECTOR_TYPES: readonly ["rules", "hook", "mcp"];
|
|
9
10
|
export type ConnectorType = (typeof CONNECTOR_TYPES)[number];
|
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
*
|
|
5
5
|
* - 'rules': Agent reads instructions from a rule file (e.g., CLAUDE.md)
|
|
6
6
|
* - 'hook': Instructions are injected on each prompt via agent hooks
|
|
7
|
+
* - 'mcp': Agent uses mcp tools to interact with brv
|
|
7
8
|
*/
|
|
8
|
-
export const CONNECTOR_TYPES = ['rules', 'hook'];
|
|
9
|
+
export const CONNECTOR_TYPES = ['rules', 'hook', 'mcp'];
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { ConnectorType } from '../../domain/entities/connector-type.js';
|
|
2
|
+
/**
|
|
3
|
+
* Instructions for manual MCP setup when automatic configuration is not possible.
|
|
4
|
+
*/
|
|
5
|
+
export type ManualInstallInstructions = {
|
|
6
|
+
/** The config content to copy (JSON or TOML formatted) */
|
|
7
|
+
configContent: string;
|
|
8
|
+
/** Guide URL or step-by-step instructions */
|
|
9
|
+
guide: string;
|
|
10
|
+
};
|
|
2
11
|
/**
|
|
3
12
|
* Result of a connector installation operation.
|
|
4
13
|
*/
|
|
@@ -7,8 +16,12 @@ export type ConnectorInstallResult = {
|
|
|
7
16
|
alreadyInstalled: boolean;
|
|
8
17
|
/** Path to the configuration/rule file */
|
|
9
18
|
configPath: string;
|
|
19
|
+
/** Instructions for manual setup (present when requiresManualSetup is true) */
|
|
20
|
+
manualInstructions?: ManualInstallInstructions;
|
|
10
21
|
/** Human-readable message describing the result */
|
|
11
22
|
message: string;
|
|
23
|
+
/** Whether this requires manual setup by the user */
|
|
24
|
+
requiresManualSetup?: boolean;
|
|
12
25
|
/** Whether the installation was successful */
|
|
13
26
|
success: boolean;
|
|
14
27
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { McpServerConfig } from '../../infra/connectors/mcp/mcp-connector-config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of checking if MCP config exists.
|
|
4
|
+
*/
|
|
5
|
+
export type McpConfigExistsResult = {
|
|
6
|
+
/** Whether the config file exists */
|
|
7
|
+
fileExists: boolean;
|
|
8
|
+
/** Whether the BRV MCP server entry exists in the config */
|
|
9
|
+
serverExists: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Interface for writing MCP server configurations to agent config files.
|
|
13
|
+
* Different implementations handle different file formats (JSON, TOML, etc.).
|
|
14
|
+
*/
|
|
15
|
+
export interface IMcpConfigWriter {
|
|
16
|
+
/**
|
|
17
|
+
* Check if the config file and BRV server entry exist.
|
|
18
|
+
*
|
|
19
|
+
* @param filePath - Absolute path to the config file
|
|
20
|
+
* @returns Object indicating file and server existence
|
|
21
|
+
*/
|
|
22
|
+
exists(filePath: string): Promise<McpConfigExistsResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Remove the BRV MCP server entry from the config file.
|
|
25
|
+
* Does not delete the file, only removes the server entry.
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - Absolute path to the config file
|
|
28
|
+
* @returns True if the server was removed, false if it didn't exist
|
|
29
|
+
*/
|
|
30
|
+
remove(filePath: string): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Write the MCP server configuration to the config file.
|
|
33
|
+
* Creates the file if it doesn't exist.
|
|
34
|
+
* Preserves existing configuration.
|
|
35
|
+
*
|
|
36
|
+
* @param filePath - Absolute path to the config file
|
|
37
|
+
* @param serverConfig - The MCP server configuration to write
|
|
38
|
+
*/
|
|
39
|
+
write(filePath: string, serverConfig: McpServerConfig): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Agent } from '../domain/entities/agent.js';
|
|
2
|
+
import { ConnectorType } from '../domain/entities/connector-type.js';
|
|
2
3
|
/**
|
|
3
4
|
* Interface for rule template service operations.
|
|
4
5
|
*/
|
|
5
6
|
export interface IRuleTemplateService {
|
|
6
7
|
/**
|
|
7
|
-
* Generates rule content based on the provided agent.
|
|
8
|
+
* Generates rule content based on the provided agent and connector type.
|
|
8
9
|
*
|
|
9
10
|
* @param agent The agent for which to generate the rule content.
|
|
11
|
+
* @param type The connector type (rules or mcp). Defaults to 'rules'.
|
|
10
12
|
* @returns Promise resolving to the generated rule content.
|
|
11
13
|
*/
|
|
12
|
-
generateRuleContent: (agent: Agent) => Promise<string>;
|
|
14
|
+
generateRuleContent: (agent: Agent, type: ConnectorType) => Promise<string>;
|
|
13
15
|
}
|
|
@@ -54,6 +54,13 @@ export interface ITransportClient {
|
|
|
54
54
|
* Returns the current connection state.
|
|
55
55
|
*/
|
|
56
56
|
getState: () => ConnectionState;
|
|
57
|
+
/**
|
|
58
|
+
* Checks if the socket is actually connected and responsive.
|
|
59
|
+
* Verifies bidirectional communication by sending a ping and waiting for response.
|
|
60
|
+
* @param timeoutMs - Timeout in milliseconds (default: 2000)
|
|
61
|
+
* @returns true if socket is connected and responsive, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
isConnected: (timeoutMs?: number) => Promise<boolean>;
|
|
57
64
|
/**
|
|
58
65
|
* Joins a room for targeted broadcasts.
|
|
59
66
|
* @param room - The room identifier to join
|
|
@@ -158,6 +158,14 @@ export declare class CipherAgent extends BaseAgent implements ICipherAgent {
|
|
|
158
158
|
* @returns AsyncIterator that yields StreamingEvent objects
|
|
159
159
|
*/
|
|
160
160
|
stream(input: string, options?: StreamOptions): Promise<AsyncIterableIterator<StreamingEvent>>;
|
|
161
|
+
/**
|
|
162
|
+
* Switch the default session to a different session ID.
|
|
163
|
+
* The session must already exist (created via createSession).
|
|
164
|
+
*
|
|
165
|
+
* @param sessionId - The session ID to switch to
|
|
166
|
+
* @throws Error if session does not exist
|
|
167
|
+
*/
|
|
168
|
+
switchDefaultSession(sessionId: string): void;
|
|
161
169
|
private getHistoryStorageInternal;
|
|
162
170
|
private getSessionIdInternal;
|
|
163
171
|
private getSessionManagerInternal;
|
|
@@ -520,6 +520,22 @@ export class CipherAgent extends BaseAgent {
|
|
|
520
520
|
};
|
|
521
521
|
return iterator;
|
|
522
522
|
}
|
|
523
|
+
/**
|
|
524
|
+
* Switch the default session to a different session ID.
|
|
525
|
+
* The session must already exist (created via createSession).
|
|
526
|
+
*
|
|
527
|
+
* @param sessionId - The session ID to switch to
|
|
528
|
+
* @throws Error if session does not exist
|
|
529
|
+
*/
|
|
530
|
+
switchDefaultSession(sessionId) {
|
|
531
|
+
this.ensureStarted();
|
|
532
|
+
// Verify the session exists
|
|
533
|
+
const session = this.getSessionManagerInternal().getSession(sessionId);
|
|
534
|
+
if (!session) {
|
|
535
|
+
throw new Error(`Session ${sessionId} does not exist. Create it first with createSession().`);
|
|
536
|
+
}
|
|
537
|
+
this._sessionId = sessionId;
|
|
538
|
+
}
|
|
523
539
|
// === Private Helpers (alphabetical order) ===
|
|
524
540
|
getHistoryStorageInternal() {
|
|
525
541
|
const storage = this.services?.historyStorage;
|
|
@@ -178,6 +178,14 @@ export declare class ContextManager<T> {
|
|
|
178
178
|
* Also clears persisted history if storage is enabled.
|
|
179
179
|
*/
|
|
180
180
|
clearHistory(): Promise<void>;
|
|
181
|
+
/**
|
|
182
|
+
* Compress messages by removing oldest messages until total tokens fit within the budget.
|
|
183
|
+
* This directly modifies the internal messages array by slicing from the beginning.
|
|
184
|
+
*
|
|
185
|
+
* @param maxTokens - Maximum token budget allowed
|
|
186
|
+
* @param messageTokens - Array of token counts corresponding to each message
|
|
187
|
+
*/
|
|
188
|
+
compressMessage(maxTokens: number, messageTokens: number[]): void;
|
|
181
189
|
/**
|
|
182
190
|
* Flush any pending history writes to storage.
|
|
183
191
|
* Provides explicit durability guarantee - ensures all messages
|