byterover-cli 1.0.4 → 1.1.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 (172) hide show
  1. package/README.md +24 -11
  2. package/dist/commands/curate.js +1 -1
  3. package/dist/commands/hook-prompt-submit.d.ts +27 -0
  4. package/dist/commands/hook-prompt-submit.js +39 -0
  5. package/dist/commands/main.d.ts +13 -0
  6. package/dist/commands/main.js +53 -2
  7. package/dist/commands/query.js +1 -1
  8. package/dist/commands/status.js +8 -3
  9. package/dist/constants.d.ts +2 -2
  10. package/dist/constants.js +2 -2
  11. package/dist/core/domain/cipher/llm/registry.js +53 -2
  12. package/dist/core/domain/cipher/llm/types.d.ts +2 -0
  13. package/dist/core/domain/cipher/process/types.d.ts +7 -0
  14. package/dist/core/domain/cipher/session/session-metadata.d.ts +178 -0
  15. package/dist/core/domain/cipher/session/session-metadata.js +147 -0
  16. package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
  17. package/dist/core/domain/cipher/tools/constants.js +1 -0
  18. package/dist/core/domain/entities/agent.d.ts +16 -0
  19. package/dist/core/domain/entities/agent.js +24 -0
  20. package/dist/core/domain/entities/connector-type.d.ts +9 -0
  21. package/dist/core/domain/entities/connector-type.js +8 -0
  22. package/dist/core/domain/entities/event.d.ts +1 -1
  23. package/dist/core/domain/entities/event.js +2 -0
  24. package/dist/core/domain/errors/task-error.d.ts +4 -0
  25. package/dist/core/domain/errors/task-error.js +7 -0
  26. package/dist/core/domain/knowledge/markdown-writer.d.ts +15 -18
  27. package/dist/core/domain/knowledge/markdown-writer.js +232 -34
  28. package/dist/core/domain/knowledge/relation-parser.d.ts +25 -39
  29. package/dist/core/domain/knowledge/relation-parser.js +39 -61
  30. package/dist/core/domain/transport/schemas.d.ts +77 -2
  31. package/dist/core/domain/transport/schemas.js +51 -2
  32. package/dist/core/interfaces/cipher/i-session-persistence.d.ts +133 -0
  33. package/dist/core/interfaces/cipher/i-session-persistence.js +7 -0
  34. package/dist/core/interfaces/cipher/message-types.d.ts +6 -0
  35. package/dist/core/interfaces/connectors/connector-types.d.ts +57 -0
  36. package/dist/core/interfaces/connectors/i-connector-manager.d.ts +72 -0
  37. package/dist/core/interfaces/connectors/i-connector.d.ts +54 -0
  38. package/dist/core/interfaces/connectors/i-connector.js +1 -0
  39. package/dist/core/interfaces/executor/i-curate-executor.d.ts +2 -2
  40. package/dist/core/interfaces/i-context-file-reader.d.ts +3 -0
  41. package/dist/core/interfaces/i-file-service.d.ts +7 -0
  42. package/dist/core/interfaces/usecase/i-connectors-use-case.d.ts +3 -0
  43. package/dist/core/interfaces/usecase/i-connectors-use-case.js +1 -0
  44. package/dist/core/interfaces/usecase/{i-clear-use-case.d.ts → i-reset-use-case.d.ts} +1 -1
  45. package/dist/core/interfaces/usecase/i-reset-use-case.js +1 -0
  46. package/dist/hooks/init/update-notifier.d.ts +1 -0
  47. package/dist/hooks/init/update-notifier.js +10 -1
  48. package/dist/infra/cipher/agent/agent-schemas.d.ts +6 -6
  49. package/dist/infra/cipher/agent/service-initializer.js +4 -4
  50. package/dist/infra/cipher/file-system/binary-utils.d.ts +7 -12
  51. package/dist/infra/cipher/file-system/binary-utils.js +46 -31
  52. package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +3 -2
  53. package/dist/infra/cipher/file-system/file-system-service.js +1 -0
  54. package/dist/infra/cipher/http/internal-llm-http-service.js +3 -5
  55. package/dist/infra/cipher/interactive-loop.js +3 -1
  56. package/dist/infra/cipher/llm/context/context-manager.d.ts +2 -2
  57. package/dist/infra/cipher/llm/context/context-manager.js +63 -18
  58. package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +13 -0
  59. package/dist/infra/cipher/llm/formatters/gemini-formatter.js +146 -15
  60. package/dist/infra/cipher/llm/generators/byterover-content-generator.js +6 -2
  61. package/dist/infra/cipher/llm/internal-llm-service.js +2 -2
  62. package/dist/infra/cipher/llm/thought-parser.d.ts +21 -0
  63. package/dist/infra/cipher/llm/thought-parser.js +27 -0
  64. package/dist/infra/cipher/llm/tool-output-processor.d.ts +10 -0
  65. package/dist/infra/cipher/llm/tool-output-processor.js +80 -7
  66. package/dist/infra/cipher/process/process-service.js +11 -3
  67. package/dist/infra/cipher/session/chat-session.d.ts +7 -2
  68. package/dist/infra/cipher/session/chat-session.js +90 -52
  69. package/dist/infra/cipher/session/session-metadata-store.d.ts +52 -0
  70. package/dist/infra/cipher/session/session-metadata-store.js +406 -0
  71. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +6 -7
  72. package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +57 -18
  73. package/dist/infra/cipher/tools/implementations/curate-tool.js +132 -36
  74. package/dist/infra/cipher/tools/implementations/read-file-tool.js +38 -17
  75. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.d.ts +7 -0
  76. package/dist/infra/cipher/tools/implementations/search-knowledge-tool.js +303 -0
  77. package/dist/infra/cipher/tools/implementations/task-tool.js +1 -0
  78. package/dist/infra/cipher/tools/index.d.ts +1 -0
  79. package/dist/infra/cipher/tools/index.js +1 -0
  80. package/dist/infra/cipher/tools/tool-manager.js +1 -0
  81. package/dist/infra/cipher/tools/tool-registry.js +7 -0
  82. package/dist/infra/connectors/connector-manager.d.ts +32 -0
  83. package/dist/infra/connectors/connector-manager.js +156 -0
  84. package/dist/infra/connectors/hook/hook-connector-config.d.ts +52 -0
  85. package/dist/infra/connectors/hook/hook-connector-config.js +41 -0
  86. package/dist/infra/connectors/hook/hook-connector.d.ts +46 -0
  87. package/dist/infra/connectors/hook/hook-connector.js +231 -0
  88. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.d.ts +2 -2
  89. package/dist/infra/{rule → connectors/rules}/legacy-rule-detector.js +1 -1
  90. package/dist/infra/connectors/rules/rules-connector-config.d.ts +95 -0
  91. package/dist/infra/{rule/agent-rule-config.js → connectors/rules/rules-connector-config.js} +10 -10
  92. package/dist/infra/connectors/rules/rules-connector.d.ts +41 -0
  93. package/dist/infra/connectors/rules/rules-connector.js +204 -0
  94. package/dist/infra/{rule/rule-template-service.d.ts → connectors/shared/template-service.d.ts} +3 -3
  95. package/dist/infra/{rule/rule-template-service.js → connectors/shared/template-service.js} +1 -1
  96. package/dist/infra/context-tree/file-context-file-reader.js +4 -0
  97. package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +5 -2
  98. package/dist/infra/context-tree/file-context-tree-writer-service.js +20 -5
  99. package/dist/infra/core/executors/curate-executor.d.ts +2 -2
  100. package/dist/infra/core/executors/curate-executor.js +7 -7
  101. package/dist/infra/core/executors/query-executor.d.ts +12 -0
  102. package/dist/infra/core/executors/query-executor.js +62 -1
  103. package/dist/infra/core/task-processor.d.ts +2 -2
  104. package/dist/infra/file/fs-file-service.d.ts +7 -0
  105. package/dist/infra/file/fs-file-service.js +15 -1
  106. package/dist/infra/process/agent-worker.d.ts +2 -2
  107. package/dist/infra/process/agent-worker.js +626 -142
  108. package/dist/infra/process/constants.d.ts +1 -1
  109. package/dist/infra/process/constants.js +1 -1
  110. package/dist/infra/process/ipc-types.d.ts +17 -4
  111. package/dist/infra/process/ipc-types.js +3 -3
  112. package/dist/infra/process/parent-heartbeat.d.ts +47 -0
  113. package/dist/infra/process/parent-heartbeat.js +118 -0
  114. package/dist/infra/process/process-manager.d.ts +89 -1
  115. package/dist/infra/process/process-manager.js +293 -9
  116. package/dist/infra/process/task-queue-manager.d.ts +13 -0
  117. package/dist/infra/process/task-queue-manager.js +19 -0
  118. package/dist/infra/process/transport-handlers.d.ts +3 -0
  119. package/dist/infra/process/transport-handlers.js +82 -5
  120. package/dist/infra/process/transport-worker.js +9 -69
  121. package/dist/infra/repl/commands/connectors-command.d.ts +8 -0
  122. package/dist/infra/repl/commands/{gen-rules-command.js → connectors-command.js} +21 -10
  123. package/dist/infra/repl/commands/index.js +8 -4
  124. package/dist/infra/repl/commands/init-command.js +11 -7
  125. package/dist/infra/repl/commands/new-command.d.ts +14 -0
  126. package/dist/infra/repl/commands/new-command.js +61 -0
  127. package/dist/infra/repl/commands/query-command.js +22 -2
  128. package/dist/infra/repl/commands/{clear-command.d.ts → reset-command.d.ts} +2 -2
  129. package/dist/infra/repl/commands/{clear-command.js → reset-command.js} +11 -11
  130. package/dist/infra/transport/socket-io-transport-client.d.ts +68 -0
  131. package/dist/infra/transport/socket-io-transport-client.js +283 -7
  132. package/dist/infra/usecase/connectors-use-case.d.ts +59 -0
  133. package/dist/infra/usecase/connectors-use-case.js +203 -0
  134. package/dist/infra/usecase/init-use-case.d.ts +8 -43
  135. package/dist/infra/usecase/init-use-case.js +29 -253
  136. package/dist/infra/usecase/logout-use-case.js +2 -2
  137. package/dist/infra/usecase/pull-use-case.js +5 -5
  138. package/dist/infra/usecase/push-use-case.js +5 -5
  139. package/dist/infra/usecase/{clear-use-case.d.ts → reset-use-case.d.ts} +5 -5
  140. package/dist/infra/usecase/{clear-use-case.js → reset-use-case.js} +7 -8
  141. package/dist/infra/usecase/space-list-use-case.js +3 -3
  142. package/dist/infra/usecase/space-switch-use-case.js +3 -3
  143. package/dist/resources/prompts/curate.yml +75 -13
  144. package/dist/resources/prompts/explore.yml +34 -0
  145. package/dist/resources/prompts/query-orchestrator.yml +112 -0
  146. package/dist/resources/prompts/system-prompt.yml +12 -2
  147. package/dist/resources/tools/curate.txt +60 -15
  148. package/dist/resources/tools/search_knowledge.txt +32 -0
  149. package/dist/templates/sections/brv-instructions.md +98 -0
  150. package/dist/tui/components/inline-prompts/inline-confirm.js +2 -2
  151. package/dist/tui/components/onboarding/onboarding-flow.js +14 -10
  152. package/dist/tui/components/onboarding/welcome-box.js +1 -1
  153. package/dist/tui/contexts/onboarding-context.d.ts +4 -0
  154. package/dist/tui/contexts/onboarding-context.js +14 -2
  155. package/dist/tui/views/command-view.js +19 -0
  156. package/dist/utils/file-validator.d.ts +1 -1
  157. package/dist/utils/file-validator.js +34 -35
  158. package/dist/utils/type-guards.d.ts +5 -0
  159. package/dist/utils/type-guards.js +7 -0
  160. package/oclif.manifest.json +32 -6
  161. package/package.json +4 -1
  162. package/dist/config/context-tree-domains.d.ts +0 -29
  163. package/dist/config/context-tree-domains.js +0 -29
  164. package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +0 -3
  165. package/dist/infra/repl/commands/gen-rules-command.d.ts +0 -7
  166. package/dist/infra/rule/agent-rule-config.d.ts +0 -19
  167. package/dist/infra/usecase/generate-rules-use-case.d.ts +0 -61
  168. package/dist/infra/usecase/generate-rules-use-case.js +0 -285
  169. /package/dist/core/interfaces/{usecase/i-clear-use-case.js → connectors/connector-types.js} +0 -0
  170. /package/dist/core/interfaces/{usecase/i-generate-rules-use-case.js → connectors/i-connector-manager.js} +0 -0
  171. /package/dist/infra/{rule → connectors/shared}/constants.d.ts +0 -0
  172. /package/dist/infra/{rule → connectors/shared}/constants.js +0 -0
