byterover-cli 0.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 (193) hide show
  1. package/README.md +781 -0
  2. package/bin/dev.cmd +4 -0
  3. package/bin/dev.js +7 -0
  4. package/bin/run.cmd +4 -0
  5. package/bin/run.js +7 -0
  6. package/dist/commands/add.d.ts +60 -0
  7. package/dist/commands/add.js +230 -0
  8. package/dist/commands/clear.d.ts +13 -0
  9. package/dist/commands/clear.js +57 -0
  10. package/dist/commands/complete.d.ts +108 -0
  11. package/dist/commands/complete.js +340 -0
  12. package/dist/commands/gen-rules.d.ts +26 -0
  13. package/dist/commands/gen-rules.js +89 -0
  14. package/dist/commands/init.d.ts +24 -0
  15. package/dist/commands/init.js +135 -0
  16. package/dist/commands/login.d.ts +22 -0
  17. package/dist/commands/login.js +103 -0
  18. package/dist/commands/push.d.ts +33 -0
  19. package/dist/commands/push.js +150 -0
  20. package/dist/commands/retrieve.d.ts +26 -0
  21. package/dist/commands/retrieve.js +101 -0
  22. package/dist/commands/space/list.d.ts +22 -0
  23. package/dist/commands/space/list.js +105 -0
  24. package/dist/commands/space/switch.d.ts +20 -0
  25. package/dist/commands/space/switch.js +110 -0
  26. package/dist/commands/status.d.ts +22 -0
  27. package/dist/commands/status.js +116 -0
  28. package/dist/config/auth.config.d.ts +32 -0
  29. package/dist/config/auth.config.js +35 -0
  30. package/dist/config/environment.d.ts +35 -0
  31. package/dist/config/environment.js +39 -0
  32. package/dist/constants.d.ts +11 -0
  33. package/dist/constants.js +12 -0
  34. package/dist/core/domain/entities/agent.d.ts +5 -0
  35. package/dist/core/domain/entities/agent.js +23 -0
  36. package/dist/core/domain/entities/auth-token.d.ts +43 -0
  37. package/dist/core/domain/entities/auth-token.js +70 -0
  38. package/dist/core/domain/entities/br-config.d.ts +25 -0
  39. package/dist/core/domain/entities/br-config.js +58 -0
  40. package/dist/core/domain/entities/bullet.d.ts +51 -0
  41. package/dist/core/domain/entities/bullet.js +94 -0
  42. package/dist/core/domain/entities/curator-output.d.ts +14 -0
  43. package/dist/core/domain/entities/curator-output.js +23 -0
  44. package/dist/core/domain/entities/delta-batch.d.ts +30 -0
  45. package/dist/core/domain/entities/delta-batch.js +52 -0
  46. package/dist/core/domain/entities/delta-operation.d.ts +31 -0
  47. package/dist/core/domain/entities/delta-operation.js +50 -0
  48. package/dist/core/domain/entities/event.d.ts +8 -0
  49. package/dist/core/domain/entities/event.js +15 -0
  50. package/dist/core/domain/entities/executor-output.d.ts +27 -0
  51. package/dist/core/domain/entities/executor-output.js +33 -0
  52. package/dist/core/domain/entities/memory.d.ts +55 -0
  53. package/dist/core/domain/entities/memory.js +90 -0
  54. package/dist/core/domain/entities/oauth-token-data.d.ts +13 -0
  55. package/dist/core/domain/entities/oauth-token-data.js +20 -0
  56. package/dist/core/domain/entities/playbook.d.ts +97 -0
  57. package/dist/core/domain/entities/playbook.js +275 -0
  58. package/dist/core/domain/entities/presigned-url.d.ts +9 -0
  59. package/dist/core/domain/entities/presigned-url.js +18 -0
  60. package/dist/core/domain/entities/presigned-urls-response.d.ts +10 -0
  61. package/dist/core/domain/entities/presigned-urls-response.js +18 -0
  62. package/dist/core/domain/entities/reflector-output.d.ts +38 -0
  63. package/dist/core/domain/entities/reflector-output.js +44 -0
  64. package/dist/core/domain/entities/retrieve-result.d.ts +35 -0
  65. package/dist/core/domain/entities/retrieve-result.js +35 -0
  66. package/dist/core/domain/entities/space.d.ts +24 -0
  67. package/dist/core/domain/entities/space.js +52 -0
  68. package/dist/core/domain/entities/team.d.ts +42 -0
  69. package/dist/core/domain/entities/team.js +89 -0
  70. package/dist/core/domain/entities/user.d.ts +20 -0
  71. package/dist/core/domain/entities/user.js +32 -0
  72. package/dist/core/domain/errors/ace-error.d.ts +34 -0
  73. package/dist/core/domain/errors/ace-error.js +53 -0
  74. package/dist/core/domain/errors/auth-error.d.ts +10 -0
  75. package/dist/core/domain/errors/auth-error.js +20 -0
  76. package/dist/core/domain/errors/discovery-error.d.ts +21 -0
  77. package/dist/core/domain/errors/discovery-error.js +33 -0
  78. package/dist/core/domain/errors/rule-error.d.ts +6 -0
  79. package/dist/core/domain/errors/rule-error.js +12 -0
  80. package/dist/core/interfaces/i-ace-prompt-builder.d.ts +48 -0
  81. package/dist/core/interfaces/i-ace-prompt-builder.js +1 -0
  82. package/dist/core/interfaces/i-auth-service.d.ts +35 -0
  83. package/dist/core/interfaces/i-auth-service.js +1 -0
  84. package/dist/core/interfaces/i-browser-launcher.d.ts +11 -0
  85. package/dist/core/interfaces/i-browser-launcher.js +1 -0
  86. package/dist/core/interfaces/i-bullet-content-store.d.ts +36 -0
  87. package/dist/core/interfaces/i-bullet-content-store.js +1 -0
  88. package/dist/core/interfaces/i-callback-handler.d.ts +35 -0
  89. package/dist/core/interfaces/i-callback-handler.js +1 -0
  90. package/dist/core/interfaces/i-delta-store.d.ts +15 -0
  91. package/dist/core/interfaces/i-delta-store.js +1 -0
  92. package/dist/core/interfaces/i-executor-output-store.d.ts +14 -0
  93. package/dist/core/interfaces/i-executor-output-store.js +1 -0
  94. package/dist/core/interfaces/i-file-service.d.ts +34 -0
  95. package/dist/core/interfaces/i-file-service.js +1 -0
  96. package/dist/core/interfaces/i-http-client.d.ts +33 -0
  97. package/dist/core/interfaces/i-http-client.js +1 -0
  98. package/dist/core/interfaces/i-memory-retrieval-service.d.ts +40 -0
  99. package/dist/core/interfaces/i-memory-retrieval-service.js +1 -0
  100. package/dist/core/interfaces/i-memory-storage-service.d.ts +55 -0
  101. package/dist/core/interfaces/i-memory-storage-service.js +1 -0
  102. package/dist/core/interfaces/i-oidc-discovery-service.d.ts +20 -0
  103. package/dist/core/interfaces/i-oidc-discovery-service.js +1 -0
  104. package/dist/core/interfaces/i-playbook-service.d.ts +69 -0
  105. package/dist/core/interfaces/i-playbook-service.js +1 -0
  106. package/dist/core/interfaces/i-playbook-store.d.ts +38 -0
  107. package/dist/core/interfaces/i-playbook-store.js +1 -0
  108. package/dist/core/interfaces/i-project-config-store.d.ts +26 -0
  109. package/dist/core/interfaces/i-project-config-store.js +1 -0
  110. package/dist/core/interfaces/i-reflection-store.d.ts +21 -0
  111. package/dist/core/interfaces/i-reflection-store.js +1 -0
  112. package/dist/core/interfaces/i-rule-template-service.d.ts +17 -0
  113. package/dist/core/interfaces/i-rule-template-service.js +4 -0
  114. package/dist/core/interfaces/i-rule-writer-service.d.ts +13 -0
  115. package/dist/core/interfaces/i-rule-writer-service.js +1 -0
  116. package/dist/core/interfaces/i-space-service.d.ts +28 -0
  117. package/dist/core/interfaces/i-space-service.js +1 -0
  118. package/dist/core/interfaces/i-team-service.d.ts +29 -0
  119. package/dist/core/interfaces/i-team-service.js +1 -0
  120. package/dist/core/interfaces/i-template-loader.d.ts +29 -0
  121. package/dist/core/interfaces/i-template-loader.js +1 -0
  122. package/dist/core/interfaces/i-token-store.d.ts +22 -0
  123. package/dist/core/interfaces/i-token-store.js +1 -0
  124. package/dist/core/interfaces/i-tracking-service.d.ts +21 -0
  125. package/dist/core/interfaces/i-tracking-service.js +1 -0
  126. package/dist/core/interfaces/i-user-service.d.ts +14 -0
  127. package/dist/core/interfaces/i-user-service.js +1 -0
  128. package/dist/index.d.ts +1 -0
  129. package/dist/index.js +1 -0
  130. package/dist/infra/ace/ace-file-utils.d.ts +46 -0
  131. package/dist/infra/ace/ace-file-utils.js +83 -0
  132. package/dist/infra/ace/ace-prompt-templates.d.ts +13 -0
  133. package/dist/infra/ace/ace-prompt-templates.js +177 -0
  134. package/dist/infra/ace/file-bullet-content-store.d.ts +27 -0
  135. package/dist/infra/ace/file-bullet-content-store.js +89 -0
  136. package/dist/infra/ace/file-delta-store.d.ts +9 -0
  137. package/dist/infra/ace/file-delta-store.js +26 -0
  138. package/dist/infra/ace/file-executor-output-store.d.ts +9 -0
  139. package/dist/infra/ace/file-executor-output-store.js +26 -0
  140. package/dist/infra/ace/file-playbook-store.d.ts +29 -0
  141. package/dist/infra/ace/file-playbook-store.js +107 -0
  142. package/dist/infra/ace/file-reflection-store.d.ts +10 -0
  143. package/dist/infra/ace/file-reflection-store.js +55 -0
  144. package/dist/infra/auth/oauth-service.d.ts +49 -0
  145. package/dist/infra/auth/oauth-service.js +126 -0
  146. package/dist/infra/auth/oidc-discovery-service.d.ts +51 -0
  147. package/dist/infra/auth/oidc-discovery-service.js +145 -0
  148. package/dist/infra/browser/system-browser-launcher.d.ts +10 -0
  149. package/dist/infra/browser/system-browser-launcher.js +18 -0
  150. package/dist/infra/config/file-config-store.d.ts +21 -0
  151. package/dist/infra/config/file-config-store.js +57 -0
  152. package/dist/infra/file/fs-file-service.d.ts +28 -0
  153. package/dist/infra/file/fs-file-service.js +57 -0
  154. package/dist/infra/http/authenticated-http-client.d.ts +46 -0
  155. package/dist/infra/http/authenticated-http-client.js +99 -0
  156. package/dist/infra/http/callback-handler.d.ts +13 -0
  157. package/dist/infra/http/callback-handler.js +24 -0
  158. package/dist/infra/http/callback-server.d.ts +18 -0
  159. package/dist/infra/http/callback-server.js +93 -0
  160. package/dist/infra/memory/http-memory-retrieval-service.d.ts +18 -0
  161. package/dist/infra/memory/http-memory-retrieval-service.js +63 -0
  162. package/dist/infra/memory/http-memory-storage-service.d.ts +18 -0
  163. package/dist/infra/memory/http-memory-storage-service.js +67 -0
  164. package/dist/infra/memory/memory-to-playbook-mapper.d.ts +33 -0
  165. package/dist/infra/memory/memory-to-playbook-mapper.js +51 -0
  166. package/dist/infra/playbook/file-playbook-service.d.ts +43 -0
  167. package/dist/infra/playbook/file-playbook-service.js +133 -0
  168. package/dist/infra/rule/agent-rule-config.d.ts +19 -0
  169. package/dist/infra/rule/agent-rule-config.js +77 -0
  170. package/dist/infra/rule/rule-template-service.d.ts +18 -0
  171. package/dist/infra/rule/rule-template-service.js +80 -0
  172. package/dist/infra/rule/rule-writer-service.d.ts +19 -0
  173. package/dist/infra/rule/rule-writer-service.js +43 -0
  174. package/dist/infra/space/http-space-service.d.ts +20 -0
  175. package/dist/infra/space/http-space-service.js +67 -0
  176. package/dist/infra/storage/keychain-token-store.d.ts +10 -0
  177. package/dist/infra/storage/keychain-token-store.js +40 -0
  178. package/dist/infra/team/http-team-service.d.ts +21 -0
  179. package/dist/infra/team/http-team-service.js +71 -0
  180. package/dist/infra/template/fs-template-loader.d.ts +33 -0
  181. package/dist/infra/template/fs-template-loader.js +62 -0
  182. package/dist/infra/tracking/mixpanel-tracking-service.d.ts +14 -0
  183. package/dist/infra/tracking/mixpanel-tracking-service.js +44 -0
  184. package/dist/infra/user/http-user-service.d.ts +12 -0
  185. package/dist/infra/user/http-user-service.js +26 -0
  186. package/dist/templates/README.md +103 -0
  187. package/dist/templates/base.md +3 -0
  188. package/dist/templates/sections/command-reference.md +141 -0
  189. package/dist/templates/sections/workflow.md +46 -0
  190. package/dist/utils/file-helpers.d.ts +15 -0
  191. package/dist/utils/file-helpers.js +45 -0
  192. package/oclif.manifest.json +476 -0
  193. package/package.json +82 -0
