bktide 1.0.1755267617 → 1.0.1755559112

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 (93) hide show
  1. package/README.md +107 -1
  2. package/WORKFLOW_README.md +1 -1
  3. package/completions/bktide-dynamic.fish +171 -0
  4. package/completions/bktide.bash +124 -0
  5. package/completions/bktide.fish +107 -0
  6. package/completions/bktide.zsh +139 -0
  7. package/dist/commands/BaseCommand.js +7 -7
  8. package/dist/commands/BaseCommand.js.map +1 -1
  9. package/dist/commands/GenerateCompletions.js +238 -0
  10. package/dist/commands/GenerateCompletions.js.map +1 -0
  11. package/dist/commands/ListAnnotations.js +7 -0
  12. package/dist/commands/ListAnnotations.js.map +1 -1
  13. package/dist/commands/ListBuilds.js +67 -3
  14. package/dist/commands/ListBuilds.js.map +1 -1
  15. package/dist/commands/ListOrganizations.js +6 -0
  16. package/dist/commands/ListOrganizations.js.map +1 -1
  17. package/dist/commands/ListPipelines.js +87 -12
  18. package/dist/commands/ListPipelines.js.map +1 -1
  19. package/dist/commands/ManageToken.js +32 -9
  20. package/dist/commands/ManageToken.js.map +1 -1
  21. package/dist/commands/ShowBuild.js +88 -0
  22. package/dist/commands/ShowBuild.js.map +1 -0
  23. package/dist/commands/ShowViewer.js +7 -1
  24. package/dist/commands/ShowViewer.js.map +1 -1
  25. package/dist/commands/index.js +2 -0
  26. package/dist/commands/index.js.map +1 -1
  27. package/dist/formatters/FormatterFactory.js +4 -0
  28. package/dist/formatters/FormatterFactory.js.map +1 -1
  29. package/dist/formatters/annotations/PlainTextFormatter.js +37 -9
  30. package/dist/formatters/annotations/PlainTextFormatter.js.map +1 -1
  31. package/dist/formatters/build-detail/AlfredFormatter.js +113 -0
  32. package/dist/formatters/build-detail/AlfredFormatter.js.map +1 -0
  33. package/dist/formatters/build-detail/Formatter.js +3 -0
  34. package/dist/formatters/build-detail/Formatter.js.map +1 -0
  35. package/dist/formatters/build-detail/JsonFormatter.js +132 -0
  36. package/dist/formatters/build-detail/JsonFormatter.js.map +1 -0
  37. package/dist/formatters/build-detail/PlainTextFormatter.js +680 -0
  38. package/dist/formatters/build-detail/PlainTextFormatter.js.map +1 -0
  39. package/dist/formatters/build-detail/index.js +21 -0
  40. package/dist/formatters/build-detail/index.js.map +1 -0
  41. package/dist/formatters/builds/PlainTextFormatter.js +82 -60
  42. package/dist/formatters/builds/PlainTextFormatter.js.map +1 -1
  43. package/dist/formatters/errors/AlfredFormatter.js +20 -0
  44. package/dist/formatters/errors/AlfredFormatter.js.map +1 -1
  45. package/dist/formatters/errors/PlainTextFormatter.js +121 -23
  46. package/dist/formatters/errors/PlainTextFormatter.js.map +1 -1
  47. package/dist/formatters/organizations/PlainTextFormatter.js +37 -6
  48. package/dist/formatters/organizations/PlainTextFormatter.js.map +1 -1
  49. package/dist/formatters/pipelines/AlfredFormatter.js.map +1 -1
  50. package/dist/formatters/pipelines/Formatter.js.map +1 -1
  51. package/dist/formatters/pipelines/JsonFormatter.js.map +1 -1
  52. package/dist/formatters/pipelines/PlainTextFormatter.js +165 -19
  53. package/dist/formatters/pipelines/PlainTextFormatter.js.map +1 -1
  54. package/dist/formatters/token/AlfredFormatter.js +15 -2
  55. package/dist/formatters/token/AlfredFormatter.js.map +1 -1
  56. package/dist/formatters/token/PlainTextFormatter.js +56 -18
  57. package/dist/formatters/token/PlainTextFormatter.js.map +1 -1
  58. package/dist/formatters/viewer/PlainTextFormatter.js +8 -7
  59. package/dist/formatters/viewer/PlainTextFormatter.js.map +1 -1
  60. package/dist/graphql/queries.js +181 -0
  61. package/dist/graphql/queries.js.map +1 -1
  62. package/dist/index.js +67 -6
  63. package/dist/index.js.map +1 -1
  64. package/dist/services/BuildkiteClient.js +61 -1
  65. package/dist/services/BuildkiteClient.js.map +1 -1
  66. package/dist/services/CredentialManager.js +80 -10
  67. package/dist/services/CredentialManager.js.map +1 -1
  68. package/dist/ui/help.js +69 -0
  69. package/dist/ui/help.js.map +1 -0
  70. package/dist/ui/progress.js +356 -0
  71. package/dist/ui/progress.js.map +1 -0
  72. package/dist/ui/reporter.js +111 -0
  73. package/dist/ui/reporter.js.map +1 -0
  74. package/dist/ui/responsive-table.js +183 -0
  75. package/dist/ui/responsive-table.js.map +1 -0
  76. package/dist/ui/spinner.js +20 -0
  77. package/dist/ui/spinner.js.map +1 -0
  78. package/dist/ui/symbols.js +46 -0
  79. package/dist/ui/symbols.js.map +1 -0
  80. package/dist/ui/table.js +32 -0
  81. package/dist/ui/table.js.map +1 -0
  82. package/dist/ui/theme.js +280 -0
  83. package/dist/ui/theme.js.map +1 -0
  84. package/dist/ui/width.js +111 -0
  85. package/dist/ui/width.js.map +1 -0
  86. package/dist/utils/alfred.js +6 -0
  87. package/dist/utils/alfred.js.map +1 -0
  88. package/dist/utils/cli-error-handler.js +35 -20
  89. package/dist/utils/cli-error-handler.js.map +1 -1
  90. package/dist/utils/pagination.js +92 -0
  91. package/dist/utils/pagination.js.map +1 -0
  92. package/info.plist +51 -218
  93. package/package.json +24 -5
