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.
Files changed (171) hide show
  1. package/README.md +71 -6
  2. package/dist/core/domain/cipher/errors/file-system-error.d.ts +11 -0
  3. package/dist/core/domain/cipher/errors/file-system-error.js +17 -0
  4. package/dist/core/domain/cipher/file-system/types.d.ts +40 -6
  5. package/dist/core/domain/cipher/process/types.d.ts +1 -1
  6. package/dist/core/domain/entities/agent.d.ts +1 -1
  7. package/dist/core/domain/entities/agent.js +5 -0
  8. package/dist/core/domain/entities/provider-config.d.ts +92 -0
  9. package/dist/core/domain/entities/provider-config.js +181 -0
  10. package/dist/core/domain/entities/provider-registry.d.ts +55 -0
  11. package/dist/core/domain/entities/provider-registry.js +74 -0
  12. package/dist/core/interfaces/cipher/cipher-services.d.ts +0 -3
  13. package/dist/core/interfaces/cipher/i-content-generator.d.ts +30 -0
  14. package/dist/core/interfaces/cipher/i-content-generator.js +12 -1
  15. package/dist/core/interfaces/cipher/index.d.ts +0 -2
  16. package/dist/core/interfaces/cipher/message-factory.d.ts +4 -1
  17. package/dist/core/interfaces/cipher/message-factory.js +5 -0
  18. package/dist/core/interfaces/cipher/message-types.d.ts +19 -1
  19. package/dist/core/interfaces/i-provider-config-store.d.ts +88 -0
  20. package/dist/core/interfaces/i-provider-keychain-store.d.ts +33 -0
  21. package/dist/infra/cipher/file-system/binary-utils.d.ts +15 -2
  22. package/dist/infra/cipher/file-system/binary-utils.js +26 -3
  23. package/dist/infra/cipher/file-system/file-system-service.d.ts +9 -0
  24. package/dist/infra/cipher/file-system/file-system-service.js +96 -13
  25. package/dist/infra/cipher/file-system/pdf-extractor.d.ts +100 -0
  26. package/dist/infra/cipher/file-system/pdf-extractor.js +226 -0
  27. package/dist/infra/cipher/http/internal-llm-http-service.d.ts +40 -0
  28. package/dist/infra/cipher/http/internal-llm-http-service.js +152 -2
  29. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +8 -1
  30. package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +2 -3
  31. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +20 -11
  32. package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +1 -0
  33. package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +26 -0
  34. package/dist/infra/cipher/llm/internal-llm-service.d.ts +13 -0
  35. package/dist/infra/cipher/llm/internal-llm-service.js +75 -4
  36. package/dist/infra/cipher/llm/model-capabilities.d.ts +74 -0
  37. package/dist/infra/cipher/llm/model-capabilities.js +157 -0
  38. package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +35 -1
  39. package/dist/infra/cipher/llm/openrouter-llm-service.js +216 -28
  40. package/dist/infra/cipher/llm/stream-processor.d.ts +22 -2
  41. package/dist/infra/cipher/llm/stream-processor.js +78 -4
  42. package/dist/infra/cipher/llm/thought-parser.d.ts +1 -1
  43. package/dist/infra/cipher/llm/thought-parser.js +5 -5
  44. package/dist/infra/cipher/llm/transformers/openrouter-stream-transformer.d.ts +49 -0
  45. package/dist/infra/cipher/llm/transformers/openrouter-stream-transformer.js +272 -0
  46. package/dist/infra/cipher/llm/transformers/reasoning-extractor.d.ts +71 -0
  47. package/dist/infra/cipher/llm/transformers/reasoning-extractor.js +253 -0
  48. package/dist/infra/cipher/process/process-service.js +1 -1
  49. package/dist/infra/cipher/session/chat-session.d.ts +2 -0
  50. package/dist/infra/cipher/session/chat-session.js +13 -2
  51. package/dist/infra/cipher/storage/message-storage-service.js +4 -0
  52. package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +3 -3
  53. package/dist/infra/cipher/tools/implementations/read-file-tool.js +24 -4
  54. package/dist/infra/cipher/tools/implementations/task-tool.js +1 -1
  55. package/dist/infra/connectors/rules/rules-connector-config.d.ts +4 -0
  56. package/dist/infra/connectors/rules/rules-connector-config.js +4 -0
  57. package/dist/infra/http/openrouter-api-client.d.ts +148 -0
  58. package/dist/infra/http/openrouter-api-client.js +161 -0
  59. package/dist/infra/mcp/tools/brv-curate-tool.d.ts +10 -4
  60. package/dist/infra/mcp/tools/brv-curate-tool.js +9 -4
  61. package/dist/infra/mcp/tools/task-result-waiter.js +9 -1
  62. package/dist/infra/process/agent-worker.js +178 -70
  63. package/dist/infra/process/transport-handlers.d.ts +25 -4
  64. package/dist/infra/process/transport-handlers.js +57 -10
  65. package/dist/infra/repl/commands/connectors-command.js +2 -2
  66. package/dist/infra/repl/commands/index.js +5 -0
  67. package/dist/infra/repl/commands/model-command.d.ts +13 -0
  68. package/dist/infra/repl/commands/model-command.js +212 -0
  69. package/dist/infra/repl/commands/provider-command.d.ts +13 -0
  70. package/dist/infra/repl/commands/provider-command.js +181 -0
  71. package/dist/infra/repl/commands/space/switch-command.js +0 -2
  72. package/dist/infra/repl/transport-client-helper.js +6 -2
  73. package/dist/infra/storage/file-provider-config-store.d.ts +83 -0
  74. package/dist/infra/storage/file-provider-config-store.js +157 -0
  75. package/dist/infra/storage/provider-keychain-store.d.ts +37 -0
  76. package/dist/infra/storage/provider-keychain-store.js +75 -0
  77. package/dist/infra/transport/socket-io-transport-client.d.ts +20 -0
  78. package/dist/infra/transport/socket-io-transport-client.js +88 -1
  79. package/dist/infra/usecase/curate-use-case.js +10 -4
  80. package/dist/infra/usecase/space-switch-use-case.d.ts +0 -10
  81. package/dist/infra/usecase/space-switch-use-case.js +7 -37
  82. package/dist/oclif/hooks/init/welcome.js +4 -17
  83. package/dist/resources/prompts/curate.yml +1 -0
  84. package/dist/resources/tools/bash_exec.txt +1 -1
  85. package/dist/resources/tools/read_file.txt +5 -2
  86. package/dist/tui/components/api-key-dialog.d.ts +39 -0
  87. package/dist/tui/components/api-key-dialog.js +94 -0
  88. package/dist/tui/components/execution/execution-changes.d.ts +3 -1
  89. package/dist/tui/components/execution/execution-changes.js +4 -4
  90. package/dist/tui/components/execution/execution-content.d.ts +1 -1
  91. package/dist/tui/components/execution/execution-content.js +4 -12
  92. package/dist/tui/components/execution/execution-input.js +1 -1
  93. package/dist/tui/components/execution/execution-progress.d.ts +10 -13
  94. package/dist/tui/components/execution/execution-progress.js +70 -17
  95. package/dist/tui/components/execution/execution-reasoning.d.ts +16 -0
  96. package/dist/tui/components/execution/execution-reasoning.js +34 -0
  97. package/dist/tui/components/execution/execution-tool.d.ts +23 -0
  98. package/dist/tui/components/execution/execution-tool.js +125 -0
  99. package/dist/tui/components/execution/expanded-log-view.js +3 -3
  100. package/dist/tui/components/execution/log-item.d.ts +2 -0
  101. package/dist/tui/components/execution/log-item.js +6 -4
  102. package/dist/tui/components/index.d.ts +2 -0
  103. package/dist/tui/components/index.js +2 -0
  104. package/dist/tui/components/inline-prompts/inline-select.js +3 -2
  105. package/dist/tui/components/model-dialog.d.ts +63 -0
  106. package/dist/tui/components/model-dialog.js +89 -0
  107. package/dist/tui/components/onboarding/onboarding-flow.js +8 -2
  108. package/dist/tui/components/provider-dialog.d.ts +27 -0
  109. package/dist/tui/components/provider-dialog.js +31 -0
  110. package/dist/tui/components/reasoning-text.d.ts +26 -0
  111. package/dist/tui/components/reasoning-text.js +49 -0
  112. package/dist/tui/components/selectable-list.d.ts +54 -0
  113. package/dist/tui/components/selectable-list.js +180 -0
  114. package/dist/tui/components/streaming-text.d.ts +30 -0
  115. package/dist/tui/components/streaming-text.js +52 -0
  116. package/dist/tui/contexts/tasks-context.d.ts +15 -0
  117. package/dist/tui/contexts/tasks-context.js +224 -40
  118. package/dist/tui/contexts/theme-context.d.ts +1 -0
  119. package/dist/tui/contexts/theme-context.js +3 -2
  120. package/dist/tui/hooks/use-activity-logs.js +7 -1
  121. package/dist/tui/types/messages.d.ts +32 -5
  122. package/dist/tui/utils/index.d.ts +1 -1
  123. package/dist/tui/utils/index.js +1 -1
  124. package/dist/tui/utils/log.d.ts +0 -9
  125. package/dist/tui/utils/log.js +2 -53
  126. package/dist/tui/views/command-view.js +4 -1
  127. package/dist/utils/file-validator.js +8 -4
  128. package/oclif.manifest.json +1 -54
  129. package/package.json +4 -2
  130. package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +0 -20
  131. package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +0 -31
  132. package/dist/core/interfaces/i-file-watcher-service.d.ts +0 -41
  133. package/dist/core/interfaces/i-file-watcher-service.js +0 -1
  134. package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +0 -18
  135. package/dist/core/interfaces/parser/i-clean-parser-service.js +0 -1
  136. package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +0 -17
  137. package/dist/core/interfaces/parser/i-raw-parser-service.js +0 -1
  138. package/dist/core/interfaces/parser/i-session-normalizer.d.ts +0 -56
  139. package/dist/core/interfaces/parser/i-session-normalizer.js +0 -1
  140. package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +0 -24
  141. package/dist/infra/cipher/parsers/coding-agent-log-parser.js +0 -51
  142. package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +0 -14
  143. package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +0 -55
  144. package/dist/infra/parsers/clean/clean-claude-service.d.ts +0 -111
  145. package/dist/infra/parsers/clean/clean-claude-service.js +0 -271
  146. package/dist/infra/parsers/clean/clean-codex-service.d.ts +0 -231
  147. package/dist/infra/parsers/clean/clean-codex-service.js +0 -534
  148. package/dist/infra/parsers/clean/clean-copilot-service.d.ts +0 -255
  149. package/dist/infra/parsers/clean/clean-copilot-service.js +0 -729
  150. package/dist/infra/parsers/clean/clean-cursor-service.d.ts +0 -161
  151. package/dist/infra/parsers/clean/clean-cursor-service.js +0 -432
  152. package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +0 -54
  153. package/dist/infra/parsers/clean/clean-parser-service-factory.js +0 -80
  154. package/dist/infra/parsers/clean/shared.d.ts +0 -84
  155. package/dist/infra/parsers/clean/shared.js +0 -273
  156. package/dist/infra/parsers/raw/raw-claude-service.d.ts +0 -195
  157. package/dist/infra/parsers/raw/raw-claude-service.js +0 -548
  158. package/dist/infra/parsers/raw/raw-codex-service.d.ts +0 -313
  159. package/dist/infra/parsers/raw/raw-codex-service.js +0 -782
  160. package/dist/infra/parsers/raw/raw-copilot-service.d.ts +0 -196
  161. package/dist/infra/parsers/raw/raw-copilot-service.js +0 -558
  162. package/dist/infra/parsers/raw/raw-cursor-service.d.ts +0 -316
  163. package/dist/infra/parsers/raw/raw-cursor-service.js +0 -818
  164. package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +0 -54
  165. package/dist/infra/parsers/raw/raw-parser-service-factory.js +0 -81
  166. package/dist/infra/watcher/file-watcher-service.d.ts +0 -10
  167. package/dist/infra/watcher/file-watcher-service.js +0 -81
  168. package/dist/oclif/commands/watch.d.ts +0 -25
  169. package/dist/oclif/commands/watch.js +0 -175
  170. /package/dist/core/interfaces/{cipher/i-coding-agent-log-parser.js → i-provider-config-store.js} +0 -0
  171. /package/dist/core/interfaces/{cipher/i-coding-agent-log-watcher.js → i-provider-keychain-store.js} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ByteRover CLI
