@codeguide/core 0.0.27 → 0.0.29

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 (92) hide show
  1. package/README.md +50 -41
  2. package/__tests__/services/codespace/codespace-v2.test.ts +29 -18
  3. package/__tests__/services/usage/usage-service.test.ts +597 -85
  4. package/codeguide.ts +6 -0
  5. package/dist/codeguide.d.ts +3 -1
  6. package/dist/codeguide.js +2 -0
  7. package/dist/index.d.ts +4 -3
  8. package/dist/services/base/base-service.d.ts +21 -0
  9. package/dist/services/base/base-service.js +114 -0
  10. package/dist/services/codespace/codespace-service.d.ts +55 -1
  11. package/dist/services/codespace/codespace-service.js +260 -5
  12. package/dist/services/codespace/codespace-types.d.ts +193 -13
  13. package/dist/services/codespace/index.d.ts +1 -1
  14. package/dist/services/index.d.ts +4 -0
  15. package/dist/services/index.js +7 -1
  16. package/dist/services/projects/project-types.d.ts +66 -32
  17. package/dist/services/repository-analysis/repository-types.d.ts +1 -0
  18. package/dist/services/starter-kits/index.d.ts +2 -0
  19. package/dist/services/starter-kits/index.js +20 -0
  20. package/dist/services/starter-kits/starter-kits-service.d.ts +13 -0
  21. package/dist/services/starter-kits/starter-kits-service.js +27 -0
  22. package/dist/services/starter-kits/starter-kits-types.d.ts +34 -0
  23. package/dist/services/starter-kits/starter-kits-types.js +2 -0
  24. package/dist/services/tasks/task-service.d.ts +2 -1
  25. package/dist/services/tasks/task-service.js +8 -0
  26. package/dist/services/tasks/task-types.d.ts +26 -7
  27. package/dist/services/usage/usage-service.d.ts +5 -2
  28. package/dist/services/usage/usage-service.js +58 -9
  29. package/dist/services/usage/usage-types.d.ts +207 -34
  30. package/dist/services/users/index.d.ts +2 -0
  31. package/dist/services/users/index.js +20 -0
  32. package/dist/services/users/user-service.d.ts +12 -0
  33. package/dist/services/users/user-service.js +17 -0
  34. package/dist/services/users/user-types.d.ts +55 -0
  35. package/dist/services/users/user-types.js +2 -0
  36. package/docs/.vitepress/README.md +51 -0
  37. package/docs/.vitepress/config.ts +139 -0
  38. package/docs/.vitepress/theme/custom.css +80 -0
  39. package/docs/.vitepress/theme/index.ts +13 -0
  40. package/docs/.vitepress/tsconfig.json +19 -0
  41. package/docs/QUICKSTART.md +77 -0
  42. package/docs/README.md +134 -0
  43. package/docs/README_SETUP.md +46 -0
  44. package/docs/authentication.md +351 -0
  45. package/docs/codeguide-client.md +350 -0
  46. package/docs/codespace-models.md +1004 -0
  47. package/docs/codespace-service.md +558 -81
  48. package/docs/index.md +135 -0
  49. package/docs/package.json +14 -0
  50. package/docs/projects-service.md +688 -0
  51. package/docs/security-keys-service.md +773 -0
  52. package/docs/starter-kits-service.md +249 -0
  53. package/docs/task-service.md +955 -0
  54. package/docs/testsprite_tests/TC001_Homepage_Load_and_Hero_Section_Display.py +70 -0
  55. package/docs/testsprite_tests/TC002_Sidebar_Navigation_ExpandCollapse_Functionality.py +73 -0
  56. package/docs/testsprite_tests/TC003_Full_Text_Local_Search_with_Keyboard_Shortcut.py +90 -0
  57. package/docs/testsprite_tests/TC004_Dark_Mode_Toggle_and_Persistence.py +73 -0
  58. package/docs/testsprite_tests/TC005_Mobile_Responsiveness_and_Touch_Navigation.py +113 -0
  59. package/docs/testsprite_tests/TC006_GitHub_Integration_Edit_this_page_Links.py +73 -0
  60. package/docs/testsprite_tests/TC007_Syntax_Highlighting_and_Code_Copy_Functionality.py +73 -0
  61. package/docs/testsprite_tests/TC008_Auto_Generated_Table_of_Contents_Accuracy.py +73 -0
  62. package/docs/testsprite_tests/TC009_SEO_and_Content_Discoverability_Verification.py +73 -0
  63. package/docs/testsprite_tests/TC010_Accessibility_Compliance_WCAG_AA.py +73 -0
  64. package/docs/testsprite_tests/TC011_Local_Development_Workflow_Build_and_Hot_Reload.py +74 -0
  65. package/docs/testsprite_tests/TC012_Performance_Metrics_Compliance.py +73 -0
  66. package/docs/testsprite_tests/standard_prd.json +122 -0
  67. package/docs/testsprite_tests/testsprite-mcp-test-report.html +2508 -0
  68. package/docs/testsprite_tests/testsprite-mcp-test-report.md +273 -0
  69. package/docs/testsprite_tests/testsprite_frontend_test_plan.json +390 -0
  70. package/docs/usage-service.md +616 -0
  71. package/index.ts +11 -3
  72. package/package.json +16 -2
  73. package/plans/CODESPACE_LOGS_STREAMING_GUIDE.md +320 -0
  74. package/plans/CODESPACE_TASK_LOGS_API_COMPLETE_GUIDE.md +821 -0
  75. package/services/base/base-service.ts +130 -0
  76. package/services/codespace/codespace-service.ts +347 -8
  77. package/services/codespace/codespace-types.ts +263 -14
  78. package/services/codespace/index.ts +16 -1
  79. package/services/index.ts +4 -0
  80. package/services/projects/README.md +107 -34
  81. package/services/projects/project-types.ts +69 -32
  82. package/services/repository-analysis/repository-types.ts +1 -0
  83. package/services/starter-kits/index.ts +2 -0
  84. package/services/starter-kits/starter-kits-service.ts +33 -0
  85. package/services/starter-kits/starter-kits-types.ts +38 -0
  86. package/services/tasks/task-service.ts +10 -0
  87. package/services/tasks/task-types.ts +29 -7
  88. package/services/usage/usage-service.ts +59 -10
  89. package/services/usage/usage-types.ts +239 -34
  90. package/services/users/index.ts +2 -0
  91. package/services/users/user-service.ts +15 -0
  92. package/services/users/user-types.ts +59 -0
