viberag 0.3.2 → 0.4.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 +2 -2
- package/dist/cli/app.d.ts +3 -0
- package/dist/cli/app.js +100 -102
- package/dist/cli/commands/handlers.d.ts +8 -6
- package/dist/cli/commands/handlers.js +90 -32
- package/dist/cli/commands/useCommands.d.ts +20 -0
- package/dist/cli/commands/useCommands.js +189 -0
- package/dist/cli/commands/useRagCommands.d.ts +2 -5
- package/dist/cli/commands/useRagCommands.js +11 -18
- package/dist/cli/components/InitWizard.js +66 -27
- package/dist/cli/components/McpSetupWizard.js +23 -4
- package/dist/cli/components/SlotRow.d.ts +22 -0
- package/dist/cli/components/SlotRow.js +55 -0
- package/dist/cli/components/StatusBar.d.ts +14 -0
- package/dist/cli/components/StatusBar.js +156 -0
- package/dist/cli/contexts/DaemonStatusContext.d.ts +38 -0
- package/dist/cli/contexts/DaemonStatusContext.js +106 -0
- package/dist/cli/hooks/useStatusPolling.d.ts +34 -0
- package/dist/cli/hooks/useStatusPolling.js +121 -0
- package/dist/cli/store/app/selectors.d.ts +87 -0
- package/dist/cli/store/app/selectors.js +28 -0
- package/dist/cli/store/app/slice.d.ts +1013 -0
- package/dist/cli/store/app/slice.js +112 -0
- package/dist/cli/store/hooks.d.ts +22 -0
- package/dist/cli/store/hooks.js +17 -0
- package/dist/cli/store/store.d.ts +17 -0
- package/dist/cli/store/store.js +18 -0
- package/dist/cli/store/wizard/selectors.d.ts +115 -0
- package/dist/cli/store/wizard/selectors.js +36 -0
- package/dist/cli/store/wizard/slice.d.ts +523 -0
- package/dist/cli/store/wizard/slice.js +119 -0
- package/dist/cli/utils/error-handler.d.ts +55 -0
- package/dist/cli/utils/error-handler.js +92 -0
- package/dist/client/auto-start.d.ts +42 -0
- package/dist/client/auto-start.js +250 -0
- package/dist/client/connection.d.ts +48 -0
- package/dist/client/connection.js +200 -0
- package/dist/client/index.d.ts +93 -0
- package/dist/client/index.js +209 -0
- package/dist/client/types.d.ts +105 -0
- package/dist/client/types.js +7 -0
- package/dist/common/components/SlotRow.d.ts +22 -0
- package/dist/common/components/SlotRow.js +53 -0
- package/dist/common/components/StatusBar.js +82 -31
- package/dist/common/types.d.ts +12 -13
- package/dist/daemon/handlers.d.ts +15 -0
- package/dist/daemon/handlers.js +157 -0
- package/dist/daemon/index.d.ts +21 -0
- package/dist/daemon/index.js +123 -0
- package/dist/daemon/lib/chunker/bounded-channel.d.ts +51 -0
- package/dist/daemon/lib/chunker/bounded-channel.js +138 -0
- package/dist/daemon/lib/chunker/index.d.ts +135 -0
- package/dist/daemon/lib/chunker/index.js +1370 -0
- package/dist/daemon/lib/chunker/types.d.ts +77 -0
- package/dist/daemon/lib/chunker/types.js +50 -0
- package/dist/daemon/lib/config.d.ts +73 -0
- package/dist/daemon/lib/config.js +149 -0
- package/dist/daemon/lib/constants.d.ts +75 -0
- package/dist/daemon/lib/constants.js +114 -0
- package/dist/daemon/lib/gitignore.d.ts +57 -0
- package/dist/daemon/lib/gitignore.js +246 -0
- package/dist/daemon/lib/logger.d.ts +51 -0
- package/dist/daemon/lib/logger.js +167 -0
- package/dist/daemon/lib/manifest.d.ts +58 -0
- package/dist/daemon/lib/manifest.js +116 -0
- package/dist/daemon/lib/merkle/diff.d.ts +32 -0
- package/dist/daemon/lib/merkle/diff.js +107 -0
- package/dist/daemon/lib/merkle/hash.d.ts +40 -0
- package/dist/daemon/lib/merkle/hash.js +180 -0
- package/dist/daemon/lib/merkle/index.d.ts +71 -0
- package/dist/daemon/lib/merkle/index.js +309 -0
- package/dist/daemon/lib/merkle/node.d.ts +55 -0
- package/dist/daemon/lib/merkle/node.js +82 -0
- package/dist/daemon/lifecycle.d.ts +50 -0
- package/dist/daemon/lifecycle.js +142 -0
- package/dist/daemon/owner.d.ts +175 -0
- package/dist/daemon/owner.js +609 -0
- package/dist/daemon/protocol.d.ts +100 -0
- package/dist/daemon/protocol.js +163 -0
- package/dist/daemon/providers/api-utils.d.ts +130 -0
- package/dist/daemon/providers/api-utils.js +248 -0
- package/dist/daemon/providers/gemini.d.ts +39 -0
- package/dist/daemon/providers/gemini.js +205 -0
- package/dist/daemon/providers/index.d.ts +14 -0
- package/dist/daemon/providers/index.js +14 -0
- package/dist/daemon/providers/local-4b.d.ts +28 -0
- package/dist/daemon/providers/local-4b.js +51 -0
- package/dist/daemon/providers/local.d.ts +36 -0
- package/dist/daemon/providers/local.js +166 -0
- package/dist/daemon/providers/mistral.d.ts +35 -0
- package/dist/daemon/providers/mistral.js +160 -0
- package/dist/daemon/providers/mock.d.ts +35 -0
- package/dist/daemon/providers/mock.js +69 -0
- package/dist/daemon/providers/openai.d.ts +41 -0
- package/dist/daemon/providers/openai.js +190 -0
- package/dist/daemon/providers/types.d.ts +68 -0
- package/dist/daemon/providers/types.js +6 -0
- package/dist/daemon/providers/validate.d.ts +30 -0
- package/dist/daemon/providers/validate.js +162 -0
- package/dist/daemon/server.d.ts +79 -0
- package/dist/daemon/server.js +293 -0
- package/dist/daemon/services/index.d.ts +11 -0
- package/dist/daemon/services/index.js +16 -0
- package/dist/daemon/services/indexing.d.ts +117 -0
- package/dist/daemon/services/indexing.js +573 -0
- package/dist/daemon/services/search/filters.d.ts +21 -0
- package/dist/daemon/services/search/filters.js +106 -0
- package/dist/daemon/services/search/fts.d.ts +32 -0
- package/dist/daemon/services/search/fts.js +61 -0
- package/dist/daemon/services/search/hybrid.d.ts +17 -0
- package/dist/daemon/services/search/hybrid.js +58 -0
- package/dist/daemon/services/search/index.d.ts +108 -0
- package/dist/daemon/services/search/index.js +417 -0
- package/dist/daemon/services/search/types.d.ts +126 -0
- package/dist/daemon/services/search/types.js +4 -0
- package/dist/daemon/services/search/vector.d.ts +25 -0
- package/dist/daemon/services/search/vector.js +44 -0
- package/dist/daemon/services/storage/index.d.ts +110 -0
- package/dist/daemon/services/storage/index.js +378 -0
- package/dist/daemon/services/storage/schema.d.ts +24 -0
- package/dist/daemon/services/storage/schema.js +51 -0
- package/dist/daemon/services/storage/types.d.ts +105 -0
- package/dist/daemon/services/storage/types.js +71 -0
- package/dist/daemon/services/types.d.ts +192 -0
- package/dist/daemon/services/types.js +53 -0
- package/dist/daemon/services/watcher.d.ts +98 -0
- package/dist/daemon/services/watcher.js +386 -0
- package/dist/daemon/state.d.ts +119 -0
- package/dist/daemon/state.js +161 -0
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +44 -60
- package/dist/mcp/server.d.ts +10 -14
- package/dist/mcp/server.js +75 -74
- package/dist/mcp/services/lazy-loader.d.ts +23 -0
- package/dist/mcp/services/lazy-loader.js +34 -0
- package/dist/mcp/warmup.d.ts +3 -3
- package/dist/mcp/warmup.js +39 -40
- package/dist/mcp/watcher.d.ts +5 -7
- package/dist/mcp/watcher.js +73 -64
- package/dist/rag/config/index.d.ts +2 -0
- package/dist/rag/constants.d.ts +30 -0
- package/dist/rag/constants.js +38 -0
- package/dist/rag/embeddings/api-utils.d.ts +121 -0
- package/dist/rag/embeddings/api-utils.js +259 -0
- package/dist/rag/embeddings/gemini.d.ts +4 -12
- package/dist/rag/embeddings/gemini.js +22 -72
- package/dist/rag/embeddings/index.d.ts +5 -3
- package/dist/rag/embeddings/index.js +5 -2
- package/dist/rag/embeddings/local-4b.d.ts +2 -2
- package/dist/rag/embeddings/local-4b.js +1 -1
- package/dist/rag/embeddings/local.d.ts +10 -3
- package/dist/rag/embeddings/local.js +58 -12
- package/dist/rag/embeddings/mistral.d.ts +4 -12
- package/dist/rag/embeddings/mistral.js +22 -72
- package/dist/rag/embeddings/mock.d.ts +35 -0
- package/dist/rag/embeddings/mock.js +69 -0
- package/dist/rag/embeddings/openai.d.ts +11 -13
- package/dist/rag/embeddings/openai.js +47 -75
- package/dist/rag/embeddings/types.d.ts +27 -1
- package/dist/rag/embeddings/validate.d.ts +9 -1
- package/dist/rag/embeddings/validate.js +17 -4
- package/dist/rag/index.d.ts +2 -2
- package/dist/rag/index.js +1 -1
- package/dist/rag/indexer/bounded-channel.d.ts +51 -0
- package/dist/rag/indexer/bounded-channel.js +138 -0
- package/dist/rag/indexer/indexer.d.ts +4 -14
- package/dist/rag/indexer/indexer.js +246 -169
- package/dist/rag/indexer/types.d.ts +1 -0
- package/dist/rag/logger/index.d.ts +22 -0
- package/dist/rag/logger/index.js +78 -1
- package/dist/rag/manifest/index.js +1 -2
- package/dist/rag/search/index.js +1 -1
- package/dist/rag/storage/schema.d.ts +2 -4
- package/dist/rag/storage/schema.js +3 -5
- package/dist/store/app/selectors.d.ts +87 -0
- package/dist/store/app/selectors.js +28 -0
- package/dist/store/app/slice.d.ts +1013 -0
- package/dist/store/app/slice.js +112 -0
- package/dist/store/hooks.d.ts +22 -0
- package/dist/store/hooks.js +17 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +18 -0
- package/dist/store/indexing/listeners.d.ts +25 -0
- package/dist/store/indexing/listeners.js +46 -0
- package/dist/store/indexing/selectors.d.ts +195 -0
- package/dist/store/indexing/selectors.js +69 -0
- package/dist/store/indexing/slice.d.ts +309 -0
- package/dist/store/indexing/slice.js +113 -0
- package/dist/store/slot-progress/listeners.d.ts +23 -0
- package/dist/store/slot-progress/listeners.js +33 -0
- package/dist/store/slot-progress/selectors.d.ts +67 -0
- package/dist/store/slot-progress/selectors.js +36 -0
- package/dist/store/slot-progress/slice.d.ts +246 -0
- package/dist/store/slot-progress/slice.js +70 -0
- package/dist/store/store.d.ts +17 -0
- package/dist/store/store.js +18 -0
- package/dist/store/warmup/selectors.d.ts +109 -0
- package/dist/store/warmup/selectors.js +44 -0
- package/dist/store/warmup/slice.d.ts +137 -0
- package/dist/store/warmup/slice.js +72 -0
- package/dist/store/watcher/selectors.d.ts +115 -0
- package/dist/store/watcher/selectors.js +52 -0
- package/dist/store/watcher/slice.d.ts +269 -0
- package/dist/store/watcher/slice.js +100 -0
- package/dist/store/wizard/selectors.d.ts +115 -0
- package/dist/store/wizard/selectors.js +36 -0
- package/dist/store/wizard/slice.d.ts +523 -0
- package/dist/store/wizard/slice.js +119 -0
- package/package.json +10 -2
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon Client
|
|
3
|
+
*
|
|
4
|
+
* High-level client for daemon communication.
|
|
5
|
+
* Provides typed API methods and handles connection lifecycle.
|
|
6
|
+
*
|
|
7
|
+
* Simplified for polling-based architecture:
|
|
8
|
+
* - Pure request/response, no push notifications
|
|
9
|
+
* - No reconnection logic - clients poll and reconnect as needed
|
|
10
|
+
* - Auto-starts daemon if not running
|
|
11
|
+
*/
|
|
12
|
+
import type { DaemonClientOptions, ClientSearchOptions, ClientIndexOptions, IndexStartResponse, DaemonStatusResponse, PingResponse, SearchResults, IndexStats, WatcherStatus } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Client for communicating with the VibeRAG daemon.
|
|
15
|
+
* Pure request/response - clients poll status() for updates.
|
|
16
|
+
*/
|
|
17
|
+
export declare class DaemonClient {
|
|
18
|
+
private readonly projectRoot;
|
|
19
|
+
private readonly socketPath;
|
|
20
|
+
private readonly autoStart;
|
|
21
|
+
private readonly connectTimeout;
|
|
22
|
+
private connection;
|
|
23
|
+
private connectPromise;
|
|
24
|
+
constructor(options: DaemonClientOptions | string);
|
|
25
|
+
/**
|
|
26
|
+
* Check if connected.
|
|
27
|
+
*/
|
|
28
|
+
isConnected(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Connect to the daemon.
|
|
31
|
+
* Auto-starts daemon if not running (when autoStart is true).
|
|
32
|
+
* Safe for concurrent calls - will reuse in-flight connection attempt.
|
|
33
|
+
*/
|
|
34
|
+
connect(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Internal connection logic.
|
|
37
|
+
*/
|
|
38
|
+
private doConnect;
|
|
39
|
+
/**
|
|
40
|
+
* Disconnect from the daemon.
|
|
41
|
+
*/
|
|
42
|
+
disconnect(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if daemon is running (without connecting).
|
|
45
|
+
*/
|
|
46
|
+
isRunning(): Promise<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* Ensure connected before making a request.
|
|
49
|
+
*/
|
|
50
|
+
private ensureConnected;
|
|
51
|
+
/**
|
|
52
|
+
* Search the codebase.
|
|
53
|
+
*/
|
|
54
|
+
search(query: string, options?: ClientSearchOptions): Promise<SearchResults>;
|
|
55
|
+
/**
|
|
56
|
+
* Index the codebase.
|
|
57
|
+
*/
|
|
58
|
+
index(options?: ClientIndexOptions): Promise<IndexStats>;
|
|
59
|
+
/**
|
|
60
|
+
* Start indexing asynchronously.
|
|
61
|
+
*/
|
|
62
|
+
indexAsync(options?: ClientIndexOptions): Promise<IndexStartResponse>;
|
|
63
|
+
/**
|
|
64
|
+
* Get daemon status.
|
|
65
|
+
* Clients should poll this endpoint for state updates.
|
|
66
|
+
*/
|
|
67
|
+
status(): Promise<DaemonStatusResponse>;
|
|
68
|
+
/**
|
|
69
|
+
* Get watcher status.
|
|
70
|
+
*/
|
|
71
|
+
watchStatus(): Promise<WatcherStatus>;
|
|
72
|
+
/**
|
|
73
|
+
* Request daemon shutdown.
|
|
74
|
+
*/
|
|
75
|
+
shutdown(reason?: string): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Ping the daemon.
|
|
78
|
+
*/
|
|
79
|
+
ping(): Promise<PingResponse>;
|
|
80
|
+
/**
|
|
81
|
+
* Get health information.
|
|
82
|
+
*/
|
|
83
|
+
health(): Promise<{
|
|
84
|
+
healthy: boolean;
|
|
85
|
+
uptime: number;
|
|
86
|
+
memoryUsage: NodeJS.MemoryUsage;
|
|
87
|
+
clients: number;
|
|
88
|
+
indexStatus: string;
|
|
89
|
+
protocolVersion: number;
|
|
90
|
+
}>;
|
|
91
|
+
}
|
|
92
|
+
export { getSocketPath, getLockPath, isDaemonRunning, isDaemonLocked, } from './auto-start.js';
|
|
93
|
+
export type { DaemonClientOptions, ClientSearchOptions, ClientIndexOptions, DaemonStatusResponse, PingResponse, SearchResults, IndexStats, WatcherStatus, SlotState, FailedChunk, } from './types.js';
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon Client
|
|
3
|
+
*
|
|
4
|
+
* High-level client for daemon communication.
|
|
5
|
+
* Provides typed API methods and handles connection lifecycle.
|
|
6
|
+
*
|
|
7
|
+
* Simplified for polling-based architecture:
|
|
8
|
+
* - Pure request/response, no push notifications
|
|
9
|
+
* - No reconnection logic - clients poll and reconnect as needed
|
|
10
|
+
* - Auto-starts daemon if not running
|
|
11
|
+
*/
|
|
12
|
+
import { DaemonConnection } from './connection.js';
|
|
13
|
+
import { ensureDaemonRunning, isDaemonRunning, getSocketPath, } from './auto-start.js';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// DaemonClient
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Client for communicating with the VibeRAG daemon.
|
|
19
|
+
* Pure request/response - clients poll status() for updates.
|
|
20
|
+
*/
|
|
21
|
+
export class DaemonClient {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
Object.defineProperty(this, "projectRoot", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "socketPath", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "autoStart", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: void 0
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "connectTimeout", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(this, "connection", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: null
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(this, "connectPromise", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
configurable: true,
|
|
56
|
+
writable: true,
|
|
57
|
+
value: null
|
|
58
|
+
});
|
|
59
|
+
// Handle simple string constructor
|
|
60
|
+
if (typeof options === 'string') {
|
|
61
|
+
this.projectRoot = options;
|
|
62
|
+
this.autoStart = true;
|
|
63
|
+
this.connectTimeout = 5000;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.projectRoot = options.projectRoot;
|
|
67
|
+
this.autoStart = options.autoStart ?? true;
|
|
68
|
+
this.connectTimeout = options.connectTimeout ?? 5000;
|
|
69
|
+
}
|
|
70
|
+
this.socketPath = getSocketPath(this.projectRoot);
|
|
71
|
+
}
|
|
72
|
+
// ==========================================================================
|
|
73
|
+
// Connection Management
|
|
74
|
+
// ==========================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Check if connected.
|
|
77
|
+
*/
|
|
78
|
+
isConnected() {
|
|
79
|
+
return this.connection?.isConnected() === true;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Connect to the daemon.
|
|
83
|
+
* Auto-starts daemon if not running (when autoStart is true).
|
|
84
|
+
* Safe for concurrent calls - will reuse in-flight connection attempt.
|
|
85
|
+
*/
|
|
86
|
+
async connect() {
|
|
87
|
+
if (this.isConnected()) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// Reuse existing connection attempt if one is in progress
|
|
91
|
+
if (this.connectPromise) {
|
|
92
|
+
return this.connectPromise;
|
|
93
|
+
}
|
|
94
|
+
this.connectPromise = this.doConnect();
|
|
95
|
+
try {
|
|
96
|
+
await this.connectPromise;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
this.connectPromise = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Internal connection logic.
|
|
104
|
+
*/
|
|
105
|
+
async doConnect() {
|
|
106
|
+
try {
|
|
107
|
+
// Auto-start daemon if needed
|
|
108
|
+
if (this.autoStart) {
|
|
109
|
+
await ensureDaemonRunning(this.projectRoot);
|
|
110
|
+
}
|
|
111
|
+
// Create connection
|
|
112
|
+
this.connection = new DaemonConnection(this.socketPath);
|
|
113
|
+
// Connect
|
|
114
|
+
await this.connection.connect(this.connectTimeout);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
this.connection = null;
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Disconnect from the daemon.
|
|
123
|
+
*/
|
|
124
|
+
async disconnect() {
|
|
125
|
+
if (this.connection) {
|
|
126
|
+
this.connection.disconnect();
|
|
127
|
+
this.connection = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if daemon is running (without connecting).
|
|
132
|
+
*/
|
|
133
|
+
async isRunning() {
|
|
134
|
+
return isDaemonRunning(this.projectRoot);
|
|
135
|
+
}
|
|
136
|
+
// ==========================================================================
|
|
137
|
+
// API Methods
|
|
138
|
+
// ==========================================================================
|
|
139
|
+
/**
|
|
140
|
+
* Ensure connected before making a request.
|
|
141
|
+
*/
|
|
142
|
+
async ensureConnected() {
|
|
143
|
+
if (!this.isConnected()) {
|
|
144
|
+
await this.connect();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Search the codebase.
|
|
149
|
+
*/
|
|
150
|
+
async search(query, options) {
|
|
151
|
+
await this.ensureConnected();
|
|
152
|
+
return this.connection.request('search', {
|
|
153
|
+
query,
|
|
154
|
+
...options,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Index the codebase.
|
|
159
|
+
*/
|
|
160
|
+
async index(options) {
|
|
161
|
+
await this.ensureConnected();
|
|
162
|
+
return this.connection.request('index', options);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Start indexing asynchronously.
|
|
166
|
+
*/
|
|
167
|
+
async indexAsync(options) {
|
|
168
|
+
await this.ensureConnected();
|
|
169
|
+
return this.connection.request('indexAsync', options);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get daemon status.
|
|
173
|
+
* Clients should poll this endpoint for state updates.
|
|
174
|
+
*/
|
|
175
|
+
async status() {
|
|
176
|
+
await this.ensureConnected();
|
|
177
|
+
return this.connection.request('status');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get watcher status.
|
|
181
|
+
*/
|
|
182
|
+
async watchStatus() {
|
|
183
|
+
await this.ensureConnected();
|
|
184
|
+
return this.connection.request('watchStatus');
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Request daemon shutdown.
|
|
188
|
+
*/
|
|
189
|
+
async shutdown(reason) {
|
|
190
|
+
await this.ensureConnected();
|
|
191
|
+
await this.connection.request('shutdown', { reason });
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Ping the daemon.
|
|
195
|
+
*/
|
|
196
|
+
async ping() {
|
|
197
|
+
await this.ensureConnected();
|
|
198
|
+
return this.connection.request('ping');
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get health information.
|
|
202
|
+
*/
|
|
203
|
+
async health() {
|
|
204
|
+
await this.ensureConnected();
|
|
205
|
+
return this.connection.request('health');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Re-export types and utilities
|
|
209
|
+
export { getSocketPath, getLockPath, isDaemonRunning, isDaemonLocked, } from './auto-start.js';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Types
|
|
3
|
+
*
|
|
4
|
+
* Types for daemon client communication.
|
|
5
|
+
* Simplified for polling-based architecture.
|
|
6
|
+
*/
|
|
7
|
+
import type { SearchResults } from '../daemon/services/search/types.js';
|
|
8
|
+
import type { IndexStats } from '../daemon/services/indexing.js';
|
|
9
|
+
import type { WatcherStatus } from '../daemon/services/watcher.js';
|
|
10
|
+
/**
|
|
11
|
+
* Slot state for concurrent embedding tracking.
|
|
12
|
+
*/
|
|
13
|
+
export interface SlotState {
|
|
14
|
+
state: 'idle' | 'processing' | 'rate-limited';
|
|
15
|
+
batchInfo: string | null;
|
|
16
|
+
retryInfo: string | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Failed chunk info.
|
|
20
|
+
*/
|
|
21
|
+
export interface FailedChunk {
|
|
22
|
+
batchInfo: string;
|
|
23
|
+
error: string;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Options for DaemonClient constructor.
|
|
28
|
+
*/
|
|
29
|
+
export interface DaemonClientOptions {
|
|
30
|
+
/** Project root directory */
|
|
31
|
+
projectRoot: string;
|
|
32
|
+
/** Auto-start daemon if not running (default: true) */
|
|
33
|
+
autoStart?: boolean;
|
|
34
|
+
/** Connection timeout in ms (default: 5000) */
|
|
35
|
+
connectTimeout?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Search options for client.
|
|
39
|
+
*/
|
|
40
|
+
export interface ClientSearchOptions {
|
|
41
|
+
mode?: 'semantic' | 'exact' | 'hybrid' | 'definition' | 'similar';
|
|
42
|
+
limit?: number;
|
|
43
|
+
bm25Weight?: number;
|
|
44
|
+
minScore?: number;
|
|
45
|
+
filters?: Record<string, unknown>;
|
|
46
|
+
codeSnippet?: string;
|
|
47
|
+
symbolName?: string;
|
|
48
|
+
autoBoost?: boolean;
|
|
49
|
+
autoBoostThreshold?: number;
|
|
50
|
+
returnDebug?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Index options for client.
|
|
54
|
+
*/
|
|
55
|
+
export interface ClientIndexOptions {
|
|
56
|
+
force?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Index start response for async indexing.
|
|
60
|
+
*/
|
|
61
|
+
export interface IndexStartResponse {
|
|
62
|
+
started: boolean;
|
|
63
|
+
reason?: 'in_progress';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Daemon status response.
|
|
67
|
+
* Enhanced to support polling-based state synchronization.
|
|
68
|
+
*/
|
|
69
|
+
export interface DaemonStatusResponse {
|
|
70
|
+
initialized: boolean;
|
|
71
|
+
indexed: boolean;
|
|
72
|
+
version?: number;
|
|
73
|
+
createdAt?: string;
|
|
74
|
+
updatedAt?: string;
|
|
75
|
+
totalFiles?: number;
|
|
76
|
+
totalChunks?: number;
|
|
77
|
+
embeddingProvider?: string;
|
|
78
|
+
embeddingModel?: string;
|
|
79
|
+
warmupStatus: string;
|
|
80
|
+
warmupElapsedMs?: number;
|
|
81
|
+
watcherStatus: WatcherStatus;
|
|
82
|
+
indexing: {
|
|
83
|
+
status: 'idle' | 'initializing' | 'indexing' | 'complete' | 'error';
|
|
84
|
+
current: number;
|
|
85
|
+
total: number;
|
|
86
|
+
stage: string;
|
|
87
|
+
chunksProcessed: number;
|
|
88
|
+
throttleMessage: string | null;
|
|
89
|
+
error: string | null;
|
|
90
|
+
lastCompleted: string | null;
|
|
91
|
+
lastStats: IndexStats | null;
|
|
92
|
+
percent: number;
|
|
93
|
+
};
|
|
94
|
+
slots: SlotState[];
|
|
95
|
+
failures: FailedChunk[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Ping response.
|
|
99
|
+
*/
|
|
100
|
+
export interface PingResponse {
|
|
101
|
+
pong: boolean;
|
|
102
|
+
timestamp: number;
|
|
103
|
+
protocolVersion: number;
|
|
104
|
+
}
|
|
105
|
+
export type { SearchResults, IndexStats, WatcherStatus };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Individual slot row component for displaying batch processing progress.
|
|
3
|
+
*
|
|
4
|
+
* Each SlotRow watches its own slice of Redux state and renders independently.
|
|
5
|
+
* This follows the Single Responsibility Principle - each row manages its own
|
|
6
|
+
* rendering logic based on its slot index.
|
|
7
|
+
*/
|
|
8
|
+
import React from 'react';
|
|
9
|
+
type Props = {
|
|
10
|
+
/** The slot index (0 to CONCURRENCY-1) */
|
|
11
|
+
slotIndex: number;
|
|
12
|
+
/** Whether this is the last visible slot (for tree-drawing) */
|
|
13
|
+
isLast: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Renders a single slot's progress status.
|
|
17
|
+
*
|
|
18
|
+
* Always renders a fixed-height row to prevent UI jumping when slots
|
|
19
|
+
* become active/idle. Idle slots show an empty placeholder.
|
|
20
|
+
*/
|
|
21
|
+
export declare function SlotRow({ slotIndex, isLast }: Props): React.ReactElement;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Individual slot row component for displaying batch processing progress.
|
|
3
|
+
*
|
|
4
|
+
* Each SlotRow watches its own slice of Redux state and renders independently.
|
|
5
|
+
* This follows the Single Responsibility Principle - each row manages its own
|
|
6
|
+
* rendering logic based on its slot index.
|
|
7
|
+
*/
|
|
8
|
+
import React, { useState, useEffect } from 'react';
|
|
9
|
+
import { Box, Text } from 'ink';
|
|
10
|
+
import { useAppSelector } from '../../store/hooks.js';
|
|
11
|
+
import { selectSlot } from '../../store/slot-progress/selectors.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Constants
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/** Braille dots spinner frames */
|
|
16
|
+
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
17
|
+
/**
|
|
18
|
+
* Renders a single slot's progress status.
|
|
19
|
+
*
|
|
20
|
+
* Always renders a fixed-height row to prevent UI jumping when slots
|
|
21
|
+
* become active/idle. Idle slots show an empty placeholder.
|
|
22
|
+
*/
|
|
23
|
+
export function SlotRow({ slotIndex, isLast }) {
|
|
24
|
+
const slot = useAppSelector(state => selectSlot(state, slotIndex));
|
|
25
|
+
const [frame, setFrame] = useState(0);
|
|
26
|
+
// Spinner animation - only runs when processing
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (slot.state !== 'processing')
|
|
29
|
+
return;
|
|
30
|
+
const timer = setInterval(() => {
|
|
31
|
+
setFrame(f => (f + 1) % SPINNER_FRAMES.length);
|
|
32
|
+
}, 80);
|
|
33
|
+
return () => clearInterval(timer);
|
|
34
|
+
}, [slot.state]);
|
|
35
|
+
// Tree-drawing prefix
|
|
36
|
+
const prefix = isLast ? '└ ' : '├ ';
|
|
37
|
+
// Idle slots render empty placeholder to maintain fixed height
|
|
38
|
+
if (slot.state === 'idle') {
|
|
39
|
+
return (React.createElement(Box, null,
|
|
40
|
+
React.createElement(Text, { dimColor: true }, prefix),
|
|
41
|
+
React.createElement(Text, { dimColor: true }, "\u00B7")));
|
|
42
|
+
}
|
|
43
|
+
return (React.createElement(Box, null,
|
|
44
|
+
React.createElement(Text, { dimColor: true }, prefix),
|
|
45
|
+
slot.state === 'rate-limited' ? (React.createElement(Text, { color: "yellow" },
|
|
46
|
+
"\u26A0 ",
|
|
47
|
+
slot.batchInfo,
|
|
48
|
+
slot.retryInfo && ` · ${slot.retryInfo}`)) : (React.createElement(React.Fragment, null,
|
|
49
|
+
React.createElement(Text, { color: "cyan" },
|
|
50
|
+
SPINNER_FRAMES[frame],
|
|
51
|
+
" "),
|
|
52
|
+
React.createElement(Text, { dimColor: true }, slot.batchInfo)))));
|
|
53
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
|
+
import { useAppSelector } from '../../store/hooks.js';
|
|
4
|
+
import { selectSlotCount, selectFailures, selectHasActiveSlots, } from '../../store/slot-progress/selectors.js';
|
|
5
|
+
import { selectIndexingDisplay, selectIsIndexing, } from '../../store/indexing/selectors.js';
|
|
6
|
+
import { SlotRow } from './SlotRow.js';
|
|
3
7
|
/** Braille dots spinner frames */
|
|
4
8
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
5
9
|
/**
|
|
@@ -17,37 +21,25 @@ function Spinner({ color }) {
|
|
|
17
21
|
SPINNER_FRAMES[frame],
|
|
18
22
|
" ");
|
|
19
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Progress bar component for visual progress indication.
|
|
26
|
+
*/
|
|
27
|
+
function ProgressBar({ percent, width = 20, }) {
|
|
28
|
+
const filled = Math.round((percent / 100) * width);
|
|
29
|
+
const empty = width - filled;
|
|
30
|
+
return (React.createElement(Text, null,
|
|
31
|
+
React.createElement(Text, { color: "cyan" }, '█'.repeat(filled)),
|
|
32
|
+
React.createElement(Text, { dimColor: true }, '░'.repeat(empty))));
|
|
33
|
+
}
|
|
20
34
|
/**
|
|
21
35
|
* Format status message for display.
|
|
36
|
+
* Note: Indexing state is derived from Redux via selectIsIndexing.
|
|
37
|
+
* This function only handles non-indexing app states.
|
|
22
38
|
*/
|
|
23
|
-
function
|
|
39
|
+
function formatNonIndexingStatus(status) {
|
|
24
40
|
switch (status.state) {
|
|
25
41
|
case 'ready':
|
|
26
42
|
return { text: 'Ready', color: 'green', showSpinner: false };
|
|
27
|
-
case 'indexing': {
|
|
28
|
-
// Throttle status takes precedence - show in yellow
|
|
29
|
-
if (status.throttleMessage) {
|
|
30
|
-
return {
|
|
31
|
-
text: status.throttleMessage,
|
|
32
|
-
color: 'yellow',
|
|
33
|
-
showSpinner: true,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// Normal indexing display
|
|
37
|
-
if (status.total === 0) {
|
|
38
|
-
return { text: `${status.stage}`, color: 'cyan', showSpinner: true };
|
|
39
|
-
}
|
|
40
|
-
const percent = Math.round((status.current / status.total) * 100);
|
|
41
|
-
// Include chunk count if available
|
|
42
|
-
const chunkInfo = status.chunksProcessed !== undefined
|
|
43
|
-
? ` · ${status.chunksProcessed} chunks`
|
|
44
|
-
: '';
|
|
45
|
-
return {
|
|
46
|
-
text: `${status.stage} ${status.current}/${status.total} (${percent}%)${chunkInfo}`,
|
|
47
|
-
color: 'cyan',
|
|
48
|
-
showSpinner: true,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
43
|
case 'searching':
|
|
52
44
|
return { text: 'Searching', color: 'cyan', showSpinner: true };
|
|
53
45
|
case 'warning':
|
|
@@ -67,11 +59,70 @@ function formatStats(stats) {
|
|
|
67
59
|
return `${stats.totalFiles} files · ${stats.totalChunks} chunks`;
|
|
68
60
|
}
|
|
69
61
|
export default function StatusBar({ status, stats }) {
|
|
70
|
-
const { text, color, showSpinner } = formatStatus(status);
|
|
71
62
|
const statsText = formatStats(stats);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
// Redux selectors for indexing progress
|
|
64
|
+
const indexingDisplay = useAppSelector(selectIndexingDisplay);
|
|
65
|
+
const isIndexingActive = useAppSelector(selectIsIndexing);
|
|
66
|
+
// Redux selectors for slot progress
|
|
67
|
+
const slotCount = useAppSelector(selectSlotCount);
|
|
68
|
+
const failures = useAppSelector(selectFailures);
|
|
69
|
+
const hasActiveSlots = useAppSelector(selectHasActiveSlots);
|
|
70
|
+
// Determine display values based on state source
|
|
71
|
+
// For indexing: use Redux state (synced from daemon - single source of truth)
|
|
72
|
+
// For other states: use props (local app state)
|
|
73
|
+
const nonIndexingStatus = formatNonIndexingStatus(status);
|
|
74
|
+
// Use Redux for indexing display, props for everything else
|
|
75
|
+
const displayValues = isIndexingActive
|
|
76
|
+
? {
|
|
77
|
+
text: indexingDisplay.stage,
|
|
78
|
+
color: indexingDisplay.color,
|
|
79
|
+
showSpinner: true,
|
|
80
|
+
showProgressBar: indexingDisplay.showProgressBar,
|
|
81
|
+
percent: indexingDisplay.percent,
|
|
82
|
+
stage: indexingDisplay.stage,
|
|
83
|
+
chunkInfo: indexingDisplay.chunkInfo,
|
|
84
|
+
throttleInfo: indexingDisplay.throttleInfo,
|
|
85
|
+
}
|
|
86
|
+
: {
|
|
87
|
+
text: nonIndexingStatus.text,
|
|
88
|
+
color: nonIndexingStatus.color,
|
|
89
|
+
showSpinner: nonIndexingStatus.showSpinner,
|
|
90
|
+
showProgressBar: false,
|
|
91
|
+
percent: 0,
|
|
92
|
+
stage: '',
|
|
93
|
+
chunkInfo: undefined,
|
|
94
|
+
throttleInfo: null,
|
|
95
|
+
};
|
|
96
|
+
const { text, color, showSpinner, showProgressBar, percent, stage, chunkInfo, throttleInfo, } = displayValues;
|
|
97
|
+
// Only show slots when there's actual activity (API providers use slots, local doesn't)
|
|
98
|
+
const showSlots = isIndexingActive && hasActiveSlots;
|
|
99
|
+
// Show failure summary if any batches failed
|
|
100
|
+
const hasFailures = failures.length > 0;
|
|
101
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
102
|
+
React.createElement(Box, { paddingX: 1, justifyContent: "space-between" },
|
|
103
|
+
React.createElement(Box, null,
|
|
104
|
+
showSpinner && React.createElement(Spinner, { color: color }),
|
|
105
|
+
showProgressBar ? (React.createElement(React.Fragment, null,
|
|
106
|
+
React.createElement(Text, { color: color },
|
|
107
|
+
stage,
|
|
108
|
+
" "),
|
|
109
|
+
React.createElement(Text, null, "["),
|
|
110
|
+
React.createElement(ProgressBar, { percent: percent }),
|
|
111
|
+
React.createElement(Text, null, "] "),
|
|
112
|
+
React.createElement(Text, { color: color },
|
|
113
|
+
percent,
|
|
114
|
+
"%"),
|
|
115
|
+
chunkInfo && React.createElement(Text, { dimColor: true },
|
|
116
|
+
" \u00B7 ",
|
|
117
|
+
chunkInfo),
|
|
118
|
+
throttleInfo && React.createElement(Text, { color: "yellow" },
|
|
119
|
+
" \u00B7 ",
|
|
120
|
+
throttleInfo))) : (React.createElement(Text, { color: color }, text))),
|
|
121
|
+
React.createElement(Text, { dimColor: true }, statsText)),
|
|
122
|
+
showSlots && (React.createElement(Box, { flexDirection: "column", paddingLeft: 2 }, Array.from({ length: slotCount }, (_, i) => (React.createElement(SlotRow, { key: i, slotIndex: i, isLast: i === slotCount - 1 }))))),
|
|
123
|
+
hasFailures && (React.createElement(Box, { paddingLeft: 2 },
|
|
124
|
+
React.createElement(Text, { color: "red" },
|
|
125
|
+
"\u26A0 ",
|
|
126
|
+
failures.length,
|
|
127
|
+
" batch(es) failed - see .viberag/debug.log")))));
|
|
77
128
|
}
|
package/dist/common/types.d.ts
CHANGED
|
@@ -53,18 +53,12 @@ export type TextBufferState = {
|
|
|
53
53
|
};
|
|
54
54
|
/**
|
|
55
55
|
* App status for the status bar.
|
|
56
|
+
*
|
|
57
|
+
* Note: Indexing state is derived from the indexing Redux slice (synced from daemon).
|
|
58
|
+
* Do NOT use appStatus for indexing - use selectIsIndexing() instead.
|
|
56
59
|
*/
|
|
57
60
|
export type AppStatus = {
|
|
58
61
|
state: 'ready';
|
|
59
|
-
} | {
|
|
60
|
-
state: 'indexing';
|
|
61
|
-
current: number;
|
|
62
|
-
total: number;
|
|
63
|
-
stage: string;
|
|
64
|
-
/** Rate limit message (shown in yellow when set) */
|
|
65
|
-
throttleMessage?: string | null;
|
|
66
|
-
/** Number of chunks embedded so far */
|
|
67
|
-
chunksProcessed?: number;
|
|
68
62
|
} | {
|
|
69
63
|
state: 'searching';
|
|
70
64
|
} | {
|
|
@@ -81,16 +75,19 @@ export type IndexDisplayStats = {
|
|
|
81
75
|
/**
|
|
82
76
|
* Embedding provider types.
|
|
83
77
|
*
|
|
84
|
-
* Local
|
|
78
|
+
* Local provider (no API key required):
|
|
85
79
|
* - local: Qwen3-Embedding-0.6B Q8 (1024d) - ~700MB download, ~1.2GB RAM
|
|
86
|
-
* - local-4b: Qwen3-Embedding-4B FP32 (2560d) - ~8GB download, ~8GB RAM
|
|
87
80
|
*
|
|
88
81
|
* API providers:
|
|
89
82
|
* - gemini: gemini-embedding-001 (1536d) - Free tier
|
|
90
83
|
* - mistral: codestral-embed (1536d) - Code-optimized
|
|
91
|
-
* - openai: text-embedding-3-
|
|
84
|
+
* - openai: text-embedding-3-large (1536d) - Highest quality
|
|
85
|
+
*/
|
|
86
|
+
export type EmbeddingProviderType = 'local' | 'gemini' | 'mistral' | 'openai';
|
|
87
|
+
/**
|
|
88
|
+
* OpenAI API regional endpoints for data residency.
|
|
92
89
|
*/
|
|
93
|
-
export type
|
|
90
|
+
export type OpenAIRegion = 'default' | 'us' | 'eu';
|
|
94
91
|
/**
|
|
95
92
|
* Configuration collected from the init wizard.
|
|
96
93
|
*/
|
|
@@ -98,6 +95,8 @@ export type InitWizardConfig = {
|
|
|
98
95
|
provider: EmbeddingProviderType;
|
|
99
96
|
/** API key for cloud providers (gemini, mistral, openai) */
|
|
100
97
|
apiKey?: string;
|
|
98
|
+
/** OpenAI regional endpoint (for corporate accounts with data residency) */
|
|
99
|
+
openaiRegion?: OpenAIRegion;
|
|
101
100
|
};
|
|
102
101
|
/**
|
|
103
102
|
* MCP editor identifiers.
|