@@ -1 +1 @@
1
- {"version":3,"file":"AlfredFormatter.js","sourceRoot":"/","sources":["formatters/token/AlfredFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { TokenStatus, TokenValidationStatus } from '../../types/credentials.js';\nimport { BaseTokenFormatter } from './Formatter.js';\n\ninterface AlfredItem {\n title: string;\n subtitle: string;\n icon: string;\n arg: string;\n}\n\n/**\n * Alfred formatter for tokens\n */\nexport class AlfredFormatter extends BaseTokenFormatter {\n name = 'alfred';\n\n /**\n * Format token status information for Alfred\n * \n * @param status The token status information\n * @returns Formatted token status message for Alfred\n */\n formatTokenStatus(status: TokenStatus): string {\n const items = this.formatTokenStatusAsItems(status);\n return JSON.stringify({ items });\n }\n\n /**\n * Format token storage result for Alfred\n * \n * @param success Whether the token was successfully stored\n * @returns Formatted token storage result message for Alfred\n */\n formatTokenStorageResult(success: boolean): string {\n const items: AlfredItem[] = [{\n title: success ? 'Token Stored Successfully' : 'Failed to Store Token',\n subtitle: success ? 'Token was saved to system keychain' : 'Could not save token to system keychain',\n icon: this.getIcon(success),\n arg: success ? 'token:stored' : 'token:store-failed'\n }];\n return JSON.stringify({ items });\n }\n\n /**\n * Format token reset result for Alfred\n * \n * @param success Whether the token was successfully reset\n * @param hadToken Whether there was a token before reset\n * @returns Formatted token reset result message for Alfred\n */\n formatTokenResetResult(success: boolean, hadToken: boolean): string {\n const items: AlfredItem[] = [{\n title: success ? 'Token Reset Successfully' : 'Failed to Reset Token',\n subtitle: success \n ? hadToken \n ? 'Token was removed from system keychain' \n : 'No token was present to reset'\n : 'Could not remove token from system keychain',\n icon: this.getIcon(success),\n arg: success ? 'token:reset' : 'token:reset-failed'\n }];\n return JSON.stringify({ items });\n }\n\n /**\n * Format token validation error for Alfred\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation error message for Alfred\n */\n formatTokenValidationError(validation: TokenValidationStatus): string {\n const items = this.formatTokenValidationStatusAsItems(validation);\n return JSON.stringify({ items });\n }\n\n /**\n * Format token validation status for Alfred\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation status message for Alfred\n */\n formatTokenValidationStatus(validation: TokenValidationStatus): string {\n const items = this.formatTokenValidationStatusAsItems(validation);\n return JSON.stringify({ items });\n }\n\n /**\n * Format error message(s) for Alfred\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param error The error that occurred, or an array of errors\n * @returns Formatted error message(s) for Alfred\n */\n formatError(operation: string, error: unknown | unknown[]): string {\n const errors = Array.isArray(error) ? error : [error];\n const items: AlfredItem[] = errors.map(err => ({\n title: `Error during ${operation}`,\n subtitle: err instanceof Error ? err.message : String(err),\n icon: this.getIcon(false),\n arg: `error:${operation}`\n }));\n return JSON.stringify({ items });\n }\n\n /**\n * Format authentication error message(s) for Alfred\n * \n * @param operation The authentication operation that failed (e.g., 'storing', 'validating')\n * @param error The authentication error that occurred, or an array of errors\n * @returns Formatted authentication error message(s) for Alfred\n */\n formatAuthErrors(operation: string, error: unknown | unknown[]): string {\n const errors = Array.isArray(error) ? error : [error];\n const items: AlfredItem[] = errors.map(err => ({\n title: `Authentication Error during ${operation}`,\n subtitle: err instanceof Error ? err.message : String(err),\n icon: this.getIcon(false),\n arg: `auth-error:${operation}`\n }));\n return JSON.stringify({ items });\n }\n\n private getIcon(isValid: boolean): string {\n return isValid ? '✅' : '❌';\n }\n\n private formatTokenStatusAsItems(status: TokenStatus): AlfredItem[] {\n const items: AlfredItem[] = [];\n \n // Add token status item\n items.push({\n title: `Token Status: ${status.hasToken ? 'Present' : 'Not Present'}`,\n subtitle: status.hasToken ? 'Token is stored in system keychain' : 'No token found in system keychain',\n icon: this.getIcon(status.hasToken),\n arg: status.hasToken ? 'token:present' : 'token:not-present'\n });\n\n if (status.hasToken) {\n // Add overall validity item\n items.push({\n title: `Valid: ${status.isValid ? 'Yes' : 'No'}`,\n subtitle: status.isValid ? 'Token is valid for all required APIs' : 'Token has limited access',\n icon: this.getIcon(status.isValid),\n arg: status.isValid ? 'token:valid' : 'token:invalid'\n });\n\n if (status.validation.canListOrganizations) {\n // Add organization status items\n Object.entries(status.validation.organizations).forEach(([org, orgStatus]) => {\n const isValid = orgStatus.graphql && orgStatus.builds && orgStatus.organizations;\n const invalidApis = [];\n if (!orgStatus.graphql) invalidApis.push('GraphQL');\n if (!orgStatus.builds) invalidApis.push('Builds');\n if (!orgStatus.organizations) invalidApis.push('Organizations');\n \n items.push({\n title: `Organization: ${org}`,\n subtitle: isValid \n ? 'Full access to all APIs'\n : `Limited access: ${invalidApis.join(', ')}`,\n icon: this.getIcon(isValid),\n arg: isValid ? `org:${org}:valid` : `org:${org}:invalid`\n });\n });\n } else {\n items.push({\n title: 'Cannot list organizations',\n subtitle: 'Token may be invalid or lacks necessary permissions',\n icon: this.getIcon(false),\n arg: 'token:no-org-access'\n });\n }\n }\n\n return items;\n }\n\n private formatTokenValidationStatusAsItems(validation: TokenValidationStatus): AlfredItem[] {\n const items: AlfredItem[] = [];\n\n if (!validation.canListOrganizations) {\n items.push({\n title: 'Cannot list organizations',\n subtitle: 'Token may be invalid or lacks necessary permissions',\n icon: this.getIcon(false),\n arg: 'token:no-org-access'\n });\n return items;\n }\n\n // Add organization status items\n Object.entries(validation.organizations).forEach(([org, orgStatus]) => {\n const isValid = orgStatus.graphql && orgStatus.builds && orgStatus.organizations;\n const invalidApis = [];\n if (!orgStatus.graphql) invalidApis.push('GraphQL');\n if (!orgStatus.builds) invalidApis.push('Builds');\n if (!orgStatus.organizations) invalidApis.push('Organizations');\n \n items.push({\n title: `Organization: ${org}`,\n subtitle: isValid \n ? 'Full access to all APIs'\n : `Limited access: ${invalidApis.join(', ')}`,\n icon: this.getIcon(isValid),\n arg: isValid ? `org:${org}:valid` : `org:${org}:invalid`\n });\n });\n\n return items;\n }\n} "]}
1
+ {"version":3,"file":"AlfredFormatter.js","sourceRoot":"/","sources":["formatters/token/AlfredFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { TokenStatus, TokenValidationStatus } from '../../types/credentials.js';\nimport { isRunningInAlfred } from '../../utils/alfred.js';\nimport { BaseTokenFormatter } from './Formatter.js';\n\ninterface AlfredItem {\n title: string;\n subtitle: string;\n icon: string;\n arg: string;\n}\n\n/**\n * Alfred formatter for tokens\n */\nexport class AlfredFormatter extends BaseTokenFormatter {\n name = 'alfred';\n\n /**\n * Format token status information for Alfred\n * \n * @param status The token status information\n * @returns Formatted token status message for Alfred\n */\n formatTokenStatus(status: TokenStatus): string {\n const items = this.formatTokenStatusAsItems(status);\n return JSON.stringify({ items });\n }\n\n /**\n * Format token storage result for Alfred\n * \n * @param success Whether the token was successfully stored\n * @returns Formatted token storage result message for Alfred\n */\n formatTokenStorageResult(success: boolean): string {\n const items: AlfredItem[] = [{\n title: success ? 'Token Stored Successfully' : 'Failed to Store Token',\n subtitle: success ? 'Token was saved to system keychain' : 'Could not save token to system keychain',\n icon: this.getIcon(success),\n arg: success ? 'token:stored' : 'token:store-failed'\n }];\n return JSON.stringify({ items });\n }\n\n /**\n * Format token reset result for Alfred\n * \n * @param success Whether the token was successfully reset\n * @param hadToken Whether there was a token before reset\n * @returns Formatted token reset result message for Alfred\n */\n formatTokenResetResult(success: boolean, hadToken: boolean): string {\n const items: AlfredItem[] = [{\n title: success ? 'Token Reset Successfully' : 'Failed to Reset Token',\n subtitle: success \n ? hadToken \n ? 'Token was removed from system keychain' \n : 'No token was present to reset'\n : 'Could not remove token from system keychain',\n icon: this.getIcon(success),\n arg: success ? 'token:reset' : 'token:reset-failed'\n }];\n return JSON.stringify({ items });\n }\n\n /**\n * Format token validation error for Alfred\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation error message for Alfred\n */\n formatTokenValidationError(validation: TokenValidationStatus): string {\n const items = this.formatTokenValidationStatusAsItems(validation);\n return JSON.stringify({ items });\n }\n\n /**\n * Format token validation status for Alfred\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation status message for Alfred\n */\n formatTokenValidationStatus(validation: TokenValidationStatus): string {\n const items = this.formatTokenValidationStatusAsItems(validation);\n return JSON.stringify({ items });\n }\n\n /**\n * Format error message(s) for Alfred\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param error The error that occurred, or an array of errors\n * @returns Formatted error message(s) for Alfred\n */\n formatError(operation: string, error: unknown | unknown[]): string {\n const errors = Array.isArray(error) ? error : [error];\n const items: AlfredItem[] = errors.map(err => ({\n title: `Error during ${operation}`,\n subtitle: err instanceof Error ? err.message : String(err),\n icon: this.getIcon(false),\n arg: `error:${operation}`\n }));\n return JSON.stringify({ items });\n }\n\n /**\n * Format authentication error message(s) for Alfred\n * \n * @param operation The authentication operation that failed (e.g., 'storing', 'validating')\n * @param error The authentication error that occurred, or an array of errors\n * @returns Formatted authentication error message(s) for Alfred\n */\n formatAuthErrors(operation: string, error: unknown | unknown[]): string {\n const errors = Array.isArray(error) ? error : [error];\n const items: AlfredItem[] = errors.map(err => ({\n title: `Authentication Error during ${operation}`,\n subtitle: err instanceof Error ? err.message : String(err),\n icon: this.getIcon(false),\n arg: `auth-error:${operation}`\n }));\n return JSON.stringify({ items });\n }\n\n private getIcon(isValid: boolean): string {\n return isValid ? '✅' : '❌';\n }\n\n private formatTokenStatusAsItems(status: TokenStatus): AlfredItem[] {\n const items: AlfredItem[] = [];\n \n const inAlfred = isRunningInAlfred();\n\n // Alfred-first UX: if no token, present actionable item to open config\n if (inAlfred && !status.hasToken) {\n items.push({\n title: 'Set Buildkite token',\n subtitle: 'Open Workflow Configuration to set BUILDKITE_API_TOKEN',\n icon: 'icons/info.png',\n arg: 'alfred:open-config'\n });\n }\n\n // Add token status item with context-aware subtitle\n items.push({\n title: `Token Status: ${status.hasToken ? 'Present' : 'Not Present'}`,\n subtitle: status.hasToken\n ? (inAlfred ? 'Token provided via Workflow Configuration' : 'Token is stored in system keychain')\n : (inAlfred ? 'No token set in Workflow Configuration' : 'No token found in system keychain'),\n icon: this.getIcon(status.hasToken),\n arg: status.hasToken ? 'token:present' : 'token:not-present'\n });\n\n if (status.hasToken) {\n // Add overall validity item\n items.push({\n title: `Valid: ${status.isValid ? 'Yes' : 'No'}`,\n subtitle: status.isValid ? 'Token is valid for all required APIs' : 'Token has limited access',\n icon: this.getIcon(status.isValid),\n arg: status.isValid ? 'token:valid' : 'token:invalid'\n });\n\n if (status.validation.canListOrganizations) {\n // Add organization status items\n Object.entries(status.validation.organizations).forEach(([org, orgStatus]) => {\n const isValid = orgStatus.graphql && orgStatus.builds && orgStatus.organizations;\n const invalidApis = [];\n if (!orgStatus.graphql) invalidApis.push('GraphQL');\n if (!orgStatus.builds) invalidApis.push('Builds');\n if (!orgStatus.organizations) invalidApis.push('Organizations');\n \n items.push({\n title: `Organization: ${org}`,\n subtitle: isValid \n ? 'Full access to all APIs'\n : `Limited access: ${invalidApis.join(', ')}`,\n icon: this.getIcon(isValid),\n arg: isValid ? `org:${org}:valid` : `org:${org}:invalid`\n });\n });\n } else {\n items.push({\n title: 'Cannot list organizations',\n subtitle: 'Token may be invalid or lacks necessary permissions',\n icon: this.getIcon(false),\n arg: 'token:no-org-access'\n });\n }\n }\n\n return items;\n }\n\n private formatTokenValidationStatusAsItems(validation: TokenValidationStatus): AlfredItem[] {\n const items: AlfredItem[] = [];\n\n if (!validation.canListOrganizations) {\n items.push({\n title: 'Cannot list organizations',\n subtitle: 'Token may be invalid or lacks necessary permissions',\n icon: this.getIcon(false),\n arg: 'token:no-org-access'\n });\n return items;\n }\n\n // Add organization status items\n Object.entries(validation.organizations).forEach(([org, orgStatus]) => {\n const isValid = orgStatus.graphql && orgStatus.builds && orgStatus.organizations;\n const invalidApis = [];\n if (!orgStatus.graphql) invalidApis.push('GraphQL');\n if (!orgStatus.builds) invalidApis.push('Builds');\n if (!orgStatus.organizations) invalidApis.push('Organizations');\n \n items.push({\n title: `Organization: ${org}`,\n subtitle: isValid \n ? 'Full access to all APIs'\n : `Limited access: ${invalidApis.join(', ')}`,\n icon: this.getIcon(isValid),\n arg: isValid ? `org:${org}:valid` : `org:${org}:invalid`\n });\n });\n\n return items;\n }\n} "]}
@@ -1,4 +1,5 @@
1
1
  import { BaseTokenFormatter } from './Formatter.js';
