byterover-cli 1.3.0 → 1.5.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 +71 -6
- package/dist/core/domain/cipher/errors/file-system-error.d.ts +11 -0
- package/dist/core/domain/cipher/errors/file-system-error.js +17 -0
- package/dist/core/domain/cipher/file-system/types.d.ts +40 -6
- package/dist/core/domain/cipher/process/types.d.ts +1 -1
- package/dist/core/domain/entities/agent.d.ts +1 -1
- package/dist/core/domain/entities/agent.js +5 -0
- package/dist/core/domain/entities/provider-config.d.ts +92 -0
- package/dist/core/domain/entities/provider-config.js +181 -0
- package/dist/core/domain/entities/provider-registry.d.ts +55 -0
- package/dist/core/domain/entities/provider-registry.js +74 -0
- package/dist/core/interfaces/cipher/cipher-services.d.ts +0 -3
- package/dist/core/interfaces/cipher/i-content-generator.d.ts +30 -0
- package/dist/core/interfaces/cipher/i-content-generator.js +12 -1
- package/dist/core/interfaces/cipher/index.d.ts +0 -2
- package/dist/core/interfaces/cipher/message-factory.d.ts +4 -1
- package/dist/core/interfaces/cipher/message-factory.js +5 -0
- package/dist/core/interfaces/cipher/message-types.d.ts +19 -1
- package/dist/core/interfaces/i-provider-config-store.d.ts +88 -0
- package/dist/core/interfaces/i-provider-keychain-store.d.ts +33 -0
- package/dist/infra/cipher/file-system/binary-utils.d.ts +15 -2
- package/dist/infra/cipher/file-system/binary-utils.js +26 -3
- package/dist/infra/cipher/file-system/file-system-service.d.ts +9 -0
- package/dist/infra/cipher/file-system/file-system-service.js +96 -13
- package/dist/infra/cipher/file-system/pdf-extractor.d.ts +100 -0
- package/dist/infra/cipher/file-system/pdf-extractor.js +226 -0
- package/dist/infra/cipher/http/internal-llm-http-service.d.ts +40 -0
- package/dist/infra/cipher/http/internal-llm-http-service.js +152 -2
- package/dist/infra/cipher/llm/formatters/gemini-formatter.js +8 -1
- package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +2 -3
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +20 -11
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +1 -0
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +26 -0
- package/dist/infra/cipher/llm/internal-llm-service.d.ts +13 -0
- package/dist/infra/cipher/llm/internal-llm-service.js +75 -4
- package/dist/infra/cipher/llm/model-capabilities.d.ts +74 -0
- package/dist/infra/cipher/llm/model-capabilities.js +157 -0
- package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +35 -1
- package/dist/infra/cipher/llm/openrouter-llm-service.js +216 -28
- package/dist/infra/cipher/llm/stream-processor.d.ts +22 -2
- package/dist/infra/cipher/llm/stream-processor.js +78 -4
- package/dist/infra/cipher/llm/thought-parser.d.ts +1 -1
- package/dist/infra/cipher/llm/thought-parser.js +5 -5
- package/dist/infra/cipher/llm/transformers/openrouter-stream-transformer.d.ts +49 -0
- package/dist/infra/cipher/llm/transformers/openrouter-stream-transformer.js +272 -0
- package/dist/infra/cipher/llm/transformers/reasoning-extractor.d.ts +71 -0
- package/dist/infra/cipher/llm/transformers/reasoning-extractor.js +253 -0
- package/dist/infra/cipher/process/process-service.js +1 -1
- package/dist/infra/cipher/session/chat-session.d.ts +2 -0
- package/dist/infra/cipher/session/chat-session.js +13 -2
- package/dist/infra/cipher/storage/message-storage-service.js +4 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +3 -3
- package/dist/infra/cipher/tools/implementations/read-file-tool.js +24 -4
- package/dist/infra/cipher/tools/implementations/task-tool.js +1 -1
- package/dist/infra/connectors/rules/rules-connector-config.d.ts +4 -0
- package/dist/infra/connectors/rules/rules-connector-config.js +4 -0
- package/dist/infra/http/openrouter-api-client.d.ts +148 -0
- package/dist/infra/http/openrouter-api-client.js +161 -0
- package/dist/infra/mcp/tools/brv-curate-tool.d.ts +10 -4
- package/dist/infra/mcp/tools/brv-curate-tool.js +9 -4
- package/dist/infra/mcp/tools/task-result-waiter.js +9 -1
- package/dist/infra/process/agent-worker.js +178 -70
- package/dist/infra/process/transport-handlers.d.ts +25 -4
- package/dist/infra/process/transport-handlers.js +57 -10
- package/dist/infra/repl/commands/connectors-command.js +2 -2
- package/dist/infra/repl/commands/index.js +5 -0
- package/dist/infra/repl/commands/model-command.d.ts +13 -0
- package/dist/infra/repl/commands/model-command.js +212 -0
- package/dist/infra/repl/commands/provider-command.d.ts +13 -0
- package/dist/infra/repl/commands/provider-command.js +181 -0
- package/dist/infra/repl/commands/space/switch-command.js +0 -2
- package/dist/infra/repl/transport-client-helper.js +6 -2
- package/dist/infra/storage/file-provider-config-store.d.ts +83 -0
- package/dist/infra/storage/file-provider-config-store.js +157 -0
- package/dist/infra/storage/provider-keychain-store.d.ts +37 -0
- package/dist/infra/storage/provider-keychain-store.js +75 -0
- package/dist/infra/transport/socket-io-transport-client.d.ts +20 -0
- package/dist/infra/transport/socket-io-transport-client.js +88 -1
- package/dist/infra/usecase/curate-use-case.js +10 -4
- package/dist/infra/usecase/space-switch-use-case.d.ts +0 -10
- package/dist/infra/usecase/space-switch-use-case.js +7 -37
- package/dist/oclif/hooks/init/welcome.js +4 -17
- package/dist/resources/prompts/curate.yml +1 -0
- package/dist/resources/tools/bash_exec.txt +1 -1
- package/dist/resources/tools/read_file.txt +5 -2
- package/dist/tui/components/api-key-dialog.d.ts +39 -0
- package/dist/tui/components/api-key-dialog.js +94 -0
- package/dist/tui/components/execution/execution-changes.d.ts +3 -1
- package/dist/tui/components/execution/execution-changes.js +4 -4
- package/dist/tui/components/execution/execution-content.d.ts +1 -1
- package/dist/tui/components/execution/execution-content.js +4 -12
- package/dist/tui/components/execution/execution-input.js +1 -1
- package/dist/tui/components/execution/execution-progress.d.ts +10 -13
- package/dist/tui/components/execution/execution-progress.js +70 -17
- package/dist/tui/components/execution/execution-reasoning.d.ts +16 -0
- package/dist/tui/components/execution/execution-reasoning.js +34 -0
- package/dist/tui/components/execution/execution-tool.d.ts +23 -0
- package/dist/tui/components/execution/execution-tool.js +125 -0
- package/dist/tui/components/execution/expanded-log-view.js +3 -3
- package/dist/tui/components/execution/log-item.d.ts +2 -0
- package/dist/tui/components/execution/log-item.js +6 -4
- package/dist/tui/components/index.d.ts +2 -0
- package/dist/tui/components/index.js +2 -0
- package/dist/tui/components/inline-prompts/inline-select.js +3 -2
- package/dist/tui/components/model-dialog.d.ts +63 -0
- package/dist/tui/components/model-dialog.js +89 -0
- package/dist/tui/components/onboarding/onboarding-flow.js +8 -2
- package/dist/tui/components/provider-dialog.d.ts +27 -0
- package/dist/tui/components/provider-dialog.js +31 -0
- package/dist/tui/components/reasoning-text.d.ts +26 -0
- package/dist/tui/components/reasoning-text.js +49 -0
- package/dist/tui/components/selectable-list.d.ts +54 -0
- package/dist/tui/components/selectable-list.js +180 -0
- package/dist/tui/components/streaming-text.d.ts +30 -0
- package/dist/tui/components/streaming-text.js +52 -0
- package/dist/tui/contexts/tasks-context.d.ts +15 -0
- package/dist/tui/contexts/tasks-context.js +224 -40
- package/dist/tui/contexts/theme-context.d.ts +1 -0
- package/dist/tui/contexts/theme-context.js +3 -2
- package/dist/tui/hooks/use-activity-logs.js +7 -1
- package/dist/tui/types/messages.d.ts +32 -5
- package/dist/tui/utils/index.d.ts +1 -1
- package/dist/tui/utils/index.js +1 -1
- package/dist/tui/utils/log.d.ts +0 -9
- package/dist/tui/utils/log.js +2 -53
- package/dist/tui/views/command-view.js +4 -1
- package/dist/utils/file-validator.js +8 -4
- package/oclif.manifest.json +1 -54
- package/package.json +4 -2
- package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +0 -20
- package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +0 -31
- package/dist/core/interfaces/i-file-watcher-service.d.ts +0 -41
- package/dist/core/interfaces/i-file-watcher-service.js +0 -1
- package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +0 -18
- package/dist/core/interfaces/parser/i-clean-parser-service.js +0 -1
- package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +0 -17
- package/dist/core/interfaces/parser/i-raw-parser-service.js +0 -1
- package/dist/core/interfaces/parser/i-session-normalizer.d.ts +0 -56
- package/dist/core/interfaces/parser/i-session-normalizer.js +0 -1
- package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +0 -24
- package/dist/infra/cipher/parsers/coding-agent-log-parser.js +0 -51
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +0 -14
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +0 -55
- package/dist/infra/parsers/clean/clean-claude-service.d.ts +0 -111
- package/dist/infra/parsers/clean/clean-claude-service.js +0 -271
- package/dist/infra/parsers/clean/clean-codex-service.d.ts +0 -231
- package/dist/infra/parsers/clean/clean-codex-service.js +0 -534
- package/dist/infra/parsers/clean/clean-copilot-service.d.ts +0 -255
- package/dist/infra/parsers/clean/clean-copilot-service.js +0 -729
- package/dist/infra/parsers/clean/clean-cursor-service.d.ts +0 -161
- package/dist/infra/parsers/clean/clean-cursor-service.js +0 -432
- package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +0 -54
- package/dist/infra/parsers/clean/clean-parser-service-factory.js +0 -80
- package/dist/infra/parsers/clean/shared.d.ts +0 -84
- package/dist/infra/parsers/clean/shared.js +0 -273
- package/dist/infra/parsers/raw/raw-claude-service.d.ts +0 -195
- package/dist/infra/parsers/raw/raw-claude-service.js +0 -548
- package/dist/infra/parsers/raw/raw-codex-service.d.ts +0 -313
- package/dist/infra/parsers/raw/raw-codex-service.js +0 -782
- package/dist/infra/parsers/raw/raw-copilot-service.d.ts +0 -196
- package/dist/infra/parsers/raw/raw-copilot-service.js +0 -558
- package/dist/infra/parsers/raw/raw-cursor-service.d.ts +0 -316
- package/dist/infra/parsers/raw/raw-cursor-service.js +0 -818
- package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +0 -54
- package/dist/infra/parsers/raw/raw-parser-service-factory.js +0 -81
- package/dist/infra/watcher/file-watcher-service.d.ts +0 -10
- package/dist/infra/watcher/file-watcher-service.js +0 -81
- package/dist/oclif/commands/watch.d.ts +0 -25
- package/dist/oclif/commands/watch.js +0 -175
- /package/dist/core/interfaces/{cipher/i-coding-agent-log-parser.js → i-provider-config-store.js} +0 -0
- /package/dist/core/interfaces/{cipher/i-coding-agent-log-watcher.js → i-provider-keychain-store.js} +0 -0
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw Parser Service Factory
|
|
3
|
-
* Routes IDE-based parsing requests to the appropriate parser service
|
|
4
|
-
* Supports: Claude Code, Cursor, GitHub Copilot, Codex
|
|
5
|
-
*/
|
|
6
|
-
import { Agent } from '../../../core/domain/entities/agent.js';
|
|
7
|
-
import { IRawParserService } from '../../../core/interfaces/parser/i-raw-parser-service.js';
|
|
8
|
-
/**
|
|
9
|
-
* Raw Parser Service Factory
|
|
10
|
-
* Creates and returns appropriate parser service for the given IDE
|
|
11
|
-
*/
|
|
12
|
-
export declare class RawParserServiceFactory {
|
|
13
|
-
private static readonly SUPPORTED_IDES;
|
|
14
|
-
/**
|
|
15
|
-
* Create a raw parser service for the specified IDE
|
|
16
|
-
*
|
|
17
|
-
* Factory method that instantiates the appropriate raw parser service
|
|
18
|
-
* based on the provided IDE type. Routes to specialized service classes.
|
|
19
|
-
*
|
|
20
|
-
* @param ide - The IDE type: 'Claude Code', 'Cursor', 'Github Copilot', or 'Codex'
|
|
21
|
-
* @returns The appropriate raw parser service instance
|
|
22
|
-
* @throws Error if IDE is not supported
|
|
23
|
-
*/
|
|
24
|
-
static createRawParserService(ide: Agent): IRawParserService;
|
|
25
|
-
/**
|
|
26
|
-
* Get list of supported IDEs
|
|
27
|
-
*
|
|
28
|
-
* Returns array of all IDE types that have corresponding raw parser services.
|
|
29
|
-
*
|
|
30
|
-
* @returns Array of supported IDE type strings
|
|
31
|
-
*/
|
|
32
|
-
static getSupportedIDEs(): Agent[];
|
|
33
|
-
/**
|
|
34
|
-
* Check if IDE is supported
|
|
35
|
-
*
|
|
36
|
-
* Validates whether the provided IDE string corresponds to a supported IDE.
|
|
37
|
-
*
|
|
38
|
-
* @param ide - IDE name to validate
|
|
39
|
-
* @returns True if IDE is in supported list, false otherwise
|
|
40
|
-
*/
|
|
41
|
-
static isSupported(ide: Agent): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Parse conversations for the specified IDE
|
|
44
|
-
*
|
|
45
|
-
* Creates appropriate service and delegates to its parse method to extract
|
|
46
|
-
* and transform raw conversation data from IDE storage.
|
|
47
|
-
*
|
|
48
|
-
* @param ide - The IDE type (Claude Code, Cursor, Github Copilot, Codex)
|
|
49
|
-
* @param customDir - Path to custom directory containing IDE session data
|
|
50
|
-
* @param outputDir - Optional output directory (defaults to process.cwd()/.brv/logs/{ide}/raw)
|
|
51
|
-
* @returns Promise resolving to true if parsing succeeded, false otherwise
|
|
52
|
-
*/
|
|
53
|
-
static parseConversations(ide: Agent, customDir: string, outputDir?: string): Promise<boolean>;
|
|
54
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw Parser Service Factory
|
|
3
|
-
* Routes IDE-based parsing requests to the appropriate parser service
|
|
4
|
-
* Supports: Claude Code, Cursor, GitHub Copilot, Codex
|
|
5
|
-
*/
|
|
6
|
-
import { ClaudeRawService } from './raw-claude-service.js';
|
|
7
|
-
import { CodexRawService } from './raw-codex-service.js';
|
|
8
|
-
import { CopilotRawService } from './raw-copilot-service.js';
|
|
9
|
-
import { CursorRawService } from './raw-cursor-service.js';
|
|
10
|
-
/**
|
|
11
|
-
* Raw Parser Service Factory
|
|
12
|
-
* Creates and returns appropriate parser service for the given IDE
|
|
13
|
-
*/
|
|
14
|
-
export class RawParserServiceFactory {
|
|
15
|
-
static SUPPORTED_IDES = ['Claude Code', 'Cursor', 'Github Copilot', 'Codex'];
|
|
16
|
-
/**
|
|
17
|
-
* Create a raw parser service for the specified IDE
|
|
18
|
-
*
|
|
19
|
-
* Factory method that instantiates the appropriate raw parser service
|
|
20
|
-
* based on the provided IDE type. Routes to specialized service classes.
|
|
21
|
-
*
|
|
22
|
-
* @param ide - The IDE type: 'Claude Code', 'Cursor', 'Github Copilot', or 'Codex'
|
|
23
|
-
* @returns The appropriate raw parser service instance
|
|
24
|
-
* @throws Error if IDE is not supported
|
|
25
|
-
*/
|
|
26
|
-
static createRawParserService(ide) {
|
|
27
|
-
switch (ide) {
|
|
28
|
-
case 'Claude Code': {
|
|
29
|
-
return new ClaudeRawService(ide);
|
|
30
|
-
}
|
|
31
|
-
case 'Codex': {
|
|
32
|
-
return new CodexRawService(ide);
|
|
33
|
-
}
|
|
34
|
-
case 'Cursor': {
|
|
35
|
-
return new CursorRawService(ide);
|
|
36
|
-
}
|
|
37
|
-
case 'Github Copilot': {
|
|
38
|
-
return new CopilotRawService(ide);
|
|
39
|
-
}
|
|
40
|
-
default: {
|
|
41
|
-
throw new Error(`Unsupported IDE: ${ide}. Supported IDEs are: claude, cursor, copilot, codex`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Get list of supported IDEs
|
|
47
|
-
*
|
|
48
|
-
* Returns array of all IDE types that have corresponding raw parser services.
|
|
49
|
-
*
|
|
50
|
-
* @returns Array of supported IDE type strings
|
|
51
|
-
*/
|
|
52
|
-
static getSupportedIDEs() {
|
|
53
|
-
return [...this.SUPPORTED_IDES];
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Check if IDE is supported
|
|
57
|
-
*
|
|
58
|
-
* Validates whether the provided IDE string corresponds to a supported IDE.
|
|
59
|
-
*
|
|
60
|
-
* @param ide - IDE name to validate
|
|
61
|
-
* @returns True if IDE is in supported list, false otherwise
|
|
62
|
-
*/
|
|
63
|
-
static isSupported(ide) {
|
|
64
|
-
return this.getSupportedIDEs().includes(ide);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Parse conversations for the specified IDE
|
|
68
|
-
*
|
|
69
|
-
* Creates appropriate service and delegates to its parse method to extract
|
|
70
|
-
* and transform raw conversation data from IDE storage.
|
|
71
|
-
*
|
|
72
|
-
* @param ide - The IDE type (Claude Code, Cursor, Github Copilot, Codex)
|
|
73
|
-
* @param customDir - Path to custom directory containing IDE session data
|
|
74
|
-
* @param outputDir - Optional output directory (defaults to process.cwd()/.brv/logs/{ide}/raw)
|
|
75
|
-
* @returns Promise resolving to true if parsing succeeded, false otherwise
|
|
76
|
-
*/
|
|
77
|
-
static async parseConversations(ide, customDir, outputDir) {
|
|
78
|
-
const service = this.createRawParserService(ide);
|
|
79
|
-
return service.parse(customDir, outputDir);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { FileEvent, IFileWatcherService } from '../../core/interfaces/i-file-watcher-service.js';
|
|
2
|
-
export declare class FileWatcherService implements IFileWatcherService {
|
|
3
|
-
private eventHandler;
|
|
4
|
-
private watcher;
|
|
5
|
-
constructor();
|
|
6
|
-
setFileEventHandler(handler: (event: FileEvent) => Promise<void>): void;
|
|
7
|
-
start(paths: string[]): Promise<void>;
|
|
8
|
-
stop(): Promise<void>;
|
|
9
|
-
private invokeHandler;
|
|
10
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { watch } from 'chokidar';
|
|
2
|
-
export class FileWatcherService {
|
|
3
|
-
eventHandler;
|
|
4
|
-
watcher;
|
|
5
|
-
constructor() {
|
|
6
|
-
this.eventHandler = undefined;
|
|
7
|
-
this.watcher = undefined;
|
|
8
|
-
}
|
|
9
|
-
setFileEventHandler(handler) {
|
|
10
|
-
this.eventHandler = handler;
|
|
11
|
-
}
|
|
12
|
-
async start(paths) {
|
|
13
|
-
this.watcher = watch(paths, {
|
|
14
|
-
// `false` means the `add` events will be emitted for files already existing when the watcher starts.
|
|
15
|
-
// May need to change to `true` in the future because:
|
|
16
|
-
// - We only care about NEW LOGS that agents write AFTER we start watching.
|
|
17
|
-
// - We don't want to process old/existing log files that were already there.
|
|
18
|
-
// - Cleaner output - no flood of events when watcher starts.
|
|
19
|
-
ignoreInitial: true,
|
|
20
|
-
// Keep watching indefinitely (we want a long-running watcher)
|
|
21
|
-
persistent: true,
|
|
22
|
-
});
|
|
23
|
-
// Register event LISTENERS for all file system events
|
|
24
|
-
// Note: invokeHandler is async and handles errors internally
|
|
25
|
-
this.watcher.on('add', async (path) => {
|
|
26
|
-
await this.invokeHandler('add', path);
|
|
27
|
-
});
|
|
28
|
-
this.watcher.on('addDir', async (path) => {
|
|
29
|
-
await this.invokeHandler('addDir', path);
|
|
30
|
-
});
|
|
31
|
-
this.watcher.on('change', async (path) => {
|
|
32
|
-
await this.invokeHandler('change', path);
|
|
33
|
-
});
|
|
34
|
-
this.watcher.on('unlink', async (path) => {
|
|
35
|
-
await this.invokeHandler('unlink', path);
|
|
36
|
-
});
|
|
37
|
-
this.watcher.on('unlinkDir', async (path) => {
|
|
38
|
-
await this.invokeHandler('unlinkDir', path);
|
|
39
|
-
});
|
|
40
|
-
// Wait for watcher to be ready.
|
|
41
|
-
// The 'ready' event fires when
|
|
42
|
-
// chokidar has completed its initial scan of the directories (regardless of ignoreInitial setting)
|
|
43
|
-
// With ignoreInitial: false, the timeline is:
|
|
44
|
-
// 1. chokidar.watch() called
|
|
45
|
-
// 2. Scans directories
|
|
46
|
-
// 3. Emits 'add' events for 100 existing files
|
|
47
|
-
// 4. 'ready' event fires ← "Done with initial scan"
|
|
48
|
-
// 5. Now watching for new changes
|
|
49
|
-
//
|
|
50
|
-
// With ignoreInitial: true, timeline is:
|
|
51
|
-
// 1. chokidar.watch() called
|
|
52
|
-
// 2. Scans directories (still happens!)
|
|
53
|
-
// 3. Doesn't emit 'add' events for existing files
|
|
54
|
-
// 4. 'ready' event fires ← "Done with initial scan"
|
|
55
|
-
// 5. Now watching for new changes
|
|
56
|
-
// 'ready' is still useful for ignoreInitial: true.
|
|
57
|
-
await new Promise((resolve) => {
|
|
58
|
-
this.watcher?.on('ready', () => {
|
|
59
|
-
resolve();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
async stop() {
|
|
64
|
-
if (this.watcher !== undefined) {
|
|
65
|
-
await this.watcher.close();
|
|
66
|
-
this.watcher = undefined;
|
|
67
|
-
}
|
|
68
|
-
this.eventHandler = undefined;
|
|
69
|
-
}
|
|
70
|
-
async invokeHandler(type, path) {
|
|
71
|
-
if (this.eventHandler !== undefined) {
|
|
72
|
-
const event = { path, type };
|
|
73
|
-
try {
|
|
74
|
-
await this.eventHandler(event);
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
console.error(`[FileWatcherService] Error in event handler for ${type} ${path}:`, error);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
import type { IFileWatcherService } from '../../core/interfaces/i-file-watcher-service.js';
|
|
3
|
-
import type { IProjectConfigStore } from '../../core/interfaces/i-project-config-store.js';
|
|
4
|
-
import type { ITerminal } from '../../core/interfaces/i-terminal.js';
|
|
5
|
-
export default class Watch extends Command {
|
|
6
|
-
static description: string;
|
|
7
|
-
static examples: string[];
|
|
8
|
-
static flags: {
|
|
9
|
-
clean: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
debounce: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
paths: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
};
|
|
13
|
-
static hidden: boolean;
|
|
14
|
-
protected terminal: ITerminal;
|
|
15
|
-
private lastParseTime;
|
|
16
|
-
private parsingInProgress;
|
|
17
|
-
private pendingParse;
|
|
18
|
-
protected createServices(): {
|
|
19
|
-
fileWatcherService: IFileWatcherService;
|
|
20
|
-
projectConfigStore: IProjectConfigStore;
|
|
21
|
-
};
|
|
22
|
-
run(): Promise<void>;
|
|
23
|
-
protected waitForShutdownSignal(): Promise<void>;
|
|
24
|
-
private triggerParsing;
|
|
25
|
-
}
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import { isDevelopment } from '../../config/environment.js';
|
|
3
|
-
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
4
|
-
import { CleanParserServiceFactory } from '../../infra/parsers/clean/clean-parser-service-factory.js';
|
|
5
|
-
import { RawParserServiceFactory } from '../../infra/parsers/raw/raw-parser-service-factory.js';
|
|
6
|
-
import { OclifTerminal } from '../../infra/terminal/oclif-terminal.js';
|
|
7
|
-
import { FileWatcherService } from '../../infra/watcher/file-watcher-service.js';
|
|
8
|
-
export default class Watch extends Command {
|
|
9
|
-
static description = 'Watch file system directories for changes and trigger parsing pipeline [Development only]';
|
|
10
|
-
static examples = [
|
|
11
|
-
'<%= config.bin %> <%= command.id %> --paths ./agent-logs',
|
|
12
|
-
'<%= config.bin %> <%= command.id %> --paths ./logs,./outputs,./workspace',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> -p ./src,./lib',
|
|
14
|
-
'# Use chat log path from config (if IDE was configured during init):',
|
|
15
|
-
'<%= config.bin %> <%= command.id %>',
|
|
16
|
-
];
|
|
17
|
-
static flags = {
|
|
18
|
-
clean: Flags.boolean({
|
|
19
|
-
allowNo: true,
|
|
20
|
-
default: true,
|
|
21
|
-
description: 'Run clean parsing after raw parsing (default: true)',
|
|
22
|
-
}),
|
|
23
|
-
debounce: Flags.integer({
|
|
24
|
-
default: 2000,
|
|
25
|
-
description: 'Debounce time in milliseconds before triggering parsing (default: 2000)',
|
|
26
|
-
}),
|
|
27
|
-
paths: Flags.string({
|
|
28
|
-
char: 'p',
|
|
29
|
-
description: 'Comma-separated list of directories to watch (defaults to configured chat log path)',
|
|
30
|
-
required: false,
|
|
31
|
-
}),
|
|
32
|
-
};
|
|
33
|
-
static hidden = !isDevelopment();
|
|
34
|
-
terminal = {};
|
|
35
|
-
lastParseTime = 0;
|
|
36
|
-
parsingInProgress = false;
|
|
37
|
-
pendingParse = false;
|
|
38
|
-
createServices() {
|
|
39
|
-
this.terminal = new OclifTerminal(this);
|
|
40
|
-
return {
|
|
41
|
-
fileWatcherService: new FileWatcherService(),
|
|
42
|
-
projectConfigStore: new ProjectConfigStore(),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
async run() {
|
|
46
|
-
const { flags } = await this.parse(Watch);
|
|
47
|
-
const { fileWatcherService, projectConfigStore } = this.createServices();
|
|
48
|
-
if (!isDevelopment()) {
|
|
49
|
-
this.terminal.error('This command is only available in development environment');
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
let paths = [];
|
|
53
|
-
let ideConfig = null;
|
|
54
|
-
// Use explicit paths if provided
|
|
55
|
-
if (flags.paths) {
|
|
56
|
-
paths = flags.paths.split(',').map((p) => p.trim());
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// Try to load chat log path from config
|
|
60
|
-
try {
|
|
61
|
-
const configExists = await projectConfigStore.exists();
|
|
62
|
-
if (configExists) {
|
|
63
|
-
const config = await projectConfigStore.read();
|
|
64
|
-
if (config?.chatLogPath && config?.ide) {
|
|
65
|
-
paths = [config.chatLogPath];
|
|
66
|
-
ideConfig = config.ide;
|
|
67
|
-
this.terminal.log(`ℹ Using chat log path from config (${config.ide})`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
// Silently ignore config loading errors
|
|
73
|
-
}
|
|
74
|
-
if (paths.length === 0) {
|
|
75
|
-
this.terminal.error('No paths specified. Either:\n' +
|
|
76
|
-
' 1. Use --paths flag: brv watch --paths ./logs,./outputs\n' +
|
|
77
|
-
' 2. Run "brv init" to configure IDE and detect workspaces');
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
// Set up file event handler with parsing pipeline
|
|
82
|
-
fileWatcherService.setFileEventHandler(async (event) => {
|
|
83
|
-
this.terminal.log(`[${event.type}] ${event.path}`);
|
|
84
|
-
// Only trigger parsing if IDE is configured
|
|
85
|
-
if (ideConfig && (event.type === 'add' || event.type === 'change' || event.type === 'unlink')) {
|
|
86
|
-
this.pendingParse = true;
|
|
87
|
-
// Debounce parsing to avoid too frequent triggers
|
|
88
|
-
if (!this.parsingInProgress && Date.now() - this.lastParseTime > flags.debounce) {
|
|
89
|
-
this.triggerParsing(ideConfig, paths[0]).catch((error) => {
|
|
90
|
-
this.terminal.warn(`⚠️ Parsing error: ${error instanceof Error ? error.message : String(error)}`);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
await fileWatcherService.start(paths);
|
|
96
|
-
this.terminal.log(`\n🔍 Watching paths: ${paths.join(', ')}`);
|
|
97
|
-
if (ideConfig) {
|
|
98
|
-
this.terminal.log(`📊 Parsing pipeline enabled for: ${ideConfig}`);
|
|
99
|
-
}
|
|
100
|
-
this.terminal.log('Press Ctrl+C to stop...\n');
|
|
101
|
-
await this.waitForShutdownSignal();
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
this.terminal.error(error instanceof Error ? error.message : 'Unknown Error');
|
|
105
|
-
}
|
|
106
|
-
finally {
|
|
107
|
-
await fileWatcherService.stop();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
async waitForShutdownSignal() {
|
|
111
|
-
return new Promise((resolve) => {
|
|
112
|
-
const handleSignal = () => {
|
|
113
|
-
this.terminal.log('\nShutting down watcher...');
|
|
114
|
-
process.off('SIGINT', handleSignal);
|
|
115
|
-
process.off('SIGTERM', handleSignal);
|
|
116
|
-
resolve();
|
|
117
|
-
};
|
|
118
|
-
process.on('SIGINT', handleSignal);
|
|
119
|
-
process.on('SIGTERM', handleSignal);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
async triggerParsing(ide, chatLogPath) {
|
|
123
|
-
if (this.parsingInProgress) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
this.parsingInProgress = true;
|
|
127
|
-
this.pendingParse = false;
|
|
128
|
-
this.lastParseTime = Date.now();
|
|
129
|
-
try {
|
|
130
|
-
// Normalize IDE name for factory
|
|
131
|
-
// Validate IDE is supported
|
|
132
|
-
if (!RawParserServiceFactory.isSupported(ide)) {
|
|
133
|
-
this.terminal.warn(`⚠️ Unsupported IDE: ${ide}`);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
this.terminal.log('\n📥 Parsing triggered...');
|
|
137
|
-
// Raw parsing phase
|
|
138
|
-
let isRawSuccess = false;
|
|
139
|
-
try {
|
|
140
|
-
// Cast is safe because we already validated with isSupported()
|
|
141
|
-
isRawSuccess = await RawParserServiceFactory.parseConversations(ide, chatLogPath);
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
this.terminal.warn(`⚠️ Raw parsing error: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
// Clean parsing phase (if enabled)
|
|
148
|
-
const { flags } = await this.parse(Watch);
|
|
149
|
-
if (isRawSuccess && flags.clean) {
|
|
150
|
-
try {
|
|
151
|
-
const rawOutputDir = `${process.cwd()}/.brv/logs/${ide}/raw`;
|
|
152
|
-
const cleanSessions = await CleanParserServiceFactory.parseConversations(ide, rawOutputDir);
|
|
153
|
-
if (cleanSessions.length > 0) {
|
|
154
|
-
this.terminal.log('✅ Clean parsing complete\n');
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
this.terminal.warn('⚠️ Clean parsing failed');
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
this.terminal.warn(`⚠️ Clean parsing error: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
this.parsingInProgress = false;
|
|
167
|
-
// If more files were added while parsing, queue another parse
|
|
168
|
-
if (this.pendingParse) {
|
|
169
|
-
this.triggerParsing(ide, chatLogPath).catch((error) => {
|
|
170
|
-
this.terminal.warn(`⚠️ Parsing error: ${error instanceof Error ? error.message : String(error)}`);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
/package/dist/core/interfaces/{cipher/i-coding-agent-log-parser.js → i-provider-config-store.js}
RENAMED
|
File without changes
|
/package/dist/core/interfaces/{cipher/i-coding-agent-log-watcher.js → i-provider-keychain-store.js}
RENAMED
|
File without changes
|