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.
- package/README.md +145 -0
- package/WORKFLOW_README.md +65 -0
- package/bin/alfred-entrypoint +54 -0
- package/dist/commands/BaseCommand.js +159 -0
- package/dist/commands/BaseCommand.js.map +1 -0
- package/dist/commands/BaseCommandHandler.js +80 -0
- package/dist/commands/BaseCommandHandler.js.map +1 -0
- package/dist/commands/BuildCommandHandler.js +28 -0
- package/dist/commands/BuildCommandHandler.js.map +1 -0
- package/dist/commands/HelloCommandHandler.js +6 -0
- package/dist/commands/HelloCommandHandler.js.map +1 -0
- package/dist/commands/ListAnnotations.js +60 -0
- package/dist/commands/ListAnnotations.js.map +1 -0
- package/dist/commands/ListBuilds.js +137 -0
- package/dist/commands/ListBuilds.js.map +1 -0
- package/dist/commands/ListOrganizations.js +27 -0
- package/dist/commands/ListOrganizations.js.map +1 -0
- package/dist/commands/ListPipelines.js +114 -0
- package/dist/commands/ListPipelines.js.map +1 -0
- package/dist/commands/ManageToken.js +180 -0
- package/dist/commands/ManageToken.js.map +1 -0
- package/dist/commands/OrganizationCommandHandler.js +53 -0
- package/dist/commands/OrganizationCommandHandler.js.map +1 -0
- package/dist/commands/PipelineCommandHandler.js +142 -0
- package/dist/commands/PipelineCommandHandler.js.map +1 -0
- package/dist/commands/ShowViewer.js +26 -0
- package/dist/commands/ShowViewer.js.map +1 -0
- package/dist/commands/UserBuildsCommandHandler.js +61 -0
- package/dist/commands/UserBuildsCommandHandler.js.map +1 -0
- package/dist/commands/ViewerBuildsCommandHandler.js +176 -0
- package/dist/commands/ViewerBuildsCommandHandler.js.map +1 -0
- package/dist/commands/ViewerCommandHandler.js +46 -0
- package/dist/commands/ViewerCommandHandler.js.map +1 -0
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/formatters/BaseFormatter.js +14 -0
- package/dist/formatters/BaseFormatter.js.map +1 -0
- package/dist/formatters/FormatterFactory.js +48 -0
- package/dist/formatters/FormatterFactory.js.map +1 -0
- package/dist/formatters/annotations/Formatter.js +10 -0
- package/dist/formatters/annotations/Formatter.js.map +1 -0
- package/dist/formatters/annotations/JsonFormatter.js +20 -0
- package/dist/formatters/annotations/JsonFormatter.js.map +1 -0
- package/dist/formatters/annotations/PlainTextFormatter.js +35 -0
- package/dist/formatters/annotations/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/annotations/index.js +23 -0
- package/dist/formatters/annotations/index.js.map +1 -0
- package/dist/formatters/builds/AlfredFormatter.js +135 -0
- package/dist/formatters/builds/AlfredFormatter.js.map +1 -0
- package/dist/formatters/builds/Formatter.js +10 -0
- package/dist/formatters/builds/Formatter.js.map +1 -0
- package/dist/formatters/builds/JsonFormatter.js +44 -0
- package/dist/formatters/builds/JsonFormatter.js.map +1 -0
- package/dist/formatters/builds/PlainTextFormatter.js +113 -0
- package/dist/formatters/builds/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/builds/index.js +26 -0
- package/dist/formatters/builds/index.js.map +1 -0
- package/dist/formatters/errors/AlfredFormatter.js +110 -0
- package/dist/formatters/errors/AlfredFormatter.js.map +1 -0
- package/dist/formatters/errors/Formatter.js +98 -0
- package/dist/formatters/errors/Formatter.js.map +1 -0
- package/dist/formatters/errors/JsonFormatter.js +63 -0
- package/dist/formatters/errors/JsonFormatter.js.map +1 -0
- package/dist/formatters/errors/PlainTextFormatter.js +52 -0
- package/dist/formatters/errors/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/errors/index.js +26 -0
- package/dist/formatters/errors/index.js.map +1 -0
- package/dist/formatters/index.js +9 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/organizations/Formatter.js +10 -0
- package/dist/formatters/organizations/Formatter.js.map +1 -0
- package/dist/formatters/organizations/JsonFormatter.js +16 -0
- package/dist/formatters/organizations/JsonFormatter.js.map +1 -0
- package/dist/formatters/organizations/PlainTextFormatter.js +15 -0
- package/dist/formatters/organizations/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/organizations/index.js +21 -0
- package/dist/formatters/organizations/index.js.map +1 -0
- package/dist/formatters/pipelines/AlfredFormatter.js +42 -0
- package/dist/formatters/pipelines/AlfredFormatter.js.map +1 -0
- package/dist/formatters/pipelines/Formatter.js +10 -0
- package/dist/formatters/pipelines/Formatter.js.map +1 -0
- package/dist/formatters/pipelines/JsonFormatter.js +13 -0
- package/dist/formatters/pipelines/JsonFormatter.js.map +1 -0
- package/dist/formatters/pipelines/PlainTextFormatter.js +47 -0
- package/dist/formatters/pipelines/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/pipelines/index.js +28 -0
- package/dist/formatters/pipelines/index.js.map +1 -0
- package/dist/formatters/token/AlfredFormatter.js +191 -0
- package/dist/formatters/token/AlfredFormatter.js.map +1 -0
- package/dist/formatters/token/Formatter.js +13 -0
- package/dist/formatters/token/Formatter.js.map +1 -0
- package/dist/formatters/token/JsonFormatter.js +211 -0
- package/dist/formatters/token/JsonFormatter.js.map +1 -0
- package/dist/formatters/token/PlainTextFormatter.js +184 -0
- package/dist/formatters/token/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/token/index.js +26 -0
- package/dist/formatters/token/index.js.map +1 -0
- package/dist/formatters/viewer/Formatter.js +10 -0
- package/dist/formatters/viewer/Formatter.js.map +1 -0
- package/dist/formatters/viewer/JsonFormatter.js +20 -0
- package/dist/formatters/viewer/JsonFormatter.js.map +1 -0
- package/dist/formatters/viewer/PlainTextFormatter.js +20 -0
- package/dist/formatters/viewer/PlainTextFormatter.js.map +1 -0
- package/dist/formatters/viewer/index.js +21 -0
- package/dist/formatters/viewer/index.js.map +1 -0
- package/dist/graphql/generated/fragment-masking.js +17 -0
- package/dist/graphql/generated/fragment-masking.js.map +1 -0
- package/dist/graphql/generated/gql.js +13 -0
- package/dist/graphql/generated/gql.js.map +1 -0
- package/dist/graphql/generated/graphql.js +852 -0
- package/dist/graphql/generated/graphql.js.map +1 -0
- package/dist/graphql/generated/index.js +3 -0
- package/dist/graphql/generated/index.js.map +1 -0
- package/dist/graphql/generated/sdk.js +872 -0
- package/dist/graphql/generated/sdk.js.map +1 -0
- package/dist/graphql/queries.js +138 -0
- package/dist/graphql/queries.js.map +1 -0
- package/dist/index.js +271 -0
- package/dist/index.js.map +1 -0
- package/dist/services/BuildkiteClient.js +520 -0
- package/dist/services/BuildkiteClient.js.map +1 -0
- package/dist/services/BuildkiteRestClient.js +244 -0
- package/dist/services/BuildkiteRestClient.js.map +1 -0
- package/dist/services/CacheManager.js +221 -0
- package/dist/services/CacheManager.js.map +1 -0
- package/dist/services/CredentialManager.js +158 -0
- package/dist/services/CredentialManager.js.map +1 -0
- package/dist/services/EnhancedBuildkiteClient.js +297 -0
- package/dist/services/EnhancedBuildkiteClient.js.map +1 -0
- package/dist/services/logger.js +107 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/types/buildkite.js +5 -0
- package/dist/types/buildkite.js.map +1 -0
- package/dist/types/credentials.js +2 -0
- package/dist/types/credentials.js.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/cli-error-handler.js +172 -0
- package/dist/utils/cli-error-handler.js.map +1 -0
- package/dist/utils/errorUtils.js +59 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/parseBuildRef.js +31 -0
- package/dist/utils/parseBuildRef.js.map +1 -0
- package/dist/utils/textFormatter.js +53 -0
- package/dist/utils/textFormatter.js.map +1 -0
- package/dist/utils/xdgPaths.js +95 -0
- package/dist/utils/xdgPaths.js.map +1 -0
- package/env.example +66 -0
- package/icons/README.md +68 -0
- package/icons/blocked.png +0 -0
- package/icons/buildkite.png +0 -0
- package/icons/failed.png +0 -0
- package/icons/failing.png +0 -0
- package/icons/passed.png +0 -0
- package/icons/running.png +0 -0
- package/icons/scheduled.png +0 -0
- package/icons/skipped.png +0 -0
- package/icons/unknown.png +0 -0
- package/info.plist +734 -0
- package/package.json +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["types/index.ts"],"names":[],"mappings":"AAAA,uCAAuC","sourcesContent":["// Buildkite GraphQL API response types\n\n// Viewer types\nexport interface ViewerUser {\n id: string;\n uuid: string;\n name: string;\n email: string;\n}\n\nexport interface Viewer {\n id: string;\n user?: ViewerUser;\n}\n\nexport interface ViewerData {\n viewer: Viewer;\n}\n\n// Organization types\nexport interface Organization {\n id: string;\n name: string;\n slug: string;\n}\n\n// Pipeline types\nexport interface Repository {\n url: string;\n}\n\nexport interface Pipeline {\n uuid: string;\n id: string;\n name: string;\n slug: string;\n description?: string;\n url?: string;\n organization?: string;\n repository?: Repository;\n}\n\n// Build types\nexport interface BuildPipeline {\n name: string;\n slug: string;\n}\n\nexport interface BuildOrganization {\n name: string;\n slug: string;\n}\n\nexport interface Build {\n id: string;\n number: number;\n url?: string;\n web_url?: string;\n state?: string;\n message?: string;\n commit?: string;\n branch?: string;\n createdAt?: string;\n created_at?: string;\n startedAt?: string;\n started_at?: string;\n finishedAt?: string;\n finished_at?: string;\n pipeline?: BuildPipeline;\n organization?: BuildOrganization;\n}\n\n// Annotation types\nexport interface Annotation {\n context: string;\n style: string;\n body: {\n html: string;\n };\n}\n\n// GraphQL API response structure types\nexport interface GraphQLEdge<T> {\n node: T;\n}\n\nexport interface GraphQLConnection<T> {\n edges: GraphQLEdge<T>[];\n pageInfo?: {\n hasNextPage: boolean;\n endCursor?: string;\n };\n}\n\nexport interface ViewerOrganizationsData {\n viewer: {\n organizations: GraphQLConnection<Organization>;\n };\n}\n\nexport interface PipelineQueryResponse {\n organization: {\n pipelines: GraphQLConnection<Pipeline>;\n };\n}\n\nexport interface ViewerBuildsQueryResponse {\n viewer: {\n builds: GraphQLConnection<Build>;\n };\n}\n\nexport interface OrganizationsQueryResponse {\n viewer: {\n organizations: GraphQLConnection<Organization>;\n };\n} "]}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Error Handler - Provides error display for CLI applications
|
|
3
|
+
*/
|
|
4
|
+
import { logger } from '../services/logger.js';
|
|
5
|
+
import { FormatterFactory, FormatterType } from '../formatters/FormatterFactory.js';
|
|
6
|
+
// Default format to use for error output
|
|
7
|
+
let globalErrorFormat = 'plain';
|
|
8
|
+
/**
|
|
9
|
+
* Set the global error output format
|
|
10
|
+
* @param format The format to use ('plain', 'json', 'alfred')
|
|
11
|
+
*/
|
|
12
|
+
export function setErrorFormat(format) {
|
|
13
|
+
const normalizedFormat = format.toLowerCase().trim();
|
|
14
|
+
if (['plain', 'json', 'alfred'].includes(normalizedFormat)) {
|
|
15
|
+
globalErrorFormat = normalizedFormat;
|
|
16
|
+
logger.debug(`Error output format set to ${normalizedFormat}`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
logger.warn(`Unknown format '${format}', error output format remains as ${globalErrorFormat}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Display a formatted error message
|
|
24
|
+
*
|
|
25
|
+
* @param error The error to display
|
|
26
|
+
* @param debug Whether to include debug information
|
|
27
|
+
* @param format Output format (plain, json, alfred), defaults to global setting
|
|
28
|
+
*/
|
|
29
|
+
export function displayCLIError(error, debug = false, format) {
|
|
30
|
+
// Use provided format or fall back to global format
|
|
31
|
+
const outputFormat = format || globalErrorFormat;
|
|
32
|
+
// Get the appropriate formatter based on format
|
|
33
|
+
const formatter = FormatterFactory.getFormatter(FormatterType.ERROR, outputFormat);
|
|
34
|
+
// Format the error using the selected formatter
|
|
35
|
+
const formattedError = formatter.formatError(error, { debug });
|
|
36
|
+
// Print the formatted output
|
|
37
|
+
if (outputFormat === 'plain') {
|
|
38
|
+
logger.error(formattedError);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
logger.console(formattedError);
|
|
42
|
+
}
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the current global error output format
|
|
47
|
+
* @returns The current format
|
|
48
|
+
*/
|
|
49
|
+
export function getErrorFormat() {
|
|
50
|
+
return globalErrorFormat;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Format an error object for display in the CLI
|
|
54
|
+
* Extracts as much useful information as possible, including stack traces
|
|
55
|
+
*
|
|
56
|
+
* @param error The error object to format
|
|
57
|
+
* @param debug Whether to include debug information
|
|
58
|
+
* @returns Formatted error message
|
|
59
|
+
*/
|
|
60
|
+
export function formatErrorForCLI(error, debug = false) {
|
|
61
|
+
let output = '';
|
|
62
|
+
// Add a separator and heading
|
|
63
|
+
output += '\n\x1b[31m════════════════════════ ERROR ════════════════════════\x1b[0m\n\n';
|
|
64
|
+
if (error instanceof Error) {
|
|
65
|
+
// Handle standard Error objects
|
|
66
|
+
output += `\x1b[31m${error.name}: ${error.message}\x1b[0m\n\n`;
|
|
67
|
+
if (error.stack) {
|
|
68
|
+
const stackLines = error.stack.split('\n');
|
|
69
|
+
// First line usually contains the error message, which we've already displayed
|
|
70
|
+
const stackTrace = stackLines.slice(1).join('\n');
|
|
71
|
+
output += `\x1b[33mStack Trace:\x1b[0m\n${stackTrace}\n\n`;
|
|
72
|
+
}
|
|
73
|
+
// Handle additional properties that might be present in API errors
|
|
74
|
+
const apiError = error;
|
|
75
|
+
if (apiError.response?.errors) {
|
|
76
|
+
output += '\x1b[33mAPI Errors:\x1b[0m\n';
|
|
77
|
+
apiError.response.errors.forEach((e, i) => {
|
|
78
|
+
output += ` Error ${i + 1}: ${e.message || 'Unknown error'}\n`;
|
|
79
|
+
if (e.path)
|
|
80
|
+
output += ` Path: ${e.path.join('.')}\n`;
|
|
81
|
+
if (e.locations)
|
|
82
|
+
output += ` Locations: ${JSON.stringify(e.locations)}\n`;
|
|
83
|
+
output += '\n';
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (debug && apiError.request) {
|
|
87
|
+
output += '\x1b[36mRequest Details:\x1b[0m\n';
|
|
88
|
+
output += ` URL: ${apiError.request.url || 'N/A'}\n`;
|
|
89
|
+
output += ` Method: ${apiError.request.method || 'N/A'}\n\n`;
|
|
90
|
+
}
|
|
91
|
+
// If error has a cause, include it
|
|
92
|
+
if (apiError.cause) {
|
|
93
|
+
output += '\x1b[33mCaused by:\x1b[0m\n';
|
|
94
|
+
output += formatErrorForCLI(apiError.cause, debug);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (error && typeof error === 'object') {
|
|
98
|
+
// Handle non-Error objects
|
|
99
|
+
try {
|
|
100
|
+
output += '\x1b[31mError Object:\x1b[0m\n';
|
|
101
|
+
output += JSON.stringify(error, null, 2) + '\n\n';
|
|
102
|
+
// Try to extract more detailed information
|
|
103
|
+
const errorObj = error;
|
|
104
|
+
if (errorObj.message) {
|
|
105
|
+
output += `Message: ${errorObj.message}\n`;
|
|
106
|
+
}
|
|
107
|
+
if (debug) {
|
|
108
|
+
output += '\x1b[36mProperties:\x1b[0m\n';
|
|
109
|
+
for (const key in errorObj) {
|
|
110
|
+
try {
|
|
111
|
+
if (key !== 'stack' && key !== 'message') {
|
|
112
|
+
const value = errorObj[key];
|
|
113
|
+
output += ` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}\n`;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
output += ` ${key}: [Cannot stringify]\n`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
output += '\n';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
output += '\x1b[31mUnable to stringify error object\x1b[0m\n\n';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// Handle primitive values
|
|
129
|
+
output += `\x1b[31m${String(error)}\x1b[0m\n\n`;
|
|
130
|
+
}
|
|
131
|
+
if (debug) {
|
|
132
|
+
// Add debug information
|
|
133
|
+
output += '\x1b[36mDebug Information:\x1b[0m\n';
|
|
134
|
+
output += ` Timestamp: ${new Date().toISOString()}\n`;
|
|
135
|
+
output += ` Node Version: ${process.version}\n`;
|
|
136
|
+
output += ` Platform: ${process.platform} (${process.arch})\n`;
|
|
137
|
+
try {
|
|
138
|
+
// Get the current call stack
|
|
139
|
+
const stack = new Error().stack;
|
|
140
|
+
if (stack) {
|
|
141
|
+
const stackLines = stack.split('\n').slice(2); // Skip the Error creation line and this function
|
|
142
|
+
output += '\n\x1b[36mCurrent Stack:\x1b[0m\n';
|
|
143
|
+
output += stackLines.join('\n') + '\n';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Ignore stack trace errors
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Add a closing separator
|
|
151
|
+
output += '\n\x1b[31m═══════════════════════════════════════════════════════\x1b[0m\n';
|
|
152
|
+
return output;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Wraps a function with CLI error handling
|
|
156
|
+
*
|
|
157
|
+
* @param fn The function to wrap
|
|
158
|
+
* @param options Error handling options
|
|
159
|
+
* @returns A wrapped function with error handling
|
|
160
|
+
*/
|
|
161
|
+
export function withCLIErrorHandling(fn, options = {}) {
|
|
162
|
+
return async function (...args) {
|
|
163
|
+
try {
|
|
164
|
+
return await fn(...args);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
displayCLIError(error, options.debugMode || false, options.format);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=cli-error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-error-handler.js","sourceRoot":"/","sources":["utils/cli-error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI Error Handler - Provides error display for CLI applications\n */\n\nimport { logger } from '../services/logger.js';\nimport { FormatterFactory, FormatterType } from '../formatters/FormatterFactory.js';\nimport { ErrorFormatter } from '../formatters/errors/index.js';\n\n// Default format to use for error output\nlet globalErrorFormat = 'plain';\n\n/**\n * Set the global error output format\n * @param format The format to use ('plain', 'json', 'alfred')\n */\nexport function setErrorFormat(format: string): void {\n const normalizedFormat = format.toLowerCase().trim();\n if (['plain', 'json', 'alfred'].includes(normalizedFormat)) {\n globalErrorFormat = normalizedFormat;\n logger.debug(`Error output format set to ${normalizedFormat}`);\n } else {\n logger.warn(`Unknown format '${format}', error output format remains as ${globalErrorFormat}`);\n }\n}\n\n/**\n * Display a formatted error message\n * \n * @param error The error to display\n * @param debug Whether to include debug information\n * @param format Output format (plain, json, alfred), defaults to global setting\n */\nexport function displayCLIError(\n error: unknown, \n debug = false, \n format?: string\n): void {\n // Use provided format or fall back to global format\n const outputFormat = format || globalErrorFormat;\n \n // Get the appropriate formatter based on format\n const formatter = FormatterFactory.getFormatter(FormatterType.ERROR, outputFormat) as ErrorFormatter;\n \n // Format the error using the selected formatter\n const formattedError = formatter.formatError(error, { debug });\n \n // Print the formatted output\n if (outputFormat === 'plain') {\n logger.error(formattedError);\n } else {\n logger.console(formattedError);\n }\n \n process.exit(1);\n}\n\n/**\n * Get the current global error output format\n * @returns The current format\n */\nexport function getErrorFormat(): string {\n return globalErrorFormat;\n}\n\n/**\n * Format an error object for display in the CLI\n * Extracts as much useful information as possible, including stack traces\n * \n * @param error The error object to format\n * @param debug Whether to include debug information\n * @returns Formatted error message\n */\nexport function formatErrorForCLI(error: unknown, debug = false): string {\n let output = '';\n \n // Add a separator and heading\n output += '\\n\\x1b[31m════════════════════════ ERROR ════════════════════════\\x1b[0m\\n\\n';\n \n if (error instanceof Error) {\n // Handle standard Error objects\n output += `\\x1b[31m${error.name}: ${error.message}\\x1b[0m\\n\\n`;\n \n if (error.stack) {\n const stackLines = error.stack.split('\\n');\n // First line usually contains the error message, which we've already displayed\n const stackTrace = stackLines.slice(1).join('\\n');\n output += `\\x1b[33mStack Trace:\\x1b[0m\\n${stackTrace}\\n\\n`;\n }\n \n // Handle additional properties that might be present in API errors\n const apiError = error as any;\n if (apiError.response?.errors) {\n output += '\\x1b[33mAPI Errors:\\x1b[0m\\n';\n apiError.response.errors.forEach((e: any, i: number) => {\n output += ` Error ${i + 1}: ${e.message || 'Unknown error'}\\n`;\n if (e.path) output += ` Path: ${e.path.join('.')}\\n`;\n if (e.locations) output += ` Locations: ${JSON.stringify(e.locations)}\\n`;\n output += '\\n';\n });\n }\n \n if (debug && apiError.request) {\n output += '\\x1b[36mRequest Details:\\x1b[0m\\n';\n output += ` URL: ${apiError.request.url || 'N/A'}\\n`;\n output += ` Method: ${apiError.request.method || 'N/A'}\\n\\n`;\n }\n \n // If error has a cause, include it\n if (apiError.cause) {\n output += '\\x1b[33mCaused by:\\x1b[0m\\n';\n output += formatErrorForCLI(apiError.cause, debug);\n }\n } else if (error && typeof error === 'object') {\n // Handle non-Error objects\n try {\n output += '\\x1b[31mError Object:\\x1b[0m\\n';\n output += JSON.stringify(error, null, 2) + '\\n\\n';\n \n // Try to extract more detailed information\n const errorObj = error as Record<string, any>;\n if (errorObj.message) {\n output += `Message: ${errorObj.message}\\n`;\n }\n \n if (debug) {\n output += '\\x1b[36mProperties:\\x1b[0m\\n';\n for (const key in errorObj) {\n try {\n if (key !== 'stack' && key !== 'message') {\n const value = errorObj[key];\n output += ` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}\\n`;\n }\n } catch {\n output += ` ${key}: [Cannot stringify]\\n`;\n }\n }\n output += '\\n';\n }\n } catch {\n output += '\\x1b[31mUnable to stringify error object\\x1b[0m\\n\\n';\n }\n } else {\n // Handle primitive values\n output += `\\x1b[31m${String(error)}\\x1b[0m\\n\\n`;\n }\n \n if (debug) {\n // Add debug information\n output += '\\x1b[36mDebug Information:\\x1b[0m\\n';\n output += ` Timestamp: ${new Date().toISOString()}\\n`;\n output += ` Node Version: ${process.version}\\n`;\n output += ` Platform: ${process.platform} (${process.arch})\\n`;\n \n try {\n // Get the current call stack\n const stack = new Error().stack;\n if (stack) {\n const stackLines = stack.split('\\n').slice(2); // Skip the Error creation line and this function\n output += '\\n\\x1b[36mCurrent Stack:\\x1b[0m\\n';\n output += stackLines.join('\\n') + '\\n';\n }\n } catch {\n // Ignore stack trace errors\n }\n }\n \n // Add a closing separator\n output += '\\n\\x1b[31m═══════════════════════════════════════════════════════\\x1b[0m\\n';\n \n return output;\n}\n\n/**\n * Wraps a function with CLI error handling\n * \n * @param fn The function to wrap\n * @param options Error handling options\n * @returns A wrapped function with error handling\n */\nexport function withCLIErrorHandling<T extends (...args: any[]) => Promise<any>>(\n fn: T,\n options: {\n debugMode?: boolean;\n format?: string;\n } = {}\n): (...args: Parameters<T>) => Promise<ReturnType<T>> {\n return async function(...args: Parameters<T>): Promise<ReturnType<T>> {\n try {\n return await fn(...args);\n } catch (error) {\n displayCLIError(\n error, \n options.debugMode || false, \n options.format\n );\n process.exit(1);\n }\n };\n} "]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities
|
|
3
|
+
*/
|
|
4
|
+
import * as sourceMap from 'source-map-support';
|
|
5
|
+
import { logger } from '../services/logger.js';
|
|
6
|
+
import { displayCLIError } from './cli-error-handler.js';
|
|
7
|
+
/**
|
|
8
|
+
* Initialize error handling for the application
|
|
9
|
+
*/
|
|
10
|
+
export function initializeErrorHandling() {
|
|
11
|
+
// Install source map support for better stack traces
|
|
12
|
+
sourceMap.install({
|
|
13
|
+
handleUncaughtExceptions: false,
|
|
14
|
+
hookRequire: true
|
|
15
|
+
});
|
|
16
|
+
// Set up handlers for uncaught exceptions and unhandled rejections
|
|
17
|
+
process.on('uncaughtException', (err) => {
|
|
18
|
+
displayCLIError(err, false);
|
|
19
|
+
});
|
|
20
|
+
process.on('unhandledRejection', (reason) => {
|
|
21
|
+
displayCLIError(reason, false);
|
|
22
|
+
});
|
|
23
|
+
logger.debug('Error handling system initialized');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Log an error with proper formatting
|
|
27
|
+
* @param error The error to log
|
|
28
|
+
*/
|
|
29
|
+
export function logError(error) {
|
|
30
|
+
if (error instanceof Error) {
|
|
31
|
+
logger.error(error, 'Error occurred');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
logger.error({ error }, 'Unknown error occurred');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Wrap an async function with better error handling
|
|
39
|
+
*
|
|
40
|
+
* @param fn Function to wrap
|
|
41
|
+
* @returns Wrapped function with better error handling
|
|
42
|
+
*/
|
|
43
|
+
export function withErrorHandling(fn) {
|
|
44
|
+
return async function (...args) {
|
|
45
|
+
try {
|
|
46
|
+
return await fn(...args);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof Error) {
|
|
50
|
+
logger.error(error, 'Error occurred');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
logger.error({ error }, 'Unknown error occurred');
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=errorUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorUtils.js","sourceRoot":"/","sources":["utils/errorUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,SAAS,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,qDAAqD;IACrD,SAAS,CAAC,OAAO,CAAC;QAChB,wBAAwB,EAAE,KAAK;QAC/B,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;QACtC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;QAC1C,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,wBAAwB,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAK;IAEL,OAAO,KAAK,WAAU,GAAG,IAAmB;QAC1C,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,wBAAwB,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Error handling utilities\n */\nimport * as sourceMap from 'source-map-support';\nimport { logger } from '../services/logger.js';\nimport { displayCLIError } from './cli-error-handler.js';\n\n/**\n * Initialize error handling for the application\n */\nexport function initializeErrorHandling(): void {\n // Install source map support for better stack traces\n sourceMap.install({\n handleUncaughtExceptions: false,\n hookRequire: true\n });\n \n // Set up handlers for uncaught exceptions and unhandled rejections\n process.on('uncaughtException', (err) => {\n displayCLIError(err, false);\n });\n\n process.on('unhandledRejection', (reason) => {\n displayCLIError(reason, false);\n });\n\n logger.debug('Error handling system initialized');\n}\n\n/**\n * Log an error with proper formatting\n * @param error The error to log\n */\nexport function logError(error: unknown): void {\n if (error instanceof Error) {\n logger.error(error, 'Error occurred');\n } else {\n logger.error({ error }, 'Unknown error occurred');\n }\n}\n\n/**\n * Wrap an async function with better error handling\n * \n * @param fn Function to wrap\n * @returns Wrapped function with better error handling\n */\nexport function withErrorHandling<T extends (...args: any[]) => Promise<any>>(\n fn: T\n): (...args: Parameters<T>) => Promise<ReturnType<T>> {\n return async function(...args: Parameters<T>): Promise<ReturnType<T>> {\n try {\n return await fn(...args);\n } catch (error) {\n if (error instanceof Error) {\n logger.error(error, 'Error occurred');\n } else {\n logger.error({ error }, 'Unknown error occurred');\n }\n throw error;\n }\n };\n} "]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function parseBuildRef(input) {
|
|
2
|
+
if (!input) {
|
|
3
|
+
throw new Error('Build reference is required');
|
|
4
|
+
}
|
|
5
|
+
// Remove optional leading @
|
|
6
|
+
const cleanInput = input.startsWith('@') ? input.slice(1) : input;
|
|
7
|
+
// Try URL format first: https://buildkite.com/org/pipeline/builds/number
|
|
8
|
+
const urlRegex = /^https?:\/\/buildkite\.com\/([^\/]+)\/([^\/]+)\/builds\/(\d+)$/;
|
|
9
|
+
const urlMatch = cleanInput.match(urlRegex);
|
|
10
|
+
if (urlMatch) {
|
|
11
|
+
const [, org, pipeline, numberStr] = urlMatch;
|
|
12
|
+
const number = parseInt(numberStr, 10);
|
|
13
|
+
if (isNaN(number)) {
|
|
14
|
+
throw new Error(`Invalid build number: ${numberStr}`);
|
|
15
|
+
}
|
|
16
|
+
return { org, pipeline, number };
|
|
17
|
+
}
|
|
18
|
+
// Try slug format: org/pipeline/number
|
|
19
|
+
const slugRegex = /^([^\/]+)\/([^\/]+)\/(\d+)$/;
|
|
20
|
+
const slugMatch = cleanInput.match(slugRegex);
|
|
21
|
+
if (slugMatch) {
|
|
22
|
+
const [, org, pipeline, numberStr] = slugMatch;
|
|
23
|
+
const number = parseInt(numberStr, 10);
|
|
24
|
+
if (isNaN(number)) {
|
|
25
|
+
throw new Error(`Invalid build number: ${numberStr}`);
|
|
26
|
+
}
|
|
27
|
+
return { org, pipeline, number };
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Invalid build reference format: ${input}. Expected org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number`);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=parseBuildRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseBuildRef.js","sourceRoot":"/","sources":["utils/parseBuildRef.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,4BAA4B;IAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAElE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,gEAAgE,CAAC;IAClF,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC;QAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEvC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAED,uCAAuC;IACvC,MAAM,SAAS,GAAG,6BAA6B,CAAC;IAChD,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAE9C,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC;QAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEvC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,qFAAqF,CAAC,CAAC;AACjJ,CAAC","sourcesContent":["export interface BuildRef {\n org: string;\n pipeline: string;\n number: number;\n}\n\nexport function parseBuildRef(input: string): BuildRef {\n if (!input) {\n throw new Error('Build reference is required');\n }\n\n // Remove optional leading @\n const cleanInput = input.startsWith('@') ? input.slice(1) : input;\n\n // Try URL format first: https://buildkite.com/org/pipeline/builds/number\n const urlRegex = /^https?:\\/\\/buildkite\\.com\\/([^\\/]+)\\/([^\\/]+)\\/builds\\/(\\d+)$/;\n const urlMatch = cleanInput.match(urlRegex);\n \n if (urlMatch) {\n const [, org, pipeline, numberStr] = urlMatch;\n const number = parseInt(numberStr, 10);\n \n if (isNaN(number)) {\n throw new Error(`Invalid build number: ${numberStr}`);\n }\n \n return { org, pipeline, number };\n }\n\n // Try slug format: org/pipeline/number\n const slugRegex = /^([^\\/]+)\\/([^\\/]+)\\/(\\d+)$/;\n const slugMatch = cleanInput.match(slugRegex);\n \n if (slugMatch) {\n const [, org, pipeline, numberStr] = slugMatch;\n const number = parseInt(numberStr, 10);\n \n if (isNaN(number)) {\n throw new Error(`Invalid build number: ${numberStr}`);\n }\n \n return { org, pipeline, number };\n }\n\n throw new Error(`Invalid build reference format: ${input}. Expected org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number`);\n}\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { htmlToText } from 'html-to-text';
|
|
2
|
+
/**
|
|
3
|
+
* Formats HTML text for terminal display
|
|
4
|
+
*/
|
|
5
|
+
export function formatTextForTerminal(text, options = {}) {
|
|
6
|
+
const { maxWidth = 80, preserveLinks = true } = options;
|
|
7
|
+
if (!text || typeof text !== 'string') {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
// Convert HTML to text with better structure preservation
|
|
11
|
+
const htmlToTextOptions = {
|
|
12
|
+
wordwrap: maxWidth,
|
|
13
|
+
preserveNewlines: true,
|
|
14
|
+
selectors: [
|
|
15
|
+
{ selector: 'a', format: 'anchor' }
|
|
16
|
+
],
|
|
17
|
+
formatters: {
|
|
18
|
+
anchor: (elem, _walk, builder) => {
|
|
19
|
+
const href = elem.attribs?.href;
|
|
20
|
+
const text = elem.children?.[0]?.data || href;
|
|
21
|
+
if (preserveLinks && href) {
|
|
22
|
+
builder.addInline(`${text} (${href})`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
builder.addInline(text);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
try {
|
|
31
|
+
const formattedText = htmlToText(text, htmlToTextOptions);
|
|
32
|
+
// Clean up any excessive whitespace while preserving structure
|
|
33
|
+
return formattedText
|
|
34
|
+
.replace(/\n{3,}/g, '\n\n') // Replace 3+ newlines with 2
|
|
35
|
+
.trim();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// If HTML parsing fails, fall back to original text
|
|
39
|
+
console.warn('Failed to parse HTML, using original text:', error);
|
|
40
|
+
return text.trim();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Formats annotation body text specifically for terminal display
|
|
45
|
+
*/
|
|
46
|
+
export function formatAnnotationBody(bodyText, options = {}) {
|
|
47
|
+
return formatTextForTerminal(bodyText, {
|
|
48
|
+
maxWidth: 100,
|
|
49
|
+
preserveLinks: true,
|
|
50
|
+
...options
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=textFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textFormatter.js","sourceRoot":"/","sources":["utils/textFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAO1C;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,UAAiC,EAAE;IACrF,MAAM,EACJ,QAAQ,GAAG,EAAE,EACb,aAAa,GAAG,IAAI,EACrB,GAAG,OAAO,CAAC;IAEZ,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0DAA0D;IAC1D,MAAM,iBAAiB,GAAG;QACxB,QAAQ,EAAE,QAAQ;QAClB,gBAAgB,EAAE,IAAI;QACtB,SAAS,EAAE;YACT,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE;SACpC;QACD,UAAU,EAAE;YACV,MAAM,EAAE,CAAC,IAAS,EAAE,KAAU,EAAE,OAAY,EAAE,EAAE;gBAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;gBAChC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;gBAC9C,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;oBAC1B,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;gBACzC,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;SACF;KACF,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAE1D,+DAA+D;QAC/D,OAAO,aAAa;aACjB,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,6BAA6B;aACxD,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oDAAoD;QACpD,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,UAAiC,EAAE;IACxF,OAAO,qBAAqB,CAAC,QAAQ,EAAE;QACrC,QAAQ,EAAE,GAAG;QACb,aAAa,EAAE,IAAI;QACnB,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { htmlToText } from 'html-to-text';\n\nexport interface TextFormattingOptions {\n maxWidth?: number;\n preserveLinks?: boolean;\n}\n\n/**\n * Formats HTML text for terminal display\n */\nexport function formatTextForTerminal(text: string, options: TextFormattingOptions = {}): string {\n const {\n maxWidth = 80,\n preserveLinks = true\n } = options;\n\n if (!text || typeof text !== 'string') {\n return '';\n }\n\n // Convert HTML to text with better structure preservation\n const htmlToTextOptions = {\n wordwrap: maxWidth,\n preserveNewlines: true,\n selectors: [\n { selector: 'a', format: 'anchor' }\n ],\n formatters: {\n anchor: (elem: any, _walk: any, builder: any) => {\n const href = elem.attribs?.href;\n const text = elem.children?.[0]?.data || href;\n if (preserveLinks && href) {\n builder.addInline(`${text} (${href})`);\n } else {\n builder.addInline(text);\n }\n }\n }\n };\n\n try {\n const formattedText = htmlToText(text, htmlToTextOptions);\n \n // Clean up any excessive whitespace while preserving structure\n return formattedText\n .replace(/\\n{3,}/g, '\\n\\n') // Replace 3+ newlines with 2\n .trim();\n } catch (error) {\n // If HTML parsing fails, fall back to original text\n console.warn('Failed to parse HTML, using original text:', error);\n return text.trim();\n }\n}\n\n/**\n * Formats annotation body text specifically for terminal display\n */\nexport function formatAnnotationBody(bodyText: string, options: TextFormattingOptions = {}): string {\n return formatTextForTerminal(bodyText, {\n maxWidth: 100,\n preserveLinks: true,\n ...options\n });\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
/**
|
|
5
|
+
* XDG Base Directory Specification utility
|
|
6
|
+
* https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
|
7
|
+
*/
|
|
8
|
+
export class XDGPaths {
|
|
9
|
+
/**
|
|
10
|
+
* Get XDG_CONFIG_HOME directory path
|
|
11
|
+
* Defaults to $HOME/.config
|
|
12
|
+
*/
|
|
13
|
+
static getConfigHome() {
|
|
14
|
+
return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get XDG_DATA_HOME directory path
|
|
18
|
+
* Defaults to $HOME/.local/share
|
|
19
|
+
*/
|
|
20
|
+
static getDataHome() {
|
|
21
|
+
return process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get XDG_CACHE_HOME directory path
|
|
25
|
+
* Defaults to $HOME/.cache
|
|
26
|
+
*/
|
|
27
|
+
static getCacheHome() {
|
|
28
|
+
return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get XDG_STATE_HOME directory path
|
|
32
|
+
* Defaults to $HOME/.local/state
|
|
33
|
+
*/
|
|
34
|
+
static getStateHome() {
|
|
35
|
+
return process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the appropriate application directory within an XDG directory
|
|
39
|
+
* @param base XDG base directory
|
|
40
|
+
* @param appName Application name
|
|
41
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
42
|
+
*/
|
|
43
|
+
static getAppDir(base, appName, create = true) {
|
|
44
|
+
const dir = path.join(base, appName);
|
|
45
|
+
if (create) {
|
|
46
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
return dir;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get application's cache directory
|
|
52
|
+
* @param appName Application name
|
|
53
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
54
|
+
*/
|
|
55
|
+
static getAppCacheDir(appName, create = true) {
|
|
56
|
+
return this.getAppDir(this.getCacheHome(), appName, create);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get application's config directory
|
|
60
|
+
* @param appName Application name
|
|
61
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
62
|
+
*/
|
|
63
|
+
static getAppConfigDir(appName, create = true) {
|
|
64
|
+
return this.getAppDir(this.getConfigHome(), appName, create);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get application's data directory
|
|
68
|
+
* @param appName Application name
|
|
69
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
70
|
+
*/
|
|
71
|
+
static getAppDataDir(appName, create = true) {
|
|
72
|
+
return this.getAppDir(this.getDataHome(), appName, create);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get application's state directory (for logs, etc.)
|
|
76
|
+
* @param appName Application name
|
|
77
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
78
|
+
*/
|
|
79
|
+
static getAppStateDir(appName, create = true) {
|
|
80
|
+
return this.getAppDir(this.getStateHome(), appName, create);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get application's log directory (typically in state home)
|
|
84
|
+
* @param appName Application name
|
|
85
|
+
* @param create Whether to create the directory if it doesn't exist
|
|
86
|
+
*/
|
|
87
|
+
static getAppLogDir(appName, create = true) {
|
|
88
|
+
const logDir = path.join(this.getAppStateDir(appName, create), 'logs');
|
|
89
|
+
if (create) {
|
|
90
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
91
|
+
}
|
|
92
|
+
return logDir;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=xdgPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xdgPaths.js","sourceRoot":"/","sources":["utils/xdgPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB;;;GAGG;AACH,MAAM,OAAO,QAAQ;IACnB;;;OAGG;IACH,MAAM,CAAC,aAAa;QAClB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,WAAW;QAChB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjF,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,YAAY;QACjB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;IACzE,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,YAAY;QACjB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClF,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,MAAM,GAAG,IAAI;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,OAAe,EAAE,MAAM,GAAG,IAAI;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,eAAe,CAAC,OAAe,EAAE,MAAM,GAAG,IAAI;QACnD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,OAAe,EAAE,MAAM,GAAG,IAAI;QACjD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,OAAe,EAAE,MAAM,GAAG,IAAI;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,OAAe,EAAE,MAAM,GAAG,IAAI;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QACvE,IAAI,MAAM,EAAE,CAAC;YACX,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF","sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/**\n * XDG Base Directory Specification utility\n * https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n */\nexport class XDGPaths {\n /**\n * Get XDG_CONFIG_HOME directory path\n * Defaults to $HOME/.config\n */\n static getConfigHome(): string {\n return process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n }\n\n /**\n * Get XDG_DATA_HOME directory path\n * Defaults to $HOME/.local/share\n */\n static getDataHome(): string {\n return process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n }\n\n /**\n * Get XDG_CACHE_HOME directory path\n * Defaults to $HOME/.cache\n */\n static getCacheHome(): string {\n return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');\n }\n\n /**\n * Get XDG_STATE_HOME directory path\n * Defaults to $HOME/.local/state\n */\n static getStateHome(): string {\n return process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n }\n\n /**\n * Get the appropriate application directory within an XDG directory\n * @param base XDG base directory\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppDir(base: string, appName: string, create = true): string {\n const dir = path.join(base, appName);\n if (create) {\n fs.mkdirSync(dir, { recursive: true });\n }\n return dir;\n }\n\n /**\n * Get application's cache directory\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppCacheDir(appName: string, create = true): string {\n return this.getAppDir(this.getCacheHome(), appName, create);\n }\n\n /**\n * Get application's config directory\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppConfigDir(appName: string, create = true): string {\n return this.getAppDir(this.getConfigHome(), appName, create);\n }\n\n /**\n * Get application's data directory\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppDataDir(appName: string, create = true): string {\n return this.getAppDir(this.getDataHome(), appName, create);\n }\n\n /**\n * Get application's state directory (for logs, etc.)\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppStateDir(appName: string, create = true): string {\n return this.getAppDir(this.getStateHome(), appName, create);\n }\n\n /**\n * Get application's log directory (typically in state home)\n * @param appName Application name\n * @param create Whether to create the directory if it doesn't exist\n */\n static getAppLogDir(appName: string, create = true): string {\n const logDir = path.join(this.getAppStateDir(appName, create), 'logs');\n if (create) {\n fs.mkdirSync(logDir, { recursive: true });\n }\n return logDir;\n }\n} "]}
|
package/env.example
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# bktide Environment Configuration
|
|
2
|
+
# Copy this file to ~/.config/bktide/env or to the workflow directory as .env
|
|
3
|
+
|
|
4
|
+
# Node.js Configuration
|
|
5
|
+
# ===================
|
|
6
|
+
|
|
7
|
+
# Path to the Node.js binary
|
|
8
|
+
# If Node.js is not in your PATH or you want to use a specific version,
|
|
9
|
+
# set this to the full path of the node binary
|
|
10
|
+
# Examples:
|
|
11
|
+
# NODE_BIN=node # Use node from PATH (default)
|
|
12
|
+
# NODE_BIN=/opt/homebrew/bin/node # Homebrew on Apple Silicon
|
|
13
|
+
# NODE_BIN=/usr/local/bin/node # Homebrew on Intel Mac
|
|
14
|
+
# NODE_BIN=/Users/username/.nvm/versions/node/v18.17.0/bin/node # nvm
|
|
15
|
+
#NODE_BIN=node
|
|
16
|
+
|
|
17
|
+
# PATH Configuration
|
|
18
|
+
# =================
|
|
19
|
+
|
|
20
|
+
# You can extend the PATH to include additional directories where Node.js might be located
|
|
21
|
+
# This is useful if your Node.js installation is not in the default system PATH
|
|
22
|
+
# Examples:
|
|
23
|
+
# export PATH="/opt/homebrew/bin:$PATH" # Add Homebrew (Apple Silicon)
|
|
24
|
+
# export PATH="/usr/local/bin:$PATH" # Add Homebrew (Intel)
|
|
25
|
+
# export PATH="/Users/username/.nvm/versions/node/v18.17.0/bin:$PATH" # Add nvm
|
|
26
|
+
|
|
27
|
+
# Buildkite API Configuration
|
|
28
|
+
# ==========================
|
|
29
|
+
|
|
30
|
+
# Buildkite API token
|
|
31
|
+
# This can also be stored securely using: bktide token --store
|
|
32
|
+
# Or passed as a command line argument: --token your_token_here
|
|
33
|
+
#BUILDKITE_API_TOKEN=your_buildkite_api_token_here
|
|
34
|
+
|
|
35
|
+
# Debugging and Development
|
|
36
|
+
# ========================
|
|
37
|
+
|
|
38
|
+
# Enable debug logging (equivalent to --debug flag)
|
|
39
|
+
#DEBUG=true
|
|
40
|
+
|
|
41
|
+
# Disable caching (equivalent to --no-cache flag)
|
|
42
|
+
#NO_CACHE=true
|
|
43
|
+
|
|
44
|
+
# Custom cache directory (defaults to ~/.cache/bktide)
|
|
45
|
+
#CACHE_DIR=/custom/path/to/cache
|
|
46
|
+
|
|
47
|
+
# Custom log directory (defaults to ~/.local/state/bktide/logs)
|
|
48
|
+
#LOG_DIR=/custom/path/to/logs
|
|
49
|
+
|
|
50
|
+
# Example configurations for common setups:
|
|
51
|
+
# ========================================
|
|
52
|
+
|
|
53
|
+
# For Homebrew on Apple Silicon Macs:
|
|
54
|
+
# export PATH="/opt/homebrew/bin:$PATH"
|
|
55
|
+
# NODE_BIN=/opt/homebrew/bin/node
|
|
56
|
+
|
|
57
|
+
# For Homebrew on Intel Macs:
|
|
58
|
+
# export PATH="/usr/local/bin:$PATH"
|
|
59
|
+
# NODE_BIN=/usr/local/bin/node
|
|
60
|
+
|
|
61
|
+
# For nvm users (replace with your Node version):
|
|
62
|
+
# export PATH="/Users/$(whoami)/.nvm/versions/node/v18.17.0/bin:$PATH"
|
|
63
|
+
# NODE_BIN="/Users/$(whoami)/.nvm/versions/node/v18.17.0/bin/node"
|
|
64
|
+
|
|
65
|
+
# For system Node.js installation:
|
|
66
|
+
# NODE_BIN=node
|
package/icons/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[Possible States](https://buildkite.com/user/graphql/documentation/type/BuildStates)
|
|
2
|
+
|
|
3
|
+
SKIPPED
|
|
4
|
+
The build was skipped
|
|
5
|
+
|
|
6
|
+
CREATING
|
|
7
|
+
The build is currently being created
|
|
8
|
+
|
|
9
|
+
SCHEDULED
|
|
10
|
+
The build has yet to start running jobs
|
|
11
|
+
|
|
12
|
+
RUNNING
|
|
13
|
+
The build is currently running jobs
|
|
14
|
+
|
|
15
|
+
PASSED
|
|
16
|
+
The build passed
|
|
17
|
+
|
|
18
|
+
FAILED
|
|
19
|
+
The build failed
|
|
20
|
+
|
|
21
|
+
FAILING
|
|
22
|
+
The build is failing
|
|
23
|
+
|
|
24
|
+
CANCELING
|
|
25
|
+
The build is currently being canceled
|
|
26
|
+
|
|
27
|
+
CANCELED
|
|
28
|
+
The build was canceled
|
|
29
|
+
|
|
30
|
+
BLOCKED
|
|
31
|
+
The build is blocked
|
|
32
|
+
|
|
33
|
+
NOT_RUN
|
|
34
|
+
The build wasn't run
|
|
35
|
+
|
|
36
|
+
Material Icons
|
|
37
|
+
Size: 256x256
|
|
38
|
+
|
|
39
|
+
* icons/pass.png
|
|
40
|
+
* [Check Circle](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:check_circle:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=check&icon.size=256&icon.color=%2375FB4C)
|
|
41
|
+
* icons/fail.png
|
|
42
|
+
* [Error](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:error:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=error&icon.size=256&icon.color=%23BB271A)
|
|
43
|
+
* icons/running.png
|
|
44
|
+
* [Sync](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:sync:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=sync&icon.size=256&icon.color=%23F19E39)
|
|
45
|
+
* icons/cancelled.png
|
|
46
|
+
* [Cancel](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:cancel:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=cancel&icon.size=256&icon.color=%23EA3323)
|
|
47
|
+
* Red
|
|
48
|
+
* icons/cancelling.png
|
|
49
|
+
* [Sync Problem](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:sync_problem:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=sync&icon.size=256&icon.color=%23EA3323)
|
|
50
|
+
* Red
|
|
51
|
+
* icons/failing.png
|
|
52
|
+
* [Sync Problem](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:sync_problem:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=sync&icon.size=256&icon.color=%23EA3323)
|
|
53
|
+
* Red
|
|
54
|
+
* icons/skipped.png
|
|
55
|
+
* [Next Plan](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:next_plan:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=skip&icon.size=256&icon.color=%23999999)
|
|
56
|
+
* Gray
|
|
57
|
+
* icons/blocked.png
|
|
58
|
+
* [Pause](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:pause:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=pause&icon.size=256&icon.color=%238C1AF6)
|
|
59
|
+
* purple
|
|
60
|
+
* icons/scheduled.png
|
|
61
|
+
* [Schedule](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:schedule:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=schedule&icon.size=256&icon.color=%23999999)
|
|
62
|
+
* gray
|
|
63
|
+
* icons/unknown.png
|
|
64
|
+
* [Question Mark](https://fonts.google.com/icons?selected=Material+Symbols+Outlined:question_mark:FILL@0;wght@400;GRAD@0;opsz@48&icon.query=unknown&icon.size=256&icon.color=%23999999)
|
|
65
|
+
* gray
|
|
66
|
+
* icons/building.png
|
|
67
|
+
* https://buildkite.com/about/brand-assets/
|
|
68
|
+
* secondary logo, mark
|
|
Binary file
|
|
Binary file
|
package/icons/failed.png
ADDED
|
Binary file
|
|
Binary file
|
package/icons/passed.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|