bktide 0.0.1

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 (160) hide show
  1. package/README.md +145 -0
  2. package/WORKFLOW_README.md +65 -0
  3. package/bin/alfred-entrypoint +54 -0
  4. package/dist/commands/BaseCommand.js +159 -0
  5. package/dist/commands/BaseCommand.js.map +1 -0
  6. package/dist/commands/BaseCommandHandler.js +80 -0
  7. package/dist/commands/BaseCommandHandler.js.map +1 -0
  8. package/dist/commands/BuildCommandHandler.js +28 -0
  9. package/dist/commands/BuildCommandHandler.js.map +1 -0
  10. package/dist/commands/HelloCommandHandler.js +6 -0
  11. package/dist/commands/HelloCommandHandler.js.map +1 -0
  12. package/dist/commands/ListAnnotations.js +60 -0
  13. package/dist/commands/ListAnnotations.js.map +1 -0
  14. package/dist/commands/ListBuilds.js +137 -0
  15. package/dist/commands/ListBuilds.js.map +1 -0
  16. package/dist/commands/ListOrganizations.js +27 -0
  17. package/dist/commands/ListOrganizations.js.map +1 -0
  18. package/dist/commands/ListPipelines.js +114 -0
  19. package/dist/commands/ListPipelines.js.map +1 -0
  20. package/dist/commands/ManageToken.js +180 -0
  21. package/dist/commands/ManageToken.js.map +1 -0
  22. package/dist/commands/OrganizationCommandHandler.js +53 -0
  23. package/dist/commands/OrganizationCommandHandler.js.map +1 -0
  24. package/dist/commands/PipelineCommandHandler.js +142 -0
  25. package/dist/commands/PipelineCommandHandler.js.map +1 -0
  26. package/dist/commands/ShowViewer.js +26 -0
  27. package/dist/commands/ShowViewer.js.map +1 -0
  28. package/dist/commands/UserBuildsCommandHandler.js +61 -0
  29. package/dist/commands/UserBuildsCommandHandler.js.map +1 -0
  30. package/dist/commands/ViewerBuildsCommandHandler.js +176 -0
  31. package/dist/commands/ViewerBuildsCommandHandler.js.map +1 -0
  32. package/dist/commands/ViewerCommandHandler.js +46 -0
  33. package/dist/commands/ViewerCommandHandler.js.map +1 -0
  34. package/dist/commands/index.js +8 -0
  35. package/dist/commands/index.js.map +1 -0
  36. package/dist/formatters/BaseFormatter.js +14 -0
  37. package/dist/formatters/BaseFormatter.js.map +1 -0
  38. package/dist/formatters/FormatterFactory.js +48 -0
  39. package/dist/formatters/FormatterFactory.js.map +1 -0
  40. package/dist/formatters/annotations/Formatter.js +10 -0
  41. package/dist/formatters/annotations/Formatter.js.map +1 -0
  42. package/dist/formatters/annotations/JsonFormatter.js +20 -0
  43. package/dist/formatters/annotations/JsonFormatter.js.map +1 -0
  44. package/dist/formatters/annotations/PlainTextFormatter.js +35 -0
  45. package/dist/formatters/annotations/PlainTextFormatter.js.map +1 -0
  46. package/dist/formatters/annotations/index.js +23 -0
  47. package/dist/formatters/annotations/index.js.map +1 -0
  48. package/dist/formatters/builds/AlfredFormatter.js +135 -0
  49. package/dist/formatters/builds/AlfredFormatter.js.map +1 -0
  50. package/dist/formatters/builds/Formatter.js +10 -0
  51. package/dist/formatters/builds/Formatter.js.map +1 -0
  52. package/dist/formatters/builds/JsonFormatter.js +44 -0
  53. package/dist/formatters/builds/JsonFormatter.js.map +1 -0
  54. package/dist/formatters/builds/PlainTextFormatter.js +113 -0
  55. package/dist/formatters/builds/PlainTextFormatter.js.map +1 -0
  56. package/dist/formatters/builds/index.js +26 -0
  57. package/dist/formatters/builds/index.js.map +1 -0
  58. package/dist/formatters/errors/AlfredFormatter.js +110 -0
  59. package/dist/formatters/errors/AlfredFormatter.js.map +1 -0
  60. package/dist/formatters/errors/Formatter.js +98 -0
  61. package/dist/formatters/errors/Formatter.js.map +1 -0
  62. package/dist/formatters/errors/JsonFormatter.js +63 -0
  63. package/dist/formatters/errors/JsonFormatter.js.map +1 -0
  64. package/dist/formatters/errors/PlainTextFormatter.js +52 -0
  65. package/dist/formatters/errors/PlainTextFormatter.js.map +1 -0
  66. package/dist/formatters/errors/index.js +26 -0
  67. package/dist/formatters/errors/index.js.map +1 -0
  68. package/dist/formatters/index.js +9 -0
  69. package/dist/formatters/index.js.map +1 -0
  70. package/dist/formatters/organizations/Formatter.js +10 -0
  71. package/dist/formatters/organizations/Formatter.js.map +1 -0
  72. package/dist/formatters/organizations/JsonFormatter.js +16 -0
  73. package/dist/formatters/organizations/JsonFormatter.js.map +1 -0
  74. package/dist/formatters/organizations/PlainTextFormatter.js +15 -0
  75. package/dist/formatters/organizations/PlainTextFormatter.js.map +1 -0
  76. package/dist/formatters/organizations/index.js +21 -0
  77. package/dist/formatters/organizations/index.js.map +1 -0
  78. package/dist/formatters/pipelines/AlfredFormatter.js +42 -0
  79. package/dist/formatters/pipelines/AlfredFormatter.js.map +1 -0
  80. package/dist/formatters/pipelines/Formatter.js +10 -0
  81. package/dist/formatters/pipelines/Formatter.js.map +1 -0
  82. package/dist/formatters/pipelines/JsonFormatter.js +13 -0
  83. package/dist/formatters/pipelines/JsonFormatter.js.map +1 -0
  84. package/dist/formatters/pipelines/PlainTextFormatter.js +47 -0
  85. package/dist/formatters/pipelines/PlainTextFormatter.js.map +1 -0
  86. package/dist/formatters/pipelines/index.js +28 -0
  87. package/dist/formatters/pipelines/index.js.map +1 -0
  88. package/dist/formatters/token/AlfredFormatter.js +191 -0
  89. package/dist/formatters/token/AlfredFormatter.js.map +1 -0
  90. package/dist/formatters/token/Formatter.js +13 -0
  91. package/dist/formatters/token/Formatter.js.map +1 -0
  92. package/dist/formatters/token/JsonFormatter.js +211 -0
  93. package/dist/formatters/token/JsonFormatter.js.map +1 -0
  94. package/dist/formatters/token/PlainTextFormatter.js +184 -0
  95. package/dist/formatters/token/PlainTextFormatter.js.map +1 -0
  96. package/dist/formatters/token/index.js +26 -0
  97. package/dist/formatters/token/index.js.map +1 -0
  98. package/dist/formatters/viewer/Formatter.js +10 -0
  99. package/dist/formatters/viewer/Formatter.js.map +1 -0
  100. package/dist/formatters/viewer/JsonFormatter.js +20 -0
  101. package/dist/formatters/viewer/JsonFormatter.js.map +1 -0
  102. package/dist/formatters/viewer/PlainTextFormatter.js +20 -0
  103. package/dist/formatters/viewer/PlainTextFormatter.js.map +1 -0
  104. package/dist/formatters/viewer/index.js +21 -0
  105. package/dist/formatters/viewer/index.js.map +1 -0
  106. package/dist/graphql/generated/fragment-masking.js +17 -0
  107. package/dist/graphql/generated/fragment-masking.js.map +1 -0
  108. package/dist/graphql/generated/gql.js +13 -0
  109. package/dist/graphql/generated/gql.js.map +1 -0
  110. package/dist/graphql/generated/graphql.js +852 -0
  111. package/dist/graphql/generated/graphql.js.map +1 -0
  112. package/dist/graphql/generated/index.js +3 -0
  113. package/dist/graphql/generated/index.js.map +1 -0
  114. package/dist/graphql/generated/sdk.js +872 -0
  115. package/dist/graphql/generated/sdk.js.map +1 -0
  116. package/dist/graphql/queries.js +138 -0
  117. package/dist/graphql/queries.js.map +1 -0
  118. package/dist/index.js +271 -0
  119. package/dist/index.js.map +1 -0
  120. package/dist/services/BuildkiteClient.js +520 -0
  121. package/dist/services/BuildkiteClient.js.map +1 -0
  122. package/dist/services/BuildkiteRestClient.js +244 -0
  123. package/dist/services/BuildkiteRestClient.js.map +1 -0
  124. package/dist/services/CacheManager.js +221 -0
  125. package/dist/services/CacheManager.js.map +1 -0
  126. package/dist/services/CredentialManager.js +158 -0
  127. package/dist/services/CredentialManager.js.map +1 -0
  128. package/dist/services/EnhancedBuildkiteClient.js +297 -0
  129. package/dist/services/EnhancedBuildkiteClient.js.map +1 -0
  130. package/dist/services/logger.js +107 -0
  131. package/dist/services/logger.js.map +1 -0
  132. package/dist/types/buildkite.js +5 -0
  133. package/dist/types/buildkite.js.map +1 -0
  134. package/dist/types/credentials.js +2 -0
  135. package/dist/types/credentials.js.map +1 -0
  136. package/dist/types/index.js +3 -0
  137. package/dist/types/index.js.map +1 -0
  138. package/dist/utils/cli-error-handler.js +172 -0
  139. package/dist/utils/cli-error-handler.js.map +1 -0
  140. package/dist/utils/errorUtils.js +59 -0
  141. package/dist/utils/errorUtils.js.map +1 -0
  142. package/dist/utils/parseBuildRef.js +31 -0
  143. package/dist/utils/parseBuildRef.js.map +1 -0
  144. package/dist/utils/textFormatter.js +53 -0
  145. package/dist/utils/textFormatter.js.map +1 -0
  146. package/dist/utils/xdgPaths.js +95 -0
  147. package/dist/utils/xdgPaths.js.map +1 -0
  148. package/env.example +66 -0
  149. package/icons/README.md +68 -0
  150. package/icons/blocked.png +0 -0
  151. package/icons/buildkite.png +0 -0
  152. package/icons/failed.png +0 -0
  153. package/icons/failing.png +0 -0
  154. package/icons/passed.png +0 -0
  155. package/icons/running.png +0 -0
  156. package/icons/scheduled.png +0 -0
  157. package/icons/skipped.png +0 -0
  158. package/icons/unknown.png +0 -0
  159. package/info.plist +734 -0
  160. package/package.json +87 -0
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Common GraphQL queries for the Buildkite API
3
+ */
4
+ import { gql } from 'graphql-request';
5
+ export const GET_VIEWER = gql `
6
+ query GetViewer {
7
+ viewer {
8
+ id
9
+ user {
10
+ id
11
+ uuid
12
+ name
13
+ email
14
+ }
15
+ }
16
+ }
17
+ `;
18
+ export const GET_ORGANIZATIONS = gql `
19
+ query GetOrganizations {
20
+ viewer {
21
+ organizations {
22
+ edges {
23
+ node {
24
+ id
25
+ name
26
+ slug
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ `;
33
+ export const GET_PIPELINES = gql `
34
+ query GetPipelines($organizationSlug: ID!, $first: Int, $after: String) {
35
+ organization(slug: $organizationSlug) {
36
+ pipelines(first: $first, after: $after, archived: false) {
37
+ edges {
38
+ node {
39
+ uuid
40
+ id
41
+ name
42
+ slug
43
+ description
44
+ url
45
+ repository {
46
+ url
47
+ }
48
+ }
49
+ }
50
+ pageInfo {
51
+ hasNextPage
52
+ endCursor
53
+ }
54
+ }
55
+ }
56
+ }
57
+ `;
58
+ export const GET_BUILDS = gql `
59
+ query GetBuilds($pipelineSlug: String!, $organizationSlug: ID!, $first: Int) {
60
+ organization(slug: $organizationSlug) {
61
+ pipelines(first: 1, search: $pipelineSlug) {
62
+ edges {
63
+ node {
64
+ builds(first: $first) {
65
+ edges {
66
+ node {
67
+ id
68
+ number
69
+ url
70
+ state
71
+ message
72
+ commit
73
+ branch
74
+ createdAt
75
+ startedAt
76
+ finishedAt
77
+ }
78
+ }
79
+ pageInfo {
80
+ hasNextPage
81
+ endCursor
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ `;
90
+ export const GET_VIEWER_BUILDS = gql `
91
+ query GetViewerBuilds($first: Int!) {
92
+ viewer {
93
+ builds(first: $first) {
94
+ edges {
95
+ node {
96
+ id
97
+ number
98
+ state
99
+ url
100
+ createdAt
101
+ branch
102
+ message
103
+ pipeline {
104
+ name
105
+ slug
106
+ }
107
+ organization {
108
+ name
109
+ slug
110
+ }
111
+ }
112
+ }
113
+ pageInfo {
114
+ hasNextPage
115
+ endCursor
116
+ }
117
+ }
118
+ }
119
+ }
120
+ `;
121
+ export const GET_BUILD_ANNOTATIONS = gql `
122
+ query GetBuildAnnotations($buildSlug: ID!) {
123
+ build(slug: $buildSlug) {
124
+ annotations(first: 100) {
125
+ edges {
126
+ node {
127
+ context
128
+ style
129
+ body {
130
+ html
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ `;
138
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +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`; "]}
package/dist/index.js ADDED
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import { BaseCommand, ShowViewer, ListOrganizations, ListBuilds, ListPipelines, ManageToken, ListAnnotations } from './commands/index.js';
7
+ import { initializeErrorHandling } from './utils/errorUtils.js';
8
+ import { displayCLIError, setErrorFormat } from './utils/cli-error-handler.js';
9
+ import { logger, setLogLevel } from './services/logger.js';
10
+ // Set a global error handler for uncaught exceptions
11
+ const uncaughtExceptionHandler = (err) => {
12
+ // Remove any existing handlers to avoid duplicates
13
+ const handlers = process.listeners('uncaughtException');
14
+ handlers.forEach(listener => {
15
+ if (listener !== uncaughtExceptionHandler) {
16
+ process.removeListener('uncaughtException', listener);
17
+ }
18
+ });
19
+ displayCLIError(err, process.argv.includes('--debug'));
20
+ };
21
+ process.on('uncaughtException', uncaughtExceptionHandler);
22
+ // Set a global error handler for unhandled promise rejections
23
+ const unhandledRejectionHandler = (reason) => {
24
+ // Remove any existing handlers to avoid duplicates
25
+ const handlers = process.listeners('unhandledRejection');
26
+ handlers.forEach(listener => {
27
+ if (listener !== unhandledRejectionHandler) {
28
+ process.removeListener('unhandledRejection', listener);
29
+ }
30
+ });
31
+ displayCLIError(reason, process.argv.includes('--debug'));
32
+ };
33
+ process.on('unhandledRejection', unhandledRejectionHandler);
34
+ // Initialize error handling after our handlers are registered
35
+ initializeErrorHandling();
36
+ const program = new Command();
37
+ // Handler for executing commands with proper option handling
38
+ const createCommandHandler = (CommandClass) => {
39
+ return async function () {
40
+ try {
41
+ const options = this.mergedOptions || this.opts();
42
+ const cacheOptions = { enabled: options.cache !== false, ttl: options.cacheTtl, clear: options.clearCache };
43
+ if (CommandClass.requiresToken) {
44
+ const token = await BaseCommand.getToken(options);
45
+ options.token = token;
46
+ }
47
+ const handler = new CommandClass({
48
+ ...cacheOptions,
49
+ token: options.token,
50
+ debug: options.debug,
51
+ format: options.format,
52
+ });
53
+ // Pass command-specific options if available
54
+ const commandName = this.name();
55
+ if (commandName === 'pipelines' && this.pipelineOptions) {
56
+ logger.debug('Using pipeline options:', this.pipelineOptions);
57
+ }
58
+ else if (commandName === 'builds' && this.buildOptions) {
59
+ logger.debug('Using build options:', this.buildOptions);
60
+ }
61
+ const exitCode = await handler.execute(options);
62
+ // Set process.exitCode to propagate the exit code
63
+ process.exitCode = exitCode;
64
+ }
65
+ catch (error) {
66
+ const debug = this.mergedOptions?.debug || this.opts().debug || false;
67
+ // No need to pass format - will use global format set in preAction hook
68
+ displayCLIError(error, debug);
69
+ process.exitCode = 1; // Set error exit code
70
+ }
71
+ };
72
+ };
73
+ function resolveAppVersion() {
74
+ // Prefer environment-provided version (set in CI before publish)
75
+ if (process.env.BKTIDE_VERSION && process.env.BKTIDE_VERSION.trim().length > 0) {
76
+ return process.env.BKTIDE_VERSION.trim();
77
+ }
78
+ try {
79
+ // Attempt to read package.json near compiled dist/index.js
80
+ const __filename = fileURLToPath(import.meta.url);
81
+ const __dirname = path.dirname(__filename);
82
+ const candidatePaths = [
83
+ path.resolve(__dirname, '..', 'package.json'), // when running from dist/
84
+ path.resolve(__dirname, '..', '..', 'package.json'), // fallback
85
+ ];
86
+ for (const pkgPath of candidatePaths) {
87
+ if (fs.existsSync(pkgPath)) {
88
+ const raw = fs.readFileSync(pkgPath, 'utf-8');
89
+ const pkg = JSON.parse(raw);
90
+ if (pkg.version)
91
+ return pkg.version;
92
+ }
93
+ }
94
+ }
95
+ catch {
96
+ // ignore
97
+ }
98
+ // Last resort
99
+ return '0.0.0';
100
+ }
101
+ program
102
+ .name('bktide')
103
+ .description('Buildkite CLI tool')
104
+ .version(resolveAppVersion())
105
+ .configureHelp({ showGlobalOptions: true })
106
+ .option('--log-level <level>', 'Set logging level (trace, debug, info, warn, error, fatal)', 'info')
107
+ .option('-d, --debug', 'Show debug information for errors')
108
+ .option('--no-cache', 'Disable caching of API responses')
109
+ .option('--cache-ttl <milliseconds>', 'Set cache time-to-live in milliseconds', parseInt)
110
+ .option('--clear-cache', 'Clear all cached data before executing command')
111
+ .option('-t, --token <token>', 'Buildkite API token (or set BK_TOKEN env var)', process.env.BK_TOKEN)
112
+ .option('--save-token', 'Save the token to system keychain for future use')
113
+ .option('-f, --format <format>', 'Output format for results and errors (plain, json, alfred)', 'plain');
114
+ // Add hooks for handling options
115
+ program
116
+ .hook('preAction', (_thisCommand, actionCommand) => {
117
+ // Cast to our extended command type
118
+ const cmd = actionCommand;
119
+ // Merge global options with command-specific options
120
+ const globalOpts = program.opts();
121
+ const commandOpts = cmd.opts();
122
+ const mergedOptions = { ...globalOpts, ...commandOpts };
123
+ // Set the global error format from the command line options
124
+ if (mergedOptions.format) {
125
+ setErrorFormat(mergedOptions.format);
126
+ }
127
+ if (mergedOptions.cacheTtl && (isNaN(mergedOptions.cacheTtl) || mergedOptions.cacheTtl <= 0)) {
128
+ logger.error('cache-ttl must be a positive number');
129
+ process.exit(1);
130
+ }
131
+ if (mergedOptions.cache === false && mergedOptions.cacheTtl) {
132
+ logger.warn('--no-cache and --cache-ttl used together. Cache will be disabled regardless of TTL setting.');
133
+ }
134
+ // Validate count options
135
+ if (mergedOptions.count && (isNaN(parseInt(mergedOptions.count)) || parseInt(mergedOptions.count) <= 0)) {
136
+ logger.error('count must be a positive number');
137
+ process.exit(1);
138
+ }
139
+ cmd.mergedOptions = mergedOptions;
140
+ const commandName = cmd.name();
141
+ if (commandName === 'pipelines') {
142
+ // Create pipeline-specific options structure
143
+ cmd.pipelineOptions = {
144
+ organization: mergedOptions.org,
145
+ count: mergedOptions.count ? parseInt(mergedOptions.count) : undefined,
146
+ filter: mergedOptions.filter
147
+ };
148
+ if (mergedOptions.debug) {
149
+ logger.debug('Pipeline options:', cmd.pipelineOptions);
150
+ }
151
+ }
152
+ else if (commandName === 'builds') {
153
+ // Create builds-specific options structure
154
+ cmd.buildOptions = {
155
+ organization: mergedOptions.org,
156
+ pipeline: mergedOptions.pipeline,
157
+ branch: mergedOptions.branch,
158
+ state: mergedOptions.state,
159
+ count: mergedOptions.count ? parseInt(mergedOptions.count) : 10,
160
+ page: mergedOptions.page ? parseInt(mergedOptions.page) : 1,
161
+ filter: mergedOptions.filter
162
+ };
163
+ if (mergedOptions.debug) {
164
+ logger.debug('Build options:', cmd.buildOptions);
165
+ }
166
+ }
167
+ else if (commandName === 'annotations') {
168
+ // Attach the build argument to options
169
+ cmd.mergedOptions.buildArg = cmd.args?.[0];
170
+ if (mergedOptions.debug) {
171
+ logger.debug('Annotations build arg:', cmd.mergedOptions.buildArg);
172
+ logger.debug('Annotations context filter:', mergedOptions.context);
173
+ }
174
+ }
175
+ if (mergedOptions.debug) {
176
+ logger.debug(`Executing command: ${commandName}`);
177
+ logger.debug('Options:', mergedOptions);
178
+ }
179
+ })
180
+ .hook('postAction', (_thisCommand, actionCommand) => {
181
+ // Cast to our extended command type
182
+ const cmd = actionCommand;
183
+ // Accessing the custom property
184
+ const options = cmd.mergedOptions || {};
185
+ if (options.debug) {
186
+ logger.debug(`Command ${cmd.name()} completed`);
187
+ }
188
+ });
189
+ program
190
+ .command('viewer')
191
+ .description('Show logged in user information')
192
+ .action(createCommandHandler(ShowViewer));
193
+ program
194
+ .command('orgs')
195
+ .description('List organizations')
196
+ .action(createCommandHandler(ListOrganizations));
197
+ program
198
+ .command('pipelines')
199
+ .description('List pipelines for an organization')
200
+ .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')
201
+ .option('-n, --count <count>', 'Limit to specified number of pipelines per organization')
202
+ .option('--filter <name>', 'Filter pipelines by name (case insensitive)')
203
+ .action(createCommandHandler(ListPipelines));
204
+ // Update the builds command to include REST API filtering options
205
+ program
206
+ .command('builds')
207
+ .description('List builds for the current user')
208
+ .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')
209
+ .option('-p, --pipeline <pipeline>', 'Filter by pipeline slug')
210
+ .option('-b, --branch <branch>', 'Filter by branch name')
211
+ .option('-s, --state <state>', 'Filter by build state (running, scheduled, passed, failing, failed, canceled, etc.)')
212
+ .option('-n, --count <count>', 'Number of builds per page', '10')
213
+ .option('--page <page>', 'Page number', '1')
214
+ .option('--filter <filter>', 'Fuzzy filter builds by name or other properties')
215
+ .action(createCommandHandler(ListBuilds));
216
+ // Add token management command
217
+ program
218
+ .command('token')
219
+ .description('Manage API tokens')
220
+ .option('--check', 'Check if a token is stored in the system keychain')
221
+ .option('--store', 'Store a token in the system keychain')
222
+ .option('--reset', 'Delete the stored token from system keychain')
223
+ .action(createCommandHandler(ManageToken));
224
+ // Add annotations command
225
+ program
226
+ .command('annotations')
227
+ .description('Show annotations for a build')
228
+ .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')
229
+ .option('--context <context>', 'Filter annotations by context (e.g., rspec, build-resources)')
230
+ .action(createCommandHandler(ListAnnotations));
231
+ program
232
+ .command('boom')
233
+ .description('Test error handling')
234
+ .option('--type <type>', 'Type of error to throw (basic, api, object)', 'basic')
235
+ .option('--format <format>', 'Output format (plain, json, alfred)', 'plain')
236
+ .action((options) => {
237
+ switch (options.type) {
238
+ case 'api':
239
+ const apiError = new Error('API request failed');
240
+ apiError.response = {
241
+ errors: [
242
+ { message: 'Invalid token', path: ['viewer'] }
243
+ ]
244
+ };
245
+ throw apiError;
246
+ case 'object':
247
+ throw {
248
+ message: 'This is not an Error instance',
249
+ code: 'CUSTOM_ERROR'
250
+ };
251
+ case 'basic':
252
+ default:
253
+ throw new Error('Boom! This is a test error');
254
+ }
255
+ });
256
+ program.parse();
257
+ // Apply log level from command line options
258
+ const options = program.opts();
259
+ if (options.debug) {
260
+ // Debug mode takes precedence over log-level
261
+ setLogLevel('debug');
262
+ logger.debug('Debug mode enabled via --debug flag');
263
+ }
264
+ else if (options.logLevel) {
265
+ setLogLevel(options.logLevel);
266
+ logger.debug(`Log level set to ${options.logLevel} via --log-level option`);
267
+ }
268
+ logger.debug({
269
+ pid: process.pid,
270
+ }, 'Buildkite CLI started');
271
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport {\n BaseCommand,\n ShowViewer,\n ListOrganizations,\n ListBuilds,\n ListPipelines,\n ManageToken,\n ListAnnotations\n} from './commands/index.js';\nimport { initializeErrorHandling } from './utils/errorUtils.js';\nimport { displayCLIError, setErrorFormat } from './utils/cli-error-handler.js';\nimport { logger, setLogLevel } from './services/logger.js';\n\n// Set a global error handler for uncaught exceptions\nconst uncaughtExceptionHandler = (err: Error) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('uncaughtException');\n handlers.forEach(listener => {\n if (listener !== uncaughtExceptionHandler) {\n process.removeListener('uncaughtException', listener);\n }\n });\n \n displayCLIError(\n err, \n process.argv.includes('--debug')\n );\n};\nprocess.on('uncaughtException', uncaughtExceptionHandler);\n\n// Set a global error handler for unhandled promise rejections\nconst unhandledRejectionHandler = (reason: unknown) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('unhandledRejection');\n handlers.forEach(listener => {\n if (listener !== unhandledRejectionHandler) {\n process.removeListener('unhandledRejection', listener);\n }\n });\n \n displayCLIError(\n reason, \n process.argv.includes('--debug')\n );\n};\nprocess.on('unhandledRejection', unhandledRejectionHandler);\n\n// Initialize error handling after our handlers are registered\ninitializeErrorHandling();\n\nconst program = new Command();\n\n// Define a generic interface for the command classes that includes the execute method\ninterface CommandWithExecute {\n execute(options: any): Promise<number>;\n}\n\n// Define a type for the constructor that includes static properties\ntype CommandConstructor = {\n new (options?: any): BaseCommand & CommandWithExecute;\n requiresToken: boolean;\n}\n\n// Extend the Command type to include our custom properties\ninterface ExtendedCommand extends Command {\n mergedOptions?: any;\n pipelineOptions?: {\n organization?: string;\n count?: number;\n filter?: string;\n };\n buildOptions?: {\n organization?: string;\n pipeline?: string;\n branch?: string;\n state?: string;\n count: number;\n page: number;\n filter?: string;\n };\n}\n\n// Handler for executing commands with proper option handling\nconst createCommandHandler = (CommandClass: CommandConstructor) => {\n return async function(this: ExtendedCommand) {\n try {\n const options = this.mergedOptions || this.opts();\n const cacheOptions = { enabled: options.cache !== false, ttl: options.cacheTtl, clear: options.clearCache };\n\n if (CommandClass.requiresToken) {\n const token = await BaseCommand.getToken(options);\n options.token = token;\n }\n \n const handler = new CommandClass({\n ...cacheOptions,\n token: options.token,\n debug: options.debug,\n format: options.format,\n });\n \n // Pass command-specific options if available\n const commandName = this.name();\n if (commandName === 'pipelines' && this.pipelineOptions) {\n logger.debug('Using pipeline options:', this.pipelineOptions);\n }\n else if (commandName === 'builds' && this.buildOptions) {\n logger.debug('Using build options:', this.buildOptions);\n }\n \n const exitCode = await handler.execute(options);\n // Set process.exitCode to propagate the exit code\n process.exitCode = exitCode;\n } catch (error) {\n const debug = this.mergedOptions?.debug || this.opts().debug || false;\n // No need to pass format - will use global format set in preAction hook\n displayCLIError(error, debug);\n process.exitCode = 1; // Set error exit code\n }\n };\n};\n\nfunction resolveAppVersion(): string {\n // Prefer environment-provided version (set in CI before publish)\n if (process.env.BKTIDE_VERSION && process.env.BKTIDE_VERSION.trim().length > 0) {\n return process.env.BKTIDE_VERSION.trim();\n }\n\n try {\n // Attempt to read package.json near compiled dist/index.js\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidatePaths = [\n path.resolve(__dirname, '..', 'package.json'), // when running from dist/\n path.resolve(__dirname, '..', '..', 'package.json'), // fallback\n ];\n for (const pkgPath of candidatePaths) {\n if (fs.existsSync(pkgPath)) {\n const raw = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string };\n if (pkg.version) return pkg.version;\n }\n }\n } catch {\n // ignore\n }\n\n // Last resort\n return '0.0.0';\n}\n\nprogram\n .name('bktide')\n .description('Buildkite CLI tool')\n .version(resolveAppVersion())\n .configureHelp({ showGlobalOptions: true })\n .option('--log-level <level>', 'Set logging level (trace, debug, info, warn, error, fatal)', 'info')\n .option('-d, --debug', 'Show debug information for errors')\n .option('--no-cache', 'Disable caching of API responses')\n .option('--cache-ttl <milliseconds>', 'Set cache time-to-live in milliseconds', parseInt)\n .option('--clear-cache', 'Clear all cached data before executing command')\n .option('-t, --token <token>', 'Buildkite API token (or set BK_TOKEN env var)', process.env.BK_TOKEN)\n .option('--save-token', 'Save the token to system keychain for future use')\n .option('-f, --format <format>', 'Output format for results and errors (plain, json, alfred)', 'plain');\n\n// Add hooks for handling options\nprogram\n .hook('preAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Merge global options with command-specific options\n const globalOpts = program.opts();\n const commandOpts = cmd.opts();\n const mergedOptions = { ...globalOpts, ...commandOpts };\n \n // Set the global error format from the command line options\n if (mergedOptions.format) {\n setErrorFormat(mergedOptions.format);\n }\n \n if (mergedOptions.cacheTtl && (isNaN(mergedOptions.cacheTtl) || mergedOptions.cacheTtl <= 0)) {\n logger.error('cache-ttl must be a positive number');\n process.exit(1);\n }\n \n if (mergedOptions.cache === false && mergedOptions.cacheTtl) {\n logger.warn('--no-cache and --cache-ttl used together. Cache will be disabled regardless of TTL setting.');\n }\n \n // Validate count options\n if (mergedOptions.count && (isNaN(parseInt(mergedOptions.count)) || parseInt(mergedOptions.count) <= 0)) {\n logger.error('count must be a positive number');\n process.exit(1);\n }\n\n cmd.mergedOptions = mergedOptions;\n\n const commandName = cmd.name();\n\n if (commandName === 'pipelines') {\n // Create pipeline-specific options structure\n cmd.pipelineOptions = {\n organization: mergedOptions.org,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : undefined,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Pipeline options:', cmd.pipelineOptions);\n }\n }\n else if (commandName === 'builds') {\n // Create builds-specific options structure\n cmd.buildOptions = {\n organization: mergedOptions.org,\n pipeline: mergedOptions.pipeline,\n branch: mergedOptions.branch,\n state: mergedOptions.state,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : 10,\n page: mergedOptions.page ? parseInt(mergedOptions.page) : 1,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Build options:', cmd.buildOptions);\n }\n }\n else if (commandName === 'annotations') {\n // Attach the build argument to options\n cmd.mergedOptions.buildArg = cmd.args?.[0];\n \n if (mergedOptions.debug) {\n logger.debug('Annotations build arg:', cmd.mergedOptions.buildArg);\n logger.debug('Annotations context filter:', mergedOptions.context);\n }\n }\n \n if (mergedOptions.debug) {\n logger.debug(`Executing command: ${commandName}`);\n logger.debug('Options:', mergedOptions);\n }\n })\n .hook('postAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Accessing the custom property\n const options = cmd.mergedOptions || {};\n if (options.debug) {\n logger.debug(`Command ${cmd.name()} completed`);\n }\n });\n\nprogram\n .command('viewer')\n .description('Show logged in user information')\n .action(createCommandHandler(ShowViewer));\n\nprogram\n .command('orgs')\n .description('List organizations')\n .action(createCommandHandler(ListOrganizations));\n\nprogram\n .command('pipelines')\n .description('List pipelines for an organization')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-n, --count <count>', 'Limit to specified number of pipelines per organization')\n .option('--filter <name>', 'Filter pipelines by name (case insensitive)')\n .action(createCommandHandler(ListPipelines));\n\n// Update the builds command to include REST API filtering options\nprogram\n .command('builds')\n .description('List builds for the current user')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-p, --pipeline <pipeline>', 'Filter by pipeline slug')\n .option('-b, --branch <branch>', 'Filter by branch name')\n .option('-s, --state <state>', 'Filter by build state (running, scheduled, passed, failing, failed, canceled, etc.)')\n .option('-n, --count <count>', 'Number of builds per page', '10')\n .option('--page <page>', 'Page number', '1')\n .option('--filter <filter>', 'Fuzzy filter builds by name or other properties')\n .action(createCommandHandler(ListBuilds));\n\n// Add token management command\nprogram\n .command('token')\n .description('Manage API tokens')\n .option('--check', 'Check if a token is stored in the system keychain')\n .option('--store', 'Store a token in the system keychain')\n .option('--reset', 'Delete the stored token from system keychain')\n .action(createCommandHandler(ManageToken));\n\n// Add annotations command\nprogram\n .command('annotations')\n .description('Show annotations for a build')\n .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')\n .option('--context <context>', 'Filter annotations by context (e.g., rspec, build-resources)')\n .action(createCommandHandler(ListAnnotations));\n\nprogram\n .command('boom')\n .description('Test error handling')\n .option('--type <type>', 'Type of error to throw (basic, api, object)', 'basic')\n .option('--format <format>', 'Output format (plain, json, alfred)', 'plain')\n .action((options) => {\n switch (options.type) {\n case 'api':\n const apiError = new Error('API request failed');\n (apiError as any).response = {\n errors: [\n { message: 'Invalid token', path: ['viewer'] }\n ]\n };\n throw apiError;\n \n case 'object':\n throw {\n message: 'This is not an Error instance',\n code: 'CUSTOM_ERROR'\n };\n \n case 'basic':\n default:\n throw new Error('Boom! This is a test error');\n }\n });\n\nprogram.parse();\n\n// Apply log level from command line options\nconst options = program.opts();\nif (options.debug) {\n // Debug mode takes precedence over log-level\n setLogLevel('debug');\n logger.debug('Debug mode enabled via --debug flag');\n} else if (options.logLevel) {\n setLogLevel(options.logLevel);\n logger.debug(`Log level set to ${options.logLevel} via --log-level option`);\n}\n\nlogger.debug({ \n pid: process.pid, \n}, 'Buildkite CLI started'); "]}