2
2
 
3
- Command-line interface for ByteRover, featuring an interactive REPL with a modern React/Ink terminal UI for managing your project's context tree and knowledge storage. Seamlessly integrate with 18 AI coding agents via modern skill files, MCP tools, or rules-based integration—supports Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and 13 more.
3
+ Command-line interface for ByteRover, featuring an interactive REPL with a modern React/Ink terminal UI for managing your project's context tree and knowledge storage. Seamlessly integrate with 19 AI coding agents via modern skill files, MCP tools, or rules-based integration—supports Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and more.
4
4
 
5
5
  [![Version](https://img.shields.io/npm/v/byterover-cli.svg)](https://npmjs.org/package/byterover-cli)
6
6
  [![Downloads/week](https://img.shields.io/npm/dw/byterover-cli.svg)](https://npmjs.org/package/byterover-cli)
@@ -14,6 +14,7 @@ Command-line interface for ByteRover, featuring an interactive REPL with a moder
14
14
  * [Keyboard Shortcuts](#keyboard-shortcuts)
15
15
  * [What is Context Tree?](#what-is-context-tree)
16
16
  * [Supported AI Agents](#supported-ai-agents)
17
+ * [LLM Providers](#llm-providers) (BETA)
17
18
  * [Slash Commands Reference](#slash-commands-reference)
18
19
  * [Authentication](#authentication)
19
20
  * [Configuration](#configuration)
@@ -51,7 +52,7 @@ brv --version
51
52
 
52
53
  Visit [**ByteRover Docs**](https://docs.byterover.dev) for more information.
53
54
 
54
- Get started with ByteRover CLI in three simple steps:
55
+ Get started with ByteRover CLI:
55
56
 
56
57
  ### 1. Start the REPL
57
58
 
@@ -91,6 +92,14 @@ ByteRover automatically configures the best connector for your installed agents:
91
92
  - **MCP tools** for most other agents (universal protocol)
92
93
  - Switch connector types anytime via `/connectors`
93
94
 
95
+ ### 5. (Optional) Connect an LLM Provider
96
+
97
+ ```
98
+ /provider
99
+ ```
100
+
101
+ ByteRover works out of the box with its built-in LLM provider. To use your own models, connect to [OpenRouter](https://openrouter.ai/keys) for access to 200+ models. See [LLM Providers](#llm-providers) for details.
102
+
94
103
  You're now ready to use ByteRover! Try `/status` to see your project's current state.
95
104
 
96
105
  ## Interactive REPL
@@ -154,7 +163,7 @@ The **Context Tree** is ByteRover's structured knowledge system that helps you a
154
163
  - **Organized Knowledge**: Structure your project knowledge by domain and topic
155
164
  - **Easy Retrieval**: Find relevant context quickly when you need it
156
165
  - **Persistent Memory**: Maintain project-specific knowledge across sessions
157
- - **Agent-Friendly**: Works seamlessly with 18 AI coding agents (Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and 13 more) via skill files, MCP tools, hooks, or rules
166
+ - **Agent-Friendly**: Works seamlessly with 19 AI coding agents (Claude Code, Cursor, Windsurf, GitHub Copilot, Cline, and more) via skill files, MCP tools, hooks, or rules
158
167
  - **Cloud Sync**: Push and sync your context tree to ByteRover's cloud storage for backup and team collaboration
159
168
  - **Dynamic Domains**: Automatically creates new domains as your knowledge grows
160
169
 
@@ -167,13 +176,16 @@ The context tree organizes knowledge into:
167
176
 
168
177
  ## Supported AI Agents
169
178
 
170
- ByteRover integrates with 18 AI coding agents:
179
+ ByteRover integrates with 19 AI coding agents:
171
180
 
172
181
  **Skill Connector (Default):**
173
182
  - Claude Code, Cursor
174
183
 
175
184
  **MCP Connector (Default):**
176
- - Amp, Augment Code, Cline, Gemini CLI, Github Copilot, Junie, Kilo Code, Kiro, Qoder, Qwen Code, Roo Code, Trae.ai, Warp, Windsurf, Zed (and Codex via global scope)
185
+ - Amp, Augment Code, Cline, Codex, Gemini CLI, Github Copilot, Junie, Kilo Code, Kiro, Qoder, Qwen Code, Roo Code, Trae.ai, Warp, Windsurf, Zed
186
+
187
+ **Rules Connector (Default):**
188
+ - Antigravity (rules-only integration)
177
189
 
178
190
  **All agents support rules-based integration as a universal fallback option.**
179
191
 
@@ -190,15 +202,58 @@ Use `/connectors` to manage integrations with your AI coding agents:
190
202
  ByteRover supports four connector types:
191
203
 
192
204
  1. **Skill integration** (Claude Code, Cursor - default): Modern integration that writes 3 markdown files (SKILL.md, TROUBLESHOOTING.md, WORKFLOWS.md) to your agent's skills directory for easy discovery and guidance
193
- 2. **MCP integration** (16 other agents - default): Exposes brv-query and brv-curate as Model Context Protocol tools that AI agents can call directly
205
+ 2. **MCP integration** (16 agents - default): Exposes brv-query and brv-curate as Model Context Protocol tools that AI agents can call directly
194
206
  3. **Rules-based** (all agents): Generates agent-specific rule files (e.g., CLAUDE.md, .cursorrules) with instructions for using ByteRover
195
207
  4. **Hook integration** (Claude Code only - legacy): Direct injection via IDE settings, replaced by skill connector
196
208
 
197
209
  **Defaults by agent:**
198
210
  - Claude Code, Cursor: Skill connector
211
+ - Antigravity: Rules connector (only supported type)
199
212
  - All others (16 agents): MCP connector
200
213
  - Rules: Available for all agents as fallback
201
214
 
215
+ ## LLM Providers (BETA)
216
+
217
+ ByteRover uses LLMs internally to power `/curate` and `/query` operations. By default, the built-in ByteRover provider is used with no configuration required. You can optionally connect to OpenRouter to access 200+ models.
218
+
219
+ ### Available Providers
220
+
221
+ | Provider | API Key Required | Models |
222
+ |----------|-----------------|--------|
223
+ | **ByteRover** (default) | No | Built-in internal model |
224
+ | **OpenRouter** | Yes | 200+ models from Anthropic, OpenAI, Google, Meta, and more |
225
+
226
+ ### Connecting a Provider
227
+
228
+ Use `/provider` (aliases: `/providers`, `/connect`) to switch providers:
229
+
230
+ ```
231
+ /provider
232
+ ```
233
+
234
+ This opens an interactive prompt showing all available providers with their connection status.
235
+
236
+ ### Selecting a Model
237
+
238
+ When connected to OpenRouter, use `/model` (alias: `/models`) to browse and select models:
239
+
240
+ ```
241
+ /model
242
+ ```
243
+
244
+ The model browser shows:
245
+ - **Pricing**: Input/output cost per million tokens (e.g., `$3.00/$15.00/M`)
246
+ - **Context window**: Maximum token capacity (e.g., `200K ctx`)
247
+ - **Free models**: Marked with `[Free]`
248
+ - **Favorites and recents**: Starred and recently used models appear first
249
+
250
+ ### OpenRouter Setup
251
+
252
+ 1. Get an API key at [openrouter.ai/keys](https://openrouter.ai/keys)
253
+ 2. Run `/provider` and select **OpenRouter**
254
+ 3. Paste your API key when prompted (stored securely in system keychain)
255
+ 4. Run `/model` to select a model (default: `anthropic/claude-3.5-sonnet`)
256
+
202
257
  ## Slash Commands Reference
203
258
 
204
259
  ### Core Workflow
@@ -269,11 +324,21 @@ ByteRover supports four connector types:
269
324
 
270
325
  **Defaults:**
271
326
  - Claude Code, Cursor: `skill`
327
+ - Antigravity: `rules` (only supported type)
272
328
  - All others: `mcp`
273
329
 
274
330
  **Reset options:**
275
331
  - `-y, --yes`: Skip confirmation prompt
276
332
 
333
+ ### LLM Providers (BETA)
334
+
335
+ | Command | Description |
336
+ |---------|-------------|
337
+ | `/provider` | Connect to and switch between LLM providers |
338
+ | `/model` | Select a model from the active provider (OpenRouter) |
339
+
340
+ **Aliases:** `/providers` and `/connect` for `/provider`; `/models` for `/model`
341
+
277
342
  ### Session Management
278
343
 
279
344
  | Command | Description |
@@ -210,3 +210,14 @@ export declare class TooManyResultsError extends FileSystemError {
210
210
  */
211
211
  constructor(operation: string, count: number, maxResults: number);
212
212
  }
213
+ /**
214
+ * Error thrown when PDF text extraction fails.
215
+ */
216
+ export declare class PdfExtractionError extends FileSystemError {
217
+ /**
218
+ * Creates a new PDF extraction error
219
+ * @param path - Path to the PDF file
220
+ * @param reason - Reason for the extraction failure
221
+ */
222
+ constructor(path: string, reason: string);
223
+ }
@@ -290,3 +290,20 @@ export class TooManyResultsError extends FileSystemError {
290
290
  this.name = 'TooManyResultsError';
291
291
  }
292
292
  }
293
+ /**
294
+ * Error thrown when PDF text extraction fails.
295
+ */
296
+ export class PdfExtractionError extends FileSystemError {
297
+ /**
298
+ * Creates a new PDF extraction error
299
+ * @param path - Path to the PDF file
300
+ * @param reason - Reason for the extraction failure
301
+ */
302
+ constructor(path, reason) {
303
+ super(`Failed to extract text from PDF: ${path}. ${reason}`, 'PDF_EXTRACTION_FAILED', {
304
+ path,
305
+ reason,
306
+ });
307
+ this.name = 'PdfExtractionError';
308
+ }
309
+ }
@@ -18,16 +18,46 @@ export interface FileSystemConfig {
18
18
  /** Working directory for relative path resolution */
19
19
  workingDirectory: string;
20
20
  }
21
+ /**
22
+ * PDF read mode for controlling how PDF files are returned.
23
+ * - 'text': Extract text content page by page (default)
24
+ * - 'base64': Return raw PDF as base64 attachment (for multimodal LLMs)
25
+ */
26
+ export type PdfReadMode = 'base64' | 'text';
27
+ /**
28
+ * Metadata extracted from a PDF file.
29
+ */
30
+ export interface PdfMetadata {
31
+ /** Author of the PDF (if available) */
32
+ author?: string;
33
+ /** Creation date of the PDF (if available) */
34
+ creationDate?: Date;
35
+ /** Total number of pages in the PDF */
36
+ pageCount: number;
37
+ /** Title of the PDF (if available) */
38
+ title?: string;
39
+ }
40
+ /**
41
+ * Content extracted from a single PDF page.
42
+ */
43
+ export interface PdfPageContent {
44
+ /** 1-based page number */
45
+ pageNumber: number;
46
+ /** Extracted text content from the page */
47
+ text: string;
48
+ }
21
49
  /**
22
50
  * Options for reading files.
23
51
  */
24
52
  export interface ReadFileOptions {
25
53
  /** Character encoding */
26
54
  encoding?: BufferEncoding;
27
- /** Maximum number of lines to read */
55
+ /** Maximum number of lines to read (for text files) or pages (for PDFs in text mode) */
28
56
  limit?: number;
29
- /** Starting line number (1-based, like text editors) */
57
+ /** Starting line number (1-based) for text files, or starting page number for PDFs */
30
58
  offset?: number;
59
+ /** PDF read mode: 'text' (default) extracts text, 'base64' returns raw attachment */
60
+ pdfMode?: PdfReadMode;
31
61
  }
32
62
  /**
33
63
  * Options for writing files.
@@ -126,23 +156,27 @@ export interface FileAttachment {
126
156
  * Result of a file read operation.
127
157
  */
128
158
  export interface FileContent {
129
- /** Attachment data for binary files (images, PDFs) */
159
+ /** Attachment data for binary files (images, PDFs in base64 mode) */
130
160
  attachment?: FileAttachment;
131
161
  /** File content as string */
132
162
  content: string;
133
163
  /** Character encoding used */
134
164
  encoding: string;
135
- /** Formatted content with line numbers (00001| content format) */
165
+ /** Formatted content with line numbers (00001| content format) or PDF page separators */
136
166
  formattedContent: string;
137
- /** Total number of lines in the returned content */
167
+ /** Total number of lines in the returned content (or pages for PDF text mode) */
138
168
  lines: number;
139
169
  /** Human-readable message about file status (truncation info, etc.) */
140
170
  message: string;
171
+ /** PDF metadata when reading PDF in text mode */
172
+ pdfMetadata?: PdfMetadata;
173
+ /** PDF page contents when reading PDF in text mode */
174
+ pdfPages?: PdfPageContent[];
141
175
  /** Preview of content (first 20 lines) for UI display */
142
176
  preview?: string;
143
177
  /** File size in bytes */
144
178
  size: number;
145
- /** Total lines in the entire file */
179
+ /** Total lines in the entire file (or total pages for PDF text mode) */
146
180
  totalLines: number;
147
181
  /** Whether content was truncated due to size/line limits */
148
182
  truncated: boolean;
@@ -82,7 +82,7 @@ export interface ExecuteOptions {
82
82
  /**
83
83
  * Timeout in milliseconds (max: ProcessConfig.maxTimeout).
84
84
  *
85
- * @default 120000 (2 minutes)
85
+ * @default 300000 (5 minutes)
86
86
  */
87
87
  timeout?: number;
88
88
  }
@@ -2,7 +2,7 @@ import type { ConnectorType } from './connector-type.js';
2
2
  /**
3
3
  * Array of all supported Agents.
4
4
  */
5
- export declare const AGENT_VALUES: readonly ["Amp", "Augment Code", "Claude Code", "Cline", "Codex", "Cursor", "Gemini CLI", "Github Copilot", "Junie", "Kilo Code", "Kiro", "Qoder", "Qwen Code", "Roo Code", "Trae.ai", "Warp", "Windsurf", "Zed"];
5
+ export declare const AGENT_VALUES: readonly ["Amp", "Antigravity", "Augment Code", "Claude Code", "Cline", "Codex", "Cursor", "Gemini CLI", "Github Copilot", "Junie", "Kilo Code", "Kiro", "Qoder", "Qwen Code", "Roo Code", "Trae.ai", "Warp", "Windsurf", "Zed"];
6
6
  export type Agent = (typeof AGENT_VALUES)[number];
7
7
  /**
8
8
  * Connector availability configuration for an agent.
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export const AGENT_VALUES = [
5
5
  'Amp',
6
+ 'Antigravity',
6
7
  'Augment Code',
7
8
  'Claude Code',
8
9
  'Cline',
@@ -30,6 +31,10 @@ export const AGENT_CONNECTOR_CONFIG = {
30
31
  default: 'mcp',
31
32
  supported: ['rules', 'mcp'],
32
33
  },
34
+ Antigravity: {
35
+ default: 'rules',
36
+ supported: ['rules'],
37
+ },
33
38
  'Augment Code': {
34
39
  default: 'mcp',
35
40
  supported: ['rules', 'mcp'],
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Provider Configuration Entity
3
+ *
4
+ * Stores user's provider preferences and connection state.
5
+ * Non-sensitive data (API keys stored separately in keychain).
6
+ */
7
+ /**
8
+ * Configuration for a single connected provider.
9
+ */
10
+ export interface ConnectedProviderConfig {
11
+ /** Currently active model for this provider */
12
+ readonly activeModel?: string;
13
+ /** When the provider was connected */
14
+ readonly connectedAt: string;
15
+ /** User's favorite models (for quick access) */
16
+ readonly favoriteModels: readonly string[];
17
+ /** Recently used models (last 10) */
18
+ readonly recentModels: readonly string[];
19
+ }
20
+ /**
21
+ * Parameters for creating a ProviderConfig.
22
+ */
23
+ export interface ProviderConfigParams {
24
+ /** Currently active provider ID */
25
+ readonly activeProvider: string;
26
+ /** Configuration for each connected provider */
27
+ readonly providers: Readonly<Record<string, ConnectedProviderConfig>>;
28
+ }
29
+ /**
30
+ * Default configuration when no providers are connected.
31
+ */
32
+ export declare const DEFAULT_PROVIDER_CONFIG: ProviderConfigParams;
33
+ /**
34
+ * Represents the provider configuration for the CLI.
35
+ * Tracks which providers are connected and user preferences.
36
+ */
37
+ export declare class ProviderConfig {
38
+ readonly activeProvider: string;
39
+ readonly providers: Readonly<Record<string, ConnectedProviderConfig>>;
40
+ private constructor();
41
+ /**
42
+ * Creates a new ProviderConfig with default values.
43
+ */
44
+ static createDefault(): ProviderConfig;
45
+ /**
46
+ * Deserializes config from JSON format.
47
+ * Returns default config for invalid JSON structure.
48
+ */
49
+ static fromJson(json: unknown): ProviderConfig;
50
+ /**
51
+ * Get the active model for a provider.
52
+ */
53
+ getActiveModel(providerId: string): string | undefined;
54
+ /**
55
+ * Get favorite models for a provider.
56
+ */
57
+ getFavoriteModels(providerId: string): readonly string[];
58
+ /**
59
+ * Get recent models for a provider.
60
+ */
61
+ getRecentModels(providerId: string): readonly string[];
62
+ /**
63
+ * Check if a provider is connected.
64
+ */
65
+ isProviderConnected(providerId: string): boolean;
66
+ /**
67
+ * Serializes the config to JSON format.
68
+ */
69
+ toJson(): ProviderConfigParams;
70
+ /**
71
+ * Create a new config with the active model changed for a provider.
72
+ */
73
+ withActiveModel(providerId: string, modelId: string): ProviderConfig;
74
+ /**
75
+ * Create a new config with the active provider changed.
76
+ */
77
+ withActiveProvider(providerId: string): ProviderConfig;
78
+ /**
79
+ * Create a new config with a model toggled as favorite.
80
+ */
81
+ withFavoriteToggled(providerId: string, modelId: string): ProviderConfig;
82
+ /**
83
+ * Create a new config with a provider connected.
84
+ */
85
+ withProviderConnected(providerId: string, options?: {
86
+ activeModel?: string;
87
+ }): ProviderConfig;
88
+ /**
89
+ * Create a new config with a provider disconnected.
90
+ */
91
+ withProviderDisconnected(providerId: string): ProviderConfig;
92
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Provider Configuration Entity
3
+ *
4
+ * Stores user's provider preferences and connection state.
5
+ * Non-sensitive data (API keys stored separately in keychain).
6
+ */
7
+ /**
8
+ * Type guard for ProviderConfig JSON validation.
9
+ */
10
+ const isProviderConfigJson = (json) => {
11
+ if (typeof json !== 'object' || json === null)
12
+ return false;
13
+ const obj = json;
14
+ if (typeof obj.activeProvider !== 'string')
15
+ return false;
16
+ if (typeof obj.providers !== 'object' || obj.providers === null)
17
+ return false;
18
+ return true;
19
+ };
20
+ /**
21
+ * Default configuration when no providers are connected.
22
+ */
23
+ export const DEFAULT_PROVIDER_CONFIG = {
24
+ activeProvider: 'byterover',
25
+ providers: {},
26
+ };
27
+ /**
28
+ * Maximum number of recent models to track.
29
+ */
30
+ const MAX_RECENT_MODELS = 10;
31
+ /**
32
+ * Represents the provider configuration for the CLI.
33
+ * Tracks which providers are connected and user preferences.
34
+ */
35
+ export class ProviderConfig {
36
+ activeProvider;
37
+ providers;
38
+ constructor(params) {
39
+ this.activeProvider = params.activeProvider;
40
+ this.providers = params.providers;
41
+ }
42
+ /**
43
+ * Creates a new ProviderConfig with default values.
44
+ */
45
+ static createDefault() {
46
+ return new ProviderConfig(DEFAULT_PROVIDER_CONFIG);
47
+ }
48
+ /**
49
+ * Deserializes config from JSON format.
50
+ * Returns default config for invalid JSON structure.
51
+ */
52
+ static fromJson(json) {
53
+ if (!isProviderConfigJson(json)) {
54
+ return ProviderConfig.createDefault();
55
+ }
56
+ return new ProviderConfig(json);
57
+ }
58
+ /**
59
+ * Get the active model for a provider.
60
+ */
61
+ getActiveModel(providerId) {
62
+ return this.providers[providerId]?.activeModel;
63
+ }
64
+ /**
65
+ * Get favorite models for a provider.
66
+ */
67
+ getFavoriteModels(providerId) {
68
+ return this.providers[providerId]?.favoriteModels ?? [];
69
+ }
70
+ /**
71
+ * Get recent models for a provider.
72
+ */
73
+ getRecentModels(providerId) {
74
+ return this.providers[providerId]?.recentModels ?? [];
75
+ }
76
+ /**
77
+ * Check if a provider is connected.
78
+ */
79
+ isProviderConnected(providerId) {
80
+ return providerId in this.providers;
81
+ }
82
+ /**
83
+ * Serializes the config to JSON format.
84
+ */
85
+ toJson() {
86
+ return {
87
+ activeProvider: this.activeProvider,
88
+ providers: this.providers,
89
+ };
90
+ }
91
+ /**
92
+ * Create a new config with the active model changed for a provider.
93
+ */
94
+ withActiveModel(providerId, modelId) {
95
+ const existingConfig = this.providers[providerId];
96
+ if (!existingConfig) {
97
+ return this;
98
+ }
99
+ // Add to recent models (at the front, deduplicated)
100
+ const recentModels = [
101
+ modelId,
102
+ ...existingConfig.recentModels.filter((m) => m !== modelId),
103
+ ].slice(0, MAX_RECENT_MODELS);
104
+ const newProviderConfig = {
105
+ ...existingConfig,
106
+ activeModel: modelId,
107
+ recentModels,
108
+ };
109
+ return new ProviderConfig({
110
+ ...this.toJson(),
111
+ providers: {
112
+ ...this.providers,
113
+ [providerId]: newProviderConfig,
114
+ },
115
+ });
116
+ }
117
+ /**
118
+ * Create a new config with the active provider changed.
119
+ */
120
+ withActiveProvider(providerId) {
121
+ return new ProviderConfig({
122
+ ...this.toJson(),
123
+ activeProvider: providerId,
124
+ });
125
+ }
126
+ /**
127
+ * Create a new config with a model toggled as favorite.
128
+ */
129
+ withFavoriteToggled(providerId, modelId) {
130
+ const existingConfig = this.providers[providerId];
131
+ if (!existingConfig) {
132
+ return this;
133
+ }
134
+ const isFavorite = existingConfig.favoriteModels.includes(modelId);
135
+ const favoriteModels = isFavorite
136
+ ? existingConfig.favoriteModels.filter((m) => m !== modelId)
137
+ : [...existingConfig.favoriteModels, modelId];
138
+ const newProviderConfig = {
139
+ ...existingConfig,
140
+ favoriteModels,
141
+ };
142
+ return new ProviderConfig({
143
+ ...this.toJson(),
144
+ providers: {
145
+ ...this.providers,
146
+ [providerId]: newProviderConfig,
147
+ },
148
+ });
149
+ }
150
+ /**
151
+ * Create a new config with a provider connected.
152
+ */
153
+ withProviderConnected(providerId, options) {
154
+ const existingConfig = this.providers[providerId];
155
+ const newProviderConfig = {
156
+ activeModel: options?.activeModel ?? existingConfig?.activeModel,
157
+ connectedAt: existingConfig?.connectedAt ?? new Date().toISOString(),
158
+ favoriteModels: existingConfig?.favoriteModels ?? [],
159
+ recentModels: existingConfig?.recentModels ?? [],
160
+ };
161
+ return new ProviderConfig({
162
+ ...this.toJson(),
163
+ providers: {
164
+ ...this.providers,
165
+ [providerId]: newProviderConfig,
166
+ },
167
+ });
168
+ }
169
+ /**
170
+ * Create a new config with a provider disconnected.
171
+ */
172
+ withProviderDisconnected(providerId) {
173
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
174
+ const { [providerId]: _removed, ...remainingProviders } = this.providers;
175
+ const newActiveProvider = this.activeProvider === providerId ? 'byterover' : this.activeProvider;
176
+ return new ProviderConfig({
177
+ activeProvider: newActiveProvider,
178
+ providers: remainingProviders,
179
+ });
180
+ }
181
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Provider Registry
3
+ *
4
+ * Defines available LLM providers that can be connected to byterover-cli.
5
+ * Inspired by OpenCode's provider system.
6
+ */
7
+ /**
8
+ * Definition for an LLM provider.
9
+ */
10
+ export interface ProviderDefinition {
11
+ /** URL where users can get an API key */
12
+ readonly apiKeyUrl?: string;
13
+ /** API base URL (empty for internal providers) */
14
+ readonly baseUrl: string;
15
+ /** Category for grouping in UI */
16
+ readonly category: 'other' | 'popular';
17
+ /** Default model to use when first connected */
18
+ readonly defaultModel?: string;
19
+ /** Short description */
20
+ readonly description: string;
21
+ /** Default headers for API requests */
22
+ readonly headers: Readonly<Record<string, string>>;
23
+ /** Unique provider identifier */
24
+ readonly id: string;
25
+ /** Endpoint to fetch available models */
26
+ readonly modelsEndpoint: string;
27
+ /** Display name */
28
+ readonly name: string;
29
+ /** Priority for display order (lower = higher priority) */
30
+ readonly priority: number;
31
+ }
32
+ /**
33
+ * Registry of all available providers.
34
+ * Order by priority for consistent display.
35
+ */
36
+ export declare const PROVIDER_REGISTRY: Readonly<Record<string, ProviderDefinition>>;
37
+ /**
38
+ * Get all providers sorted by priority.
39
+ */
40
+ export declare function getProvidersSortedByPriority(): ProviderDefinition[];
41
+ /**
42
+ * Get providers grouped by category.
43
+ */
44
+ export declare function getProvidersGroupedByCategory(): {
45
+ other: ProviderDefinition[];
46
+ popular: ProviderDefinition[];
47
+ };
48
+ /**
49
+ * Get a provider by ID.
50
+ */
51
+ export declare function getProviderById(id: string): ProviderDefinition | undefined;
52
+ /**
53
+ * Check if a provider requires an API key.
54
+ */
55
+ export declare function providerRequiresApiKey(id: string): boolean;