2
+ import { SEMANTIC_COLORS, formatError as themeFormatError, formatTips, TipStyle } from '../../ui/theme.js';
2
3
  /**
3
4
  * Plain text formatter for tokens
4
5
  */
@@ -12,21 +13,42 @@ export class PlainTextFormatter extends BaseTokenFormatter {
12
13
  */
13
14
  formatTokenStatus(status) {
14
15
  const lines = [];
15
- lines.push(`Token Status: ${status.hasToken ? 'Present' : 'Not Present'}`);
16
+ // Header with visual emphasis
17
+ lines.push(SEMANTIC_COLORS.heading('Token Configuration'));
18
+ lines.push('');
19
+ // Token presence with semantic coloring - aligned labels
20
+ if (status.hasToken) {
21
+ if (status.isValid) {
22
+ lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.success('✓ Valid token')}`);
23
+ }
24
+ else {
25
+ lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.error('✖ Invalid token')}`);
26
+ }
27
+ }
28
+ else {
29
+ lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.muted('No token configured')}`);
30
+ }
16
31
  if (status.hasToken) {
17
- lines.push(`Valid: ${status.isValid ? 'Yes' : 'No'}`);
18
32
  if (status.validation.canListOrganizations) {
19
33
  const validOrgs = Object.entries(status.validation.organizations)
20
34
  .filter(([_, status]) => status.graphql && status.builds && status.organizations)
21
35
  .map(([org]) => org);
22
- if (validOrgs.length > 0) {
23
- lines.push('Valid Organizations:');
24
- validOrgs.forEach(org => lines.push(` - ${org}`));
25
- }
26
36
  const invalidOrgs = Object.entries(status.validation.organizations)
27
37
  .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations);
38
+ // Display access info with aligned labels
39
+ if (validOrgs.length > 0 || invalidOrgs.length > 0) {
40
+ const totalOrgs = validOrgs.length + invalidOrgs.length;
41
+ const accessLabel = totalOrgs === 1 ? 'Organization' : 'Organizations';
42
+ lines.push(`${SEMANTIC_COLORS.label('Access:')} ${SEMANTIC_COLORS.count(totalOrgs.toString())} ${accessLabel.toLowerCase()}`);
43
+ }
44
+ if (validOrgs.length > 0) {
45
+ lines.push('');
46
+ lines.push(SEMANTIC_COLORS.label('Valid Organizations:'));
47
+ validOrgs.forEach(org => lines.push(` ${SEMANTIC_COLORS.success('✓')} ${org}`));
48
+ }
28
49
  if (invalidOrgs.length > 0) {
29
- lines.push('Organizations with Limited Access:');
50
+ lines.push('');
51
+ lines.push(SEMANTIC_COLORS.warning('Limited Access:'));
30
52
  invalidOrgs.forEach(([org, status]) => {
31
53
  const invalidApis = [];
32
54
  if (!status.graphql)
@@ -35,14 +57,23 @@ export class PlainTextFormatter extends BaseTokenFormatter {
35
57
  invalidApis.push('Builds');
36
58
  if (!status.organizations)
37
59
  invalidApis.push('Organizations');
38
- lines.push(` - ${org} (${invalidApis.join(', ')})`);
60
+ lines.push(` ${SEMANTIC_COLORS.warning('⚠')} ${org} ${SEMANTIC_COLORS.dim(`(missing: ${invalidApis.join(', ')})`)} `);
39
61
  });
40
62
  }
41
63
  }
42
64
  else {
43
- lines.push('Cannot list organizations - token may be invalid');
65
+ lines.push(`${SEMANTIC_COLORS.label('Access:')} ${SEMANTIC_COLORS.error('Cannot list organizations')}`);
44
66
  }
45
67
  }
68
+ else {
69
+ // Help for users without a token
70
+ lines.push('');
71
+ const actionTips = [
72
+ 'Run: bktide token --store',
73
+ 'Or set: BUILDKITE_API_TOKEN environment variable'
74
+ ];
75
+ lines.push(formatTips(actionTips, TipStyle.ACTIONS));
76
+ }
46
77
  return lines.join('\n');
47
78
  }
48
79
  /**
@@ -53,10 +84,10 @@ export class PlainTextFormatter extends BaseTokenFormatter {
53
84
  */
54
85
  formatTokenStorageResult(success) {
55
86
  if (success) {
56
- return 'Token successfully stored in system keychain';
87
+ return `${SEMANTIC_COLORS.success('✓')} Token stored in system keychain`;
57
88
  }
58
89
  else {
59
- return 'Failed to store token';
90
+ return `${SEMANTIC_COLORS.error('✖')} Failed to store token`;
60
91
  }
61
92
  }
62
93
  /**
@@ -68,13 +99,13 @@ export class PlainTextFormatter extends BaseTokenFormatter {
68
99
  */
69
100
  formatTokenResetResult(success, hadToken) {
70
101
  if (!hadToken) {
71
- return 'No token found in system keychain';
102
+ return `${SEMANTIC_COLORS.muted('No token found in system keychain')}`;
72
103
  }
73
104
  if (success) {
74
- return 'Token successfully deleted from system keychain';
105
+ return `${SEMANTIC_COLORS.success('✓')} Token removed from system keychain`;
75
106
  }
76
107
  else {
77
- return 'Failed to delete token';
108
+ return `${SEMANTIC_COLORS.error('✖')} Failed to delete token`;
78
109
  }
79
110
  }
80
111
  /**
@@ -148,10 +179,17 @@ export class PlainTextFormatter extends BaseTokenFormatter {
148
179
  */
149
180
  formatError(operation, error) {
150
181
  const errors = Array.isArray(error) ? error : [error];
151
- return errors.map(error => {
152
- const errorMessage = error instanceof Error ? error.message : String(error);
153
- return `Error ${operation} token: ${errorMessage}`;
154
- }).join('\n');
182
+ const errorMessages = errors.map(err => {
183
+ const errorMessage = err instanceof Error ? err.message : String(err);
184
+ return errorMessage;
185
+ });
186
+ const suggestions = [];
187
+ if (operation === 'storing' || operation === 'validating') {
188
+ suggestions.push('Check your Buildkite API token permissions');
189
+ suggestions.push('Get a new token at: https://buildkite.com/user/api-access-tokens');
190
+ }
191
+ const errorText = `Error ${operation} token: ${errorMessages.join(', ')}`;
192
+ return themeFormatError(errorText, { suggestions });
155
193
  }
156
194
  /**
157
195
  * Format authentication error message(s) in plain text
@@ -1 +1 @@
1
- {"version":3,"file":"PlainTextFormatter.js","sourceRoot":"/","sources":["formatters/token/PlainTextFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseTokenFormatter, TokenFormatter } from './Formatter.js';\nimport { TokenStatus, TokenValidationStatus } from '../../types/credentials.js';\n \n/**\n * Plain text formatter for tokens\n */\nexport class PlainTextFormatter extends BaseTokenFormatter implements TokenFormatter {\n name = 'plain';\n\n /**\n * Format token status information in plain text\n * \n * @param status The token status information\n * @returns Formatted token status message\n */\n formatTokenStatus(status: TokenStatus): string {\n const lines: string[] = [];\n lines.push(`Token Status: ${status.hasToken ? 'Present' : 'Not Present'}`);\n \n if (status.hasToken) {\n lines.push(`Valid: ${status.isValid ? 'Yes' : 'No'}`);\n \n if (status.validation.canListOrganizations) {\n const validOrgs = Object.entries(status.validation.organizations)\n .filter(([_, status]) => status.graphql && status.builds && status.organizations)\n .map(([org]) => org);\n \n if (validOrgs.length > 0) {\n lines.push('Valid Organizations:');\n validOrgs.forEach(org => lines.push(` - ${org}`));\n }\n\n const invalidOrgs = Object.entries(status.validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations);\n \n if (invalidOrgs.length > 0) {\n lines.push('Organizations with Limited Access:');\n invalidOrgs.forEach(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n lines.push(` - ${org} (${invalidApis.join(', ')})`);\n });\n }\n } else {\n lines.push('Cannot list organizations - token may be invalid');\n }\n }\n \n return lines.join('\\n');\n }\n\n /**\n * Format token storage result in plain text\n * \n * @param success Whether the token was successfully stored\n * @returns Formatted token storage result message\n */\n formatTokenStorageResult(success: boolean): string {\n if (success) {\n return 'Token successfully stored in system keychain';\n } else {\n return 'Failed to store token';\n }\n }\n\n /**\n * Format token reset result in plain text\n * \n * @param success Whether the token was successfully reset\n * @param hadToken Whether there was a token before reset\n * @returns Formatted token reset result message\n */\n formatTokenResetResult(success: boolean, hadToken: boolean): string {\n if (!hadToken) {\n return 'No token found in system keychain';\n }\n\n if (success) {\n return 'Token successfully deleted from system keychain';\n } else {\n return 'Failed to delete token';\n }\n }\n\n /**\n * Format token validation error in plain text\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation error message\n */\n formatTokenValidationError(\n validation: TokenValidationStatus\n ): string {\n if (!validation.canListOrganizations) {\n return 'Token is invalid or does not have access to list organizations';\n }\n\n const invalidOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations)\n .map(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n return `${org} (${invalidApis.join(', ')})`;\n });\n\n if (invalidOrgs.length === 0) {\n return 'Token is valid for all organizations';\n }\n\n return `Token has limited access in some organizations: ${invalidOrgs.join(', ')}`;\n }\n\n /**\n * Format token validation status in plain text\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation status message\n */\n formatTokenValidationStatus(validation: TokenValidationStatus): string {\n if (!validation.canListOrganizations) {\n return 'Token is invalid or does not have access to list organizations';\n }\n\n const lines: string[] = [];\n const validOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => status.graphql && status.builds && status.organizations)\n .map(([org]) => org);\n \n if (validOrgs.length > 0) {\n lines.push('Valid Organizations:');\n validOrgs.forEach(org => lines.push(` - ${org}`));\n }\n\n const invalidOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations);\n \n if (invalidOrgs.length > 0) {\n lines.push('Organizations with Limited Access:');\n invalidOrgs.forEach(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n lines.push(` - ${org} (${invalidApis.join(', ')})`);\n });\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Format error message(s) in plain text\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param error The error that occurred, or an array of errors\n * @returns Formatted error message(s)\n */\n formatError(\n operation: string,\n error: unknown | unknown[]\n ): string {\n const errors = Array.isArray(error) ? error : [error];\n return errors.map(error => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return `Error ${operation} token: ${errorMessage}`;\n }).join('\\n');\n }\n\n /**\n * Format authentication error message(s) in plain text\n * \n * @param operation The authentication operation that failed (e.g., 'storing', 'validating')\n * @param error The authentication error that occurred, or an array of errors\n * @returns Formatted authentication error message(s)\n */\n formatAuthErrors(\n operation: string,\n error: unknown | unknown[]\n ): string {\n const errors = Array.isArray(error) ? error : [error];\n return errors.map(error => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return `Authentication error ${operation} token: ${errorMessage}\\nPlease check your token permissions and try again`;\n }).join('\\n\\n');\n }\n\n /**\n * Format multiple error messages in plain text\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param errors Array of errors that occurred\n * @returns Formatted error messages\n */\n formatErrors(\n operation: string,\n errors: unknown[]\n ): string {\n return errors.map(error => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return `Error ${operation} token: ${errorMessage}`;\n }).join('\\n');\n }\n} "]}
1
+ {"version":3,"file":"PlainTextFormatter.js","sourceRoot":"/","sources":["formatters/token/PlainTextFormatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseTokenFormatter, TokenFormatter } from './Formatter.js';\nimport { TokenStatus, TokenValidationStatus } from '../../types/credentials.js';\nimport { SEMANTIC_COLORS, formatError as themeFormatError, formatTips, TipStyle } from '../../ui/theme.js';\n \n/**\n * Plain text formatter for tokens\n */\nexport class PlainTextFormatter extends BaseTokenFormatter implements TokenFormatter {\n name = 'plain';\n\n /**\n * Format token status information in plain text\n * \n * @param status The token status information\n * @returns Formatted token status message\n */\n formatTokenStatus(status: TokenStatus): string {\n const lines: string[] = [];\n \n // Header with visual emphasis\n lines.push(SEMANTIC_COLORS.heading('Token Configuration'));\n lines.push('');\n \n // Token presence with semantic coloring - aligned labels\n if (status.hasToken) {\n if (status.isValid) {\n lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.success('✓ Valid token')}`);\n } else {\n lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.error('✖ Invalid token')}`);\n }\n } else {\n lines.push(`${SEMANTIC_COLORS.label('Status:')} ${SEMANTIC_COLORS.muted('No token configured')}`);\n }\n \n if (status.hasToken) {\n if (status.validation.canListOrganizations) {\n const validOrgs = Object.entries(status.validation.organizations)\n .filter(([_, status]) => status.graphql && status.builds && status.organizations)\n .map(([org]) => org);\n \n const invalidOrgs = Object.entries(status.validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations);\n \n // Display access info with aligned labels\n if (validOrgs.length > 0 || invalidOrgs.length > 0) {\n const totalOrgs = validOrgs.length + invalidOrgs.length;\n const accessLabel = totalOrgs === 1 ? 'Organization' : 'Organizations';\n lines.push(`${SEMANTIC_COLORS.label('Access:')} ${SEMANTIC_COLORS.count(totalOrgs.toString())} ${accessLabel.toLowerCase()}`);\n }\n \n if (validOrgs.length > 0) {\n lines.push('');\n lines.push(SEMANTIC_COLORS.label('Valid Organizations:'));\n validOrgs.forEach(org => lines.push(` ${SEMANTIC_COLORS.success('✓')} ${org}`));\n }\n\n if (invalidOrgs.length > 0) {\n lines.push('');\n lines.push(SEMANTIC_COLORS.warning('Limited Access:'));\n invalidOrgs.forEach(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n lines.push(` ${SEMANTIC_COLORS.warning('⚠')} ${org} ${SEMANTIC_COLORS.dim(`(missing: ${invalidApis.join(', ')})`)} `);\n });\n }\n } else {\n lines.push(`${SEMANTIC_COLORS.label('Access:')} ${SEMANTIC_COLORS.error('Cannot list organizations')}`);\n }\n } else {\n // Help for users without a token\n lines.push('');\n const actionTips = [\n 'Run: bktide token --store',\n 'Or set: BUILDKITE_API_TOKEN environment variable'\n ];\n lines.push(formatTips(actionTips, TipStyle.ACTIONS));\n }\n \n return lines.join('\\n');\n }\n\n /**\n * Format token storage result in plain text\n * \n * @param success Whether the token was successfully stored\n * @returns Formatted token storage result message\n */\n formatTokenStorageResult(success: boolean): string {\n if (success) {\n return `${SEMANTIC_COLORS.success('✓')} Token stored in system keychain`;\n } else {\n return `${SEMANTIC_COLORS.error('✖')} Failed to store token`;\n }\n }\n\n /**\n * Format token reset result in plain text\n * \n * @param success Whether the token was successfully reset\n * @param hadToken Whether there was a token before reset\n * @returns Formatted token reset result message\n */\n formatTokenResetResult(success: boolean, hadToken: boolean): string {\n if (!hadToken) {\n return `${SEMANTIC_COLORS.muted('No token found in system keychain')}`;\n }\n\n if (success) {\n return `${SEMANTIC_COLORS.success('✓')} Token removed from system keychain`;\n } else {\n return `${SEMANTIC_COLORS.error('✖')} Failed to delete token`;\n }\n }\n\n /**\n * Format token validation error in plain text\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation error message\n */\n formatTokenValidationError(\n validation: TokenValidationStatus\n ): string {\n if (!validation.canListOrganizations) {\n return 'Token is invalid or does not have access to list organizations';\n }\n\n const invalidOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations)\n .map(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n return `${org} (${invalidApis.join(', ')})`;\n });\n\n if (invalidOrgs.length === 0) {\n return 'Token is valid for all organizations';\n }\n\n return `Token has limited access in some organizations: ${invalidOrgs.join(', ')}`;\n }\n\n /**\n * Format token validation status in plain text\n * \n * @param validation The validation status for each API\n * @returns Formatted token validation status message\n */\n formatTokenValidationStatus(validation: TokenValidationStatus): string {\n if (!validation.canListOrganizations) {\n return 'Token is invalid or does not have access to list organizations';\n }\n\n const lines: string[] = [];\n const validOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => status.graphql && status.builds && status.organizations)\n .map(([org]) => org);\n \n if (validOrgs.length > 0) {\n lines.push('Valid Organizations:');\n validOrgs.forEach(org => lines.push(` - ${org}`));\n }\n\n const invalidOrgs = Object.entries(validation.organizations)\n .filter(([_, status]) => !status.graphql || !status.builds || !status.organizations);\n \n if (invalidOrgs.length > 0) {\n lines.push('Organizations with Limited Access:');\n invalidOrgs.forEach(([org, status]) => {\n const invalidApis = [];\n if (!status.graphql) invalidApis.push('GraphQL');\n if (!status.builds) invalidApis.push('Builds');\n if (!status.organizations) invalidApis.push('Organizations');\n lines.push(` - ${org} (${invalidApis.join(', ')})`);\n });\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Format error message(s) in plain text\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param error The error that occurred, or an array of errors\n * @returns Formatted error message(s)\n */\n formatError(\n operation: string,\n error: unknown | unknown[]\n ): string {\n const errors = Array.isArray(error) ? error : [error];\n const errorMessages = errors.map(err => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return errorMessage;\n });\n \n const suggestions = [];\n if (operation === 'storing' || operation === 'validating') {\n suggestions.push('Check your Buildkite API token permissions');\n suggestions.push('Get a new token at: https://buildkite.com/user/api-access-tokens');\n }\n \n const errorText = `Error ${operation} token: ${errorMessages.join(', ')}`;\n return themeFormatError(errorText, { suggestions });\n }\n\n /**\n * Format authentication error message(s) in plain text\n * \n * @param operation The authentication operation that failed (e.g., 'storing', 'validating')\n * @param error The authentication error that occurred, or an array of errors\n * @returns Formatted authentication error message(s)\n */\n formatAuthErrors(\n operation: string,\n error: unknown | unknown[]\n ): string {\n const errors = Array.isArray(error) ? error : [error];\n return errors.map(error => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return `Authentication error ${operation} token: ${errorMessage}\\nPlease check your token permissions and try again`;\n }).join('\\n\\n');\n }\n\n /**\n * Format multiple error messages in plain text\n * \n * @param operation The operation that failed (e.g., 'storing', 'resetting', 'validating')\n * @param errors Array of errors that occurred\n * @returns Formatted error messages\n */\n formatErrors(\n operation: string,\n errors: unknown[]\n ): string {\n return errors.map(error => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return `Error ${operation} token: ${errorMessage}`;\n }).join('\\n');\n }\n} "]}
@@ -1,20 +1,21 @@
1
1
  import { BaseFormatter } from './Formatter.js';
2
+ import { SEMANTIC_COLORS, formatEmptyState } from '../../ui/theme.js';
2
3
  export class PlainTextFormatter extends BaseFormatter {
3
4
  name = 'plain-text';
4
5
  formatViewer(viewerData, _options) {
5
6
  if (!viewerData?.viewer) {
6
- return 'No viewer data found.';
7
+ return formatEmptyState('No viewer data found', ['Check your API token is valid', 'Run "bktide token --check" to verify']);
7
8
  }
8
- let output = 'Logged in as:\n';
9
+ const lines = [];
9
10
  if (viewerData.viewer.user) {
10
- output += `- ID: ${viewerData.viewer.user?.id}\n`;
11
- output += `- Name: ${viewerData.viewer.user?.name}\n`;
12
- output += `- Email: ${viewerData.viewer.user?.email}\n`;
11
+ lines.push(`${SEMANTIC_COLORS.label('Name:')} ${viewerData.viewer.user.name || SEMANTIC_COLORS.muted('(not set)')}`);
12
+ lines.push(`${SEMANTIC_COLORS.label('Email:')} ${viewerData.viewer.user.email || SEMANTIC_COLORS.muted('(not set)')}`);
13
+ lines.push(`${SEMANTIC_COLORS.label('ID:')} ${SEMANTIC_COLORS.identifier(viewerData.viewer.user.id || '(unknown)')}`);
13
14
  }
14
15
  else {
15
- output += `- No user data found.\n`;
16
+ return formatEmptyState('No user data found', ['Your token may not have the required permissions']);
16
17
  }
17
- return output;
18
+ return lines.join('\n');
18
19
  }
19
20
  }
20
21
  //# sourceMappingURL=PlainTextFormatter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlainTextFormatter.js","sourceRoot":"/","sources":["formatters/viewer/PlainTextFormatter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,IAAI,GAAG,YAAY,CAAC;IAEpB,YAAY,CAAC,UAAsB,EAAE,QAA2B;QAC9D,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;YACxB,OAAO,uBAAuB,CAAC;QACjC,CAAC;QAED,IAAI,MAAM,GAAG,iBAAiB,CAAC;QAC/B,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC;YAClD,MAAM,IAAI,WAAW,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YACtD,MAAM,IAAI,YAAY,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,yBAAyB,CAAC;QACtC,CAAC;QAGD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF","sourcesContent":["import { FormatterOptions } from '../BaseFormatter.js';\nimport { BaseFormatter } from './Formatter.js';\nimport { ViewerData } from '../../types/index.js';\n\nexport class PlainTextFormatter extends BaseFormatter {\n name = 'plain-text';\n \n formatViewer(viewerData: ViewerData, _options?: FormatterOptions): string {\n if (!viewerData?.viewer) {\n return 'No viewer data found.';\n }\n\n let output = 'Logged in as:\\n';\n if (viewerData.viewer.user) {\n output += `- ID: ${viewerData.viewer.user?.id}\\n`;\n output += `- Name: ${viewerData.viewer.user?.name}\\n`;\n output += `- Email: ${viewerData.viewer.user?.email}\\n`;\n } else {\n output += `- No user data found.\\n`;\n }\n \n \n return output;\n }\n} "]}
1
+ {"version":3,"file":"PlainTextFormatter.js","sourceRoot":"/","sources":["formatters/viewer/PlainTextFormatter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEtE,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,IAAI,GAAG,YAAY,CAAC;IAEpB,YAAY,CAAC,UAAsB,EAAE,QAA2B;QAC9D,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;YACxB,OAAO,gBAAgB,CACrB,sBAAsB,EACtB,CAAC,+BAA+B,EAAE,sCAAsC,CAAC,CAC1E,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACtH,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YACvH,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;QAC3H,CAAC;aAAM,CAAC;YACN,OAAO,gBAAgB,CACrB,oBAAoB,EACpB,CAAC,kDAAkD,CAAC,CACrD,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF","sourcesContent":["import { FormatterOptions } from '../BaseFormatter.js';\nimport { BaseFormatter } from './Formatter.js';\nimport { ViewerData } from '../../types/index.js';\nimport { SEMANTIC_COLORS, formatEmptyState } from '../../ui/theme.js';\n\nexport class PlainTextFormatter extends BaseFormatter {\n name = 'plain-text';\n \n formatViewer(viewerData: ViewerData, _options?: FormatterOptions): string {\n if (!viewerData?.viewer) {\n return formatEmptyState(\n 'No viewer data found',\n ['Check your API token is valid', 'Run \"bktide token --check\" to verify']\n );\n }\n\n const lines: string[] = [];\n \n if (viewerData.viewer.user) {\n lines.push(`${SEMANTIC_COLORS.label('Name:')} ${viewerData.viewer.user.name || SEMANTIC_COLORS.muted('(not set)')}`);\n lines.push(`${SEMANTIC_COLORS.label('Email:')} ${viewerData.viewer.user.email || SEMANTIC_COLORS.muted('(not set)')}`);\n lines.push(`${SEMANTIC_COLORS.label('ID:')} ${SEMANTIC_COLORS.identifier(viewerData.viewer.user.id || '(unknown)')}`);\n } else {\n return formatEmptyState(\n 'No user data found',\n ['Your token may not have the required permissions']\n );\n }\n \n return lines.join('\\n');\n }\n} "]}
@@ -135,4 +135,185 @@ export const GET_BUILD_ANNOTATIONS = gql `
135
135
  }