package/codeguide.ts CHANGED
@@ -18,6 +18,8 @@ import {
18
18
  CodespaceService,
19
19
  ExternalTokenService,
20
20
  SecurityKeysService,
21
+ UserService,
22
+ StarterKitsService,
21
23
  } from './services'
22
24
  import { APIServiceConfig, CodeGuideOptions } from './types'
23
25
 
@@ -33,6 +35,8 @@ export class CodeGuide {
33
35
  public codespace: CodespaceService
34
36
  public externalTokens: ExternalTokenService
35
37
  public securityKeys: SecurityKeysService
38
+ public users: UserService
39
+ public starterKits: StarterKitsService
36
40
  private options: CodeGuideOptions
37
41
 
38
42
  constructor(config: APIServiceConfig, options: CodeGuideOptions = {}) {
@@ -50,6 +54,8 @@ export class CodeGuide {
50
54
  this.codespace = new CodespaceService(config)
51
55
  this.externalTokens = new ExternalTokenService(config)
52
56
  this.securityKeys = new SecurityKeysService(config)
57
+ this.users = new UserService(config)
58
+ this.starterKits = new StarterKitsService(config)
53
59
  }
54
60
 
55
61
  // Convenience method for backward compatibility
@@ -1,4 +1,4 @@
1
- import { GenerationService, ProjectService, UsageService, RepositoryAnalysisService, TaskService, ApiKeyEnhancedService, SubscriptionService, CancellationFunnelService, CodespaceService, ExternalTokenService, SecurityKeysService } from './services';
1
+ import { GenerationService, ProjectService, UsageService, RepositoryAnalysisService, TaskService, ApiKeyEnhancedService, SubscriptionService, CancellationFunnelService, CodespaceService, ExternalTokenService, SecurityKeysService, UserService, StarterKitsService } from './services';
2
2
  import { APIServiceConfig, CodeGuideOptions } from './types';
3
3
  export declare class CodeGuide {
4
4
  generation: GenerationService;
@@ -12,6 +12,8 @@ export declare class CodeGuide {
12
12
  codespace: CodespaceService;
13
13
  externalTokens: ExternalTokenService;
14
14
  securityKeys: SecurityKeysService;
15
+ users: UserService;
16
+ starterKits: StarterKitsService;
15
17
  private options;
16
18
  constructor(config: APIServiceConfig, options?: CodeGuideOptions);
17
19
  getGuidance(prompt: string): Promise<any>;
package/dist/codeguide.js CHANGED
@@ -27,6 +27,8 @@ class CodeGuide {
27
27
  this.codespace = new services_1.CodespaceService(config);
28
28
  this.externalTokens = new services_1.ExternalTokenService(config);
29
29
  this.securityKeys = new services_1.SecurityKeysService(config);
30
+ this.users = new services_1.UserService(config);
31
+ this.starterKits = new services_1.StarterKitsService(config);
30
32
  }
31
33
  // Convenience method for backward compatibility
32
34
  async getGuidance(prompt) {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { CodeGuide } from './codeguide';
2
2
  export * from './services';
3
3
  export * from './types';
4
- export type { ConnectRepositoryRequest, ConnectRepositoryResponse, ProjectRepository, GetProjectsRequest, PaginatedProjectsRequest, PaginatedProjectsResponse } from './services/projects/project-types';
5
- export type { CreateCodespaceTaskRequestV2 as CreateCodespaceTaskRequest, CreateCodespaceTaskResponseV2 as CreateCodespaceTaskResponse, CreateBackgroundCodespaceTaskRequest, CreateBackgroundCodespaceTaskResponse, ModelApiKey, Attachment, GetCodespaceTaskResponse, CodespaceTaskData, TechnicalDocument, GetProjectTasksByCodespaceResponse } from './services/codespace/codespace-types';
6
- export type { StoreExternalTokenRequest, StoreExternalTokenResponse, ListTokensQuery, ListTokensResponse, ValidateTokenRequest, ValidateTokenResponse, FindBestMatchRequest, FindBestMatchResponse, Platform, TokenType } from './services/external-tokens/external-tokens-types';
4
+ export type { ConnectRepositoryRequest, ConnectRepositoryResponse, ProjectRepository, GetProjectsRequest, PaginatedProjectsRequest, PaginatedProjectsResponse, } from './services/projects/project-types';
5
+ export type { CreateCodespaceTaskRequestV2 as CreateCodespaceTaskRequest, CreateCodespaceTaskResponseV2 as CreateCodespaceTaskResponse, CreateBackgroundCodespaceTaskRequest, CreateBackgroundCodespaceTaskResponse, ModelApiKey, Attachment, GetCodespaceTaskResponse, CodespaceTaskData, TechnicalDocument, GetProjectTasksByCodespaceResponse, } from './services/codespace/codespace-types';
6
+ export type { StoreExternalTokenRequest, StoreExternalTokenResponse, ListTokensQuery, ListTokensResponse, ValidateTokenRequest, ValidateTokenResponse, FindBestMatchRequest, FindBestMatchResponse, Platform, TokenType, } from './services/external-tokens/external-tokens-types';
7
+ export type { StarterKit, StarterKitMetadata, GetStarterKitsRequest, GetStarterKitsResponse, } from './services/starter-kits/starter-kits-types';
@@ -25,6 +25,27 @@ export declare abstract class BaseService {
25
25
  private formatErrorMessage;
26
26
  protected post<T>(url: string, data?: any, config?: any): Promise<T>;
27
27
  protected put<T>(url: string, data?: any, config?: any): Promise<T>;
28
+ protected patch<T>(url: string, data?: any, config?: any): Promise<T>;
28
29
  protected delete<T>(url: string, config?: any): Promise<T>;
29
30
  protected buildUrl(endpoint: string): string;
31
+ /**
32
+ * Create a streaming connection for Server-Sent Events (SSE)
33
+ *
34
+ * @param url - The endpoint URL for streaming
35
+ * @param config - Optional configuration for the stream request
36
+ * @returns Promise that resolves to EventSource for SSE streaming
37
+ */
38
+ protected createStream(url: string, config?: any): Promise<EventSource>;
39
+ /**
40
+ * Alternative streaming method using fetch for environments where EventSource is not available
41
+ * or when custom headers are needed for authentication
42
+ *
43
+ * @param url - The endpoint URL for streaming
44
+ * @param onMessage - Callback function for handling stream messages
45
+ * @param onError - Callback function for handling stream errors
46
+ * @param onComplete - Callback function for when stream completes
47
+ * @param config - Optional configuration for the stream request
48
+ * @returns Promise that resolves to a cleanup function
49
+ */
50
+ protected createStreamWithFetch(url: string, onMessage: (data: any) => void, onError?: (error: any) => void, onComplete?: () => void, config?: any): Promise<() => void>;
30
51
  }
@@ -192,6 +192,10 @@ class BaseService {
192
192
  const response = await this.client.put(url, data, config);
193
193
  return response.data;
194
194
  }
195
+ async patch(url, data, config) {
196
+ const response = await this.client.patch(url, data, config);
197
+ return response.data;
198
+ }
195
199
  async delete(url, config) {
196
200
  const response = await this.client.delete(url, config);
197
201
  return response.data;
@@ -199,5 +203,115 @@ class BaseService {
199
203
  buildUrl(endpoint) {
200
204
  return endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
201
205
  }
206
+ /**
207
+ * Create a streaming connection for Server-Sent Events (SSE)
208
+ *
209
+ * @param url - The endpoint URL for streaming
210
+ * @param config - Optional configuration for the stream request
211
+ * @returns Promise that resolves to EventSource for SSE streaming
212
+ */
213
+ async createStream(url, config) {
214
+ // Build full URL
215
+ const fullUrl = `${this.client.defaults.baseURL}${this.buildUrl(url)}`;
216
+ // For SSE, we need to use EventSource API directly
217
+ // However, we need to handle authentication differently since EventSource doesn't support custom headers
218
+ // We'll pass auth info as query parameters for SSE endpoints
219
+ return new Promise((resolve, reject) => {
220
+ try {
221
+ const eventSource = new EventSource(fullUrl);
222
+ resolve(eventSource);
223
+ }
224
+ catch (error) {
225
+ reject(error);
226
+ }
227
+ });
228
+ }
229
+ /**
230
+ * Alternative streaming method using fetch for environments where EventSource is not available
231
+ * or when custom headers are needed for authentication
232
+ *
233
+ * @param url - The endpoint URL for streaming
234
+ * @param onMessage - Callback function for handling stream messages
235
+ * @param onError - Callback function for handling stream errors
236
+ * @param onComplete - Callback function for when stream completes
237
+ * @param config - Optional configuration for the stream request
238
+ * @returns Promise that resolves to a cleanup function
239
+ */
240
+ async createStreamWithFetch(url, onMessage, onError, onComplete, config) {
241
+ const streamConfig = {
242
+ ...config,
243
+ headers: {
244
+ ...this.client.defaults.headers,
245
+ 'Accept': 'text/event-stream',
246
+ 'Cache-Control': 'no-cache',
247
+ ...config?.headers,
248
+ },
249
+ };
250
+ const fullUrl = `${this.client.defaults.baseURL}${this.buildUrl(url)}`;
251
+ try {
252
+ const response = await fetch(fullUrl, streamConfig);
253
+ if (!response.ok) {
254
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
255
+ }
256
+ const reader = response.body?.getReader();
257
+ if (!reader) {
258
+ throw new Error('Response body is not readable');
259
+ }
260
+ const decoder = new TextDecoder();
261
+ let buffer = '';
262
+ const processStream = async () => {
263
+ try {
264
+ while (true) {
265
+ const { done, value } = await reader.read();
266
+ if (done) {
267
+ onComplete?.();
268
+ break;
269
+ }
270
+ buffer += decoder.decode(value, { stream: true });
271
+ const lines = buffer.split('\n');
272
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
273
+ for (const line of lines) {
274
+ if (line.startsWith('data: ')) {
275
+ const data = line.slice(6); // Remove 'data: ' prefix
276
+ if (data.trim()) {
277
+ try {
278
+ const parsedData = JSON.parse(data);
279
+ onMessage(parsedData);
280
+ }
281
+ catch (parseError) {
282
+ console.warn('Failed to parse SSE data:', data, parseError);
283
+ }
284
+ }
285
+ }
286
+ else if (line.startsWith('event: ')) {
287
+ const eventType = line.slice(7); // Remove 'event: ' prefix
288
+ // Handle different event types if needed
289
+ if (eventType === 'complete') {
290
+ onComplete?.();
291
+ return;
292
+ }
293
+ else if (eventType === 'error') {
294
+ onError?.(new Error('Stream error event received'));
295
+ return;
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ catch (error) {
302
+ onError?.(error);
303
+ }
304
+ };
305
+ processStream();
306
+ // Return cleanup function
307
+ return () => {
308
+ reader.cancel().catch(console.warn);
309
+ };
310
+ }
311
+ catch (error) {
312
+ onError?.(error);
313
+ return () => { }; // Return empty cleanup function on error
314
+ }
315
+ }
202
316
  }
203
317
  exports.BaseService = BaseService;
@@ -1,5 +1,5 @@
1
1
  import { BaseService } from '../base/base-service';
2
- import { GenerateTaskTitleRequest, GenerateTaskTitleResponse, CreateCodespaceTaskRequest, CreateCodespaceTaskResponse, CreateCodespaceTaskRequestV2, CreateCodespaceTaskResponseV2, CreateBackgroundCodespaceTaskRequest, CreateBackgroundCodespaceTaskResponse, GetCodespaceTaskResponse, GetProjectTasksByCodespaceResponse, GetCodespaceTasksByProjectRequest, GetCodespaceTasksByProjectResponse, CodespaceTaskDetailedResponse, CodespaceQuestionnaireRequest, CodespaceQuestionnaireResponse, GetCodespaceModelsQuery, GetCodespaceModelsResponse, GetCodespaceModelResponse, GetLLMModelProvidersResponse, GetLLMModelProviderResponse, GetModelsByProviderResponse } from './codespace-types';
2
+ import { GenerateTaskTitleRequest, GenerateTaskTitleResponse, CreateCodespaceTaskRequest, CreateCodespaceTaskResponse, CreateCodespaceTaskRequestV2, CreateCodespaceTaskResponseV2, CreateBackgroundCodespaceTaskRequest, CreateBackgroundCodespaceTaskResponse, GetCodespaceTaskResponse, GetProjectTasksByCodespaceResponse, GetCodespaceTasksByProjectRequest, GetCodespaceTasksByProjectResponse, CodespaceTaskDetailedResponse, CodespaceQuestionnaireRequest, CodespaceQuestionnaireResponse, GetCodespaceModelsQuery, GetCodespaceModelsResponse, GetCodespaceModelResponse, GetLLMModelProvidersResponse, GetLLMModelProviderResponse, GetModelsByProviderResponse, GetCodespaceTasksRequest, GetCodespaceTasksResponse, GetTasksByCodespaceIdRequest, GetTasksByCodespaceIdResponse, UpdateFinalReportPopupStateRequest, UpdateFinalReportPopupStateResponse, GetCodespaceTaskLogsRequest, CodespaceTaskLogsResponse, StreamCodespaceTaskLogsRequest, CodespaceLogStreamEvent } from './codespace-types';
3
3
  export declare class CodespaceService extends BaseService {
4
4
  generateTaskTitle(request: GenerateTaskTitleRequest): Promise<GenerateTaskTitleResponse>;
5
5
  generateQuestionnaire(request: CodespaceQuestionnaireRequest): Promise<CodespaceQuestionnaireResponse>;
@@ -10,6 +10,57 @@ export declare class CodespaceService extends BaseService {
10
10
  getProjectTasksByCodespace(codespaceTaskId: string): Promise<GetProjectTasksByCodespaceResponse>;
11
11
  getCodespaceTasksByProject(params: GetCodespaceTasksByProjectRequest): Promise<GetCodespaceTasksByProjectResponse>;
12
12
  getCodespaceTaskDetailed(codespaceTaskId: string): Promise<CodespaceTaskDetailedResponse>;
13
+ /**
14
+ * Get tasks by codespace task ID with optional pagination and sorting
15
+ *
16
+ * GET /tasks/by-codespace-id/{codespace_task_id}
17
+ *
18
+ * @param params - Request parameters including codespace_task_id and optional pagination/sorting
19
+ * @returns Promise resolving to paginated list of tasks associated with the codespace task ID
20
+ */
21
+ getTasksByCodespaceId(params: GetTasksByCodespaceIdRequest): Promise<GetTasksByCodespaceIdResponse>;
22
+ /**
23
+ * Get codespace tasks with optional filtering and pagination
24
+ *
25
+ * GET /codespace/tasks
26
+ *
27
+ * @param params - Optional query parameters for filtering, sorting, and pagination
28
+ * @returns Promise resolving to paginated list of codespace tasks with model and attachment info
29
+ */
30
+ getCodespaceTasks(params?: GetCodespaceTasksRequest): Promise<GetCodespaceTasksResponse>;
31
+ /**
32
+ * Update the final report popup state for a codespace task
33
+ *
34
+ * PATCH /task/{codespace_task_id}/final-report-popup-state
35
+ *
36
+ * @param codespaceTaskId - The ID of the codespace task
37
+ * @param request - The request body containing the new popup state
38
+ * @returns Promise resolving to the updated popup state response
39
+ */
40
+ updateFinalReportPopupState(codespaceTaskId: string, request: UpdateFinalReportPopupStateRequest): Promise<UpdateFinalReportPopupStateResponse>;
41
+ /**
42
+ * Get paginated logs for a codespace task with optional filtering and sorting
43
+ *
44
+ * GET /codespace/task/{codespace_task_id}/logs
45
+ *
46
+ * @param request - Request parameters including codespace_task_id and optional filters
47
+ * @returns Promise resolving to paginated logs response
48
+ */
49
+ getCodespaceTaskLogs(request: GetCodespaceTaskLogsRequest): Promise<CodespaceTaskLogsResponse>;
50
+ /**
51
+ * Stream real-time logs from a codespace task using Server-Sent Events (SSE)
52
+ *
53
+ * GET /codespace/task/{codespace_task_id}/logs/stream
54
+ *
55
+ * @param request - Request parameters including codespace_task_id and optional streaming parameters
56
+ * @param onLog - Callback function for handling log events
57
+ * @param onHeartbeat - Callback function for handling heartbeat events
58
+ * @param onComplete - Callback function for handling completion events
59
+ * @param onError - Callback function for handling error events
60
+ * @param onTimeout - Callback function for handling timeout events
61
+ * @returns Promise resolving to a cleanup function to stop streaming
62
+ */
63
+ streamCodespaceTaskLogs(request: StreamCodespaceTaskLogsRequest, onLog: (log: CodespaceLogStreamEvent) => void, onHeartbeat?: (data: any) => void, onComplete?: (data: any) => void, onError?: (error: any) => void, onTimeout?: (data: any) => void): Promise<() => void>;
13
64
  /**
14
65
  * Get all codespace models with optional filtering
15
66
  *
@@ -63,4 +114,7 @@ export declare class CodespaceService extends BaseService {
63
114
  private buildQueryParams;
64
115
  private validateCodespaceTaskRequest;
65
116
  private validateQuestionnaireRequest;
117
+ private validateGetLogsRequest;
118
+ private validateStreamLogsRequest;
119
+ private validateGetTasksByCodespaceIdRequest;
66
120
  }
@@ -57,6 +57,167 @@ class CodespaceService extends base_service_1.BaseService {
57
57
  }
58
58
  return this.get(`/codespace/task/${codespaceTaskId}/detailed`);
59
59
  }
60
+ /**
61
+ * Get tasks by codespace task ID with optional pagination and sorting
62
+ *
63
+ * GET /tasks/by-codespace-id/{codespace_task_id}
64
+ *
65
+ * @param params - Request parameters including codespace_task_id and optional pagination/sorting
66
+ * @returns Promise resolving to paginated list of tasks associated with the codespace task ID
67
+ */
68
+ async getTasksByCodespaceId(params) {
69
+ this.validateGetTasksByCodespaceIdRequest(params);
70
+ const queryParams = new URLSearchParams();
71
+ // Add pagination parameters
72
+ if (params.limit !== undefined) {
73
+ queryParams.append('limit', params.limit.toString());
74
+ }
75
+ if (params.offset !== undefined) {
76
+ queryParams.append('offset', params.offset.toString());
77
+ }
78
+ // Add sorting parameters
79
+ if (params.sort_by) {
80
+ queryParams.append('sort_by', params.sort_by);
81
+ }
82
+ if (params.sort_order) {
83
+ queryParams.append('sort_order', params.sort_order);
84
+ }
85
+ const url = `/tasks/by-codespace-id/${params.codespace_task_id}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
86
+ return this.get(url);
87
+ }
88
+ /**
89
+ * Get codespace tasks with optional filtering and pagination
90
+ *
91
+ * GET /codespace/tasks
92
+ *
93
+ * @param params - Optional query parameters for filtering, sorting, and pagination
94
+ * @returns Promise resolving to paginated list of codespace tasks with model and attachment info
95
+ */
96
+ async getCodespaceTasks(params) {
97
+ const queryParams = new URLSearchParams();
98
+ if (params?.task_status)
99
+ queryParams.append('task_status', params.task_status);
100
+ if (params?.project_id)
101
+ queryParams.append('project_id', params.project_id);
102
+ if (params?.limit !== undefined) {
103
+ // Validate limit is between 1 and 100
104
+ if (params.limit < 1 || params.limit > 100) {
105
+ throw new Error('limit must be between 1 and 100');
106
+ }
107
+ queryParams.append('limit', params.limit.toString());
108
+ }
109
+ if (params?.offset !== undefined) {
110
+ // Validate offset is non-negative
111
+ if (params.offset < 0) {
112
+ throw new Error('offset must be 0 or greater');
113
+ }
114
+ queryParams.append('offset', params.offset.toString());
115
+ }
116
+ if (params?.sort_by)
117
+ queryParams.append('sort_by', params.sort_by);
118
+ if (params?.sort_order)
119
+ queryParams.append('sort_order', params.sort_order);
120
+ const url = `/codespace/tasks${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
121
+ return this.get(url);
122
+ }
123
+ // ============================================================================
124
+ // Task Status Update Methods
125
+ // ============================================================================
126
+ /**
127
+ * Update the final report popup state for a codespace task
128
+ *
129
+ * PATCH /task/{codespace_task_id}/final-report-popup-state
130
+ *
131
+ * @param codespaceTaskId - The ID of the codespace task
132
+ * @param request - The request body containing the new popup state
133
+ * @returns Promise resolving to the updated popup state response
134
+ */
135
+ async updateFinalReportPopupState(codespaceTaskId, request) {
136
+ if (!codespaceTaskId) {
137
+ throw new Error('codespace_task_id is required');
138
+ }
139
+ // Validate the popup state value
140
+ if (!['not_ready', 'open', 'closed'].includes(request.final_report_popup_state)) {
141
+ throw new Error('final_report_popup_state must be "not_ready", "open", or "closed"');
142
+ }
143
+ return this.patch(`/task/${codespaceTaskId}/final-report-popup-state`, request);
144
+ }
145
+ // ============================================================================
146
+ // Codespace Task Logs Methods
147
+ // ============================================================================
148
+ /**
149
+ * Get paginated logs for a codespace task with optional filtering and sorting
150
+ *
151
+ * GET /codespace/task/{codespace_task_id}/logs
152
+ *
153
+ * @param request - Request parameters including codespace_task_id and optional filters
154
+ * @returns Promise resolving to paginated logs response
155
+ */
156
+ async getCodespaceTaskLogs(request) {
157
+ this.validateGetLogsRequest(request);
158
+ const queryParams = new URLSearchParams();
159
+ // Add pagination parameters
160
+ if (request.limit !== undefined) {
161
+ queryParams.append('limit', request.limit.toString());
162
+ }
163
+ if (request.offset !== undefined) {
164
+ queryParams.append('offset', request.offset.toString());
165
+ }
166
+ // Add filter parameters
167
+ if (request.log_type) {
168
+ queryParams.append('log_type', request.log_type);
169
+ }
170
+ if (request.step_name) {
171
+ queryParams.append('step_name', request.step_name);
172
+ }
173
+ if (request.search) {
174
+ queryParams.append('search', request.search);
175
+ }
176
+ if (request.since) {
177
+ queryParams.append('since', request.since);
178
+ }
179
+ // Add sorting parameters
180
+ if (request.sort_by) {
181
+ queryParams.append('sort_by', request.sort_by);
182
+ }
183
+ if (request.sort_order) {
184
+ queryParams.append('sort_order', request.sort_order);
185
+ }
186
+ const url = `/codespace/task/${request.codespace_task_id}/logs${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
187
+ return this.get(url);
188
+ }
189
+ /**
190
+ * Stream real-time logs from a codespace task using Server-Sent Events (SSE)
191
+ *
192
+ * GET /codespace/task/{codespace_task_id}/logs/stream
193
+ *
194
+ * @param request - Request parameters including codespace_task_id and optional streaming parameters
195
+ * @param onLog - Callback function for handling log events
196
+ * @param onHeartbeat - Callback function for handling heartbeat events
197
+ * @param onComplete - Callback function for handling completion events
198
+ * @param onError - Callback function for handling error events
199
+ * @param onTimeout - Callback function for handling timeout events
200
+ * @returns Promise resolving to a cleanup function to stop streaming
201
+ */
202
+ async streamCodespaceTaskLogs(request, onLog, onHeartbeat, onComplete, onError, onTimeout) {
203
+ this.validateStreamLogsRequest(request);
204
+ const queryParams = new URLSearchParams();
205
+ // Add streaming parameters
206
+ if (request.since) {
207
+ queryParams.append('since', request.since);
208
+ }
209
+ if (request.timeout !== undefined) {
210
+ queryParams.append('timeout', request.timeout.toString());
211
+ }
212
+ const url = `/codespace/task/${request.codespace_task_id}/logs/stream${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
213
+ // Use the fetch-based streaming method since it supports custom headers for authentication
214
+ return this.createStreamWithFetch(url, data => {
215
+ // Handle different types of events based on the context
216
+ // The server will send different event types through the same data channel
217
+ onLog(data);
218
+ }, onError, () => onComplete?.({}) // Call onComplete with empty data when stream completes
219
+ );
220
+ }
60
221
  // ============================================================================
61
222
  // Codespace Models Methods
62
223
  // ============================================================================
@@ -70,9 +231,7 @@ class CodespaceService extends base_service_1.BaseService {
70
231
  */
71
232
  async getCodespaceModels(query) {
72
233
  const params = this.buildQueryParams(query);
73
- const url = params
74
- ? `/api/codespace-models/models?${params}`
75
- : '/api/codespace-models/models';
234
+ const url = params ? `/api/codespace-models/models?${params}` : '/api/codespace-models/models';
76
235
  return this.get(url);
77
236
  }
78
237
  /**
@@ -152,8 +311,8 @@ class CodespaceService extends base_service_1.BaseService {
152
311
  throw new Error('task_description is required');
153
312
  }
154
313
  if (request.execution_mode &&
155
- !['implementation', 'docs-only'].includes(request.execution_mode)) {
156
- throw new Error('execution_mode must be either "implementation" or "docs-only"');
314
+ !['implementation', 'docs-only', 'direct'].includes(request.execution_mode)) {
315
+ throw new Error('execution_mode must be either "implementation", "docs-only", or "direct"');
157
316
  }
158
317
  // Validate model_api_keys if provided
159
318
  if (request.model_api_keys) {
@@ -219,5 +378,101 @@ class CodespaceService extends base_service_1.BaseService {
219
378
  }
220
379
  }
221
380
  }
381
+ validateGetLogsRequest(request) {
382
+ if (!request.codespace_task_id) {
383
+ throw new Error('codespace_task_id is required');
384
+ }
385
+ // Validate limit
386
+ if (request.limit !== undefined) {
387
+ if (!Number.isInteger(request.limit)) {
388
+ throw new Error('limit must be an integer');
389
+ }
390
+ if (request.limit < 1 || request.limit > 500) {
391
+ throw new Error('limit must be between 1 and 500');
392
+ }
393
+ }
394
+ // Validate offset
395
+ if (request.offset !== undefined) {
396
+ if (!Number.isInteger(request.offset)) {
397
+ throw new Error('offset must be an integer');
398
+ }
399
+ if (request.offset < 0) {
400
+ throw new Error('offset must be 0 or greater');
401
+ }
402
+ }
403
+ // Validate sort_by
404
+ if (request.sort_by && !['created_at', 'step_name', 'log_type'].includes(request.sort_by)) {
405
+ throw new Error('sort_by must be one of: created_at, step_name, log_type');
406
+ }
407
+ // Validate sort_order
408
+ if (request.sort_order && !['asc', 'desc'].includes(request.sort_order)) {
409
+ throw new Error('sort_order must be either "asc" or "desc"');
410
+ }
411
+ // Validate log_type
412
+ const validLogTypes = ['thinking', 'coding', 'info', 'error', 'success'];
413
+ if (request.log_type && !validLogTypes.includes(request.log_type)) {
414
+ throw new Error(`log_type must be one of: ${validLogTypes.join(', ')}`);
415
+ }
416
+ // Validate since timestamp format (basic ISO format check)
417
+ if (request.since) {
418
+ const sinceDate = new Date(request.since);
419
+ if (isNaN(sinceDate.getTime())) {
420
+ throw new Error('since must be a valid ISO timestamp');
421
+ }
422
+ }
423
+ }
424
+ validateStreamLogsRequest(request) {
425
+ if (!request.codespace_task_id) {
426
+ throw new Error('codespace_task_id is required');
427
+ }
428
+ // Validate timeout
429
+ if (request.timeout !== undefined) {
430
+ if (!Number.isInteger(request.timeout)) {
431
+ throw new Error('timeout must be an integer');
432
+ }
433
+ if (request.timeout < 30 || request.timeout > 1800) {
434
+ throw new Error('timeout must be between 30 and 1800 seconds');
435
+ }
436
+ }
437
+ // Validate since timestamp format (basic ISO format check)
438
+ if (request.since) {
439
+ const sinceDate = new Date(request.since);
440
+ if (isNaN(sinceDate.getTime())) {
441
+ throw new Error('since must be a valid ISO timestamp');
442
+ }
443
+ }
444
+ }
445
+ validateGetTasksByCodespaceIdRequest(request) {
446
+ if (!request.codespace_task_id) {
447
+ throw new Error('codespace_task_id is required');
448
+ }
449
+ // Validate limit
450
+ if (request.limit !== undefined) {
451
+ if (!Number.isInteger(request.limit)) {
452
+ throw new Error('limit must be an integer');
453
+ }
454
+ if (request.limit < 1 || request.limit > 100) {
455
+ throw new Error('limit must be between 1 and 100');
456
+ }
457
+ }
458
+ // Validate offset
459
+ if (request.offset !== undefined) {
460
+ if (!Number.isInteger(request.offset)) {
461
+ throw new Error('offset must be an integer');
462
+ }
463
+ if (request.offset < 0) {
464
+ throw new Error('offset must be 0 or greater');
465
+ }
466
+ }
467
+ // Validate sort_by
468
+ if (request.sort_by &&
469
+ !['created_at', 'updated_at', 'status', 'title'].includes(request.sort_by)) {
470
+ throw new Error('sort_by must be one of: created_at, updated_at, status, title');
471
+ }
472
+ // Validate sort_order
473
+ if (request.sort_order && !['asc', 'desc'].includes(request.sort_order)) {
474
+ throw new Error('sort_order must be either "asc" or "desc"');
475
+ }
476
+ }
222
477
  }
223
478
  exports.CodespaceService = CodespaceService;