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
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 terminal UI for managing your project's context tree and
|
|
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 AI coding agents like Claude Code, Cursor, Windsurf, and GitHub Copilot.
|
|
4
4
|
|
|
5
5
|
[](https://npmjs.org/package/byterover-cli)
|
|
6
6
|
[](https://npmjs.org/package/byterover-cli)
|
|
@@ -15,6 +15,7 @@ Command-line interface for ByteRover, featuring an interactive REPL with a moder
|
|
|
15
15
|
* [Slash Commands Reference](#slash-commands-reference)
|
|
16
16
|
* [Authentication](#authentication)
|
|
17
17
|
* [Configuration](#configuration)
|
|
18
|
+
* [Troubleshooting](#troubleshooting)
|
|
18
19
|
* [Getting Help](#getting-help)
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
@@ -90,6 +91,16 @@ brv
|
|
|
90
91
|
|
|
91
92
|
Running `brv` without arguments starts the interactive REPL. The REPL requires an interactive terminal (TTY).
|
|
92
93
|
|
|
94
|
+
### TUI Features
|
|
95
|
+
|
|
96
|
+
The terminal UI includes:
|
|
97
|
+
|
|
98
|
+
- **Tab Navigation**: Switch between Chat and Activity views using `Tab`
|
|
99
|
+
- **Command Completion**: Type `/` to see available commands with auto-completion
|
|
100
|
+
- **Activity Log**: Real-time task status and execution progress
|
|
101
|
+
- **Streaming Output**: Live responses from AI-powered operations
|
|
102
|
+
- **File References**: Type `@` in curate mode to browse and attach files
|
|
103
|
+
|
|
93
104
|
### Using Commands
|
|
94
105
|
|
|
95
106
|
In the REPL, use slash commands (commands prefixed with `/`) to interact with ByteRover:
|
|
@@ -104,24 +115,33 @@ Commands support tab completion for quick navigation.
|
|
|
104
115
|
|
|
105
116
|
## What is Context Tree?
|
|
106
117
|
|
|
107
|
-
The **Context Tree** is ByteRover's structured
|
|
118
|
+
The **Context Tree** is ByteRover's structured knowledge system that helps you and your AI coding agents organize, store, and retrieve project context efficiently.
|
|
108
119
|
|
|
109
120
|
### Why Use Context Tree?
|
|
110
121
|
|
|
111
122
|
- **Organized Knowledge**: Structure your project knowledge by domain and topic
|
|
112
123
|
- **Easy Retrieval**: Find relevant context quickly when you need it
|
|
113
124
|
- **Persistent Memory**: Maintain project-specific knowledge across sessions
|
|
114
|
-
- **Agent-Friendly**: Works seamlessly with coding agents like Claude Code, Cursor, and
|
|
115
|
-
- **
|
|
125
|
+
- **Agent-Friendly**: Works seamlessly with AI coding agents like Claude Code, Cursor, Windsurf, and GitHub Copilot
|
|
126
|
+
- **Cloud Sync**: Push and sync your context tree to ByteRover's cloud storage for backup and team collaboration
|
|
127
|
+
- **Dynamic Domains**: Automatically creates new domains as your knowledge grows
|
|
116
128
|
|
|
117
129
|
### How It Works
|
|
118
130
|
|
|
119
131
|
The context tree organizes knowledge into:
|
|
120
|
-
- **Domains**: High-level categories (e.g., Architecture, API, Frontend)
|
|
132
|
+
- **Domains**: High-level categories (e.g., Architecture, API, Frontend) — created automatically or manually
|
|
121
133
|
- **Topics**: Specific subjects within domains (e.g., Authentication, Components)
|
|
122
134
|
- **Context Files**: Markdown files containing your actual knowledge
|
|
123
135
|
|
|
124
|
-
|
|
136
|
+
### Integrating with Coding Agents
|
|
137
|
+
|
|
138
|
+
Use `/gen-rules` to generate rule instruction files that help your AI coding agents understand and work with ByteRover:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
/gen-rules
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This creates agent-specific rule files (e.g., `CLAUDE.md`, `.cursorrules`) that instruct the agent how to read from and contribute to your context tree.
|
|
125
145
|
|
|
126
146
|
## Slash Commands Reference
|
|
127
147
|
|
|
@@ -150,8 +170,8 @@ For comprehensive instructions for coding agents, use `/gen-rules` to generate r
|
|
|
150
170
|
|
|
151
171
|
| Command | Description |
|
|
152
172
|
|---------|-------------|
|
|
153
|
-
| `/push [-b branch] [-y]` | Push context tree to ByteRover
|
|
154
|
-
| `/pull [-b branch]` | Pull context tree from ByteRover
|
|
173
|
+
| `/push [-b branch] [-y]` | Push context tree to ByteRover cloud storage |
|
|
174
|
+
| `/pull [-b branch]` | Pull context tree from ByteRover cloud storage |
|
|
155
175
|
|
|
156
176
|
**Options:**
|
|
157
177
|
- `-b, --branch <name>`: ByteRover branch name (default: `main`)
|
|
@@ -182,12 +202,23 @@ For comprehensive instructions for coding agents, use `/gen-rules` to generate r
|
|
|
182
202
|
|
|
183
203
|
| Command | Description |
|
|
184
204
|
|---------|-------------|
|
|
185
|
-
| `/gen-rules` | Generate rule
|
|
186
|
-
| `/
|
|
205
|
+
| `/gen-rules` | Generate rule files for AI coding agents (Claude Code, Cursor, etc.) |
|
|
206
|
+
| `/reset [-y] [directory]` | Reset context tree to default domains |
|
|
187
207
|
|
|
188
|
-
**
|
|
208
|
+
**Reset options:**
|
|
209
|
+
- `-y, --yes`: Skip confirmation prompt
|
|
210
|
+
|
|
211
|
+
### Session Management
|
|
212
|
+
|
|
213
|
+
| Command | Description |
|
|
214
|
+
|---------|-------------|
|
|
215
|
+
| `/new [-y]` | Start a fresh session (ends current session, clears conversation) |
|
|
216
|
+
|
|
217
|
+
**Options:**
|
|
189
218
|
- `-y, --yes`: Skip confirmation prompt
|
|
190
219
|
|
|
220
|
+
**Note:** This command does NOT affect the context tree—it only clears the conversation history and starts a new session.
|
|
221
|
+
|
|
191
222
|
### Project Setup
|
|
192
223
|
|
|
193
224
|
| Command | Description |
|
|
@@ -232,6 +263,16 @@ When you run `/init`, a configuration file is created at `.brv/config.json` in y
|
|
|
232
263
|
- **User information**: Your user ID and email
|
|
233
264
|
- **Project settings**: Project-specific configuration
|
|
234
265
|
|
|
266
|
+
### Global Configuration
|
|
267
|
+
|
|
268
|
+
User-level configuration is stored at `~/.config/brv/`:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
~/.config/brv/
|
|
272
|
+
├── config.json # Global settings and device ID
|
|
273
|
+
└── logs/ # Session logs for debugging
|
|
274
|
+
```
|
|
275
|
+
|
|
235
276
|
### Context Tree Structure
|
|
236
277
|
|
|
237
278
|
The context tree is stored in `.brv/context-tree/`:
|
|
@@ -255,7 +296,29 @@ The context tree is stored in `.brv/context-tree/`:
|
|
|
255
296
|
└── context.md
|
|
256
297
|
```
|
|
257
298
|
|
|
258
|
-
**Note**: When you run `/push`, your context tree is uploaded to ByteRover's
|
|
299
|
+
**Note**: When you run `/push`, your context tree is uploaded to ByteRover's cloud storage for version control and team collaboration.
|
|
300
|
+
|
|
301
|
+
## Troubleshooting
|
|
302
|
+
|
|
303
|
+
### Session Logs
|
|
304
|
+
|
|
305
|
+
If you encounter issues, session logs are stored at `~/.config/brv/logs/`. Each session creates a timestamped log file (e.g., `brv-2024-01-15T10-30-00.log`) that can help diagnose problems.
|
|
306
|
+
|
|
307
|
+
### Instance Lock
|
|
308
|
+
|
|
309
|
+
ByteRover CLI ensures only one instance runs per project folder. If you see an "instance already running" message:
|
|
310
|
+
|
|
311
|
+
1. Check for another terminal with `brv` running in the same directory
|
|
312
|
+
2. If no other instance is visible, the lock file may be stale — it will auto-release on the next start
|
|
313
|
+
|
|
314
|
+
### Common Issues
|
|
315
|
+
|
|
316
|
+
| Issue | Solution |
|
|
317
|
+
|-------|----------|
|
|
318
|
+
| "REPL requires an interactive terminal" | Run `brv` directly in a terminal, not through piped commands |
|
|
319
|
+
| Authentication expires frequently | Run `/login` to refresh your session |
|
|
320
|
+
| Context tree not syncing | Check `/status` for sync status, then try `/push` or `/pull` |
|
|
321
|
+
| Rule files not generated | Ensure you're in a project directory with `.brv/` initialized |
|
|
259
322
|
|
|
260
323
|
## Getting Help
|
|
261
324
|
|
package/dist/commands/curate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import { isDevelopment } from '../config/environment.js';
|
|
3
3
|
import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createTokenStore } from '../infra/storage/token-store.js';
|
|
5
5
|
import { OclifTerminal } from '../infra/terminal/oclif-terminal.js';
|
|
6
6
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
7
7
|
import { CurateUseCase } from '../infra/usecase/curate-use-case.js';
|
|
@@ -14,7 +14,7 @@ export default class Curate extends Command {
|
|
|
14
14
|
};
|
|
15
15
|
static description = `Curate context to the context tree (connects to running brv instance)
|
|
16
16
|
|
|
17
|
-
Requires a running brv instance. Start one with: brv
|
|
17
|
+
Requires a running brv instance. Start one with: brv
|
|
18
18
|
|
|
19
19
|
Good examples:
|
|
20
20
|
- "Auth uses JWT with 24h expiry. Tokens stored in httpOnly cookies via authMiddleware.ts"
|
|
@@ -49,7 +49,7 @@ Bad examples:
|
|
|
49
49
|
: {}),
|
|
50
50
|
};
|
|
51
51
|
createUseCase() {
|
|
52
|
-
const tokenStore =
|
|
52
|
+
const tokenStore = createTokenStore();
|
|
53
53
|
const globalConfigStore = new FileGlobalConfigStore();
|
|
54
54
|
const terminal = new OclifTerminal(this);
|
|
55
55
|
const trackingService = new MixpanelTrackingService({ globalConfigStore, tokenStore });
|
package/dist/commands/main.d.ts
CHANGED
|
@@ -14,4 +14,17 @@ export default class Main extends Command {
|
|
|
14
14
|
*/
|
|
15
15
|
static hidden: boolean;
|
|
16
16
|
run(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve session ID for the agent.
|
|
19
|
+
*
|
|
20
|
+
* Strategy:
|
|
21
|
+
* 1. Check for active session in .brv/sessions/active.json
|
|
22
|
+
* 2. If active session exists and is valid (not stale), resume it
|
|
23
|
+
* 3. If stale (process crashed), mark as interrupted and create new
|
|
24
|
+
* 4. If no active session, create new session
|
|
25
|
+
* 5. Run session cleanup on startup
|
|
26
|
+
*
|
|
27
|
+
* @returns Session ID to use
|
|
28
|
+
*/
|
|
29
|
+
private resolveSessionId;
|
|
17
30
|
}
|
package/dist/commands/main.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { DEFAULT_SESSION_RETENTION } from '../core/domain/cipher/session/session-metadata.js';
|
|
4
|
+
import { SessionMetadataStore } from '../infra/cipher/session/session-metadata-store.js';
|
|
2
5
|
import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
3
6
|
import { getProcessManager } from '../infra/process/index.js';
|
|
4
7
|
import { startRepl } from '../infra/repl/repl-startup.js';
|
|
5
8
|
import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
|
|
6
9
|
import { FileOnboardingPreferenceStore } from '../infra/storage/file-onboarding-preference-store.js';
|
|
7
|
-
import {
|
|
10
|
+
import { createTokenStore } from '../infra/storage/token-store.js';
|
|
8
11
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
9
|
-
import { initSessionLog } from '../utils/process-logger.js';
|
|
12
|
+
import { initSessionLog, processManagerLog } from '../utils/process-logger.js';
|
|
10
13
|
/**
|
|
11
14
|
* Main command - Entry point for ByteRover CLI.
|
|
12
15
|
*
|
|
@@ -30,10 +33,14 @@ export default class Main extends Command {
|
|
|
30
33
|
this.log("Run 'brv --help' for available commands.");
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
36
|
+
// Resolve session ID (auto-resume or create new)
|
|
37
|
+
const sessionId = await this.resolveSessionId();
|
|
38
|
+
processManagerLog(`Session ID resolved: ${sessionId}`);
|
|
33
39
|
// Start Transport and Agent processes (v0.5.0 architecture)
|
|
40
|
+
// Pass session ID to Agent via environment variable
|
|
34
41
|
const processManager = getProcessManager();
|
|
35
|
-
await processManager.start();
|
|
36
|
-
const tokenStore =
|
|
42
|
+
await processManager.start({ sessionId });
|
|
43
|
+
const tokenStore = createTokenStore();
|
|
37
44
|
const globalConfigStore = new FileGlobalConfigStore();
|
|
38
45
|
const trackingService = new MixpanelTrackingService({ globalConfigStore, tokenStore });
|
|
39
46
|
const onboardingPreferenceStore = new FileOnboardingPreferenceStore();
|
|
@@ -52,4 +59,48 @@ export default class Main extends Command {
|
|
|
52
59
|
await processManager.stop();
|
|
53
60
|
}
|
|
54
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve session ID for the agent.
|
|
64
|
+
*
|
|
65
|
+
* Strategy:
|
|
66
|
+
* 1. Check for active session in .brv/sessions/active.json
|
|
67
|
+
* 2. If active session exists and is valid (not stale), resume it
|
|
68
|
+
* 3. If stale (process crashed), mark as interrupted and create new
|
|
69
|
+
* 4. If no active session, create new session
|
|
70
|
+
* 5. Run session cleanup on startup
|
|
71
|
+
*
|
|
72
|
+
* @returns Session ID to use
|
|
73
|
+
*/
|
|
74
|
+
async resolveSessionId() {
|
|
75
|
+
const sessionStore = new SessionMetadataStore();
|
|
76
|
+
// Run cleanup on startup (async, don't wait)
|
|
77
|
+
sessionStore.cleanupSessions(DEFAULT_SESSION_RETENTION).catch((error) => {
|
|
78
|
+
processManagerLog(`Session cleanup failed: ${error}`);
|
|
79
|
+
});
|
|
80
|
+
// Check for active session
|
|
81
|
+
const activeSession = await sessionStore.getActiveSession();
|
|
82
|
+
if (activeSession) {
|
|
83
|
+
// Check if the active session is stale (process not running)
|
|
84
|
+
const isStale = await sessionStore.isActiveSessionStale();
|
|
85
|
+
if (isStale) {
|
|
86
|
+
// Mark the old session as interrupted
|
|
87
|
+
processManagerLog(`Active session ${activeSession.sessionId} is stale, marking as interrupted`);
|
|
88
|
+
await sessionStore.markSessionInterrupted(activeSession.sessionId);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Valid active session - resume it
|
|
92
|
+
processManagerLog(`Resuming active session: ${activeSession.sessionId}`);
|
|
93
|
+
return activeSession.sessionId;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Create new session
|
|
97
|
+
const newSessionId = `agent-session-${randomUUID()}`;
|
|
98
|
+
processManagerLog(`Creating new session: ${newSessionId}`);
|
|
99
|
+
// Save session metadata
|
|
100
|
+
const metadata = sessionStore.createSessionMetadata(newSessionId);
|
|
101
|
+
await sessionStore.saveSession(metadata);
|
|
102
|
+
// Set as active session
|
|
103
|
+
await sessionStore.setActiveSession(newSessionId);
|
|
104
|
+
return newSessionId;
|
|
105
|
+
}
|
|
55
106
|
}
|
package/dist/commands/query.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import { isDevelopment } from '../config/environment.js';
|
|
3
3
|
import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createTokenStore } from '../infra/storage/token-store.js';
|
|
5
5
|
import { OclifTerminal } from '../infra/terminal/oclif-terminal.js';
|
|
6
6
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
7
7
|
import { QueryUseCase } from '../infra/usecase/query-use-case.js';
|
|
@@ -14,7 +14,7 @@ export default class Query extends Command {
|
|
|
14
14
|
};
|
|
15
15
|
static description = `Query and retrieve information from the context tree (connects to running brv instance)
|
|
16
16
|
|
|
17
|
-
Requires a running brv instance. Start one with: brv
|
|
17
|
+
Requires a running brv instance. Start one with: brv
|
|
18
18
|
|
|
19
19
|
Good:
|
|
20
20
|
- "How is user authentication implemented?"
|
|
@@ -40,7 +40,7 @@ Bad:
|
|
|
40
40
|
};
|
|
41
41
|
static strict = false;
|
|
42
42
|
createUseCase() {
|
|
43
|
-
const tokenStore =
|
|
43
|
+
const tokenStore = createTokenStore();
|
|
44
44
|
const globalConfigStore = new FileGlobalConfigStore();
|
|
45
45
|
const trackingService = new MixpanelTrackingService({ globalConfigStore, tokenStore });
|
|
46
46
|
return new QueryUseCase({
|
package/dist/commands/status.js
CHANGED
|
@@ -3,7 +3,7 @@ import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
|
3
3
|
import { FileContextTreeService } from '../infra/context-tree/file-context-tree-service.js';
|
|
4
4
|
import { FileContextTreeSnapshotService } from '../infra/context-tree/file-context-tree-snapshot-service.js';
|
|
5
5
|
import { FileGlobalConfigStore } from '../infra/storage/file-global-config-store.js';
|
|
6
|
-
import {
|
|
6
|
+
import { createTokenStore } from '../infra/storage/token-store.js';
|
|
7
7
|
import { OclifTerminal } from '../infra/terminal/oclif-terminal.js';
|
|
8
8
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
9
9
|
import { StatusUseCase } from '../infra/usecase/status-use-case.js';
|
|
@@ -29,7 +29,7 @@ export default class Status extends Command {
|
|
|
29
29
|
}),
|
|
30
30
|
};
|
|
31
31
|
createUseCase() {
|
|
32
|
-
const tokenStore =
|
|
32
|
+
const tokenStore = createTokenStore();
|
|
33
33
|
const globalConfigStore = new FileGlobalConfigStore();
|
|
34
34
|
const trackingService = new MixpanelTrackingService({ globalConfigStore, tokenStore });
|
|
35
35
|
const contextTreeSnapshotService = new FileContextTreeSnapshotService();
|
package/dist/constants.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const BRV_CONFIG_VERSION = "0.0.1";
|
|
|
6
6
|
export declare const GLOBAL_CONFIG_DIR = "brv";
|
|
7
7
|
export declare const GLOBAL_CONFIG_FILE = "config.json";
|
|
8
8
|
export declare const GLOBAL_CONFIG_VERSION = "0.0.1";
|
|
9
|
+
export declare const GLOBAL_DATA_DIR = "brv";
|
|
9
10
|
export declare const ACE_DIR = "ace";
|
|
10
11
|
export declare const PROJECT = "byterover";
|
|
11
12
|
export declare const CONTEXT_TREE_DIR = "context-tree";
|
|
@@ -33,4 +34,4 @@ export declare const TRANSPORT_RECONNECTION_ATTEMPTS = 30;
|
|
|
33
34
|
export declare const TRANSPORT_PING_INTERVAL_MS = 5000;
|
|
34
35
|
export declare const TRANSPORT_PING_TIMEOUT_MS = 10000;
|
|
35
36
|
export declare const TRANSPORT_DEFAULT_TRANSPORTS: ('polling' | 'websocket')[];
|
|
36
|
-
export declare const DEFAULT_LLM_MODEL = "gemini-
|
|
37
|
+
export declare const DEFAULT_LLM_MODEL = "gemini-3-flash-preview";
|
package/dist/constants.js
CHANGED
|
@@ -7,6 +7,9 @@ export const BRV_CONFIG_VERSION = '0.0.1';
|
|
|
7
7
|
export const GLOBAL_CONFIG_DIR = 'brv';
|
|
8
8
|
export const GLOBAL_CONFIG_FILE = 'config.json';
|
|
9
9
|
export const GLOBAL_CONFIG_VERSION = '0.0.1';
|
|
10
|
+
// Global data directory name (for XDG_DATA_HOME - secrets, credentials, cache)
|
|
11
|
+
// Same value as GLOBAL_CONFIG_DIR but different semantic purpose
|
|
12
|
+
export const GLOBAL_DATA_DIR = 'brv';
|
|
10
13
|
// ACE directory structure constants
|
|
11
14
|
export const ACE_DIR = 'ace';
|
|
12
15
|
export const PROJECT = 'byterover';
|
|
@@ -40,4 +43,4 @@ export const TRANSPORT_PING_TIMEOUT_MS = 10_000; // 10s timeout - avoid false di
|
|
|
40
43
|
// HTTP polling may be blocked by IDE sandboxes causing "xhr poll error"
|
|
41
44
|
export const TRANSPORT_DEFAULT_TRANSPORTS = ['websocket'];
|
|
42
45
|
// LLM Model defaults
|
|
43
|
-
export const DEFAULT_LLM_MODEL = 'gemini-
|
|
46
|
+
export const DEFAULT_LLM_MODEL = 'gemini-3-flash-preview';
|
|
@@ -146,6 +146,8 @@ export interface FileContent {
|
|
|
146
146
|
totalLines: number;
|
|
147
147
|
/** Whether content was truncated due to size/line limits */
|
|
148
148
|
truncated: boolean;
|
|
149
|
+
/** Number of lines that were truncated due to excessive length */
|
|
150
|
+
truncatedLineCount?: number;
|
|
149
151
|
}
|
|
150
152
|
/**
|
|
151
153
|
* Result of a file write operation.
|
|
@@ -27,19 +27,54 @@ export const LLM_REGISTRY = {
|
|
|
27
27
|
supportedFileTypes: [],
|
|
28
28
|
},
|
|
29
29
|
gemini: {
|
|
30
|
-
defaultModel: 'gemini-
|
|
30
|
+
defaultModel: 'gemini-3-flash-preview',
|
|
31
31
|
models: [
|
|
32
|
-
// Gemini
|
|
32
|
+
// Gemini 3 series (Preview)
|
|
33
33
|
{
|
|
34
34
|
capabilities: {
|
|
35
35
|
supportsAudio: true,
|
|
36
36
|
supportsImages: true,
|
|
37
|
+
supportsMultimodalFunctionResponse: true,
|
|
37
38
|
supportsPdf: true,
|
|
38
39
|
supportsStreaming: true,
|
|
39
40
|
supportsThinking: true,
|
|
40
41
|
},
|
|
41
42
|
charsPerToken: 4,
|
|
42
43
|
default: true,
|
|
44
|
+
displayName: 'Gemini 3 Flash (Preview)',
|
|
45
|
+
maxInputTokens: 1_000_000,
|
|
46
|
+
maxOutputTokens: 8192,
|
|
47
|
+
name: 'gemini-3-flash-preview',
|
|
48
|
+
pricing: { inputPerM: 0.075, outputPerM: 0.3 },
|
|
49
|
+
supportedFileTypes: ['image', 'pdf', 'audio'],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
capabilities: {
|
|
53
|
+
supportsAudio: true,
|
|
54
|
+
supportsImages: true,
|
|
55
|
+
supportsMultimodalFunctionResponse: true,
|
|
56
|
+
supportsPdf: true,
|
|
57
|
+
supportsStreaming: true,
|
|
58
|
+
supportsThinking: true,
|
|
59
|
+
},
|
|
60
|
+
charsPerToken: 4,
|
|
61
|
+
displayName: 'Gemini 3 Pro (Preview)',
|
|
62
|
+
maxInputTokens: 1_000_000,
|
|
63
|
+
maxOutputTokens: 8192,
|
|
64
|
+
name: 'gemini-3-pro-preview',
|
|
65
|
+
pricing: { inputPerM: 1.25, outputPerM: 5 },
|
|
66
|
+
supportedFileTypes: ['image', 'pdf', 'audio'],
|
|
67
|
+
},
|
|
68
|
+
// Gemini 2.5 series
|
|
69
|
+
{
|
|
70
|
+
capabilities: {
|
|
71
|
+
supportsAudio: true,
|
|
72
|
+
supportsImages: true,
|
|
73
|
+
supportsPdf: true,
|
|
74
|
+
supportsStreaming: true,
|
|
75
|
+
supportsThinking: true,
|
|
76
|
+
},
|
|
77
|
+
charsPerToken: 4,
|
|
43
78
|
displayName: 'Gemini 2.5 Flash',
|
|
44
79
|
maxInputTokens: 1_000_000,
|
|
45
80
|
maxOutputTokens: 8192,
|
|
@@ -47,6 +82,22 @@ export const LLM_REGISTRY = {
|
|
|
47
82
|
pricing: { inputPerM: 0.075, outputPerM: 0.3 },
|
|
48
83
|
supportedFileTypes: ['image', 'pdf', 'audio'],
|
|
49
84
|
},
|
|
85
|
+
{
|
|
86
|
+
capabilities: {
|
|
87
|
+
supportsAudio: true,
|
|
88
|
+
supportsImages: true,
|
|
89
|
+
supportsPdf: true,
|
|
90
|
+
supportsStreaming: true,
|
|
91
|
+
supportsThinking: true,
|
|
92
|
+
},
|
|
93
|
+
charsPerToken: 4,
|
|
94
|
+
displayName: 'Gemini 2.5 Pro',
|
|
95
|
+
maxInputTokens: 1_000_000,
|
|
96
|
+
maxOutputTokens: 8192,
|
|
97
|
+
name: 'gemini-2.5-pro',
|
|
98
|
+
pricing: { inputPerM: 1.25, outputPerM: 5 },
|
|
99
|
+
supportedFileTypes: ['image', 'pdf', 'audio'],
|
|
100
|
+
},
|
|
50
101
|
// Gemini 1.5 series
|
|
51
102
|
{
|
|
52
103
|
capabilities: {
|
|
@@ -28,6 +28,8 @@ export interface ModelCapabilities {
|
|
|
28
28
|
supportsAudio: boolean;
|
|
29
29
|
/** Whether the model supports image input */
|
|
30
30
|
supportsImages: boolean;
|
|
31
|
+
/** Whether the model supports multimodal data in function responses (Gemini 3+) */
|
|
32
|
+
supportsMultimodalFunctionResponse?: boolean;
|
|
31
33
|
/** Whether the model supports PDF input */
|
|
32
34
|
supportsPdf: boolean;
|
|
33
35
|
/** Whether the model supports streaming responses */
|
|
@@ -17,6 +17,13 @@ export interface ProcessConfig {
|
|
|
17
17
|
* Custom environment variables for all commands.
|
|
18
18
|
*/
|
|
19
19
|
environment: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Grace period in milliseconds to wait after SIGTERM before sending SIGKILL.
|
|
22
|
+
* Allows processes time to clean up gracefully.
|
|
23
|
+
*
|
|
24
|
+
* @default 5000 (5 seconds)
|
|
25
|
+
*/
|
|
26
|
+
killGracePeriod: number;
|
|
20
27
|
/**
|
|
21
28
|
* Maximum number of concurrent background processes.
|
|
22
29
|
* @default 5
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Metadata Types and Schemas
|
|
3
|
+
*
|
|
4
|
+
* Defines the data structures for persistent session management.
|
|
5
|
+
* Sessions are stored in .brv/sessions/ directory as JSON files.
|
|
6
|
+
*
|
|
7
|
+
* Design adapted from gemini-cli's ChatRecordingService pattern.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
/**
|
|
11
|
+
* Session status indicating lifecycle state.
|
|
12
|
+
*/
|
|
13
|
+
export type SessionStatus = 'active' | 'ended' | 'interrupted';
|
|
14
|
+
/**
|
|
15
|
+
* Active session pointer stored in .brv/sessions/active.json
|
|
16
|
+
* Points to the currently active session for auto-resume.
|
|
17
|
+
*/
|
|
18
|
+
export interface ActiveSessionPointer {
|
|
19
|
+
/** ISO timestamp when this session became active */
|
|
20
|
+
activatedAt: string;
|
|
21
|
+
/** PID of the process that activated this session (for stale detection) */
|
|
22
|
+
pid: number;
|
|
23
|
+
/**
|
|
24
|
+
* Unique token identifying this specific process instance.
|
|
25
|
+
* Used to detect PID reuse: if the PID exists but token differs,
|
|
26
|
+
* it's a different process that got the same PID after the original crashed.
|
|
27
|
+
* Optional for backward compatibility with existing session files.
|
|
28
|
+
*/
|
|
29
|
+
processToken?: string;
|
|
30
|
+
/** Session ID of the currently active session */
|
|
31
|
+
sessionId: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Session metadata stored in .brv/sessions/session-*.json
|
|
35
|
+
* Contains metadata about a session for listing and management.
|
|
36
|
+
*/
|
|
37
|
+
export interface SessionMetadata {
|
|
38
|
+
/** ISO timestamp when session was created */
|
|
39
|
+
createdAt: string;
|
|
40
|
+
/** ISO timestamp of last activity */
|
|
41
|
+
lastUpdated: string;
|
|
42
|
+
/** Number of messages in session (cached for quick display) */
|
|
43
|
+
messageCount: number;
|
|
44
|
+
/** Unique session identifier (UUID) */
|
|
45
|
+
sessionId: string;
|
|
46
|
+
/** Session lifecycle status */
|
|
47
|
+
status: SessionStatus;
|
|
48
|
+
/** Optional AI-generated summary */
|
|
49
|
+
summary?: string;
|
|
50
|
+
/** Session title (generated from first user message) */
|
|
51
|
+
title?: string;
|
|
52
|
+
/** Project working directory (for validation) */
|
|
53
|
+
workingDirectory: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Session info for display purposes (extends metadata with computed fields).
|
|
57
|
+
*/
|
|
58
|
+
export interface SessionInfo extends SessionMetadata {
|
|
59
|
+
/** Filename without extension */
|
|
60
|
+
file: string;
|
|
61
|
+
/** Full filename including .json extension */
|
|
62
|
+
fileName: string;
|
|
63
|
+
/** First user message content (cleaned) */
|
|
64
|
+
firstUserMessage?: string;
|
|
65
|
+
/** Display index in the list (1-based) */
|
|
66
|
+
index: number;
|
|
67
|
+
/** Whether this is the currently active session */
|
|
68
|
+
isCurrentSession: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Result of resolving a session selection.
|
|
72
|
+
*/
|
|
73
|
+
export interface SessionSelectionResult {
|
|
74
|
+
/** Display info string for user feedback */
|
|
75
|
+
displayInfo: string;
|
|
76
|
+
/** Loaded session metadata */
|
|
77
|
+
sessionData: SessionMetadata;
|
|
78
|
+
/** Full path to session metadata file */
|
|
79
|
+
sessionPath: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Schema for ActiveSessionPointer validation.
|
|
83
|
+
*/
|
|
84
|
+
export declare const ActiveSessionPointerSchema: z.ZodObject<{
|
|
85
|
+
activatedAt: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
86
|
+
pid: z.ZodNumber;
|
|
87
|
+
processToken: z.ZodOptional<z.ZodString>;
|
|
88
|
+
sessionId: z.ZodString;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
pid: number;
|
|
92
|
+
activatedAt: string;
|
|
93
|
+
processToken?: string | undefined;
|
|
94
|
+
}, {
|
|
95
|
+
sessionId: string;
|
|
96
|
+
pid: number;
|
|
97
|
+
activatedAt: string;
|
|
98
|
+
processToken?: string | undefined;
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Schema for SessionMetadata validation.
|
|
102
|
+
*/
|
|
103
|
+
export declare const SessionMetadataSchema: z.ZodObject<{
|
|
104
|
+
createdAt: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
105
|
+
lastUpdated: z.ZodUnion<[z.ZodString, z.ZodString]>;
|
|
106
|
+
messageCount: z.ZodNumber;
|
|
107
|
+
sessionId: z.ZodString;
|
|
108
|
+
status: z.ZodEnum<["active", "ended", "interrupted"]>;
|
|
109
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
110
|
+
title: z.ZodOptional<z.ZodString>;
|
|
111
|
+
workingDirectory: z.ZodString;
|
|
112
|
+
}, "strip", z.ZodTypeAny, {
|
|
113
|
+
status: "active" | "ended" | "interrupted";
|
|
114
|
+
sessionId: string;
|
|
115
|
+
createdAt: string;
|
|
116
|
+
lastUpdated: string;
|
|
117
|
+
messageCount: number;
|
|
118
|
+
workingDirectory: string;
|
|
119
|
+
summary?: string | undefined;
|
|
120
|
+
title?: string | undefined;
|
|
121
|
+
}, {
|
|
122
|
+
status: "active" | "ended" | "interrupted";
|
|
123
|
+
sessionId: string;
|
|
124
|
+
createdAt: string;
|
|
125
|
+
lastUpdated: string;
|
|
126
|
+
messageCount: number;
|
|
127
|
+
workingDirectory: string;
|
|
128
|
+
summary?: string | undefined;
|
|
129
|
+
title?: string | undefined;
|
|
130
|
+
}>;
|
|
131
|
+
/** Prefix for session metadata files */
|
|
132
|
+
export declare const SESSION_FILE_PREFIX = "session-";
|
|
133
|
+
/** Directory name for session storage */
|
|
134
|
+
export declare const SESSIONS_DIR = "sessions";
|
|
135
|
+
/** Filename for active session pointer */
|
|
136
|
+
export declare const ACTIVE_SESSION_FILE = "active.json";
|
|
137
|
+
/** Default session retention config */
|
|
138
|
+
export declare const DEFAULT_SESSION_RETENTION: {
|
|
139
|
+
/** Maximum age in days before auto-cleanup */
|
|
140
|
+
maxAgeDays: number;
|
|
141
|
+
/** Maximum number of sessions to keep */
|
|
142
|
+
maxCount: number;
|
|
143
|
+
/** Run cleanup on startup */
|
|
144
|
+
runOnStartup: boolean;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Generate a session filename from timestamp and session ID.
|
|
148
|
+
*
|
|
149
|
+
* @param sessionId - The session UUID
|
|
150
|
+
* @returns Filename in format: session-YYYY-MM-DDTHH-MM-SS-<uuid-prefix>.json
|
|
151
|
+
*/
|
|
152
|
+
export declare function generateSessionFilename(sessionId: string): string;
|
|
153
|
+
/**
|
|
154
|
+
* Parse a session filename to extract timestamp and UUID prefix.
|
|
155
|
+
*
|
|
156
|
+
* @param filename - The session filename
|
|
157
|
+
* @returns Parsed components or null if invalid format
|
|
158
|
+
*/
|
|
159
|
+
export declare function parseSessionFilename(filename: string): null | {
|
|
160
|
+
timestamp: string;
|
|
161
|
+
uuidPrefix: string;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Format a timestamp as relative time.
|
|
165
|
+
*
|
|
166
|
+
* @param timestamp - ISO timestamp string
|
|
167
|
+
* @param style - 'long' (e.g., "2 hours ago") or 'short' (e.g., "2h")
|
|
168
|
+
* @returns Formatted relative time string
|
|
169
|
+
*/
|
|
170
|
+
export declare function formatRelativeTime(timestamp: string, style?: 'long' | 'short'): string;
|
|
171
|
+
/**
|
|
172
|
+
* Clean and sanitize message content for display.
|
|
173
|
+
* Converts newlines to spaces, collapses whitespace, removes non-printable chars.
|
|
174
|
+
*
|
|
175
|
+
* @param message - Raw message content
|
|
176
|
+
* @returns Cleaned message suitable for display
|
|
177
|
+
*/
|
|
178
|
+
export declare function cleanMessageForTitle(message: string): string;
|