136
136
  }
137
137
  `;
138
+ export const GET_BUILD_SUMMARY = gql `
139
+ query GetBuildSummary($slug: ID!) {
140
+ build(slug: $slug) {
141
+ id
142
+ number
143
+ state
144
+ branch
145
+ message
146
+ commit
147
+ createdAt
148
+ startedAt
149
+ finishedAt
150
+ canceledAt
151
+ url
152
+ blockedState
153
+ createdBy {
154
+ ... on User {
155
+ id
156
+ name
157
+ email
158
+ avatar {
159
+ url
160
+ }
161
+ }
162
+ ... on UnregisteredUser {
163
+ name
164
+ email
165
+ }
166
+ }
167
+ pipeline {
168
+ id
169
+ name
170
+ slug
171
+ }
172
+ organization {
173
+ id
174
+ name
175
+ slug
176
+ }
177
+ jobs(first: 100) {
178
+ edges {
179
+ node {
180
+ ... on JobTypeCommand {
181
+ id
182
+ uuid
183
+ label
184
+ state
185
+ exitStatus
186
+ startedAt
187
+ finishedAt
188
+ passed
189
+ }
190
+ ... on JobTypeWait {
191
+ id
192
+ label
193
+ }
194
+ ... on JobTypeTrigger {
195
+ id
196
+ label
197
+ state
198
+ }
199
+ }
200
+ }
201
+ }
202
+ annotations(first: 50) {
203
+ edges {
204
+ node {
205
+ id
206
+ style
207
+ context
208
+ body {
209
+ html
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+ `;
217
+ export const GET_BUILD_FULL = gql `
218
+ query GetBuildFull($slug: ID!) {
219
+ build(slug: $slug) {
220
+ id
221
+ number
222
+ state
223
+ branch
224
+ message
225
+ commit
226
+ createdAt
227
+ startedAt
228
+ finishedAt
229
+ canceledAt
230
+ url
231
+ blockedState
232
+ createdBy {
233
+ ... on User {
234
+ id
235
+ name
236
+ email
237
+ avatar {
238
+ url
239
+ }
240
+ }
241
+ ... on UnregisteredUser {
242
+ name
243
+ email
244
+ }
245
+ }
246
+ pipeline {
247
+ id
248
+ name
249
+ slug
250
+ repository {
251
+ url
252
+ }
253
+ }
254
+ organization {
255
+ id
256
+ name
257
+ slug
258
+ }
259
+ pullRequest {
260
+ id
261
+ }
262
+ jobs(first: 100) {
263
+ edges {
264
+ node {
265
+ ... on JobTypeCommand {
266
+ id
267
+ uuid
268
+ label
269
+ command
270
+ state
271
+ exitStatus
272
+ startedAt
273
+ finishedAt
274
+ passed
275
+ retried
276
+ retrySource {
277
+ ... on JobTypeCommand {
278
+ id
279
+ uuid
280
+ }
281
+ }
282
+ agent {
283
+ ... on Agent {
284
+ id
285
+ name
286
+ hostname
287
+ }
288
+ }
289
+ }
290
+ ... on JobTypeWait {
291
+ id
292
+ label
293
+ }
294
+ ... on JobTypeTrigger {
295
+ id
296
+ label
297
+ state
298
+ }
299
+ }
300
+ }
301
+ }
302
+ annotations(first: 100) {
303
+ edges {
304
+ node {
305
+ id
306
+ style
307
+ context
308
+ body {
309
+ html
310
+ }
311
+ createdAt
312
+ updatedAt
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ `;
138
319
  //# sourceMappingURL=queries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"/","sources":["graphql/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;CAY5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;CAcnC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB/B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BnC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;CAgBvC,CAAC","sourcesContent":["/**\n * Common GraphQL queries for the Buildkite API\n */\nimport { gql } from 'graphql-request';\n\nexport const GET_VIEWER = gql`\n query GetViewer {\n viewer {\n id\n user {\n id\n uuid\n name\n email\n }\n }\n }\n`;\n\nexport const GET_ORGANIZATIONS = gql`\n query GetOrganizations {\n viewer {\n organizations {\n edges {\n node {\n id\n name\n slug\n }\n }\n }\n }\n }\n`;\n\nexport const GET_PIPELINES = gql`\n query GetPipelines($organizationSlug: ID!, $first: Int, $after: String) {\n organization(slug: $organizationSlug) {\n pipelines(first: $first, after: $after, archived: false) {\n edges {\n node {\n uuid\n id\n name\n slug\n description\n url\n repository {\n url\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILDS = gql`\n query GetBuilds($pipelineSlug: String!, $organizationSlug: ID!, $first: Int) {\n organization(slug: $organizationSlug) {\n pipelines(first: 1, search: $pipelineSlug) {\n edges {\n node {\n builds(first: $first) {\n edges {\n node {\n id\n number\n url\n state\n message\n commit\n branch\n createdAt\n startedAt\n finishedAt\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_VIEWER_BUILDS = gql`\n query GetViewerBuilds($first: Int!) {\n viewer {\n builds(first: $first) {\n edges {\n node {\n id\n number\n state\n url\n createdAt\n branch\n message\n pipeline {\n name\n slug\n }\n organization {\n name\n slug\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_ANNOTATIONS = gql`\n query GetBuildAnnotations($buildSlug: ID!) {\n build(slug: $buildSlug) {\n annotations(first: 100) {\n edges {\n node {\n context\n style\n body {\n html\n }\n }\n }\n }\n }\n }\n`; "]}
1
+ {"version":3,"file":"queries.js","sourceRoot":"/","sources":["graphql/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;CAY5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;CAcnC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB/B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BnC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;CAgBvC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EnC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqGhC,CAAC","sourcesContent":["/**\n * Common GraphQL queries for the Buildkite API\n */\nimport { gql } from 'graphql-request';\n\nexport const GET_VIEWER = gql`\n query GetViewer {\n viewer {\n id\n user {\n id\n uuid\n name\n email\n }\n }\n }\n`;\n\nexport const GET_ORGANIZATIONS = gql`\n query GetOrganizations {\n viewer {\n organizations {\n edges {\n node {\n id\n name\n slug\n }\n }\n }\n }\n }\n`;\n\nexport const GET_PIPELINES = gql`\n query GetPipelines($organizationSlug: ID!, $first: Int, $after: String) {\n organization(slug: $organizationSlug) {\n pipelines(first: $first, after: $after, archived: false) {\n edges {\n node {\n uuid\n id\n name\n slug\n description\n url\n repository {\n url\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILDS = gql`\n query GetBuilds($pipelineSlug: String!, $organizationSlug: ID!, $first: Int) {\n organization(slug: $organizationSlug) {\n pipelines(first: 1, search: $pipelineSlug) {\n edges {\n node {\n builds(first: $first) {\n edges {\n node {\n id\n number\n url\n state\n message\n commit\n branch\n createdAt\n startedAt\n finishedAt\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_VIEWER_BUILDS = gql`\n query GetViewerBuilds($first: Int!) {\n viewer {\n builds(first: $first) {\n edges {\n node {\n id\n number\n state\n url\n createdAt\n branch\n message\n pipeline {\n name\n slug\n }\n organization {\n name\n slug\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_ANNOTATIONS = gql`\n query GetBuildAnnotations($buildSlug: ID!) {\n build(slug: $buildSlug) {\n annotations(first: 100) {\n edges {\n node {\n context\n style\n body {\n html\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_SUMMARY = gql`\n query GetBuildSummary($slug: ID!) {\n build(slug: $slug) {\n id\n number\n state\n branch\n message\n commit\n createdAt\n startedAt\n finishedAt\n canceledAt\n url\n blockedState\n createdBy {\n ... on User {\n id\n name\n email\n avatar {\n url\n }\n }\n ... on UnregisteredUser {\n name\n email\n }\n }\n pipeline {\n id\n name\n slug\n }\n organization {\n id\n name\n slug\n }\n jobs(first: 100) {\n edges {\n node {\n ... on JobTypeCommand {\n id\n uuid\n label\n state\n exitStatus\n startedAt\n finishedAt\n passed\n }\n ... on JobTypeWait {\n id\n label\n }\n ... on JobTypeTrigger {\n id\n label\n state\n }\n }\n }\n }\n annotations(first: 50) {\n edges {\n node {\n id\n style\n context\n body {\n html\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_FULL = gql`\n query GetBuildFull($slug: ID!) {\n build(slug: $slug) {\n id\n number\n state\n branch\n message\n commit\n createdAt\n startedAt\n finishedAt\n canceledAt\n url\n blockedState\n createdBy {\n ... on User {\n id\n name\n email\n avatar {\n url\n }\n }\n ... on UnregisteredUser {\n name\n email\n }\n }\n pipeline {\n id\n name\n slug\n repository {\n url\n }\n }\n organization {\n id\n name\n slug\n }\n pullRequest {\n id\n }\n jobs(first: 100) {\n edges {\n node {\n ... on JobTypeCommand {\n id\n uuid\n label\n command\n state\n exitStatus\n startedAt\n finishedAt\n passed\n retried\n retrySource {\n ... on JobTypeCommand {\n id\n uuid\n }\n }\n agent {\n ... on Agent {\n id\n name\n hostname\n }\n }\n }\n ... on JobTypeWait {\n id\n label\n }\n ... on JobTypeTrigger {\n id\n label\n state\n }\n }\n }\n }\n annotations(first: 100) {\n edges {\n node {\n id\n style\n context\n body {\n html\n }\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n`; "]}