codevf 1.0.0 → 1.0.2
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/LICENSE +30 -21
- package/README.md +7 -2
- package/bin/codevf-mcp.js +11 -0
- package/dist/commands/fix.d.ts +5 -1
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +170 -13
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +72 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp-tools.d.ts +17 -0
- package/dist/commands/mcp-tools.d.ts.map +1 -0
- package/dist/commands/mcp-tools.js +237 -0
- package/dist/commands/mcp-tools.js.map +1 -0
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +250 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/welcome.d.ts +9 -0
- package/dist/commands/welcome.d.ts.map +1 -0
- package/dist/commands/welcome.js +175 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/index.js +263 -207
- package/dist/index.js.map +1 -1
- package/dist/lib/api/client.d.ts +28 -0
- package/dist/lib/api/client.d.ts.map +1 -0
- package/dist/lib/api/client.js +66 -0
- package/dist/lib/api/client.js.map +1 -0
- package/dist/lib/api/projects.d.ts +32 -0
- package/dist/lib/api/projects.d.ts.map +1 -0
- package/dist/lib/api/projects.js +61 -0
- package/dist/lib/api/projects.js.map +1 -0
- package/dist/lib/api/tasks.d.ts +36 -0
- package/dist/lib/api/tasks.d.ts.map +1 -0
- package/dist/lib/api/tasks.js +62 -0
- package/dist/lib/api/tasks.js.map +1 -0
- package/dist/lib/api/websocket.d.ts +50 -0
- package/dist/lib/api/websocket.d.ts.map +1 -0
- package/dist/lib/api/websocket.js +153 -0
- package/dist/lib/api/websocket.js.map +1 -0
- package/dist/lib/auth/oauth-flow.d.ts +37 -0
- package/dist/lib/auth/oauth-flow.d.ts.map +1 -0
- package/dist/lib/auth/oauth-flow.js +119 -0
- package/dist/lib/auth/oauth-flow.js.map +1 -0
- package/dist/lib/auth/token-manager.d.ts +26 -0
- package/dist/lib/auth/token-manager.d.ts.map +1 -0
- package/dist/lib/auth/token-manager.js +87 -0
- package/dist/lib/auth/token-manager.js.map +1 -0
- package/dist/lib/config/manager.d.ts +50 -0
- package/dist/lib/config/manager.d.ts.map +1 -0
- package/dist/lib/config/manager.js +84 -0
- package/dist/lib/config/manager.js.map +1 -0
- package/dist/lib/utils/errors.d.ts +28 -0
- package/dist/lib/utils/errors.d.ts.map +1 -0
- package/dist/lib/utils/errors.js +44 -0
- package/dist/lib/utils/errors.js.map +1 -0
- package/dist/lib/utils/logger.d.ts +20 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/dist/lib/utils/logger.js +40 -0
- package/dist/lib/utils/logger.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +160 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools/chat.d.ts +30 -0
- package/dist/mcp/tools/chat.d.ts.map +1 -0
- package/dist/mcp/tools/chat.js +82 -0
- package/dist/mcp/tools/chat.js.map +1 -0
- package/dist/mcp/tools/instant.d.ts +38 -0
- package/dist/mcp/tools/instant.d.ts.map +1 -0
- package/dist/mcp/tools/instant.js +106 -0
- package/dist/mcp/tools/instant.js.map +1 -0
- package/dist/modules/aiAgent.d.ts +75 -0
- package/dist/modules/aiAgent.d.ts.map +1 -0
- package/dist/modules/aiAgent.js +707 -0
- package/dist/modules/aiAgent.js.map +1 -0
- package/dist/modules/api.d.ts +7 -0
- package/dist/modules/api.d.ts.map +1 -1
- package/dist/modules/api.js +13 -4
- package/dist/modules/api.js.map +1 -1
- package/dist/modules/commandHandler.d.ts +40 -0
- package/dist/modules/commandHandler.d.ts.map +1 -0
- package/dist/modules/commandHandler.js +328 -0
- package/dist/modules/commandHandler.js.map +1 -0
- package/dist/modules/config.d.ts +2 -0
- package/dist/modules/config.d.ts.map +1 -1
- package/dist/modules/config.js +9 -0
- package/dist/modules/config.js.map +1 -1
- package/dist/modules/constants.d.ts +83 -0
- package/dist/modules/constants.d.ts.map +1 -0
- package/dist/modules/constants.js +75 -0
- package/dist/modules/constants.js.map +1 -0
- package/dist/modules/permissions.d.ts +14 -0
- package/dist/modules/permissions.d.ts.map +1 -1
- package/dist/modules/permissions.js +94 -0
- package/dist/modules/permissions.js.map +1 -1
- package/dist/modules/toolRegistry.d.ts +50 -0
- package/dist/modules/toolRegistry.d.ts.map +1 -0
- package/dist/modules/toolRegistry.js +114 -0
- package/dist/modules/toolRegistry.js.map +1 -0
- package/dist/modules/tunnel.d.ts +33 -0
- package/dist/modules/tunnel.d.ts.map +1 -0
- package/dist/modules/tunnel.js +79 -0
- package/dist/modules/tunnel.js.map +1 -0
- package/dist/modules/vibeHelper.d.ts +16 -0
- package/dist/modules/vibeHelper.d.ts.map +1 -0
- package/dist/modules/vibeHelper.js +38 -0
- package/dist/modules/vibeHelper.js.map +1 -0
- package/dist/modules/websocket.d.ts +9 -0
- package/dist/modules/websocket.d.ts.map +1 -1
- package/dist/modules/websocket.js +70 -0
- package/dist/modules/websocket.js.map +1 -1
- package/dist/tools/consultEngineer.d.ts +13 -0
- package/dist/tools/consultEngineer.d.ts.map +1 -0
- package/dist/tools/consultEngineer.js +161 -0
- package/dist/tools/consultEngineer.js.map +1 -0
- package/dist/tools/realtimeChat.d.ts +9 -0
- package/dist/tools/realtimeChat.d.ts.map +1 -0
- package/dist/tools/realtimeChat.js +101 -0
- package/dist/tools/realtimeChat.js.map +1 -0
- package/dist/types/index.d.ts +183 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/ui/InteractiveApp.d.ts +13 -0
- package/dist/ui/InteractiveApp.d.ts.map +1 -0
- package/dist/ui/InteractiveApp.js +84 -0
- package/dist/ui/InteractiveApp.js.map +1 -0
- package/dist/ui/InteractivePrompt.d.ts +53 -0
- package/dist/ui/InteractivePrompt.d.ts.map +1 -0
- package/dist/ui/InteractivePrompt.js +422 -0
- package/dist/ui/InteractivePrompt.js.map +1 -0
- package/dist/ui/LiveSession.d.ts +2 -0
- package/dist/ui/LiveSession.d.ts.map +1 -1
- package/dist/ui/LiveSession.js +461 -180
- package/dist/ui/LiveSession.js.map +1 -1
- package/dist/ui/PromptInput.d.ts +14 -0
- package/dist/ui/PromptInput.d.ts.map +1 -0
- package/dist/ui/PromptInput.js +206 -0
- package/dist/ui/PromptInput.js.map +1 -0
- package/dist/ui/SessionUI.d.ts +40 -0
- package/dist/ui/SessionUI.d.ts.map +1 -0
- package/dist/ui/SessionUI.js +218 -0
- package/dist/ui/SessionUI.js.map +1 -0
- package/dist/ui/input/Command.d.ts +22 -0
- package/dist/ui/input/Command.d.ts.map +1 -0
- package/dist/ui/input/Command.js +30 -0
- package/dist/ui/input/Command.js.map +1 -0
- package/dist/ui/input/CustomInput.d.ts +15 -0
- package/dist/ui/input/CustomInput.d.ts.map +1 -0
- package/dist/ui/input/CustomInput.js +182 -0
- package/dist/ui/input/CustomInput.js.map +1 -0
- package/dist/ui/input/handlers/handleCursor.d.ts +22 -0
- package/dist/ui/input/handlers/handleCursor.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleCursor.js +53 -0
- package/dist/ui/input/handlers/handleCursor.js.map +1 -0
- package/dist/ui/input/handlers/handleEdit.d.ts +18 -0
- package/dist/ui/input/handlers/handleEdit.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleEdit.js +55 -0
- package/dist/ui/input/handlers/handleEdit.js.map +1 -0
- package/dist/ui/input/handlers/handleHistory.d.ts +18 -0
- package/dist/ui/input/handlers/handleHistory.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleHistory.js +85 -0
- package/dist/ui/input/handlers/handleHistory.js.map +1 -0
- package/dist/ui/input/handlers/handlePaste.d.ts +19 -0
- package/dist/ui/input/handlers/handlePaste.d.ts.map +1 -0
- package/dist/ui/input/handlers/handlePaste.js +49 -0
- package/dist/ui/input/handlers/handlePaste.js.map +1 -0
- package/dist/ui/input/handlers/handleSubmit.d.ts +18 -0
- package/dist/ui/input/handlers/handleSubmit.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleSubmit.js +39 -0
- package/dist/ui/input/handlers/handleSubmit.js.map +1 -0
- package/dist/ui/input/helpers.d.ts +4 -0
- package/dist/ui/input/helpers.d.ts.map +1 -0
- package/dist/ui/input/helpers.js +13 -0
- package/dist/ui/input/helpers.js.map +1 -0
- package/dist/ui/input/keyMatchers.d.ts +14 -0
- package/dist/ui/input/keyMatchers.d.ts.map +1 -0
- package/dist/ui/input/keyMatchers.js +49 -0
- package/dist/ui/input/keyMatchers.js.map +1 -0
- package/dist/ui/input/types.d.ts +33 -0
- package/dist/ui/input/types.d.ts.map +1 -0
- package/dist/ui/input/types.js +2 -0
- package/dist/ui/input/types.js.map +1 -0
- package/dist/ui/promptWithModes.d.ts +12 -0
- package/dist/ui/promptWithModes.d.ts.map +1 -0
- package/dist/ui/promptWithModes.js +24 -0
- package/dist/ui/promptWithModes.js.map +1 -0
- package/dist/ui/renderPrompt.d.ts +12 -0
- package/dist/ui/renderPrompt.d.ts.map +1 -0
- package/dist/ui/renderPrompt.js +14 -0
- package/dist/ui/renderPrompt.js.map +1 -0
- package/dist/ui/simplePrompt.d.ts +7 -0
- package/dist/ui/simplePrompt.d.ts.map +1 -0
- package/dist/ui/simplePrompt.js +38 -0
- package/dist/ui/simplePrompt.js.map +1 -0
- package/dist/ui/spinner.d.ts +7 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +13 -0
- package/dist/ui/spinner.js.map +1 -0
- package/package.json +36 -26
- package/ARCHITECTURE.md +0 -285
- package/BUILD_SUMMARY.md +0 -340
- package/QUICKSTART.md +0 -180
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client with automatic authentication
|
|
3
|
+
*/
|
|
4
|
+
import { NetworkError } from '../utils/errors.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
export class ApiClient {
|
|
7
|
+
constructor(baseUrl, tokenManager) {
|
|
8
|
+
this.baseUrl = baseUrl;
|
|
9
|
+
this.tokenManager = tokenManager;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Make authenticated request
|
|
13
|
+
*/
|
|
14
|
+
async request(path, options = {}) {
|
|
15
|
+
const token = await this.tokenManager.getValidToken();
|
|
16
|
+
const url = `${this.baseUrl}${path}`;
|
|
17
|
+
const headers = {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
Authorization: `Bearer ${token}`,
|
|
20
|
+
...options.headers,
|
|
21
|
+
};
|
|
22
|
+
logger.debug('API request', { method: options.method || 'GET', url });
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch(url, {
|
|
25
|
+
...options,
|
|
26
|
+
headers,
|
|
27
|
+
});
|
|
28
|
+
const data = (await response.json());
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
logger.warn('API request failed', {
|
|
31
|
+
status: response.status,
|
|
32
|
+
error: data.error,
|
|
33
|
+
});
|
|
34
|
+
if (response.status === 401) {
|
|
35
|
+
throw new NetworkError('Authentication failed. Please run: codevf setup');
|
|
36
|
+
}
|
|
37
|
+
throw new NetworkError(data.error || `Request failed: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
logger.debug('API response', { success: data.success });
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof NetworkError) {
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
logger.error('API request error', error);
|
|
47
|
+
throw new NetworkError(`Request failed: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* GET request
|
|
52
|
+
*/
|
|
53
|
+
async get(path) {
|
|
54
|
+
return this.request(path, { method: 'GET' });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* POST request
|
|
58
|
+
*/
|
|
59
|
+
async post(path, body) {
|
|
60
|
+
return this.request(path, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/lib/api/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAS5C,MAAM,OAAO,SAAS;IAIpB,YAAY,OAAe,EAAE,YAA0B;QACrD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CACX,IAAY,EACZ,UAAuB,EAAE;QAEzB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QAEtD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,GAAG,OAAO,CAAC,OAAO;SACnB,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,GAAG,OAAO;gBACV,OAAO;aACR,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;YAEvD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAChC,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB,CAAC,CAAC;gBAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,IAAI,YAAY,CACpB,iDAAiD,CAClD,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,mBAAmB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;gBAClC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YACzC,MAAM,IAAI,YAAY,CAAC,mBAAoB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAU,IAAY;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAU,IAAY,EAAE,IAAU;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAI,IAAI,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9C,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects API wrapper for CodeVF-CLI
|
|
3
|
+
*/
|
|
4
|
+
import { ApiClient } from './client.js';
|
|
5
|
+
export interface Project {
|
|
6
|
+
id: number;
|
|
7
|
+
repoUrl: string;
|
|
8
|
+
problemDescription: string | null;
|
|
9
|
+
status: string;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CreateProjectOptions {
|
|
13
|
+
repoUrl: string;
|
|
14
|
+
problemDescription?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class ProjectsApi {
|
|
17
|
+
private client;
|
|
18
|
+
constructor(client: ApiClient);
|
|
19
|
+
/**
|
|
20
|
+
* List all projects for the authenticated user
|
|
21
|
+
*/
|
|
22
|
+
list(): Promise<Project[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Create a new project
|
|
25
|
+
*/
|
|
26
|
+
create(options: CreateProjectOptions): Promise<Project>;
|
|
27
|
+
/**
|
|
28
|
+
* Get or create a default project for instant queries
|
|
29
|
+
*/
|
|
30
|
+
getOrCreateDefault(): Promise<Project>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/lib/api/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IAI7B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAchC;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB7D;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;CAkB7C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects API wrapper for CodeVF-CLI
|
|
3
|
+
*/
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export class ProjectsApi {
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* List all projects for the authenticated user
|
|
11
|
+
*/
|
|
12
|
+
async list() {
|
|
13
|
+
logger.debug('Fetching projects list');
|
|
14
|
+
const response = await this.client.get('/api/cli/projects');
|
|
15
|
+
if (!response.success) {
|
|
16
|
+
throw new Error(response.error || 'Failed to fetch projects');
|
|
17
|
+
}
|
|
18
|
+
const projects = response.projects || [];
|
|
19
|
+
logger.info('Projects fetched', { count: projects.length });
|
|
20
|
+
return projects;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a new project
|
|
24
|
+
*/
|
|
25
|
+
async create(options) {
|
|
26
|
+
logger.info('Creating project', { repoUrl: options.repoUrl });
|
|
27
|
+
const response = await this.client.post('/api/cli/projects', {
|
|
28
|
+
repoUrl: options.repoUrl,
|
|
29
|
+
problemDescription: options.problemDescription || null,
|
|
30
|
+
});
|
|
31
|
+
if (!response.success) {
|
|
32
|
+
throw new Error(response.error || 'Failed to create project');
|
|
33
|
+
}
|
|
34
|
+
const project = response.project;
|
|
35
|
+
if (!project) {
|
|
36
|
+
throw new Error('No project returned from API');
|
|
37
|
+
}
|
|
38
|
+
logger.info('Project created', { projectId: project.id });
|
|
39
|
+
return project;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get or create a default project for instant queries
|
|
43
|
+
*/
|
|
44
|
+
async getOrCreateDefault() {
|
|
45
|
+
// Try to get existing projects
|
|
46
|
+
const projects = await this.list();
|
|
47
|
+
if (projects.length > 0) {
|
|
48
|
+
// Use the most recent project
|
|
49
|
+
const project = projects[0];
|
|
50
|
+
logger.info('Using existing project', { projectId: project.id });
|
|
51
|
+
return project;
|
|
52
|
+
}
|
|
53
|
+
// No projects exist, create a default one
|
|
54
|
+
logger.info('No projects found, creating default project');
|
|
55
|
+
return await this.create({
|
|
56
|
+
repoUrl: 'CodeVF Instant Queries',
|
|
57
|
+
problemDescription: 'Default project for quick questions and instant answers',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../src/lib/api/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAe5C,MAAM,OAAO,WAAW;IAGtB,YAAY,MAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAEvC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAA0B,mBAAmB,CAAC,CAAC;QAErF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,QAAQ,GAAI,QAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5D,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAA6B;QACxC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAuB,mBAAmB,EAAE;YACjF,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,IAAI;SACvD,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,0BAA0B,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,OAAO,GAAI,QAAgB,CAAC,OAAO,CAAC;QAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB;QACtB,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,8BAA8B;YAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACjE,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,0CAA0C;QAC1C,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,wBAAwB;YACjC,kBAAkB,EAAE,yDAAyD;SAC9E,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task creation and management API wrapper
|
|
3
|
+
*/
|
|
4
|
+
import { ApiClient } from './client.js';
|
|
5
|
+
export type TaskMode = 'realtime_answer' | 'realtime_chat' | 'fast' | 'standard';
|
|
6
|
+
export interface CreateTaskOptions {
|
|
7
|
+
message: string;
|
|
8
|
+
taskMode: TaskMode;
|
|
9
|
+
maxCredits: number;
|
|
10
|
+
projectId?: string;
|
|
11
|
+
contextData?: any;
|
|
12
|
+
initiatedBy?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface CreateTaskResult {
|
|
15
|
+
taskId: string;
|
|
16
|
+
actionId: number;
|
|
17
|
+
estimatedWaitTime: number;
|
|
18
|
+
creditsRemaining: number;
|
|
19
|
+
maxCreditsAllocated: number;
|
|
20
|
+
warning?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class TasksApi {
|
|
23
|
+
private client;
|
|
24
|
+
private baseUrl;
|
|
25
|
+
private defaultProjectId;
|
|
26
|
+
constructor(client: ApiClient, baseUrl: string, defaultProjectId?: string);
|
|
27
|
+
/**
|
|
28
|
+
* Create a new task
|
|
29
|
+
*/
|
|
30
|
+
create(options: CreateTaskOptions): Promise<CreateTaskResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Get task status
|
|
33
|
+
*/
|
|
34
|
+
getStatus(taskId: string): Promise<any>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/lib/api/tasks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,MAAM,MAAM,QAAQ,GAAG,iBAAiB,GAAG,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAAS;gBAErB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAMzE;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyCnE;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAU9C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task creation and management API wrapper
|
|
3
|
+
*/
|
|
4
|
+
import { InsufficientCreditsError } from '../utils/errors.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
export class TasksApi {
|
|
7
|
+
constructor(client, baseUrl, defaultProjectId) {
|
|
8
|
+
this.client = client;
|
|
9
|
+
this.baseUrl = baseUrl;
|
|
10
|
+
this.defaultProjectId = defaultProjectId || '1'; // Default project ID
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a new task
|
|
14
|
+
*/
|
|
15
|
+
async create(options) {
|
|
16
|
+
logger.info('Creating task', {
|
|
17
|
+
mode: options.taskMode,
|
|
18
|
+
maxCredits: options.maxCredits,
|
|
19
|
+
});
|
|
20
|
+
const response = await this.client.post('/api/cli/tasks/create', {
|
|
21
|
+
issueDescription: options.message,
|
|
22
|
+
taskMode: options.taskMode,
|
|
23
|
+
maxCredits: options.maxCredits,
|
|
24
|
+
projectId: options.projectId || this.defaultProjectId,
|
|
25
|
+
contextData: options.contextData ? JSON.stringify(options.contextData) : null,
|
|
26
|
+
initiatedBy: options.initiatedBy || 'ai_tool',
|
|
27
|
+
autoApproveCommands: false,
|
|
28
|
+
});
|
|
29
|
+
if (!response.success || !response.data) {
|
|
30
|
+
// Check for credit errors
|
|
31
|
+
if (response.error?.includes('No credits available')) {
|
|
32
|
+
const pricingUrl = `${this.baseUrl}/pricing`;
|
|
33
|
+
throw new InsufficientCreditsError(0, options.maxCredits, pricingUrl);
|
|
34
|
+
}
|
|
35
|
+
throw new Error(response.error || 'Failed to create task');
|
|
36
|
+
}
|
|
37
|
+
logger.info('Task created', {
|
|
38
|
+
taskId: response.data.taskId,
|
|
39
|
+
actionId: response.data.actionId,
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
taskId: response.data.taskId,
|
|
43
|
+
actionId: response.data.actionId,
|
|
44
|
+
estimatedWaitTime: response.data.estimatedWaitTime,
|
|
45
|
+
creditsRemaining: response.data.creditsRemaining,
|
|
46
|
+
maxCreditsAllocated: response.data.maxCreditsAllocated,
|
|
47
|
+
warning: response.warning,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get task status
|
|
52
|
+
*/
|
|
53
|
+
async getStatus(taskId) {
|
|
54
|
+
logger.debug('Getting task status', { taskId });
|
|
55
|
+
const response = await this.client.get(`/api/cli/tasks/${taskId}/status`);
|
|
56
|
+
if (!response.success) {
|
|
57
|
+
throw new Error(response.error || 'Failed to get task status');
|
|
58
|
+
}
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/lib/api/tasks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAsB5C,MAAM,OAAO,QAAQ;IAKnB,YAAY,MAAiB,EAAE,OAAe,EAAE,gBAAyB;QACvE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,IAAI,GAAG,CAAC,CAAC,qBAAqB;IACxE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAA0B;QACrC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE;YAC3B,IAAI,EAAE,OAAO,CAAC,QAAQ;YACtB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE;YAC/D,gBAAgB,EAAE,OAAO,CAAC,OAAO;YACjC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,gBAAgB;YACrD,WAAW,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;YAC7E,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;YAC7C,mBAAmB,EAAE,KAAK;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,0BAA0B;YAC1B,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBACrD,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,OAAO,UAAU,CAAC;gBAC7C,MAAM,IAAI,wBAAwB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACxE,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;YAC1B,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;YAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ;SACjC,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;YAC5B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ;YAChC,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB;YAClD,gBAAgB,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB;YAChD,mBAAmB,EAAE,QAAQ,CAAC,IAAI,CAAC,mBAAmB;YACtD,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,MAAM,SAAS,CAAC,CAAC;QAE1E,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket client with reconnection support
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
export interface WebSocketMessage {
|
|
6
|
+
type: string;
|
|
7
|
+
timestamp?: string;
|
|
8
|
+
payload: any;
|
|
9
|
+
}
|
|
10
|
+
export interface EngineerMessage {
|
|
11
|
+
text: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
}
|
|
14
|
+
export interface BillingUpdate {
|
|
15
|
+
creditsUsed: number;
|
|
16
|
+
duration: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class WebSocketClient extends EventEmitter {
|
|
19
|
+
private ws;
|
|
20
|
+
private url;
|
|
21
|
+
private reconnectAttempts;
|
|
22
|
+
private maxReconnectAttempts;
|
|
23
|
+
private isClosedManually;
|
|
24
|
+
constructor(url: string);
|
|
25
|
+
/**
|
|
26
|
+
* Connect to WebSocket server
|
|
27
|
+
*/
|
|
28
|
+
connect(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Send message to server
|
|
31
|
+
*/
|
|
32
|
+
send(message: WebSocketMessage): void;
|
|
33
|
+
/**
|
|
34
|
+
* Disconnect from server
|
|
35
|
+
*/
|
|
36
|
+
disconnect(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Attempt reconnection with exponential backoff
|
|
39
|
+
*/
|
|
40
|
+
private attemptReconnect;
|
|
41
|
+
/**
|
|
42
|
+
* Wait for engineer response with timeout
|
|
43
|
+
*/
|
|
44
|
+
waitForResponse(timeoutMs?: number): Promise<{
|
|
45
|
+
text: string;
|
|
46
|
+
creditsUsed: number;
|
|
47
|
+
duration: string;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../../src/lib/api/websocket.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,GAAG,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,gBAAgB,CAAS;gBAErB,GAAG,EAAE,MAAM;IAKvB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD9B;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IASrC;;OAEG;IACH,UAAU,IAAI,IAAI;IAWlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACG,eAAe,CAAC,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC;QACzD,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CAgDH"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket client with reconnection support
|
|
3
|
+
*/
|
|
4
|
+
import WebSocket from 'ws';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { SessionError, TimeoutError } from '../utils/errors.js';
|
|
7
|
+
import { logger } from '../utils/logger.js';
|
|
8
|
+
export class WebSocketClient extends EventEmitter {
|
|
9
|
+
constructor(url) {
|
|
10
|
+
super();
|
|
11
|
+
this.ws = null;
|
|
12
|
+
this.reconnectAttempts = 0;
|
|
13
|
+
this.maxReconnectAttempts = 5;
|
|
14
|
+
this.isClosedManually = false;
|
|
15
|
+
this.url = url;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Connect to WebSocket server
|
|
19
|
+
*/
|
|
20
|
+
async connect() {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
logger.info('Connecting to WebSocket', { url: this.url });
|
|
23
|
+
this.ws = new WebSocket(this.url);
|
|
24
|
+
this.ws.on('open', () => {
|
|
25
|
+
logger.info('WebSocket connected');
|
|
26
|
+
this.reconnectAttempts = 0;
|
|
27
|
+
this.emit('connected');
|
|
28
|
+
resolve();
|
|
29
|
+
});
|
|
30
|
+
this.ws.on('message', (data) => {
|
|
31
|
+
try {
|
|
32
|
+
const message = JSON.parse(data.toString());
|
|
33
|
+
logger.debug('Received message', { type: message.type });
|
|
34
|
+
// Emit specific events based on message type
|
|
35
|
+
switch (message.type) {
|
|
36
|
+
case 'engineer_message':
|
|
37
|
+
this.emit('engineer_message', message.payload);
|
|
38
|
+
break;
|
|
39
|
+
case 'billing_update':
|
|
40
|
+
this.emit('billing_update', message.payload);
|
|
41
|
+
break;
|
|
42
|
+
case 'closure_request':
|
|
43
|
+
this.emit('closure_request', message.payload);
|
|
44
|
+
break;
|
|
45
|
+
case 'engineer_connected':
|
|
46
|
+
this.emit('engineer_connected');
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
this.emit('message', message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
logger.error('Failed to parse message', error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
this.ws.on('close', () => {
|
|
57
|
+
logger.info('WebSocket closed');
|
|
58
|
+
this.emit('disconnected');
|
|
59
|
+
if (!this.isClosedManually && this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
60
|
+
this.attemptReconnect();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
this.ws.on('error', (error) => {
|
|
64
|
+
logger.error('WebSocket error', error);
|
|
65
|
+
this.emit('error', error);
|
|
66
|
+
reject(new SessionError(`WebSocket error: ${error.message}`));
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Send message to server
|
|
72
|
+
*/
|
|
73
|
+
send(message) {
|
|
74
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
75
|
+
throw new SessionError('WebSocket not connected');
|
|
76
|
+
}
|
|
77
|
+
logger.debug('Sending message', { type: message.type });
|
|
78
|
+
this.ws.send(JSON.stringify(message));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Disconnect from server
|
|
82
|
+
*/
|
|
83
|
+
disconnect() {
|
|
84
|
+
this.isClosedManually = true;
|
|
85
|
+
if (this.ws) {
|
|
86
|
+
this.ws.close();
|
|
87
|
+
this.ws = null;
|
|
88
|
+
}
|
|
89
|
+
logger.info('WebSocket disconnected manually');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Attempt reconnection with exponential backoff
|
|
93
|
+
*/
|
|
94
|
+
attemptReconnect() {
|
|
95
|
+
this.reconnectAttempts++;
|
|
96
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 10000);
|
|
97
|
+
logger.info('Attempting reconnection', {
|
|
98
|
+
attempt: this.reconnectAttempts,
|
|
99
|
+
maxAttempts: this.maxReconnectAttempts,
|
|
100
|
+
delay,
|
|
101
|
+
});
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
this.connect().catch((error) => {
|
|
104
|
+
logger.error('Reconnection failed', error);
|
|
105
|
+
});
|
|
106
|
+
}, delay);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Wait for engineer response with timeout
|
|
110
|
+
*/
|
|
111
|
+
async waitForResponse(timeoutMs = 300000) {
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
let responseText = '';
|
|
114
|
+
let creditsUsed = 0;
|
|
115
|
+
const startTime = Date.now();
|
|
116
|
+
const onEngineerMessage = (msg) => {
|
|
117
|
+
responseText += msg.text + '\n';
|
|
118
|
+
};
|
|
119
|
+
const onBillingUpdate = (update) => {
|
|
120
|
+
creditsUsed = update.creditsUsed;
|
|
121
|
+
};
|
|
122
|
+
const onClosureRequest = () => {
|
|
123
|
+
cleanup();
|
|
124
|
+
const duration = Math.ceil((Date.now() - startTime) / 60000);
|
|
125
|
+
resolve({
|
|
126
|
+
text: responseText.trim(),
|
|
127
|
+
creditsUsed,
|
|
128
|
+
duration: `${duration} min`,
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const onError = (error) => {
|
|
132
|
+
cleanup();
|
|
133
|
+
reject(new SessionError(`WebSocket error: ${error.message}`));
|
|
134
|
+
};
|
|
135
|
+
const cleanup = () => {
|
|
136
|
+
this.off('engineer_message', onEngineerMessage);
|
|
137
|
+
this.off('billing_update', onBillingUpdate);
|
|
138
|
+
this.off('closure_request', onClosureRequest);
|
|
139
|
+
this.off('error', onError);
|
|
140
|
+
clearTimeout(timeoutHandle);
|
|
141
|
+
};
|
|
142
|
+
this.on('engineer_message', onEngineerMessage);
|
|
143
|
+
this.on('billing_update', onBillingUpdate);
|
|
144
|
+
this.on('closure_request', onClosureRequest);
|
|
145
|
+
this.on('error', onError);
|
|
146
|
+
const timeoutHandle = setTimeout(() => {
|
|
147
|
+
cleanup();
|
|
148
|
+
reject(new TimeoutError('Timeout waiting for engineer response'));
|
|
149
|
+
}, timeoutMs);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../../src/lib/api/websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth polling flow for CLI authentication
|
|
3
|
+
*/
|
|
4
|
+
export interface OAuthPollResult {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
refreshToken: string;
|
|
7
|
+
expiresAt: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class OAuthFlow {
|
|
11
|
+
private baseUrl;
|
|
12
|
+
private clientType;
|
|
13
|
+
private maxPollAttempts;
|
|
14
|
+
private pollIntervalMs;
|
|
15
|
+
constructor(baseUrl: string, clientType?: string);
|
|
16
|
+
/**
|
|
17
|
+
* Initiate OAuth flow
|
|
18
|
+
*/
|
|
19
|
+
init(): Promise<{
|
|
20
|
+
pollToken: string;
|
|
21
|
+
authUrl: string;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Open authorization URL in browser
|
|
25
|
+
*/
|
|
26
|
+
openAuthUrl(authUrl: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Poll for authentication tokens
|
|
29
|
+
*/
|
|
30
|
+
poll(pollToken: string): Promise<OAuthPollResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Complete OAuth flow
|
|
33
|
+
*/
|
|
34
|
+
authenticate(): Promise<OAuthPollResult>;
|
|
35
|
+
private sleep;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=oauth-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oauth-flow.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,cAAc,CAAQ;gBAElB,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAc;IAKvD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAmC7D;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjD;;OAEG;IACG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA2DvD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAc9C,OAAO,CAAC,KAAK;CAGd"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth polling flow for CLI authentication
|
|
3
|
+
*/
|
|
4
|
+
import { AuthenticationError, NetworkError } from '../utils/errors.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
export class OAuthFlow {
|
|
7
|
+
constructor(baseUrl, clientType = 'cli') {
|
|
8
|
+
this.maxPollAttempts = 60; // 2 minutes (60 * 2 seconds)
|
|
9
|
+
this.pollIntervalMs = 2000; // 2 seconds
|
|
10
|
+
this.baseUrl = baseUrl;
|
|
11
|
+
this.clientType = clientType;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Initiate OAuth flow
|
|
15
|
+
*/
|
|
16
|
+
async init() {
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(`${this.baseUrl}/api/cli/auth/init`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: { 'Content-Type': 'application/json' },
|
|
21
|
+
body: JSON.stringify({ clientType: this.clientType }),
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(`Init failed: ${response.status}`);
|
|
25
|
+
}
|
|
26
|
+
const data = (await response.json());
|
|
27
|
+
if (!data.success || !data.data) {
|
|
28
|
+
throw new Error('Invalid init response');
|
|
29
|
+
}
|
|
30
|
+
logger.info('OAuth flow initiated', {
|
|
31
|
+
authUrl: data.data.authUrl,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
pollToken: data.data.pollToken,
|
|
35
|
+
authUrl: data.data.authUrl,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
logger.error('OAuth init failed', error);
|
|
40
|
+
throw new NetworkError(`Failed to initialize OAuth: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Open authorization URL in browser
|
|
45
|
+
*/
|
|
46
|
+
async openAuthUrl(authUrl) {
|
|
47
|
+
try {
|
|
48
|
+
// Dynamic import for ESM-only module
|
|
49
|
+
const open = (await import('open')).default;
|
|
50
|
+
await open(authUrl);
|
|
51
|
+
logger.info('Opened authorization URL in browser');
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
logger.warn('Failed to open browser automatically', error);
|
|
55
|
+
console.log(`\nPlease open this URL in your browser:\n${authUrl}\n`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Poll for authentication tokens
|
|
60
|
+
*/
|
|
61
|
+
async poll(pollToken) {
|
|
62
|
+
let attempts = 0;
|
|
63
|
+
while (attempts < this.maxPollAttempts) {
|
|
64
|
+
attempts++;
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(`${this.baseUrl}/api/cli/auth/token?pollToken=${pollToken}`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: { 'Content-Type': 'application/json' },
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
if (response.status === 404 || response.status === 400) {
|
|
72
|
+
// Still waiting for authorization
|
|
73
|
+
await this.sleep(this.pollIntervalMs);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Poll failed: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
const data = (await response.json());
|
|
79
|
+
if (!data.success || !data.data) {
|
|
80
|
+
// Still waiting
|
|
81
|
+
await this.sleep(this.pollIntervalMs);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// Success!
|
|
85
|
+
logger.info('Authentication successful');
|
|
86
|
+
return {
|
|
87
|
+
accessToken: data.data.accessToken,
|
|
88
|
+
refreshToken: data.data.refreshToken,
|
|
89
|
+
expiresAt: data.data.expiresAt,
|
|
90
|
+
userId: data.data.userId,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (attempts >= this.maxPollAttempts) {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
await this.sleep(this.pollIntervalMs);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
throw new AuthenticationError('Authentication timeout. Please try again.');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Complete OAuth flow
|
|
104
|
+
*/
|
|
105
|
+
async authenticate() {
|
|
106
|
+
// Step 1: Initialize
|
|
107
|
+
const { pollToken, authUrl } = await this.init();
|
|
108
|
+
// Step 2: Open browser
|
|
109
|
+
await this.openAuthUrl(authUrl);
|
|
110
|
+
console.log('\nWaiting for authorization...');
|
|
111
|
+
console.log('(Complete the authorization in your browser)\n');
|
|
112
|
+
// Step 3: Poll for tokens
|
|
113
|
+
return await this.poll(pollToken);
|
|
114
|
+
}
|
|
115
|
+
sleep(ms) {
|
|
116
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=oauth-flow.js.map
|