@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
@@ -0,0 +1,773 @@
1
+ # Security Keys Service
2
+
3
+ The Security Keys Service provides methods for securely managing provider API keys (OpenAI, Anthropic, etc.) and GitHub tokens. All keys are encrypted and stored securely.
4
+
5
+ ## Overview
6
+
7
+ The Security Keys Service allows you to:
8
+ - Store and manage provider API keys (OpenAI, Anthropic, etc.)
9
+ - Store and manage GitHub personal access tokens
10
+ - Retrieve keys (with optional reveal option)
11
+ - Revoke/delete stored keys
12
+ - List all stored keys
13
+
14
+ ## Setup
15
+
16
+ ### Installation
17
+
18
+ ```bash
19
+ npm install @codeguide/core
20
+ ```
21
+
22
+ ### Basic Initialization
23
+
24
+ ```typescript
25
+ import { CodeGuide } from '@codeguide/core'
26
+
27
+ const codeguide = new CodeGuide({
28
+ baseUrl: 'https://api.codeguide.ai',
29
+ databaseApiKey: 'sk_your_database_api_key',
30
+ })
31
+
32
+ // Access the security keys service
33
+ const securityKeys = codeguide.securityKeys
34
+ ```
35
+
36
+ ## Methods Overview
37
+
38
+ ### Provider API Keys
39
+
40
+ | Method | Description | Endpoint |
41
+ |--------|-------------|----------|
42
+ | `createProviderAPIKey()` | Save a provider API key | `POST /security-keys/provider-api-key` |
43
+ | `getProviderAPIKey()` | Get a provider API key | `GET /security-keys/provider-api-key/{provider_key}` |
44
+ | `listProviderAPIKeys()` | List all provider API keys | `GET /security-keys/provider-api-keys` |
45
+ | `revokeProviderAPIKey()` | Delete a provider API key | `DELETE /security-keys/provider-api-key/{provider_key}` |
46
+
47
+ ### GitHub Tokens
48
+
49
+ | Method | Description | Endpoint |
50
+ |--------|-------------|----------|
51
+ | `createGitHubToken()` | Save a GitHub token | `POST /security-keys/github-token` |
52
+ | `getGitHubToken()` | Get the GitHub token | `GET /security-keys/github-token` |
53
+ | `revokeGitHubToken()` | Delete the GitHub token | `DELETE /security-keys/github-token` |
54
+
55
+ ## Detailed Method Documentation
56
+
57
+ ### Provider API Keys
58
+
59
+ #### 1. createProviderAPIKey()
60
+
61
+ Saves a new provider API key. The key is encrypted and stored securely.
62
+
63
+ #### Signature
64
+
65
+ ```typescript
66
+ async createProviderAPIKey(request: CreateProviderAPIKeyRequest): Promise<CreateProviderAPIKeyResponse>
67
+ ```
68
+
69
+ #### Parameters
70
+
71
+ ```typescript
72
+ interface CreateProviderAPIKeyRequest {
73
+ provider_key: string // Required: Provider key (e.g., 'openai', 'anthropic')
74
+ api_key: string // Required: The API key (minimum 10 characters)
75
+ }
76
+ ```
77
+
78
+ #### Returns
79
+
80
+ ```typescript
81
+ interface CreateProviderAPIKeyResponse {
82
+ status: 'success'
83
+ data: ProviderAPIKeyData
84
+ }
85
+
86
+ interface ProviderAPIKeyData {
87
+ id: string
88
+ created_at: string
89
+ user_id: string
90
+ name: string
91
+ displayed_name: string
92
+ value_masked: string // Masked version of the key
93
+ value?: string // Only included when reveal=true
94
+ object_value: {
95
+ provider_id: string
96
+ }
97
+ encryption: string
98
+ key_version: string
99
+ provider_id: string
100
+ provider_name: string
101
+ provider_key: string
102
+ provider_logo_src?: string // Only in list endpoint
103
+ }
104
+ ```
105
+
106
+ #### Validation
107
+
108
+ - `provider_key` is required
109
+ - `api_key` is required and must be at least 10 characters long
110
+ - Provider must exist in the system
111
+
112
+ #### Example
113
+
114
+ ```typescript
115
+ // Store an OpenAI API key
116
+ const response = await codeguide.securityKeys.createProviderAPIKey({
117
+ provider_key: 'openai',
118
+ api_key: 'sk-your-openai-api-key-here',
119
+ })
120
+
121
+ console.log(`Stored key for ${response.data.provider_name}`)
122
+ console.log(`Masked value: ${response.data.value_masked}`)
123
+ ```
124
+
125
+ #### 2. getProviderAPIKey()
126
+
127
+ Retrieves a provider API key by provider key.
128
+
129
+ #### Signature
130
+
131
+ ```typescript
132
+ async getProviderAPIKey(providerKey: string, reveal: boolean = false): Promise<GetProviderAPIKeyResponse>
133
+ ```
134
+
135
+ #### Parameters
136
+
137
+ - `providerKey` (string, required): The provider key (e.g., 'openai', 'anthropic')
138
+ - `reveal` (boolean, optional): Whether to reveal the actual API key (default: false)
139
+
140
+ #### Returns
141
+
142
+ ```typescript
143
+ interface GetProviderAPIKeyResponse {
144
+ status: 'success'
145
+ data: ProviderAPIKeyData
146
+ }
147
+ ```
148
+
149
+ #### Example
150
+
151
+ ```typescript
152
+ // Get masked key (default)
153
+ const masked = await codeguide.securityKeys.getProviderAPIKey('openai')
154
+ console.log(`Masked key: ${masked.data.value_masked}`)
155
+
156
+ // Get revealed key
157
+ const revealed = await codeguide.securityKeys.getProviderAPIKey('openai', true)
158
+ console.log(`Actual key: ${revealed.data.value}`) // Only if reveal=true
159
+ ```
160
+
161
+ #### 3. listProviderAPIKeys()
162
+
163
+ Lists all stored provider API keys.
164
+
165
+ #### Signature
166
+
167
+ ```typescript
168
+ async listProviderAPIKeys(reveal: boolean = false): Promise<ListProviderAPIKeysResponse>
169
+ ```
170
+
171
+ #### Parameters
172
+
173
+ - `reveal` (boolean, optional): Whether to reveal the actual API keys (default: false)
174
+
175
+ #### Returns
176
+
177
+ ```typescript
178
+ interface ListProviderAPIKeysResponse {
179
+ status: 'success'
180
+ data: ProviderAPIKeyData[]
181
+ }
182
+ ```
183
+
184
+ #### Example
185
+
186
+ ```typescript
187
+ // List all keys (masked)
188
+ const keys = await codeguide.securityKeys.listProviderAPIKeys()
189
+
190
+ console.log(`Found ${keys.data.length} provider keys:`)
191
+ keys.data.forEach(key => {
192
+ console.log(`- ${key.provider_name} (${key.provider_key})`)
193
+ console.log(` Masked: ${key.value_masked}`)
194
+ if (key.provider_logo_src) {
195
+ console.log(` Logo: ${key.provider_logo_src}`)
196
+ }
197
+ })
198
+
199
+ // List with revealed keys (use with caution)
200
+ const revealedKeys = await codeguide.securityKeys.listProviderAPIKeys(true)
201
+ revealedKeys.data.forEach(key => {
202
+ console.log(`${key.provider_name}: ${key.value}`)
203
+ })
204
+ ```
205
+
206
+ #### 4. revokeProviderAPIKey()
207
+
208
+ Deletes a provider API key.
209
+
210
+ #### Signature
211
+
212
+ ```typescript
213
+ async revokeProviderAPIKey(providerKey: string): Promise<RevokeProviderAPIKeyResponse>
214
+ ```
215
+
216
+ #### Parameters
217
+
218
+ - `providerKey` (string, required): The provider key to delete
219
+
220
+ #### Returns
221
+
222
+ ```typescript
223
+ interface RevokeProviderAPIKeyResponse {
224
+ status: string
225
+ message: string
226
+ revoked_provider_id: string
227
+ }
228
+ ```
229
+
230
+ #### Example
231
+
232
+ ```typescript
233
+ const result = await codeguide.securityKeys.revokeProviderAPIKey('openai')
234
+
235
+ console.log(result.status) // "success"
236
+ console.log(result.message) // "Provider API key revoked successfully"
237
+ console.log(`Revoked provider ID: ${result.revoked_provider_id}`)
238
+ ```
239
+
240
+ ### GitHub Tokens
241
+
242
+ #### 5. createGitHubToken()
243
+
244
+ Saves a GitHub personal access token. The token is encrypted and stored securely.
245
+
246
+ #### Signature
247
+
248
+ ```typescript
249
+ async createGitHubToken(request: CreateGitHubTokenRequest): Promise<CreateGitHubTokenResponse>
250
+ ```
251
+
252
+ #### Parameters
253
+
254
+ ```typescript
255
+ interface CreateGitHubTokenRequest {
256
+ github_token: string // Required: GitHub personal access token
257
+ }
258
+ ```
259
+
260
+ #### Returns
261
+
262
+ ```typescript
263
+ interface CreateGitHubTokenResponse {
264
+ status: 'success'
265
+ data: GitHubTokenData
266
+ }
267
+
268
+ interface GitHubTokenData {
269
+ id: string
270
+ created_at: string
271
+ user_id: string
272
+ name: string
273
+ displayed_name: string
274
+ value_masked: string // Masked version of the token
275
+ value?: string // Only included when reveal=true
276
+ object_value: {
277
+ token_type: string
278
+ }
279
+ encryption: string
280
+ key_version: string
281
+ }
282
+ ```
283
+
284
+ #### Validation
285
+
286
+ - `github_token` is required
287
+ - Token must be a valid GitHub token format:
288
+ - Prefixes: `ghp_`, `gho_`, `ghu_`, `ghs_`, `ghr_`, or `github_pat_`
289
+ - Minimum length: 40 characters
290
+ - Token is validated with GitHub API
291
+
292
+ #### Example
293
+
294
+ ```typescript
295
+ // Store a GitHub token
296
+ const response = await codeguide.securityKeys.createGitHubToken({
297
+ github_token: 'ghp_your_github_personal_access_token_here',
298
+ })
299
+
300
+ console.log(`GitHub token stored`)
301
+ console.log(`Masked value: ${response.data.value_masked}`)
302
+ ```
303
+
304
+ #### 6. getGitHubToken()
305
+
306
+ Retrieves the stored GitHub token.
307
+
308
+ #### Signature
309
+
310
+ ```typescript
311
+ async getGitHubToken(reveal: boolean = false): Promise<GetGitHubTokenResponse>
312
+ ```
313
+
314
+ #### Parameters
315
+
316
+ - `reveal` (boolean, optional): Whether to reveal the actual token (default: false)
317
+
318
+ #### Returns
319
+
320
+ ```typescript
321
+ interface GetGitHubTokenResponse {
322
+ status: 'success'
323
+ data: GitHubTokenData
324
+ }
325
+ ```
326
+
327
+ #### Example
328
+
329
+ ```typescript
330
+ // Get masked token (default)
331
+ const masked = await codeguide.securityKeys.getGitHubToken()
332
+ console.log(`Masked token: ${masked.data.value_masked}`)
333
+
334
+ // Get revealed token
335
+ const revealed = await codeguide.securityKeys.getGitHubToken(true)
336
+ console.log(`Actual token: ${revealed.data.value}`) // Only if reveal=true
337
+ ```
338
+
339
+ #### 7. revokeGitHubToken()
340
+
341
+ Deletes the stored GitHub token.
342
+
343
+ #### Signature
344
+
345
+ ```typescript
346
+ async revokeGitHubToken(): Promise<RevokeGitHubTokenResponse>
347
+ ```
348
+
349
+ #### Returns
350
+
351
+ ```typescript
352
+ interface RevokeGitHubTokenResponse {
353
+ status: string
354
+ message: string
355
+ revoked_at: string
356
+ }
357
+ ```
358
+
359
+ #### Example
360
+
361
+ ```typescript
362
+ const result = await codeguide.securityKeys.revokeGitHubToken()
363
+
364
+ console.log(result.status) // "success"
365
+ console.log(result.message) // "GitHub token revoked successfully"
366
+ console.log(`Revoked at: ${result.revoked_at}`)
367
+ ```
368
+
369
+ ## Error Handling
370
+
371
+ ### Common Errors
372
+
373
+ #### Provider Not Found
374
+
375
+ ```typescript
376
+ try {
377
+ await codeguide.securityKeys.createProviderAPIKey({
378
+ provider_key: 'invalid_provider',
379
+ api_key: 'sk-key-here',
380
+ })
381
+ } catch (error) {
382
+ if (error.message.includes('not found')) {
383
+ console.error('Provider not found. Please choose a valid provider.')
384
+ }
385
+ }
386
+ ```
387
+
388
+ #### Duplicate Key
389
+
390
+ ```typescript
391
+ try {
392
+ await codeguide.securityKeys.createProviderAPIKey({
393
+ provider_key: 'openai',
394
+ api_key: 'sk-key-here',
395
+ })
396
+ } catch (error) {
397
+ if (error.message.includes('already exists')) {
398
+ console.error('API key for this provider already exists. Use update endpoint to change it.')
399
+ // Or revoke the existing key first
400
+ await codeguide.securityKeys.revokeProviderAPIKey('openai')
401
+ // Then create the new one
402
+ }
403
+ }
404
+ ```
405
+
406
+ #### Invalid GitHub Token Format
407
+
408
+ ```typescript
409
+ try {
410
+ await codeguide.securityKeys.createGitHubToken({
411
+ github_token: 'invalid-token',
412
+ })
413
+ } catch (error) {
414
+ if (error.message.includes('Invalid GitHub token format')) {
415
+ console.error('Token must start with ghp_, gho_, ghu_, ghs_, ghr_, or github_pat_')
416
+ }
417
+ }
418
+ ```
419
+
420
+ #### Key Not Found
421
+
422
+ ```typescript
423
+ try {
424
+ await codeguide.securityKeys.getProviderAPIKey('openai')
425
+ } catch (error) {
426
+ if (error.message.includes('not found')) {
427
+ console.error('No API key found for this provider')
428
+ }
429
+ }
430
+ ```
431
+
432
+ #### Authentication Errors
433
+
434
+ ```typescript
435
+ try {
436
+ await codeguide.securityKeys.listProviderAPIKeys()
437
+ } catch (error) {
438
+ if (error.message.includes('401') || error.message.includes('Authentication')) {
439
+ console.error('Authentication failed. Check your API credentials.')
440
+ }
441
+ }
442
+ ```
443
+
444
+ ## Complete Examples
445
+
446
+ ### Example 1: Managing Provider API Keys
447
+
448
+ ```typescript
449
+ import { CodeGuide } from '@codeguide/core'
450
+
451
+ const codeguide = new CodeGuide({
452
+ baseUrl: 'https://api.codeguide.ai',
453
+ databaseApiKey: process.env.CODEGUIDE_API_KEY!,
454
+ })
455
+
456
+ async function manageProviderKeys() {
457
+ try {
458
+ // 1. Store OpenAI API key
459
+ const openaiKey = await codeguide.securityKeys.createProviderAPIKey({
460
+ provider_key: 'openai',
461
+ api_key: process.env.OPENAI_API_KEY!,
462
+ })
463
+ console.log(`Stored OpenAI key: ${openaiKey.data.value_masked}`)
464
+
465
+ // 2. Store Anthropic API key
466
+ const anthropicKey = await codeguide.securityKeys.createProviderAPIKey({
467
+ provider_key: 'anthropic',
468
+ api_key: process.env.ANTHROPIC_API_KEY!,
469
+ })
470
+ console.log(`Stored Anthropic key: ${anthropicKey.data.value_masked}`)
471
+
472
+ // 3. List all stored keys
473
+ const allKeys = await codeguide.securityKeys.listProviderAPIKeys()
474
+ console.log(`\nStored ${allKeys.data.length} provider keys:`)
475
+ allKeys.data.forEach(key => {
476
+ console.log(`- ${key.provider_name}: ${key.value_masked}`)
477
+ })
478
+
479
+ // 4. Get a specific key (masked)
480
+ const retrieved = await codeguide.securityKeys.getProviderAPIKey('openai')
481
+ console.log(`\nRetrieved OpenAI key: ${retrieved.data.value_masked}`)
482
+
483
+ // 5. Revoke a key
484
+ await codeguide.securityKeys.revokeProviderAPIKey('anthropic')
485
+ console.log('\nAnthropic key revoked')
486
+ } catch (error) {
487
+ console.error('Error:', error.message)
488
+ }
489
+ }
490
+
491
+ manageProviderKeys()
492
+ ```
493
+
494
+ ### Example 2: Managing GitHub Tokens
495
+
496
+ ```typescript
497
+ async function manageGitHubToken() {
498
+ try {
499
+ // 1. Store GitHub token
500
+ const token = await codeguide.securityKeys.createGitHubToken({
501
+ github_token: process.env.GITHUB_TOKEN!,
502
+ })
503
+ console.log(`GitHub token stored: ${token.data.value_masked}`)
504
+
505
+ // 2. Retrieve token (masked)
506
+ const retrieved = await codeguide.securityKeys.getGitHubToken()
507
+ console.log(`Retrieved token: ${retrieved.data.value_masked}`)
508
+
509
+ // 3. Use token in a codespace task
510
+ const task = await codeguide.codespace.createCodespaceTaskV2({
511
+ project_id: 'proj_123456',
512
+ task_description: 'Implement new feature',
513
+ github_token: process.env.GITHUB_TOKEN!, // Or retrieve with reveal=true
514
+ })
515
+
516
+ // 4. Revoke token when done
517
+ await codeguide.securityKeys.revokeGitHubToken()
518
+ console.log('GitHub token revoked')
519
+ } catch (error) {
520
+ console.error('Error:', error.message)
521
+ }
522
+ }
523
+ ```
524
+
525
+ ### Example 3: Key Rotation
526
+
527
+ ```typescript
528
+ async function rotateProviderKey(providerKey: string, newApiKey: string) {
529
+ try {
530
+ // Check if key exists
531
+ try {
532
+ const existing = await codeguide.securityKeys.getProviderAPIKey(providerKey)
533
+ console.log(`Existing key found: ${existing.data.value_masked}`)
534
+
535
+ // Revoke old key
536
+ await codeguide.securityKeys.revokeProviderAPIKey(providerKey)
537
+ console.log('Old key revoked')
538
+ } catch (error) {
539
+ if (!error.message.includes('not found')) {
540
+ throw error
541
+ }
542
+ console.log('No existing key found')
543
+ }
544
+
545
+ // Store new key
546
+ const newKey = await codeguide.securityKeys.createProviderAPIKey({
547
+ provider_key: providerKey,
548
+ api_key: newApiKey,
549
+ })
550
+
551
+ console.log(`New key stored: ${newKey.data.value_masked}`)
552
+ return newKey
553
+ } catch (error) {
554
+ console.error('Key rotation failed:', error.message)
555
+ throw error
556
+ }
557
+ }
558
+
559
+ // Usage
560
+ await rotateProviderKey('openai', process.env.NEW_OPENAI_KEY!)
561
+ ```
562
+
563
+ ### Example 4: Security Audit
564
+
565
+ ```typescript
566
+ async function securityAudit() {
567
+ try {
568
+ // List all provider keys
569
+ const providerKeys = await codeguide.securityKeys.listProviderAPIKeys()
570
+ console.log(`\nProvider API Keys (${providerKeys.data.length}):`)
571
+ providerKeys.data.forEach(key => {
572
+ console.log(`- ${key.provider_name} (${key.provider_key})`)
573
+ console.log(` Created: ${key.created_at}`)
574
+ console.log(` Masked: ${key.value_masked}`)
575
+ })
576
+
577
+ // Check GitHub token
578
+ try {
579
+ const githubToken = await codeguide.securityKeys.getGitHubToken()
580
+ console.log(`\nGitHub Token:`)
581
+ console.log(` Created: ${githubToken.data.created_at}`)
582
+ console.log(` Masked: ${githubToken.data.value_masked}`)
583
+ } catch (error) {
584
+ if (error.message.includes('not found')) {
585
+ console.log('\nGitHub Token: Not stored')
586
+ } else {
587
+ throw error
588
+ }
589
+ }
590
+ } catch (error) {
591
+ console.error('Audit failed:', error.message)
592
+ }
593
+ }
594
+ ```
595
+
596
+ ## Security Best Practices
597
+
598
+ ### 1. Never Log Revealed Keys
599
+
600
+ ```typescript
601
+ // ❌ Bad: Logging revealed keys
602
+ const key = await codeguide.securityKeys.getProviderAPIKey('openai', true)
603
+ console.log(key.data.value) // Never do this!
604
+
605
+ // ✅ Good: Only log masked values
606
+ const key = await codeguide.securityKeys.getProviderAPIKey('openai')
607
+ console.log(key.data.value_masked) // Safe to log
608
+ ```
609
+
610
+ ### 2. Use Environment Variables
611
+
612
+ ```typescript
613
+ // ✅ Good: Store keys in environment variables
614
+ const key = await codeguide.securityKeys.createProviderAPIKey({
615
+ provider_key: 'openai',
616
+ api_key: process.env.OPENAI_API_KEY!, // From environment
617
+ })
618
+
619
+ // ❌ Bad: Hardcoding keys
620
+ const key = await codeguide.securityKeys.createProviderAPIKey({
621
+ provider_key: 'openai',
622
+ api_key: 'sk-hardcoded-key-here', // Never do this!
623
+ })
624
+ ```
625
+
626
+ ### 3. Rotate Keys Regularly
627
+
628
+ ```typescript
629
+ // Implement key rotation schedule
630
+ async function rotateKeysMonthly() {
631
+ const providers = ['openai', 'anthropic']
632
+
633
+ for (const provider of providers) {
634
+ // Generate new key (implementation depends on provider)
635
+ const newKey = await generateNewKey(provider)
636
+
637
+ // Rotate
638
+ await rotateProviderKey(provider, newKey)
639
+ }
640
+ }
641
+ ```
642
+
643
+ ### 4. Handle Errors Gracefully
644
+
645
+ ```typescript
646
+ async function safeGetKey(providerKey: string) {
647
+ try {
648
+ return await codeguide.securityKeys.getProviderAPIKey(providerKey)
649
+ } catch (error) {
650
+ if (error.message.includes('not found')) {
651
+ console.warn(`No key found for ${providerKey}`)
652
+ return null
653
+ }
654
+ throw error
655
+ }
656
+ }
657
+ ```
658
+
659
+ ### 5. Revoke Unused Keys
660
+
661
+ ```typescript
662
+ async function cleanupUnusedKeys() {
663
+ const keys = await codeguide.securityKeys.listProviderAPIKeys()
664
+
665
+ // Implement logic to identify unused keys
666
+ const unusedKeys = keys.data.filter(key => {
667
+ // Your logic here
668
+ return false // Placeholder
669
+ })
670
+
671
+ for (const key of unusedKeys) {
672
+ await codeguide.securityKeys.revokeProviderAPIKey(key.provider_key)
673
+ console.log(`Revoked unused key: ${key.provider_key}`)
674
+ }
675
+ }
676
+ ```
677
+
678
+ ## Type Definitions
679
+
680
+ ### Complete Type Reference
681
+
682
+ ```typescript
683
+ // Provider API Key Types
684
+ interface CreateProviderAPIKeyRequest {
685
+ provider_key: string
686
+ api_key: string
687
+ }
688
+
689
+ interface ProviderAPIKeyData {
690
+ id: string
691
+ created_at: string
692
+ user_id: string
693
+ name: string
694
+ displayed_name: string
695
+ value_masked: string
696
+ value?: string
697
+ object_value: {
698
+ provider_id: string
699
+ }
700
+ encryption: string
701
+ key_version: string
702
+ provider_id: string
703
+ provider_name: string
704
+ provider_key: string
705
+ provider_logo_src?: string
706
+ }
707
+
708
+ // GitHub Token Types
709
+ interface CreateGitHubTokenRequest {
710
+ github_token: string
711
+ }
712
+
713
+ interface GitHubTokenData {
714
+ id: string
715
+ created_at: string
716
+ user_id: string
717
+ name: string
718
+ displayed_name: string
719
+ value_masked: string
720
+ value?: string
721
+ object_value: {
722
+ token_type: string
723
+ }
724
+ encryption: string
725
+ key_version: string
726
+ }
727
+
728
+ // Response Types
729
+ interface CreateProviderAPIKeyResponse {
730
+ status: 'success'
731
+ data: ProviderAPIKeyData
732
+ }
733
+
734
+ interface GetProviderAPIKeyResponse {
735
+ status: 'success'
736
+ data: ProviderAPIKeyData
737
+ }
738
+
739
+ interface ListProviderAPIKeysResponse {
740
+ status: 'success'
741
+ data: ProviderAPIKeyData[]
742
+ }
743
+
744
+ interface RevokeProviderAPIKeyResponse {
745
+ status: string
746
+ message: string
747
+ revoked_provider_id: string
748
+ }
749
+
750
+ interface CreateGitHubTokenResponse {
751
+ status: 'success'
752
+ data: GitHubTokenData
753
+ }
754
+
755
+ interface GetGitHubTokenResponse {
756
+ status: 'success'
757
+ data: GitHubTokenData
758
+ }
759
+
760
+ interface RevokeGitHubTokenResponse {
761
+ status: string
762
+ message: string
763
+ revoked_at: string
764
+ }
765
+ ```
766
+
767
+ ## Related Documentation
768
+
769
+ - [CodeGuide Client](./codeguide-client.md) - Client initialization
770
+ - [Authentication](./authentication.md) - Authentication methods
771
+ - [Projects Service](./projects-service.md) - Project management
772
+ - [Codespace Service](./codespace-service.md) - Using keys in codespace tasks
773
+