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.
- package/README.md +781 -0
- package/bin/dev.cmd +4 -0
- package/bin/dev.js +7 -0
- package/bin/run.cmd +4 -0
- package/bin/run.js +7 -0
- package/dist/commands/add.d.ts +60 -0
- package/dist/commands/add.js +230 -0
- package/dist/commands/clear.d.ts +13 -0
- package/dist/commands/clear.js +57 -0
- package/dist/commands/complete.d.ts +108 -0
- package/dist/commands/complete.js +340 -0
- package/dist/commands/gen-rules.d.ts +26 -0
- package/dist/commands/gen-rules.js +89 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.js +135 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +103 -0
- package/dist/commands/push.d.ts +33 -0
- package/dist/commands/push.js +150 -0
- package/dist/commands/retrieve.d.ts +26 -0
- package/dist/commands/retrieve.js +101 -0
- package/dist/commands/space/list.d.ts +22 -0
- package/dist/commands/space/list.js +105 -0
- package/dist/commands/space/switch.d.ts +20 -0
- package/dist/commands/space/switch.js +110 -0
- package/dist/commands/status.d.ts +22 -0
- package/dist/commands/status.js +116 -0
- package/dist/config/auth.config.d.ts +32 -0
- package/dist/config/auth.config.js +35 -0
- package/dist/config/environment.d.ts +35 -0
- package/dist/config/environment.js +39 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +12 -0
- package/dist/core/domain/entities/agent.d.ts +5 -0
- package/dist/core/domain/entities/agent.js +23 -0
- package/dist/core/domain/entities/auth-token.d.ts +43 -0
- package/dist/core/domain/entities/auth-token.js +70 -0
- package/dist/core/domain/entities/br-config.d.ts +25 -0
- package/dist/core/domain/entities/br-config.js +58 -0
- package/dist/core/domain/entities/bullet.d.ts +51 -0
- package/dist/core/domain/entities/bullet.js +94 -0
- package/dist/core/domain/entities/curator-output.d.ts +14 -0
- package/dist/core/domain/entities/curator-output.js +23 -0
- package/dist/core/domain/entities/delta-batch.d.ts +30 -0
- package/dist/core/domain/entities/delta-batch.js +52 -0
- package/dist/core/domain/entities/delta-operation.d.ts +31 -0
- package/dist/core/domain/entities/delta-operation.js +50 -0
- package/dist/core/domain/entities/event.d.ts +8 -0
- package/dist/core/domain/entities/event.js +15 -0
- package/dist/core/domain/entities/executor-output.d.ts +27 -0
- package/dist/core/domain/entities/executor-output.js +33 -0
- package/dist/core/domain/entities/memory.d.ts +55 -0
- package/dist/core/domain/entities/memory.js +90 -0
- package/dist/core/domain/entities/oauth-token-data.d.ts +13 -0
- package/dist/core/domain/entities/oauth-token-data.js +20 -0
- package/dist/core/domain/entities/playbook.d.ts +97 -0
- package/dist/core/domain/entities/playbook.js +275 -0
- package/dist/core/domain/entities/presigned-url.d.ts +9 -0
- package/dist/core/domain/entities/presigned-url.js +18 -0
- package/dist/core/domain/entities/presigned-urls-response.d.ts +10 -0
- package/dist/core/domain/entities/presigned-urls-response.js +18 -0
- package/dist/core/domain/entities/reflector-output.d.ts +38 -0
- package/dist/core/domain/entities/reflector-output.js +44 -0
- package/dist/core/domain/entities/retrieve-result.d.ts +35 -0
- package/dist/core/domain/entities/retrieve-result.js +35 -0
- package/dist/core/domain/entities/space.d.ts +24 -0
- package/dist/core/domain/entities/space.js +52 -0
- package/dist/core/domain/entities/team.d.ts +42 -0
- package/dist/core/domain/entities/team.js +89 -0
- package/dist/core/domain/entities/user.d.ts +20 -0
- package/dist/core/domain/entities/user.js +32 -0
- package/dist/core/domain/errors/ace-error.d.ts +34 -0
- package/dist/core/domain/errors/ace-error.js +53 -0
- package/dist/core/domain/errors/auth-error.d.ts +10 -0
- package/dist/core/domain/errors/auth-error.js +20 -0
- package/dist/core/domain/errors/discovery-error.d.ts +21 -0
- package/dist/core/domain/errors/discovery-error.js +33 -0
- package/dist/core/domain/errors/rule-error.d.ts +6 -0
- package/dist/core/domain/errors/rule-error.js +12 -0
- package/dist/core/interfaces/i-ace-prompt-builder.d.ts +48 -0
- package/dist/core/interfaces/i-ace-prompt-builder.js +1 -0
- package/dist/core/interfaces/i-auth-service.d.ts +35 -0
- package/dist/core/interfaces/i-auth-service.js +1 -0
- package/dist/core/interfaces/i-browser-launcher.d.ts +11 -0
- package/dist/core/interfaces/i-browser-launcher.js +1 -0
- package/dist/core/interfaces/i-bullet-content-store.d.ts +36 -0
- package/dist/core/interfaces/i-bullet-content-store.js +1 -0
- package/dist/core/interfaces/i-callback-handler.d.ts +35 -0
- package/dist/core/interfaces/i-callback-handler.js +1 -0
- package/dist/core/interfaces/i-delta-store.d.ts +15 -0
- package/dist/core/interfaces/i-delta-store.js +1 -0
- package/dist/core/interfaces/i-executor-output-store.d.ts +14 -0
- package/dist/core/interfaces/i-executor-output-store.js +1 -0
- package/dist/core/interfaces/i-file-service.d.ts +34 -0
- package/dist/core/interfaces/i-file-service.js +1 -0
- package/dist/core/interfaces/i-http-client.d.ts +33 -0
- package/dist/core/interfaces/i-http-client.js +1 -0
- package/dist/core/interfaces/i-memory-retrieval-service.d.ts +40 -0
- package/dist/core/interfaces/i-memory-retrieval-service.js +1 -0
- package/dist/core/interfaces/i-memory-storage-service.d.ts +55 -0
- package/dist/core/interfaces/i-memory-storage-service.js +1 -0
- package/dist/core/interfaces/i-oidc-discovery-service.d.ts +20 -0
- package/dist/core/interfaces/i-oidc-discovery-service.js +1 -0
- package/dist/core/interfaces/i-playbook-service.d.ts +69 -0
- package/dist/core/interfaces/i-playbook-service.js +1 -0
- package/dist/core/interfaces/i-playbook-store.d.ts +38 -0
- package/dist/core/interfaces/i-playbook-store.js +1 -0
- package/dist/core/interfaces/i-project-config-store.d.ts +26 -0
- package/dist/core/interfaces/i-project-config-store.js +1 -0
- package/dist/core/interfaces/i-reflection-store.d.ts +21 -0
- package/dist/core/interfaces/i-reflection-store.js +1 -0
- package/dist/core/interfaces/i-rule-template-service.d.ts +17 -0
- package/dist/core/interfaces/i-rule-template-service.js +4 -0
- package/dist/core/interfaces/i-rule-writer-service.d.ts +13 -0
- package/dist/core/interfaces/i-rule-writer-service.js +1 -0
- package/dist/core/interfaces/i-space-service.d.ts +28 -0
- package/dist/core/interfaces/i-space-service.js +1 -0
- package/dist/core/interfaces/i-team-service.d.ts +29 -0
- package/dist/core/interfaces/i-team-service.js +1 -0
- package/dist/core/interfaces/i-template-loader.d.ts +29 -0
- package/dist/core/interfaces/i-template-loader.js +1 -0
- package/dist/core/interfaces/i-token-store.d.ts +22 -0
- package/dist/core/interfaces/i-token-store.js +1 -0
- package/dist/core/interfaces/i-tracking-service.d.ts +21 -0
- package/dist/core/interfaces/i-tracking-service.js +1 -0
- package/dist/core/interfaces/i-user-service.d.ts +14 -0
- package/dist/core/interfaces/i-user-service.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/ace/ace-file-utils.d.ts +46 -0
- package/dist/infra/ace/ace-file-utils.js +83 -0
- package/dist/infra/ace/ace-prompt-templates.d.ts +13 -0
- package/dist/infra/ace/ace-prompt-templates.js +177 -0
- package/dist/infra/ace/file-bullet-content-store.d.ts +27 -0
- package/dist/infra/ace/file-bullet-content-store.js +89 -0
- package/dist/infra/ace/file-delta-store.d.ts +9 -0
- package/dist/infra/ace/file-delta-store.js +26 -0
- package/dist/infra/ace/file-executor-output-store.d.ts +9 -0
- package/dist/infra/ace/file-executor-output-store.js +26 -0
- package/dist/infra/ace/file-playbook-store.d.ts +29 -0
- package/dist/infra/ace/file-playbook-store.js +107 -0
- package/dist/infra/ace/file-reflection-store.d.ts +10 -0
- package/dist/infra/ace/file-reflection-store.js +55 -0
- package/dist/infra/auth/oauth-service.d.ts +49 -0
- package/dist/infra/auth/oauth-service.js +126 -0
- package/dist/infra/auth/oidc-discovery-service.d.ts +51 -0
- package/dist/infra/auth/oidc-discovery-service.js +145 -0
- package/dist/infra/browser/system-browser-launcher.d.ts +10 -0
- package/dist/infra/browser/system-browser-launcher.js +18 -0
- package/dist/infra/config/file-config-store.d.ts +21 -0
- package/dist/infra/config/file-config-store.js +57 -0
- package/dist/infra/file/fs-file-service.d.ts +28 -0
- package/dist/infra/file/fs-file-service.js +57 -0
- package/dist/infra/http/authenticated-http-client.d.ts +46 -0
- package/dist/infra/http/authenticated-http-client.js +99 -0
- package/dist/infra/http/callback-handler.d.ts +13 -0
- package/dist/infra/http/callback-handler.js +24 -0
- package/dist/infra/http/callback-server.d.ts +18 -0
- package/dist/infra/http/callback-server.js +93 -0
- package/dist/infra/memory/http-memory-retrieval-service.d.ts +18 -0
- package/dist/infra/memory/http-memory-retrieval-service.js +63 -0
- package/dist/infra/memory/http-memory-storage-service.d.ts +18 -0
- package/dist/infra/memory/http-memory-storage-service.js +67 -0
- package/dist/infra/memory/memory-to-playbook-mapper.d.ts +33 -0
- package/dist/infra/memory/memory-to-playbook-mapper.js +51 -0
- package/dist/infra/playbook/file-playbook-service.d.ts +43 -0
- package/dist/infra/playbook/file-playbook-service.js +133 -0
- package/dist/infra/rule/agent-rule-config.d.ts +19 -0
- package/dist/infra/rule/agent-rule-config.js +77 -0
- package/dist/infra/rule/rule-template-service.d.ts +18 -0
- package/dist/infra/rule/rule-template-service.js +80 -0
- package/dist/infra/rule/rule-writer-service.d.ts +19 -0
- package/dist/infra/rule/rule-writer-service.js +43 -0
- package/dist/infra/space/http-space-service.d.ts +20 -0
- package/dist/infra/space/http-space-service.js +67 -0
- package/dist/infra/storage/keychain-token-store.d.ts +10 -0
- package/dist/infra/storage/keychain-token-store.js +40 -0
- package/dist/infra/team/http-team-service.d.ts +21 -0
- package/dist/infra/team/http-team-service.js +71 -0
- package/dist/infra/template/fs-template-loader.d.ts +33 -0
- package/dist/infra/template/fs-template-loader.js +62 -0
- package/dist/infra/tracking/mixpanel-tracking-service.d.ts +14 -0
- package/dist/infra/tracking/mixpanel-tracking-service.js +44 -0
- package/dist/infra/user/http-user-service.d.ts +12 -0
- package/dist/infra/user/http-user-service.js +26 -0
- package/dist/templates/README.md +103 -0
- package/dist/templates/base.md +3 -0
- package/dist/templates/sections/command-reference.md +141 -0
- package/dist/templates/sections/workflow.md +46 -0
- package/dist/utils/file-helpers.d.ts +15 -0
- package/dist/utils/file-helpers.js +45 -0
- package/oclif.manifest.json +476 -0
- 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
|
+
}
|