@@ -23,7 +23,11 @@ import { SessionEventBus } from '../events/event-emitter.js';
23
23
  export declare class ChatSession implements IChatSession {
24
24
  readonly eventBus: SessionEventBus;
25
25
  readonly id: string;
26
+ /** Map of taskId -> AbortController for concurrent task cancellation */
27
+ private readonly activeControllers;
28
+ /** Fallback controller for non-task executions (interactive mode) */
26
29
  private currentController?;
30
+ /** Fallback taskId for non-task executions - DEPRECATED: use activeControllers */
27
31
  private currentTaskId?;
28
32
  private readonly forwarders;
29
33
  private isExecuting;
@@ -39,9 +43,10 @@ export declare class ChatSession implements IChatSession {
39
43
  */
40
44
  constructor(id: string, sharedServices: CipherAgentServices, sessionServices: SessionServices);
41
45
  /**
42
- * Cancel the current operation.
46
+ * Cancel the current operation or a specific task.
47
+ * @param taskId - Optional taskId to cancel specific task, otherwise cancels fallback controller
43
48
  */
44
- cancel(): void;
49
+ cancel(taskId?: string): void;
45
50
  /**
46
51
  * Cleanup session resources but preserve history for later restoration.
47
52
  * Call this when ending a session temporarily (e.g., user navigates away).
@@ -36,7 +36,11 @@ const SESSION_EVENT_NAMES = [
36
36
  export class ChatSession {
37
37
  eventBus;
38
38
  id;
39
+ /** Map of taskId -> AbortController for concurrent task cancellation */
40
+ activeControllers = new Map();
41
+ /** Fallback controller for non-task executions (interactive mode) */
39
42
  currentController;
43
+ /** Fallback taskId for non-task executions - DEPRECATED: use activeControllers */
40
44
  currentTaskId;
41
45
  forwarders = new Map();
42
46
  isExecuting = false;
@@ -60,10 +64,18 @@ export class ChatSession {
60
64
  this.setupEventForwarding();
61
65
  }
62
66
  /**
63
- * Cancel the current operation.
67
+ * Cancel the current operation or a specific task.
68
+ * @param taskId - Optional taskId to cancel specific task, otherwise cancels fallback controller
64
69
  */
65
- cancel() {
66
- if (this.currentController) {
70
+ cancel(taskId) {
71
+ if (taskId) {
72
+ const controller = this.activeControllers.get(taskId);
73
+ if (controller) {
74
+ controller.abort();
75
+ this.activeControllers.delete(taskId);
76
+ }
77
+ }
78
+ else if (this.currentController) {
67
79
  this.currentController.abort();
68
80
  }
69
81
  }
@@ -73,7 +85,12 @@ export class ChatSession {
73
85
  * History remains in ContextManager for persistence; event listeners stay for potential reactivation.
74
86
  */
75
87
  cleanup() {
76
- // Cancel any in-flight operation
88
+ // Cancel all active task controllers
89
+ for (const controller of this.activeControllers.values()) {
90
+ controller.abort();
91
+ }
92
+ this.activeControllers.clear();
93
+ // Cancel fallback controller
77
94
  if (this.currentController) {
78
95
  this.currentController.abort();
79
96
  this.currentController = undefined;
@@ -154,44 +171,55 @@ export class ChatSession {
154
171
  * @param options.taskId - Optional task ID for concurrent task isolation
155
172
  */
156
173
  async run(input, options) {
157
- // Create abort controller for cancellation
158
- this.currentController = new AbortController();
174
+ const taskId = options?.taskId;
175
+ const controller = new AbortController();
176
+ // Track controller per-task for concurrent execution support
177
+ if (taskId) {
178
+ this.activeControllers.set(taskId, controller);
179
+ }
180
+ else {
181
+ this.currentController = controller;
182
+ }
183
+ // Store taskId for event forwarding (last-write-wins for concurrent tasks)
184
+ this.currentTaskId = taskId;
159
185
  this.isExecuting = true;
160
- // Store taskId for event forwarding
161
- this.currentTaskId = options?.taskId;
162
- // Update session status to busy
163
186
  sessionStatusManager.setBusy(this.id, this.eventBus);
164
- // Store reference to controller for use in catch/finally blocks
165
- // This prevents race conditions where currentController might be undefined
166
- const controller = this.currentController;
167
187
  try {
168
- // Process any queued messages first, coalescing with current input
169
- const queued = this.messageQueue.dequeueAll();
170
- const finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
171
- // Delegate to service - it handles everything
172
- // Pass taskId for billing tracking
188
+ let finalInput = input;
189
+ if (!taskId) {
190
+ const queued = this.messageQueue.dequeueAll();
191
+ finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
192
+ }
173
193
  const response = await this.llmService.completeTask(finalInput, {
174
194
  executionContext: options?.executionContext,
175
195
  signal: controller.signal,
176
- taskId: options?.taskId,
196
+ taskId,
177
197
  });
178
198
  return response;
179
199
  }
180
200
  catch (error) {
181
- // Check if cancelled - use stored controller reference to avoid undefined access
182
201
  if (controller.signal.aborted) {
183
202
  throw new SessionCancelledError(this.id);
184
203
  }
185
- // Wrap other errors - pass message as-is since it's already formatted
186
204
  const errorMessage = error instanceof Error ? error.message : String(error);
187
205
  throw new LLMError(errorMessage, this.id);
188
206
  }
189
207
  finally {
190
- this.isExecuting = false;
191
- this.currentController = undefined;
192
- this.currentTaskId = undefined;
193
- // Update session status back to idle
194
- sessionStatusManager.setIdle(this.id, this.eventBus);
208
+ if (taskId) {
209
+ this.activeControllers.delete(taskId);
210
+ }
211
+ else {
212
+ this.currentController = undefined;
213
+ }
214
+ // Clear taskId if this was the active one
215
+ if (this.currentTaskId === taskId) {
216
+ this.currentTaskId = undefined;
217
+ }
218
+ // Only mark idle if no active tasks
219
+ if (this.activeControllers.size === 0) {
220
+ this.isExecuting = false;
221
+ sessionStatusManager.setIdle(this.id, this.eventBus);
222
+ }
195
223
  }
196
224
  }
197
225
  /**
@@ -232,36 +260,38 @@ export class ChatSession {
232
260
  */
233
261
  async streamRun(input, options) {
234
262
  const startTime = Date.now();
263
+ const taskId = options?.taskId;
264
+ const controller = new AbortController();
235
265
  let finishReason = 'stop';
236
266
  let error;
237
- // Create abort controller for cancellation
238
- this.currentController = new AbortController();
267
+ // Track controller per-task for concurrent execution support
268
+ if (taskId) {
269
+ this.activeControllers.set(taskId, controller);
270
+ }
271
+ else {
272
+ this.currentController = controller;
273
+ }
274
+ // Store taskId for event forwarding (last-write-wins for concurrent tasks)
275
+ this.currentTaskId = taskId;
239
276
  this.isExecuting = true;
240
- // Store taskId for event forwarding
241
- this.currentTaskId = options?.taskId;
242
- // Update session status to busy
243
277
  sessionStatusManager.setBusy(this.id, this.eventBus);
244
- // Store reference to controller for use in catch/finally blocks
245
- // This prevents race conditions where currentController might be undefined
246
- const controller = this.currentController;
247
- // Link external signal if provided (use {once: true} to prevent listener accumulation)
278
+ // Link external signal if provided
248
279
  if (options?.signal) {
249
- options.signal.addEventListener('abort', () => controller?.abort(), { once: true });
280
+ options.signal.addEventListener('abort', () => controller.abort(), { once: true });
250
281
  }
251
282
  try {
252
- // Process any queued messages first, coalescing with current input
253
- const queued = this.messageQueue.dequeueAll();
254
- const finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
255
- // Delegate to service - it handles everything and emits events
256
- // Pass taskId for billing tracking
283
+ let finalInput = input;
284
+ if (!taskId) {
285
+ const queued = this.messageQueue.dequeueAll();
286
+ finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
287
+ }
257
288
  await this.llmService.completeTask(finalInput, {
258
289
  executionContext: options?.executionContext,
259
290
  signal: controller.signal,
260
- taskId: options?.taskId,
291
+ taskId,
261
292
  });
262
293
  }
263
294
  catch (error_) {
264
- // Check if cancelled - use stored controller reference to avoid undefined access
265
295
  if (controller.signal.aborted) {
266
296
  finishReason = 'cancelled';
267
297
  }
@@ -271,21 +301,29 @@ export class ChatSession {
271
301
  }
272
302
  }
273
303
  finally {
274
- this.isExecuting = false;
275
- this.currentController = undefined;
276
- // Save taskId before clearing for run:complete event
277
- const completedTaskId = this.currentTaskId;
278
- this.currentTaskId = undefined;
279
- // Update session status back to idle
280
- sessionStatusManager.setIdle(this.id, this.eventBus);
281
- // Emit run:complete event with taskId for billing tracking
304
+ if (taskId) {
305
+ this.activeControllers.delete(taskId);
306
+ }
307
+ else {
308
+ this.currentController = undefined;
309
+ }
310
+ // Clear taskId if this was the active one
311
+ if (this.currentTaskId === taskId) {
312
+ this.currentTaskId = undefined;
313
+ }
314
+ // Only mark idle if no active tasks
315
+ if (this.activeControllers.size === 0) {
316
+ this.isExecuting = false;
317
+ sessionStatusManager.setIdle(this.id, this.eventBus);
318
+ }
319
+ // Emit run:complete event with taskId
282
320
  const durationMs = Date.now() - startTime;
283
321
  this.eventBus.emit('run:complete', {
284
322
  durationMs,
285
323
  error,
286
324
  finishReason,
287
- stepCount: 0, // Can be enhanced later to track actual step count
288
- ...(completedTaskId && { taskId: completedTaskId }),
325
+ stepCount: 0,
326
+ ...(taskId && { taskId }),
289
327
  });
290
328
  }
291
329
  }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * SessionMetadataStore - Manages session metadata persistence.
3
+ *
4
+ * Stores session metadata in .brv/sessions/ directory:
5
+ * - active.json: Current active session pointer
6
+ * - session-*.json: Individual session metadata files
7
+ *
8
+ * Design adapted from gemini-cli's ChatRecordingService pattern.
9
+ */
10
+ import type { ISessionPersistence, SessionCleanupResult, SessionRetentionConfig } from '../../../core/interfaces/cipher/i-session-persistence.js';
11
+ import { type ActiveSessionPointer, type SessionInfo, type SessionMetadata } from '../../../core/domain/cipher/session/session-metadata.js';
12
+ /**
13
+ * SessionMetadataStore implementation.
14
+ *
15
+ * Manages session metadata stored in .brv/sessions/ directory.
16
+ */
17
+ export declare class SessionMetadataStore implements ISessionPersistence {
18
+ private readonly activeSessionPath;
19
+ private readonly sessionsDir;
20
+ private readonly workingDirectory;
21
+ /**
22
+ * Create a new SessionMetadataStore.
23
+ *
24
+ * @param workingDirectory - Project working directory (defaults to process.cwd())
25
+ */
26
+ constructor(workingDirectory?: string);
27
+ cleanupSessions(config: SessionRetentionConfig): Promise<SessionCleanupResult>;
28
+ clearActiveSession(): Promise<void>;
29
+ /**
30
+ * Create a new session metadata object.
31
+ *
32
+ * @param sessionId - Session ID
33
+ * @returns New session metadata with defaults
34
+ */
35
+ createSessionMetadata(sessionId: string): SessionMetadata;
36
+ deleteSession(sessionId: string): Promise<boolean>;
37
+ getActiveSession(): Promise<ActiveSessionPointer | null>;
38
+ getSession(sessionId: string): Promise<null | SessionMetadata>;
39
+ isActiveSessionStale(): Promise<boolean>;
40
+ isSessionForCurrentProject(sessionId: string): Promise<boolean>;
41
+ listSessions(): Promise<SessionInfo[]>;
42
+ markSessionEnded(sessionId: string): Promise<void>;
43
+ markSessionInterrupted(sessionId: string): Promise<void>;
44
+ saveSession(metadata: SessionMetadata): Promise<void>;
45
+ setActiveSession(sessionId: string): Promise<void>;
46
+ setSessionTitle(sessionId: string, title: string): Promise<void>;
47
+ updateSessionActivity(sessionId: string, messageCount: number): Promise<void>;
48
+ /**
49
+ * Ensure the sessions directory exists.
50
+ */
51
+ private ensureSessionsDir;
52
+ }