@@ -0,0 +1,99 @@
1
+ import axios, { isAxiosError } from 'axios';
2
+ /**
3
+ * HTTP client implementation that automatically adds authentication headers to all requests.
4
+ *
5
+ * This client wraps axios and automatically includes:
6
+ * - Authorization: Bearer {accessToken}
7
+ * - x-byterover-session-id: {sessionKey}
8
+ *
9
+ * Usage:
10
+ * ```typescript
11
+ * const client = new AuthenticatedHttpClient(accessToken, sessionKey)
12
+ * const data = await client.get<ResponseType>('https://api.example.com/endpoint')
13
+ * ```
14
+ */
15
+ export class AuthenticatedHttpClient {
16
+ accessToken;
17
+ sessionKey;
18
+ constructor(accessToken, sessionKey) {
19
+ this.accessToken = accessToken;
20
+ this.sessionKey = sessionKey;
21
+ }
22
+ /**
23
+ * Performs an HTTP GET request with authentication headers.
24
+ * @param url The URL to request
25
+ * @param config Optional request configuration (headers, timeout)
26
+ * @returns A promise that resolves to the response data
27
+ * @throws Error if the request fails
28
+ */
29
+ async get(url, config) {
30
+ try {
31
+ const axiosConfig = {
32
+ headers: this.buildHeaders(config?.headers),
33
+ timeout: config?.timeout,
34
+ };
35
+ const response = await axios.get(url, axiosConfig);
36
+ return response.data;
37
+ }
38
+ catch (error) {
39
+ throw this.handleError(error);
40
+ }
41
+ }
42
+ /**
43
+ * Performs an HTTP POST request with authentication headers.
44
+ * @param url The URL to request
45
+ * @param data The data to send in the request body
46
+ * @param config Optional request configuration (headers, timeout)
47
+ * @returns A promise that resolves to the response data
48
+ * @throws Error if the request fails
49
+ */
50
+ async post(url, data, config) {
51
+ try {
52
+ const axiosConfig = {
53
+ headers: this.buildHeaders(config?.headers),
54
+ timeout: config?.timeout,
55
+ };
56
+ const response = await axios.post(url, data, axiosConfig);
57
+ return response.data;
58
+ }
59
+ catch (error) {
60
+ throw this.handleError(error);
61
+ }
62
+ }
63
+ /**
64
+ * Builds request headers by merging authentication headers with custom headers.
65
+ * Custom headers take precedence over default headers.
66
+ */
67
+ buildHeaders(customHeaders) {
68
+ return {
69
+ Authorization: `Bearer ${this.accessToken}`,
70
+ 'x-byterover-session-id': this.sessionKey,
71
+ ...customHeaders,
72
+ };
73
+ }
74
+ /**
75
+ * Transforms axios errors into generic Error instances.
76
+ * Preserves error information while abstracting axios-specific details.
77
+ */
78
+ handleError(error) {
79
+ if (isAxiosError(error)) {
80
+ if (error.response) {
81
+ // Server responded with error status
82
+ return new Error(`HTTP ${error.response.status}: ${error.response.statusText}`);
83
+ }
84
+ if (error.code === 'ECONNABORTED' || error.message.includes('timeout')) {
85
+ // Request timeout
86
+ return new Error(`Request timeout: ${error.message}`);
87
+ }
88
+ if (error.request) {
89
+ // Request was made but no response received
90
+ return new Error('Network error: No response received from server');
91
+ }
92
+ }
93
+ // Generic error
94
+ if (error instanceof Error) {
95
+ return error;
96
+ }
97
+ return new Error('Unknown error occurred');
98
+ }
99
+ }
@@ -0,0 +1,13 @@
1
+ import type { CallbackResult, ICallbackHandler } from '../../core/interfaces/i-callback-handler.js';
2
+ /**
3
+ * Adapter implementation of ICallbackHandler that wraps CallbackServer.
4
+ * Provides OAuth callback handling functionality through a local HTTP server.
5
+ */
6
+ export declare class CallbackHandler implements ICallbackHandler {
7
+ private readonly server;
8
+ constructor();
9
+ getPort(): number | undefined;
10
+ start(): Promise<number>;
11
+ stop(): Promise<void>;
12
+ waitForCallback(expectedState: string, timeoutMs: number): Promise<CallbackResult>;
13
+ }
@@ -0,0 +1,24 @@
1
+ import { CallbackServer } from './callback-server.js';
2
+ /**
3
+ * Adapter implementation of ICallbackHandler that wraps CallbackServer.
4
+ * Provides OAuth callback handling functionality through a local HTTP server.
5
+ */
6
+ export class CallbackHandler {
7
+ server;
8
+ constructor() {
9
+ this.server = new CallbackServer();
10
+ }
11
+ getPort() {
12
+ const address = this.server.getAddress();
13
+ return address?.port;
14
+ }
15
+ async start() {
16
+ return this.server.start();
17
+ }
18
+ async stop() {
19
+ return this.server.stop();
20
+ }
21
+ async waitForCallback(expectedState, timeoutMs) {
22
+ return this.server.waitForCallback(expectedState, timeoutMs);
23
+ }
24
+ }
@@ -0,0 +1,18 @@
1
+ type CallbackResult = {
2
+ code: string;
3
+ state: string;
4
+ };
5
+ export declare class CallbackServer {
6
+ private app;
7
+ private connections;
8
+ private server;
9
+ constructor();
10
+ getAddress(): undefined | {
11
+ port: number;
12
+ };
13
+ start(): Promise<number>;
14
+ stop(): Promise<void>;
15
+ waitForCallback(expectedState: string, timeoutMs: number): Promise<CallbackResult>;
16
+ private setupRoutes;
17
+ }
18
+ export {};
@@ -0,0 +1,93 @@
1
+ import express from 'express';
2
+ import { AuthenticationError } from '../../core/domain/errors/auth-error.js';
3
+ export class CallbackServer {
4
+ app = express();
5
+ connections = new Set();
6
+ server = undefined;
7
+ constructor() {
8
+ this.setupRoutes();
9
+ }
10
+ getAddress() {
11
+ const address = this.server?.address();
12
+ if (address !== null && address !== undefined && typeof address !== 'string') {
13
+ return { port: address.port };
14
+ }
15
+ return undefined;
16
+ }
17
+ async start() {
18
+ return new Promise((resolve, reject) => {
19
+ // Listen on port 0 to get a random available port
20
+ this.server = this.app.listen(0, () => {
21
+ const address = this.server?.address();
22
+ if (address !== null && address !== undefined && typeof address !== 'string') {
23
+ resolve(address.port);
24
+ }
25
+ else {
26
+ reject(new Error('Failed to start server'));
27
+ }
28
+ });
29
+ // Track connections to allow force-closing during shutdown
30
+ this.server.on('connection', (conn) => {
31
+ this.connections.add(conn);
32
+ conn.on('close', () => {
33
+ this.connections.delete(conn);
34
+ });
35
+ });
36
+ });
37
+ }
38
+ async stop() {
39
+ return new Promise((resolve) => {
40
+ if (this.server === undefined) {
41
+ resolve();
42
+ }
43
+ else {
44
+ // Force close all active connections to prevent delays
45
+ for (const conn of this.connections) {
46
+ conn.destroy();
47
+ }
48
+ this.connections.clear();
49
+ this.server.close(() => {
50
+ this.server = undefined;
51
+ resolve();
52
+ });
53
+ }
54
+ });
55
+ }
56
+ waitForCallback(expectedState, timeoutMs) {
57
+ return new Promise((resolve, reject) => {
58
+ const timeout = setTimeout(() => {
59
+ reject(new AuthenticationError('Authentication timeout - no callback received'));
60
+ }, timeoutMs);
61
+ this.app.locals.onCallback = (code, state) => {
62
+ clearTimeout(timeout);
63
+ if (state !== expectedState) {
64
+ reject(new AuthenticationError('State mismatch - possible CSRF attack'));
65
+ return;
66
+ }
67
+ resolve({ code, state });
68
+ };
69
+ this.app.locals.onError = (error) => {
70
+ clearTimeout(timeout);
71
+ reject(new AuthenticationError(error));
72
+ };
73
+ });
74
+ }
75
+ setupRoutes() {
76
+ this.app.get('/callback', (req, res) => {
77
+ const { code, error, error_description, state } = req.query;
78
+ if (error !== undefined) {
79
+ const errorMessage = error_description ?? error;
80
+ this.app.locals.onError?.(String(errorMessage));
81
+ res.status(400).send(`Authentication failed: ${String(errorMessage)}`);
82
+ return;
83
+ }
84
+ if (code === undefined || state === undefined) {
85
+ this.app.locals.onError?.('Missing code or state parameter');
86
+ res.status(400).send('Authentication failed: Missing required parameters');
87
+ return;
88
+ }
89
+ this.app.locals.onCallback?.(String(code), String(state));
90
+ res.status(200).send('Authentication successful. You can close this window.');
91
+ });
92
+ }
93
+ }
@@ -0,0 +1,18 @@
1
+ import type { IMemoryRetrievalService, RetrieveParams } from '../../core/interfaces/i-memory-retrieval-service.js';
2
+ import { RetrieveResult } from '../../core/domain/entities/retrieve-result.js';
3
+ export type MemoryRetrievalServiceConfig = {
4
+ apiBaseUrl: string;
5
+ timeout?: number;
6
+ };
7
+ /**
8
+ * HTTP implementation of IMemoryRetrievalService for ByteRover Memora service.
9
+ * Handles retrieval of memories based on search queries.
10
+ */
11
+ export declare class HttpMemoryRetrievalService implements IMemoryRetrievalService {
12
+ private readonly config;
13
+ constructor(config: MemoryRetrievalServiceConfig);
14
+ retrieve(params: RetrieveParams): Promise<RetrieveResult>;
15
+ private buildQueryParams;
16
+ private mapToMemory;
17
+ private mapToRetrieveResult;
18
+ }
@@ -0,0 +1,63 @@
1
+ import { Memory } from '../../core/domain/entities/memory.js';
2
+ import { RetrieveResult } from '../../core/domain/entities/retrieve-result.js';
3
+ import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
4
+ /**
5
+ * HTTP implementation of IMemoryRetrievalService for ByteRover Memora service.
6
+ * Handles retrieval of memories based on search queries.
7
+ */
8
+ export class HttpMemoryRetrievalService {
9
+ config;
10
+ constructor(config) {
11
+ this.config = {
12
+ ...config,
13
+ timeout: config.timeout ?? 30_000, // Default 30 seconds timeout (memory retrieval may be slower)
14
+ };
15
+ }
16
+ async retrieve(params) {
17
+ try {
18
+ const httpClient = new AuthenticatedHttpClient(params.accessToken, params.sessionKey);
19
+ // Build query parameters
20
+ const queryParams = this.buildQueryParams(params);
21
+ const response = await httpClient.get(`${this.config.apiBaseUrl}/retrieve?${queryParams}`, {
22
+ timeout: this.config.timeout,
23
+ });
24
+ return this.mapToRetrieveResult(response);
25
+ }
26
+ catch (error) {
27
+ throw new Error(`Failed to retrieve memories: ${error.message}`);
28
+ }
29
+ }
30
+ buildQueryParams(params) {
31
+ const queryParams = new URLSearchParams({
32
+ project_id: params.spaceId,
33
+ query: params.query,
34
+ });
35
+ // Add node_keys only if provided
36
+ if (params.nodeKeys !== undefined && params.nodeKeys.length > 0) {
37
+ queryParams.set('node_keys', params.nodeKeys.join(','));
38
+ }
39
+ return queryParams.toString();
40
+ }
41
+ mapToMemory(apiMemory) {
42
+ return new Memory({
43
+ bulletId: apiMemory.bullet_id,
44
+ childrenIds: apiMemory.children_ids,
45
+ content: apiMemory.content,
46
+ id: apiMemory.id,
47
+ metadataType: apiMemory.metadata_type,
48
+ nodeKeys: apiMemory.node_keys,
49
+ parentIds: apiMemory.parent_ids,
50
+ score: apiMemory.score,
51
+ section: apiMemory.section,
52
+ tags: apiMemory.tags,
53
+ timestamp: apiMemory.timestamp,
54
+ title: apiMemory.title,
55
+ });
56
+ }
57
+ mapToRetrieveResult(response) {
58
+ return new RetrieveResult({
59
+ memories: response.memories.map((m) => this.mapToMemory(m)),
60
+ relatedMemories: response.related_memories.map((m) => this.mapToMemory(m)),
61
+ });
62
+ }
63
+ }
@@ -0,0 +1,18 @@
1
+ import type { ConfirmUploadParams, GetPresignedUrlsParams, IMemoryStorageService } from '../../core/interfaces/i-memory-storage-service.js';
2
+ import { PresignedUrlsResponse } from '../../core/domain/entities/presigned-urls-response.js';
3
+ export type MemoryStorageServiceConfig = {
4
+ apiBaseUrl: string;
5
+ timeout?: number;
6
+ };
7
+ /**
8
+ * HTTP implementation of IMemoryStorageService for ByteRover CoGit service.
9
+ * Handles uploading playbooks to blob storage.
10
+ */
11
+ export declare class HttpMemoryStorageService implements IMemoryStorageService {
12
+ private readonly config;
13
+ constructor(config: MemoryStorageServiceConfig);
14
+ confirmUpload(params: ConfirmUploadParams): Promise<void>;
15
+ getPresignedUrls(params: GetPresignedUrlsParams): Promise<PresignedUrlsResponse>;
16
+ uploadFile(uploadUrl: string, content: string): Promise<void>;
17
+ private mapToPresignedUrls;
18
+ }
@@ -0,0 +1,67 @@
1
+ /* eslint-disable camelcase */
2
+ import axios from 'axios';
3
+ import { PresignedUrl } from '../../core/domain/entities/presigned-url.js';
4
+ import { PresignedUrlsResponse } from '../../core/domain/entities/presigned-urls-response.js';
5
+ import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
6
+ /**
7
+ * HTTP implementation of IMemoryStorageService for ByteRover CoGit service.
8
+ * Handles uploading playbooks to blob storage.
9
+ */
10
+ export class HttpMemoryStorageService {
11
+ config;
12
+ constructor(config) {
13
+ this.config = {
14
+ ...config,
15
+ timeout: config.timeout ?? 30_000, // Default 30 seconds timeout
16
+ };
17
+ }
18
+ async confirmUpload(params) {
19
+ try {
20
+ const httpClient = new AuthenticatedHttpClient(params.accessToken, params.sessionKey);
21
+ const url = `${this.config.apiBaseUrl}/organizations/${params.teamId}/projects/${params.spaceId}/memory-processing/confirm-upload`;
22
+ const requestBody = {
23
+ request_id: params.requestId,
24
+ };
25
+ await httpClient.post(url, requestBody, {
26
+ timeout: this.config.timeout,
27
+ });
28
+ }
29
+ catch (error) {
30
+ throw new Error(`Failed to confirm upload: ${error.message}`);
31
+ }
32
+ }
33
+ async getPresignedUrls(params) {
34
+ try {
35
+ const httpClient = new AuthenticatedHttpClient(params.accessToken, params.sessionKey);
36
+ const url = `${this.config.apiBaseUrl}/organizations/${params.teamId}/projects/${params.spaceId}/memory-processing/presigned-urls`;
37
+ const requestBody = {
38
+ branch: params.branch,
39
+ file_names: params.fileNames,
40
+ };
41
+ const response = await httpClient.post(url, requestBody, {
42
+ timeout: this.config.timeout,
43
+ });
44
+ const presignedUrls = response.data.presigned_urls.map((presignedUrlData) => this.mapToPresignedUrls(presignedUrlData));
45
+ return new PresignedUrlsResponse(presignedUrls, response.data.request_id);
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Failed to get presigned URLs: ${error.message}`);
49
+ }
50
+ }
51
+ async uploadFile(uploadUrl, content) {
52
+ try {
53
+ await axios.put(uploadUrl, content, {
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ },
57
+ timeout: this.config.timeout,
58
+ });
59
+ }
60
+ catch (error) {
61
+ throw new Error(`Failed to upload file: ${error.message}`);
62
+ }
63
+ }
64
+ mapToPresignedUrls(presignedUrlData) {
65
+ return new PresignedUrl(presignedUrlData.file_name, presignedUrlData.presigned_url);
66
+ }
67
+ }
@@ -0,0 +1,33 @@
1
+ import type { Memory } from '../../core/domain/entities/memory.js';
2
+ import type { RetrieveResult } from '../../core/domain/entities/retrieve-result.js';
3
+ import { Bullet } from '../../core/domain/entities/bullet.js';
4
+ import { Playbook } from '../../core/domain/entities/playbook.js';
5
+ /**
6
+ * Transforms a Memory entity into a Bullet entity for playbook storage.
7
+ *
8
+ * Mapping:
9
+ * - memory.bulletId -> bullet.id
10
+ * - memory.section -> bullet.section
11
+ * - memory.content -> bullet.content
12
+ * - memory.tags -> bullet.metadata.tags
13
+ * - memory.nodeKeys -> bullet.metadata.relatedFiles
14
+ * - memory.timestamp -> bullet.metadata.timestamp
15
+ * - memory.id -> bullet.memoryId
16
+ *
17
+ * @param memory The Memory entity to transform
18
+ * @returns A Bullet entity
19
+ */
20
+ export declare const transformMemoryToBullet: (memory: Memory) => Bullet;
21
+ /**
22
+ * Transforms a RetrieveResult into a Playbook.
23
+ *
24
+ * This function:
25
+ * 1. Combines both memories and relatedMemories from the result
26
+ * 2. Transforms each Memory into a Bullet
27
+ * 3. Organizes bullets by section
28
+ * 4. Creates a new Playbook with nextId set to 1 (reset value)
29
+ *
30
+ * @param result The RetrieveResult containing memories from Memora service
31
+ * @returns A Playbook containing all retrieved memories as bullets
32
+ */
33
+ export declare const transformRetrieveResultToPlaybook: (result: RetrieveResult) => Playbook;
@@ -0,0 +1,51 @@
1
+ import { Bullet } from '../../core/domain/entities/bullet.js';
2
+ import { Playbook } from '../../core/domain/entities/playbook.js';
3
+ /**
4
+ * Transforms a Memory entity into a Bullet entity for playbook storage.
5
+ *
6
+ * Mapping:
7
+ * - memory.bulletId -> bullet.id
8
+ * - memory.section -> bullet.section
9
+ * - memory.content -> bullet.content
10
+ * - memory.tags -> bullet.metadata.tags
11
+ * - memory.nodeKeys -> bullet.metadata.relatedFiles
12
+ * - memory.timestamp -> bullet.metadata.timestamp
13
+ * - memory.id -> bullet.memoryId
14
+ *
15
+ * @param memory The Memory entity to transform
16
+ * @returns A Bullet entity
17
+ */
18
+ export const transformMemoryToBullet = (memory) => {
19
+ const metadata = {
20
+ relatedFiles: [...memory.nodeKeys],
21
+ tags: [...memory.tags],
22
+ timestamp: memory.timestamp,
23
+ };
24
+ return new Bullet(memory.bulletId, memory.section, memory.content, metadata, memory.id);
25
+ };
26
+ /**
27
+ * Transforms a RetrieveResult into a Playbook.
28
+ *
29
+ * This function:
30
+ * 1. Combines both memories and relatedMemories from the result
31
+ * 2. Transforms each Memory into a Bullet
32
+ * 3. Organizes bullets by section
33
+ * 4. Creates a new Playbook with nextId set to 1 (reset value)
34
+ *
35
+ * @param result The RetrieveResult containing memories from Memora service
36
+ * @returns A Playbook containing all retrieved memories as bullets
37
+ */
38
+ export const transformRetrieveResultToPlaybook = (result) => {
39
+ const bulletsMap = new Map();
40
+ const sectionsMap = new Map();
41
+ const allMemories = [...result.memories, ...result.relatedMemories];
42
+ for (const memory of allMemories) {
43
+ const bullet = transformMemoryToBullet(memory);
44
+ bulletsMap.set(bullet.id, bullet);
45
+ if (!sectionsMap.has(bullet.section)) {
46
+ sectionsMap.set(bullet.section, []);
47
+ }
48
+ sectionsMap.get(bullet.section).push(bullet.id);
49
+ }
50
+ return new Playbook(bulletsMap, sectionsMap, bulletsMap.size + 1);
51
+ };
@@ -0,0 +1,43 @@
1
+ import type { Bullet, BulletMetadata } from '../../core/domain/entities/bullet.js';
2
+ import type { DeltaBatch } from '../../core/domain/entities/delta-batch.js';
3
+ import type { ReflectorOutput } from '../../core/domain/entities/reflector-output.js';
4
+ import type { IPlaybookService } from '../../core/interfaces/i-playbook-service.js';
5
+ import type { IPlaybookStore } from '../../core/interfaces/i-playbook-store.js';
6
+ import { Playbook } from '../../core/domain/entities/playbook.js';
7
+ export type PlaybookServiceConfig = {
8
+ baseDirectory?: string;
9
+ };
10
+ /**
11
+ * File-based implementation of IPlaybookService.
12
+ * Provides high-level playbook operations including initialization,
13
+ * bullet management, delta application, and reflection tag processing.
14
+ */
15
+ export declare class FilePlaybookService implements IPlaybookService {
16
+ private static readonly BULLETS_DIR;
17
+ private static readonly SUBDIRS;
18
+ private readonly config;
19
+ private readonly playbookStore;
20
+ constructor(config?: PlaybookServiceConfig, playbookStore?: IPlaybookStore);
21
+ addOrUpdateBullet(params: {
22
+ bulletId?: string;
23
+ content: string;
24
+ directory?: string;
25
+ metadata?: BulletMetadata;
26
+ section: string;
27
+ }): Promise<Bullet>;
28
+ applyDelta(params: {
29
+ delta: DeltaBatch;
30
+ directory?: string;
31
+ }): Promise<{
32
+ operationsApplied: number;
33
+ playbook: Playbook;
34
+ }>;
35
+ applyReflectionTags(params: {
36
+ directory?: string;
37
+ reflection: ReflectorOutput;
38
+ }): Promise<{
39
+ playbook: Playbook;
40
+ tagsApplied: number;
41
+ }>;
42
+ initialize(directory?: string): Promise<string>;
43
+ }