byterover-cli 1.0.3 → 1.0.5
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 +75 -12
- package/dist/commands/curate.js +3 -3
- package/dist/commands/main.d.ts +13 -0
- package/dist/commands/main.js +55 -4
- package/dist/commands/query.js +3 -3
- package/dist/commands/status.js +2 -2
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +4 -1
- package/dist/core/domain/cipher/file-system/types.d.ts +2 -0
- package/dist/core/domain/cipher/llm/registry.js +53 -2
- package/dist/core/domain/cipher/llm/types.d.ts +2 -0
- package/dist/core/domain/cipher/process/types.d.ts +7 -0
- package/dist/core/domain/cipher/session/session-metadata.d.ts +178 -0
- package/dist/core/domain/cipher/session/session-metadata.js +147 -0
- package/dist/core/domain/entities/auth-token.js +6 -3
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +2 -1
- package/dist/core/domain/knowledge/markdown-writer.d.ts +15 -18
- package/dist/core/domain/knowledge/markdown-writer.js +232 -34
- package/dist/core/domain/knowledge/relation-parser.d.ts +37 -36
- package/dist/core/domain/knowledge/relation-parser.js +53 -58
- package/dist/core/domain/transport/schemas.d.ts +52 -1
- package/dist/core/domain/transport/schemas.js +30 -1
- package/dist/core/interfaces/cipher/i-blob-storage.d.ts +6 -0
- package/dist/core/interfaces/cipher/i-session-persistence.d.ts +133 -0
- package/dist/core/interfaces/cipher/i-session-persistence.js +7 -0
- package/dist/core/interfaces/cipher/index.d.ts +0 -1
- package/dist/core/interfaces/cipher/message-types.d.ts +6 -0
- package/dist/core/interfaces/executor/i-curate-executor.d.ts +2 -0
- package/dist/core/interfaces/i-context-file-reader.d.ts +3 -0
- package/dist/core/interfaces/usecase/{i-clear-use-case.d.ts → i-reset-use-case.d.ts} +1 -1
- package/dist/infra/cipher/agent/agent-schemas.d.ts +6 -6
- package/dist/infra/cipher/agent/cipher-agent.js +4 -0
- package/dist/infra/cipher/agent/service-initializer.js +4 -4
- package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +3 -2
- package/dist/infra/cipher/file-system/file-system-service.d.ts +4 -0
- package/dist/infra/cipher/file-system/file-system-service.js +6 -0
- package/dist/infra/cipher/http/internal-llm-http-service.js +3 -5
- package/dist/infra/cipher/interactive-loop.js +3 -1
- package/dist/infra/cipher/llm/context/context-manager.js +40 -16
- package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +13 -0
- package/dist/infra/cipher/llm/formatters/gemini-formatter.js +98 -6
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +6 -2
- package/dist/infra/cipher/llm/thought-parser.d.ts +21 -0
- package/dist/infra/cipher/llm/thought-parser.js +27 -0
- package/dist/infra/cipher/llm/tool-output-processor.d.ts +10 -0
- package/dist/infra/cipher/llm/tool-output-processor.js +80 -7
- package/dist/infra/cipher/process/process-service.js +11 -3
- package/dist/infra/cipher/session/chat-session.d.ts +7 -2
- package/dist/infra/cipher/session/chat-session.js +90 -52
- package/dist/infra/cipher/session/session-metadata-store.d.ts +52 -0
- package/dist/infra/cipher/session/session-metadata-store.js +406 -0
- package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +4 -2
- package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.js +24 -17
- package/dist/infra/cipher/tools/implementations/curate-tool.js +138 -65
- package/dist/infra/cipher/tools/implementations/read-file-tool.js +3 -12
- package/dist/infra/cipher/tools/implementations/spec-analyze-tool.js +18 -15
- package/dist/infra/cipher/tools/implementations/task-tool.js +54 -7
- package/dist/infra/context-tree/file-context-file-reader.js +4 -0
- package/dist/infra/context-tree/file-context-tree-service.js +4 -15
- package/dist/infra/core/executors/curate-executor.d.ts +2 -7
- package/dist/infra/core/executors/curate-executor.js +18 -53
- package/dist/infra/core/executors/query-executor.d.ts +1 -7
- package/dist/infra/core/executors/query-executor.js +10 -35
- package/dist/infra/core/task-processor.d.ts +2 -0
- package/dist/infra/core/task-processor.js +1 -0
- package/dist/infra/http/authenticated-http-client.js +5 -0
- package/dist/infra/process/agent-worker.js +113 -6
- package/dist/infra/process/constants.d.ts +1 -0
- package/dist/infra/process/constants.js +1 -0
- package/dist/infra/process/process-manager.d.ts +10 -1
- package/dist/infra/process/process-manager.js +16 -6
- package/dist/infra/process/task-queue-manager.js +2 -1
- package/dist/infra/process/transport-handlers.js +35 -0
- package/dist/infra/process/transport-worker.js +89 -1
- package/dist/infra/repl/commands/curate-command.js +2 -2
- package/dist/infra/repl/commands/gen-rules-command.js +2 -2
- package/dist/infra/repl/commands/index.js +5 -2
- package/dist/infra/repl/commands/init-command.js +2 -2
- package/dist/infra/repl/commands/login-command.js +2 -2
- package/dist/infra/repl/commands/logout-command.js +2 -2
- package/dist/infra/repl/commands/new-command.d.ts +14 -0
- package/dist/infra/repl/commands/new-command.js +61 -0
- package/dist/infra/repl/commands/pull-command.js +2 -2
- package/dist/infra/repl/commands/push-command.js +2 -2
- package/dist/infra/repl/commands/query-command.js +2 -2
- package/dist/infra/repl/commands/{clear-command.d.ts → reset-command.d.ts} +2 -2
- package/dist/infra/repl/commands/{clear-command.js → reset-command.js} +10 -10
- package/dist/infra/repl/commands/space/list-command.js +2 -2
- package/dist/infra/repl/commands/space/switch-command.js +2 -2
- package/dist/infra/repl/commands/status-command.js +2 -2
- package/dist/infra/repl/repl-startup.js +0 -2
- package/dist/infra/storage/file-token-store.d.ts +31 -0
- package/dist/infra/storage/file-token-store.js +98 -0
- package/dist/infra/storage/keychain-token-store.d.ts +4 -1
- package/dist/infra/storage/keychain-token-store.js +6 -4
- package/dist/infra/storage/token-store.d.ts +10 -0
- package/dist/infra/storage/token-store.js +14 -0
- package/dist/infra/usecase/curate-use-case.js +1 -1
- package/dist/infra/usecase/generate-rules-use-case.js +2 -2
- package/dist/infra/usecase/init-use-case.js +4 -4
- package/dist/infra/usecase/logout-use-case.js +1 -1
- package/dist/infra/usecase/push-use-case.js +1 -1
- package/dist/infra/usecase/{clear-use-case.d.ts → reset-use-case.d.ts} +5 -5
- package/dist/infra/usecase/{clear-use-case.js → reset-use-case.js} +5 -5
- package/dist/infra/user/http-user-service.js +6 -11
- package/dist/resources/prompts/curate.yml +79 -15
- package/dist/resources/prompts/plan.yml +6 -0
- package/dist/resources/tools/curate.txt +60 -15
- package/dist/tui/app.js +1 -1
- package/dist/tui/components/execution/log-item.js +2 -5
- package/dist/tui/components/header.d.ts +1 -1
- package/dist/tui/components/header.js +25 -4
- package/dist/tui/components/index.d.ts +5 -1
- package/dist/tui/components/index.js +3 -1
- package/dist/tui/components/init.d.ts +33 -0
- package/dist/tui/components/init.js +253 -0
- package/dist/tui/components/inline-prompts/inline-confirm.js +2 -2
- package/dist/tui/components/onboarding/index.d.ts +1 -0
- package/dist/tui/components/onboarding/index.js +1 -0
- package/dist/tui/components/onboarding/onboarding-flow.d.ts +2 -0
- package/dist/tui/components/onboarding/onboarding-flow.js +9 -229
- package/dist/tui/components/onboarding/onboarding-step.js +1 -1
- package/dist/tui/components/onboarding/welcome-box.d.ts +14 -0
- package/dist/tui/components/onboarding/welcome-box.js +23 -0
- package/dist/tui/components/status-badge.d.ts +22 -0
- package/dist/tui/components/status-badge.js +32 -0
- package/dist/tui/contexts/auth-context.js +2 -1
- package/dist/tui/contexts/index.d.ts +1 -0
- package/dist/tui/contexts/index.js +1 -0
- package/dist/tui/contexts/onboarding-context.d.ts +14 -0
- package/dist/tui/contexts/onboarding-context.js +17 -22
- package/dist/tui/contexts/status-context.d.ts +33 -0
- package/dist/tui/contexts/status-context.js +159 -0
- package/dist/tui/hooks/use-auth-polling.d.ts +4 -1
- package/dist/tui/hooks/use-auth-polling.js +21 -7
- package/dist/tui/hooks/use-tab-navigation.js +0 -2
- package/dist/tui/providers/app-providers.js +2 -2
- package/dist/tui/types/index.d.ts +2 -0
- package/dist/tui/types/index.js +2 -0
- package/dist/tui/types/status.d.ts +46 -0
- package/dist/tui/types/status.js +13 -0
- package/dist/tui/utils/index.d.ts +6 -0
- package/dist/tui/utils/index.js +6 -0
- package/dist/tui/utils/time.d.ts +10 -0
- package/dist/tui/utils/time.js +15 -0
- package/dist/tui/views/command-view.js +15 -2
- package/dist/tui/views/index.d.ts +1 -0
- package/dist/tui/views/index.js +1 -0
- package/dist/tui/views/init-view.d.ts +15 -0
- package/dist/tui/views/init-view.js +29 -0
- package/dist/tui/views/logs-view.js +22 -8
- package/dist/utils/environment-detector.d.ts +5 -0
- package/dist/utils/environment-detector.js +31 -0
- package/dist/utils/file-validator.js +9 -7
- package/dist/utils/global-data-path.d.ts +11 -0
- package/dist/utils/global-data-path.js +32 -0
- package/oclif.manifest.json +3 -3
- package/package.json +1 -1
- package/dist/config/context-tree-domains.d.ts +0 -17
- package/dist/config/context-tree-domains.js +0 -34
- package/dist/core/interfaces/cipher/i-agent-storage.d.ts +0 -152
- package/dist/core/interfaces/usecase/i-clear-use-case.js +0 -1
- package/dist/infra/cipher/consumer/consumer-lock.d.ts +0 -20
- package/dist/infra/cipher/consumer/consumer-lock.js +0 -41
- package/dist/infra/cipher/consumer/consumer-service.d.ts +0 -99
- package/dist/infra/cipher/consumer/consumer-service.js +0 -166
- package/dist/infra/cipher/consumer/execution-consumer.d.ts +0 -126
- package/dist/infra/cipher/consumer/execution-consumer.js +0 -561
- package/dist/infra/cipher/consumer/index.d.ts +0 -33
- package/dist/infra/cipher/consumer/index.js +0 -34
- package/dist/infra/cipher/consumer/queue-polling-service.d.ts +0 -120
- package/dist/infra/cipher/consumer/queue-polling-service.js +0 -249
- package/dist/infra/cipher/storage/agent-storage.d.ts +0 -246
- package/dist/infra/cipher/storage/agent-storage.js +0 -956
- /package/dist/core/interfaces/{cipher/i-agent-storage.js → usecase/i-reset-use-case.js} +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { homedir, platform } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { GLOBAL_DATA_DIR } from '../constants.js';
|
|
4
|
+
/**
|
|
5
|
+
* Returns the global data directory path following XDG spec:
|
|
6
|
+
* - Linux: $XDG_DATA_HOME/brv (defaults to ~/.local/share/brv)
|
|
7
|
+
* - macOS: ~/.local/share/brv
|
|
8
|
+
* - Windows: %LOCALAPPDATA%/brv
|
|
9
|
+
*
|
|
10
|
+
* Use this for user data and secrets (not config files).
|
|
11
|
+
*
|
|
12
|
+
* @returns Absolute path to the global data directory
|
|
13
|
+
*/
|
|
14
|
+
export const getGlobalDataDir = () => {
|
|
15
|
+
const currentPlatform = platform();
|
|
16
|
+
if (currentPlatform === 'win32') {
|
|
17
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
18
|
+
if (localAppData !== undefined) {
|
|
19
|
+
return join(localAppData, GLOBAL_DATA_DIR);
|
|
20
|
+
}
|
|
21
|
+
return join(homedir(), 'AppData', 'Local', GLOBAL_DATA_DIR);
|
|
22
|
+
}
|
|
23
|
+
// Linux: respect XDG_DATA_HOME if set
|
|
24
|
+
if (currentPlatform === 'linux') {
|
|
25
|
+
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
26
|
+
if (xdgDataHome !== undefined) {
|
|
27
|
+
return join(xdgDataHome, GLOBAL_DATA_DIR);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Linux (default) and macOS: use ~/.local/share/brv
|
|
31
|
+
return join(homedir(), '.local', 'share', GLOBAL_DATA_DIR);
|
|
32
|
+
};
|
package/oclif.manifest.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"required": false
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"description": "Curate context to the context tree (connects to running brv instance)\n\nRequires a running brv instance. Start one with: brv
|
|
12
|
+
"description": "Curate context to the context tree (connects to running brv instance)\n\nRequires a running brv instance. Start one with: brv\n\nGood examples:\n- \"Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts\"\n- \"API rate limit is 100 req/min per user. Implemented using Redis with sliding window in rateLimiter.ts\"\nBad examples:\n- \"Authentication\" or \"JWT tokens\" (too vague, lacks context)\n- \"Rate limiting\" (no implementation details or file references)",
|
|
13
13
|
"examples": [
|
|
14
14
|
"# Curate context - queues task for background processing",
|
|
15
15
|
"<%= config.bin %> <%= command.id %> \"Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts\"",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"required": true
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
|
-
"description": "Query and retrieve information from the context tree (connects to running brv instance)\n\nRequires a running brv instance. Start one with: brv
|
|
78
|
+
"description": "Query and retrieve information from the context tree (connects to running brv instance)\n\nRequires a running brv instance. Start one with: brv\n\nGood:\n- \"How is user authentication implemented?\"\n- \"What are the API rate limits and where are they enforced?\"\nBad:\n- \"auth\" or \"authentication\" (too vague, not a question)\n- \"show me code\" (not specific about what information is needed)",
|
|
79
79
|
"examples": [
|
|
80
80
|
"# Ask questions about patterns, decisions, or implementation details",
|
|
81
81
|
"<%= config.bin %> <%= command.id %> What are the coding standards?",
|
|
@@ -198,5 +198,5 @@
|
|
|
198
198
|
]
|
|
199
199
|
}
|
|
200
200
|
},
|
|
201
|
-
"version": "1.0.
|
|
201
|
+
"version": "1.0.5"
|
|
202
202
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Domain configurations for the context tree structure.
|
|
3
|
-
* Each domain represents a specific area of knowledge in the project.
|
|
4
|
-
*/
|
|
5
|
-
export interface DomainConfig {
|
|
6
|
-
description: string;
|
|
7
|
-
name: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Predefined domains that will be scaffolded during project initialization.
|
|
11
|
-
*/
|
|
12
|
-
export declare const DEFAULT_CONTEXT_TREE_DOMAINS: DomainConfig[];
|
|
13
|
-
/**
|
|
14
|
-
* Alias for backward compatibility.
|
|
15
|
-
* @deprecated Use DEFAULT_CONTEXT_TREE_DOMAINS instead
|
|
16
|
-
*/
|
|
17
|
-
export declare const CONTEXT_TREE_DOMAINS: DomainConfig[];
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Predefined domains that will be scaffolded during project initialization.
|
|
3
|
-
*/
|
|
4
|
-
export const DEFAULT_CONTEXT_TREE_DOMAINS = [
|
|
5
|
-
{
|
|
6
|
-
description: 'Ensure all code follows style guidelines and quality standards',
|
|
7
|
-
name: 'code_style',
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
description: 'UI libraries, themes, and design guidelines',
|
|
11
|
-
name: 'design',
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
description: 'Project structure, components, and related context',
|
|
15
|
-
name: 'structure',
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
description: 'Security and compliance information',
|
|
19
|
-
name: 'compliance',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
description: 'Testing implementation context',
|
|
23
|
-
name: 'testing',
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
description: 'Bug fixing logic and procedures',
|
|
27
|
-
name: 'bug_fixes',
|
|
28
|
-
},
|
|
29
|
-
];
|
|
30
|
-
/**
|
|
31
|
-
* Alias for backward compatibility.
|
|
32
|
-
* @deprecated Use DEFAULT_CONTEXT_TREE_DOMAINS instead
|
|
33
|
-
*/
|
|
34
|
-
export const CONTEXT_TREE_DOMAINS = DEFAULT_CONTEXT_TREE_DOMAINS;
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import type { Execution, ExecutionStatus, ExecutionType, ToolCall, ToolCallInfo, ToolCallStatus, ToolCallUpdateOptions } from '../../domain/cipher/queue/types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Interface for agent execution storage.
|
|
4
|
-
*
|
|
5
|
-
* Manages the execution queue, tool call tracking, and consumer locks.
|
|
6
|
-
* Implementations can use different storage backends (SQLite, in-memory, etc.)
|
|
7
|
-
*/
|
|
8
|
-
export interface IAgentStorage {
|
|
9
|
-
/**
|
|
10
|
-
* Acquire consumer lock (register this consumer).
|
|
11
|
-
* Only ONE consumer can run at a time.
|
|
12
|
-
* @param consumerId - Unique ID for this consumer
|
|
13
|
-
* @returns true if lock acquired, false if another consumer is already running
|
|
14
|
-
*/
|
|
15
|
-
acquireConsumerLock(consumerId: string): boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Add a tool call record.
|
|
18
|
-
* @returns tool call id
|
|
19
|
-
*/
|
|
20
|
-
addToolCall(executionId: string, info: ToolCallInfo): string;
|
|
21
|
-
/**
|
|
22
|
-
* Cleanup old executions, keep only maxKeep most recent completed/failed.
|
|
23
|
-
* @returns number of deleted executions
|
|
24
|
-
*/
|
|
25
|
-
cleanupOldExecutions(maxKeep?: number): number;
|
|
26
|
-
/**
|
|
27
|
-
* Cleanup orphaned executions (status='running') from previous session crash.
|
|
28
|
-
* @returns number of orphaned executions
|
|
29
|
-
*/
|
|
30
|
-
cleanupOrphanedExecutions(): number;
|
|
31
|
-
/**
|
|
32
|
-
* Cleanup stale consumers and orphan their executions.
|
|
33
|
-
* @param timeoutMs - heartbeat timeout (default 30 seconds)
|
|
34
|
-
* @returns number of orphaned executions
|
|
35
|
-
*/
|
|
36
|
-
cleanupStaleConsumers(timeoutMs?: number): number;
|
|
37
|
-
/**
|
|
38
|
-
* Close storage connection.
|
|
39
|
-
*/
|
|
40
|
-
close(): void;
|
|
41
|
-
/**
|
|
42
|
-
* Create a new execution.
|
|
43
|
-
* @param type - 'curate' or 'query'
|
|
44
|
-
* @param input - content (curate) or query string (query)
|
|
45
|
-
* @returns execution id
|
|
46
|
-
*/
|
|
47
|
-
createExecution(type: ExecutionType, input: string): string;
|
|
48
|
-
/**
|
|
49
|
-
* Dequeue multiple executions at once (atomic batch SELECT + UPDATE).
|
|
50
|
-
* @param limit - max number of executions to dequeue
|
|
51
|
-
* @param consumerId - ID of the consumer claiming these executions
|
|
52
|
-
* @returns array of executions (may be empty if queue is empty)
|
|
53
|
-
*/
|
|
54
|
-
dequeueBatch(limit: number, consumerId?: string): Execution[];
|
|
55
|
-
/**
|
|
56
|
-
* Dequeue next queued execution (atomic SELECT + UPDATE).
|
|
57
|
-
* @param consumerId - ID of the consumer claiming this execution
|
|
58
|
-
* @returns execution or null if queue is empty
|
|
59
|
-
*/
|
|
60
|
-
dequeueExecution(consumerId?: string): Execution | null;
|
|
61
|
-
/**
|
|
62
|
-
* Get execution by id.
|
|
63
|
-
*/
|
|
64
|
-
getExecution(id: string): Execution | null;
|
|
65
|
-
/**
|
|
66
|
-
* Get executions updated since timestamp (for incremental polling).
|
|
67
|
-
*/
|
|
68
|
-
getExecutionsSince(timestamp: number): Execution[];
|
|
69
|
-
/**
|
|
70
|
-
* Get execution with all its tool calls (for UI display).
|
|
71
|
-
*/
|
|
72
|
-
getExecutionWithToolCalls(id: string): null | {
|
|
73
|
-
execution: Execution;
|
|
74
|
-
toolCalls: ToolCall[];
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Get all queued executions.
|
|
78
|
-
*/
|
|
79
|
-
getQueuedExecutions(): Execution[];
|
|
80
|
-
/**
|
|
81
|
-
* Get recent executions (for UI display).
|
|
82
|
-
*/
|
|
83
|
-
getRecentExecutions(limit?: number): Execution[];
|
|
84
|
-
/**
|
|
85
|
-
* Get all running executions.
|
|
86
|
-
*/
|
|
87
|
-
getRunningExecutions(): Execution[];
|
|
88
|
-
/**
|
|
89
|
-
* Get all executions belonging to a specific consumer session.
|
|
90
|
-
* Returns executions ordered by created_at ASC (oldest first, newest last).
|
|
91
|
-
* @param consumerId - The consumer ID to filter by
|
|
92
|
-
*/
|
|
93
|
-
getSessionExecutions(consumerId: string): Execution[];
|
|
94
|
-
/**
|
|
95
|
-
* Get queue statistics (queries DB directly for accurate counts).
|
|
96
|
-
*/
|
|
97
|
-
getStats(): {
|
|
98
|
-
completed: number;
|
|
99
|
-
failed: number;
|
|
100
|
-
queued: number;
|
|
101
|
-
running: number;
|
|
102
|
-
total: number;
|
|
103
|
-
};
|
|
104
|
-
/**
|
|
105
|
-
* Get all tool calls for an execution.
|
|
106
|
-
*/
|
|
107
|
-
getToolCalls(executionId: string): ToolCall[];
|
|
108
|
-
/**
|
|
109
|
-
* Check if any consumer is currently active (has recent heartbeat).
|
|
110
|
-
* @param timeoutMs - heartbeat timeout (default 30 seconds)
|
|
111
|
-
*/
|
|
112
|
-
hasActiveConsumer(timeoutMs?: number): boolean;
|
|
113
|
-
/**
|
|
114
|
-
* Check if a specific consumer lock exists in the database.
|
|
115
|
-
* Used by Consumer to verify its lock is still valid after DB reconnection.
|
|
116
|
-
*/
|
|
117
|
-
hasConsumerLock(consumerId: string): boolean;
|
|
118
|
-
/**
|
|
119
|
-
* Initialize storage.
|
|
120
|
-
*/
|
|
121
|
-
initialize(options?: {
|
|
122
|
-
cleanupOrphans?: boolean;
|
|
123
|
-
}): Promise<void>;
|
|
124
|
-
/** Whether the storage has been initialized */
|
|
125
|
-
readonly initialized: boolean;
|
|
126
|
-
/**
|
|
127
|
-
* Check if the DB file has been replaced (different inode).
|
|
128
|
-
* Returns true if DB needs reconnection.
|
|
129
|
-
*/
|
|
130
|
-
isDbFileChanged(): boolean;
|
|
131
|
-
/**
|
|
132
|
-
* Reconnect to the database (close and reinitialize).
|
|
133
|
-
* Use when DB file has been replaced by another process (e.g., brv init).
|
|
134
|
-
*/
|
|
135
|
-
reconnect(): Promise<void>;
|
|
136
|
-
/**
|
|
137
|
-
* Release consumer lock (unregister this consumer).
|
|
138
|
-
*/
|
|
139
|
-
releaseConsumerLock(consumerId: string): void;
|
|
140
|
-
/**
|
|
141
|
-
* Update consumer heartbeat.
|
|
142
|
-
*/
|
|
143
|
-
updateConsumerHeartbeat(consumerId: string): void;
|
|
144
|
-
/**
|
|
145
|
-
* Update execution status.
|
|
146
|
-
*/
|
|
147
|
-
updateExecutionStatus(id: string, status: ExecutionStatus, result?: string, error?: string): void;
|
|
148
|
-
/**
|
|
149
|
-
* Update tool call status and result.
|
|
150
|
-
*/
|
|
151
|
-
updateToolCall(id: string, status: ToolCallStatus, options?: ToolCallUpdateOptions): void;
|
|
152
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DB-based consumer lock utilities
|
|
3
|
-
*
|
|
4
|
-
* The actual locking is now handled by AgentStorage methods:
|
|
5
|
-
* - acquireConsumerLock(consumerId)
|
|
6
|
-
* - releaseConsumerLock(consumerId)
|
|
7
|
-
* - hasActiveConsumer(timeoutMs)
|
|
8
|
-
*
|
|
9
|
-
* These utility functions provide a simple interface for checking consumer status.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Check if a consumer is currently running (has active heartbeat in DB)
|
|
13
|
-
* Auto-detects .brv/blobs path from cwd
|
|
14
|
-
*/
|
|
15
|
-
export declare function isConsumerRunning(): Promise<boolean>;
|
|
16
|
-
/**
|
|
17
|
-
* Check if a consumer is currently running (sync version)
|
|
18
|
-
* Assumes storage is already initialized
|
|
19
|
-
*/
|
|
20
|
-
export declare function isConsumerRunningSync(): boolean;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// TODO(v0.5.0): Remove this file. Consumer locking is no longer needed (one CoreProcess per TUI).
|
|
2
|
-
import { getAgentStorage, getAgentStorageSync } from '../storage/agent-storage.js';
|
|
3
|
-
// Consumer is considered stale after 30 seconds without heartbeat
|
|
4
|
-
const STALE_TIMEOUT_MS = 30_000;
|
|
5
|
-
/**
|
|
6
|
-
* DB-based consumer lock utilities
|
|
7
|
-
*
|
|
8
|
-
* The actual locking is now handled by AgentStorage methods:
|
|
9
|
-
* - acquireConsumerLock(consumerId)
|
|
10
|
-
* - releaseConsumerLock(consumerId)
|
|
11
|
-
* - hasActiveConsumer(timeoutMs)
|
|
12
|
-
*
|
|
13
|
-
* These utility functions provide a simple interface for checking consumer status.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Check if a consumer is currently running (has active heartbeat in DB)
|
|
17
|
-
* Auto-detects .brv/blobs path from cwd
|
|
18
|
-
*/
|
|
19
|
-
export async function isConsumerRunning() {
|
|
20
|
-
try {
|
|
21
|
-
const storage = await getAgentStorage();
|
|
22
|
-
return storage.hasActiveConsumer(STALE_TIMEOUT_MS);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
// If we can't check, assume not running
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Check if a consumer is currently running (sync version)
|
|
31
|
-
* Assumes storage is already initialized
|
|
32
|
-
*/
|
|
33
|
-
export function isConsumerRunningSync() {
|
|
34
|
-
try {
|
|
35
|
-
const storage = getAgentStorageSync();
|
|
36
|
-
return storage.hasActiveConsumer(STALE_TIMEOUT_MS);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
export interface ConsumerServiceOptions {
|
|
2
|
-
/** Max concurrent jobs (default: 5) */
|
|
3
|
-
concurrency?: number;
|
|
4
|
-
/** Poll interval in ms (default: 1000) */
|
|
5
|
-
pollInterval?: number;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* ConsumerService - Singleton background worker that processes the execution queue
|
|
9
|
-
*
|
|
10
|
-
* Architecture:
|
|
11
|
-
* ```
|
|
12
|
-
* ┌─────────────────┐
|
|
13
|
-
* │ ConsumerService │ ← Singleton, start once in main
|
|
14
|
-
* │ (process jobs) │
|
|
15
|
-
* └────────┬────────┘
|
|
16
|
-
* │ writes
|
|
17
|
-
* ▼
|
|
18
|
-
* ┌─────────────────┐
|
|
19
|
-
* │ AgentStorage │ ← SQLite DB (source of truth)
|
|
20
|
-
* │ (agent.db) │
|
|
21
|
-
* └────────┬────────┘
|
|
22
|
-
* │ polls
|
|
23
|
-
* ▼
|
|
24
|
-
* ┌─────────────────┐
|
|
25
|
-
* │QueuePollingServ │ ← UI subscribes here for updates
|
|
26
|
-
* └─────────────────┘
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* Usage:
|
|
30
|
-
* ```typescript
|
|
31
|
-
* // Main - start consumer singleton (once)
|
|
32
|
-
* const consumer = getConsumerService({ concurrency: 5 })
|
|
33
|
-
* await consumer.start()
|
|
34
|
-
*
|
|
35
|
-
* // UI components - use QueuePollingService for monitoring
|
|
36
|
-
* import { getQueuePollingService } from './queue-polling-service'
|
|
37
|
-
* const poller = getQueuePollingService({ pollInterval: 500 })
|
|
38
|
-
* poller.on('snapshot', (snapshot) => renderUI(snapshot))
|
|
39
|
-
* await poller.start()
|
|
40
|
-
*
|
|
41
|
-
* // Cleanup
|
|
42
|
-
* consumer.dispose()
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* Features:
|
|
46
|
-
* - Auto-loads auth token from Keychain
|
|
47
|
-
* - Auto-loads project config from .brv/config.json
|
|
48
|
-
* - Handles lock acquisition/release
|
|
49
|
-
* - Single dispose() for full cleanup
|
|
50
|
-
*/
|
|
51
|
-
export declare class ConsumerService {
|
|
52
|
-
private consumer;
|
|
53
|
-
private readonly options;
|
|
54
|
-
private running;
|
|
55
|
-
constructor(options?: ConsumerServiceOptions);
|
|
56
|
-
/**
|
|
57
|
-
* Stop the consumer and cleanup all resources
|
|
58
|
-
*/
|
|
59
|
-
dispose(): void;
|
|
60
|
-
/**
|
|
61
|
-
* Get the consumer ID (unique per session)
|
|
62
|
-
* Returns null if consumer hasn't started yet
|
|
63
|
-
*/
|
|
64
|
-
getConsumerId(): null | string;
|
|
65
|
-
/**
|
|
66
|
-
* Check if consumer is running
|
|
67
|
-
*/
|
|
68
|
-
isRunning(): boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Start the consumer
|
|
71
|
-
*
|
|
72
|
-
* - Loads auth token from Keychain
|
|
73
|
-
* - Loads project config from .brv/config.json
|
|
74
|
-
* - Acquires consumer lock
|
|
75
|
-
* - Starts processing queue
|
|
76
|
-
*
|
|
77
|
-
* @throws Error if not authenticated
|
|
78
|
-
* @throws Error if another consumer is already running
|
|
79
|
-
*/
|
|
80
|
-
start(): Promise<void>;
|
|
81
|
-
stop(): void;
|
|
82
|
-
private setupSignalHandlers;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Get or create singleton ConsumerService
|
|
86
|
-
*
|
|
87
|
-
* Usage:
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const consumer = getConsumerService()
|
|
90
|
-
* await consumer.start()
|
|
91
|
-
* // later...
|
|
92
|
-
* consumer.dispose()
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
export declare function getConsumerService(options?: ConsumerServiceOptions): ConsumerService;
|
|
96
|
-
/**
|
|
97
|
-
* Dispose singleton and clear reference
|
|
98
|
-
*/
|
|
99
|
-
export declare function disposeConsumerService(): void;
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
// TODO(v0.5.0): Remove this file. ConsumerService is replaced by CoreProcess → TaskProcessor.
|
|
2
|
-
import { ProjectConfigStore } from '../../config/file-config-store.js';
|
|
3
|
-
import { KeychainTokenStore } from '../../storage/keychain-token-store.js';
|
|
4
|
-
import { closeAgentStorage } from '../storage/agent-storage.js';
|
|
5
|
-
import { createExecutionConsumer } from './execution-consumer.js';
|
|
6
|
-
// ==================== SERVICE ====================
|
|
7
|
-
/**
|
|
8
|
-
* ConsumerService - Singleton background worker that processes the execution queue
|
|
9
|
-
*
|
|
10
|
-
* Architecture:
|
|
11
|
-
* ```
|
|
12
|
-
* ┌─────────────────┐
|
|
13
|
-
* │ ConsumerService │ ← Singleton, start once in main
|
|
14
|
-
* │ (process jobs) │
|
|
15
|
-
* └────────┬────────┘
|
|
16
|
-
* │ writes
|
|
17
|
-
* ▼
|
|
18
|
-
* ┌─────────────────┐
|
|
19
|
-
* │ AgentStorage │ ← SQLite DB (source of truth)
|
|
20
|
-
* │ (agent.db) │
|
|
21
|
-
* └────────┬────────┘
|
|
22
|
-
* │ polls
|
|
23
|
-
* ▼
|
|
24
|
-
* ┌─────────────────┐
|
|
25
|
-
* │QueuePollingServ │ ← UI subscribes here for updates
|
|
26
|
-
* └─────────────────┘
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* Usage:
|
|
30
|
-
* ```typescript
|
|
31
|
-
* // Main - start consumer singleton (once)
|
|
32
|
-
* const consumer = getConsumerService({ concurrency: 5 })
|
|
33
|
-
* await consumer.start()
|
|
34
|
-
*
|
|
35
|
-
* // UI components - use QueuePollingService for monitoring
|
|
36
|
-
* import { getQueuePollingService } from './queue-polling-service'
|
|
37
|
-
* const poller = getQueuePollingService({ pollInterval: 500 })
|
|
38
|
-
* poller.on('snapshot', (snapshot) => renderUI(snapshot))
|
|
39
|
-
* await poller.start()
|
|
40
|
-
*
|
|
41
|
-
* // Cleanup
|
|
42
|
-
* consumer.dispose()
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* Features:
|
|
46
|
-
* - Auto-loads auth token from Keychain
|
|
47
|
-
* - Auto-loads project config from .brv/config.json
|
|
48
|
-
* - Handles lock acquisition/release
|
|
49
|
-
* - Single dispose() for full cleanup
|
|
50
|
-
*/
|
|
51
|
-
export class ConsumerService {
|
|
52
|
-
consumer = null;
|
|
53
|
-
options;
|
|
54
|
-
running = false;
|
|
55
|
-
constructor(options) {
|
|
56
|
-
this.options = options ?? {};
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Stop the consumer and cleanup all resources
|
|
60
|
-
*/
|
|
61
|
-
dispose() {
|
|
62
|
-
if (!this.running)
|
|
63
|
-
return;
|
|
64
|
-
this.running = false;
|
|
65
|
-
if (this.consumer) {
|
|
66
|
-
this.consumer.stop();
|
|
67
|
-
this.consumer = null;
|
|
68
|
-
}
|
|
69
|
-
closeAgentStorage();
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Get the consumer ID (unique per session)
|
|
73
|
-
* Returns null if consumer hasn't started yet
|
|
74
|
-
*/
|
|
75
|
-
getConsumerId() {
|
|
76
|
-
return this.consumer?.getConsumerId() ?? null;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Check if consumer is running
|
|
80
|
-
*/
|
|
81
|
-
isRunning() {
|
|
82
|
-
return this.running && this.consumer !== null;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Start the consumer
|
|
86
|
-
*
|
|
87
|
-
* - Loads auth token from Keychain
|
|
88
|
-
* - Loads project config from .brv/config.json
|
|
89
|
-
* - Acquires consumer lock
|
|
90
|
-
* - Starts processing queue
|
|
91
|
-
*
|
|
92
|
-
* @throws Error if not authenticated
|
|
93
|
-
* @throws Error if another consumer is already running
|
|
94
|
-
*/
|
|
95
|
-
async start() {
|
|
96
|
-
if (this.running) {
|
|
97
|
-
throw new Error('Consumer already running');
|
|
98
|
-
}
|
|
99
|
-
// Load auth token
|
|
100
|
-
const tokenStore = new KeychainTokenStore();
|
|
101
|
-
const token = await tokenStore.load();
|
|
102
|
-
if (!token) {
|
|
103
|
-
throw new Error('Not authenticated. Please run "brv login" first.');
|
|
104
|
-
}
|
|
105
|
-
// Load project config (optional)
|
|
106
|
-
const configStore = new ProjectConfigStore();
|
|
107
|
-
const brvConfig = await configStore.read();
|
|
108
|
-
// Create consumer (auto-detects .brv/blobs from cwd)
|
|
109
|
-
this.consumer = createExecutionConsumer({
|
|
110
|
-
authToken: { accessToken: token.accessToken, sessionKey: token.sessionKey },
|
|
111
|
-
brvConfig: brvConfig ?? undefined,
|
|
112
|
-
maxConcurrency: this.options.concurrency ?? 5,
|
|
113
|
-
pollInterval: this.options.pollInterval ?? 1000,
|
|
114
|
-
});
|
|
115
|
-
// Start consumer
|
|
116
|
-
const started = await this.consumer.start();
|
|
117
|
-
if (!started) {
|
|
118
|
-
this.consumer = null;
|
|
119
|
-
throw new Error('Another consumer is already running in this directory');
|
|
120
|
-
}
|
|
121
|
-
this.running = true;
|
|
122
|
-
this.setupSignalHandlers();
|
|
123
|
-
}
|
|
124
|
-
// Alias for dispose
|
|
125
|
-
stop() {
|
|
126
|
-
this.dispose();
|
|
127
|
-
}
|
|
128
|
-
// ==================== PRIVATE ====================
|
|
129
|
-
setupSignalHandlers() {
|
|
130
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping -- needs 'this' context
|
|
131
|
-
const cleanup = () => {
|
|
132
|
-
this.dispose();
|
|
133
|
-
};
|
|
134
|
-
process.on('SIGTERM', cleanup);
|
|
135
|
-
process.on('SIGINT', cleanup);
|
|
136
|
-
process.on('exit', cleanup);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// ==================== SINGLETON HELPER ====================
|
|
140
|
-
let instance = null;
|
|
141
|
-
/**
|
|
142
|
-
* Get or create singleton ConsumerService
|
|
143
|
-
*
|
|
144
|
-
* Usage:
|
|
145
|
-
* ```typescript
|
|
146
|
-
* const consumer = getConsumerService()
|
|
147
|
-
* await consumer.start()
|
|
148
|
-
* // later...
|
|
149
|
-
* consumer.dispose()
|
|
150
|
-
* ```
|
|
151
|
-
*/
|
|
152
|
-
export function getConsumerService(options) {
|
|
153
|
-
if (!instance) {
|
|
154
|
-
instance = new ConsumerService(options);
|
|
155
|
-
}
|
|
156
|
-
return instance;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Dispose singleton and clear reference
|
|
160
|
-
*/
|
|
161
|
-
export function disposeConsumerService() {
|
|
162
|
-
if (instance) {
|
|
163
|
-
instance.dispose();
|
|
164
|
-
instance = null;
|
|
165
|
-
}
|
|
166
|
-
}
|