trello-cli-unofficial 0.10.8 → 0.11.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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.11.1](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.11.0...v0.11.1) (2025-11-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * use static import for Commander to fix cross-platform compatibility ([9796c57](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/9796c57b2f24638a652b4bf989e798fccbc9ea76))
7
+
8
+ # [0.11.0](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.10.8...v0.11.0) (2025-11-14)
9
+
10
+
11
+ ### Features
12
+
13
+ * add --verbose option for detailed error reporting ([76d0fbe](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/76d0fbedcc6fefbe8841dfb56e1cd095cb224548))
14
+
1
15
  ## [0.10.8](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.10.7...v0.10.8) (2025-11-14)
2
16
 
3
17
 
package/bin/cli.js CHANGED
@@ -90,6 +90,21 @@ if (!bunType) {
90
90
  const mainScript = path.join(__dirname, '..', 'dist', 'main.js');
91
91
  const args = process.argv.slice(2);
92
92
 
93
+ // Check for verbose flag
94
+ const isVerbose = args.includes('--verbose') || args.includes('-V');
95
+ if (isVerbose) {
96
+ process.env.VERBOSE_ERRORS = 'true';
97
+ // Remove verbose flag from args so it doesn't interfere
98
+ const verboseIndex = args.indexOf('--verbose');
99
+ if (verboseIndex !== -1) {
100
+ args.splice(verboseIndex, 1);
101
+ }
102
+ const shortVerboseIndex = args.indexOf('-V');
103
+ if (shortVerboseIndex !== -1) {
104
+ args.splice(shortVerboseIndex, 1);
105
+ }
106
+ }
107
+
93
108
  // Use local Bun if available, otherwise global
94
109
  const bunCommand = bunType === 'local'
95
110
  ? path.join(__dirname, '..', 'node_modules', '.bin', 'bun')
@@ -98,6 +113,7 @@ const bunCommand = bunType === 'local'
98
113
  const child = spawn(bunCommand, [mainScript, ...args], {
99
114
  stdio: 'inherit',
100
115
  cwd: process.cwd(),
116
+ env: { ...process.env, VERBOSE_ERRORS: process.env.VERBOSE_ERRORS || 'false' },
101
117
  });
102
118
 
103
119
  child.on('exit', (code) => {
package/dist/main.js CHANGED
@@ -2630,6 +2630,7 @@ var require_en = __commonJS((exports, module) => {
2630
2630
  description: "Unofficial Trello CLI using Power-Up authentication",
2631
2631
  formatOption: "Output format: table, json, csv",
2632
2632
  versionOption: "output the version number",
2633
+ verboseOption: "show detailed errors for debugging",
2633
2634
  deprecated: {
2634
2635
  boardsLegacyDescription: '[DEPRECATED] Use "boards list" instead',
2635
2636
  boardsLegacyWarning: '\u26A0\uFE0F Warning: "boards" command is deprecated. Use "boards list" instead.',
@@ -2904,6 +2905,7 @@ var require_pt_BR = __commonJS((exports, module) => {
2904
2905
  description: "CLI n\xE3o oficial do Trello usando autentica\xE7\xE3o Power-Up",
2905
2906
  formatOption: "Formato de sa\xEDda: table, json, csv",
2906
2907
  versionOption: "exibe o n\xFAmero da vers\xE3o",
2908
+ verboseOption: "mostra erros detalhados para debug",
2907
2909
  deprecated: {
2908
2910
  boardsLegacyDescription: '[DEPRECIADO] Use "boards list" ao inv\xE9s disso',
2909
2911
  boardsLegacyWarning: '\u26A0\uFE0F Aviso: comando "boards" est\xE1 depreciado. Use "boards list" ao inv\xE9s disso.',
@@ -28839,390 +28841,121 @@ var init_repositories = __esm(() => {
28839
28841
  init_TrelloApiRepository();
28840
28842
  });
28841
28843
 
28842
- // src/shared/ErrorHandler.ts
28843
- class ErrorHandler {
28844
- static handle(error, context) {
28845
- if (error instanceof TrelloCliError) {
28846
- this.handleTrelloError(error, context);
28847
- } else if (error instanceof Error) {
28848
- this.handleGenericError(error, context);
28849
- } else {
28850
- this.handleUnknownError(error, context);
28844
+ // node_modules/commander/lib/error.js
28845
+ var require_error = __commonJS((exports) => {
28846
+ class CommanderError extends Error {
28847
+ constructor(exitCode, code, message) {
28848
+ super(message);
28849
+ Error.captureStackTrace(this, this.constructor);
28850
+ this.name = this.constructor.name;
28851
+ this.code = code;
28852
+ this.exitCode = exitCode;
28853
+ this.nestedError = undefined;
28851
28854
  }
28852
28855
  }
28853
- static handleTrelloError(error, context) {
28854
- const prefix = context ? `[${context}] ` : "";
28855
- switch (error.code) {
28856
- case "AUTH_ERROR":
28857
- console.error(t2("errors.authFailed", { message: error.message }));
28858
- console.error(t2("errors.trySetup"));
28859
- break;
28860
- case "API_ERROR":
28861
- console.error(t2("errors.apiError", { statusCode: error.statusCode, message: error.message }));
28862
- if (error instanceof ApiError && error.endpoint) {
28863
- console.error(t2("errors.endpoint", { endpoint: error.endpoint }));
28864
- }
28865
- break;
28866
- case "VALIDATION_ERROR":
28867
- console.error(t2("errors.validationError", { message: error.message }));
28868
- if (error instanceof ValidationError2 && error.field) {
28869
- console.error(t2("errors.field", { field: error.field }));
28870
- }
28871
- break;
28872
- case "NOT_FOUND_ERROR":
28873
- console.error(t2("errors.notFound", { message: error.message }));
28874
- if (error instanceof NotFoundError) {
28875
- if (error.resourceType) {
28876
- console.error(t2("errors.resourceType", { resourceType: error.resourceType }));
28877
- }
28878
- if (error.resourceId) {
28879
- console.error(t2("errors.resourceId", { resourceId: error.resourceId }));
28880
- }
28881
- }
28882
- break;
28883
- case "CONFIG_ERROR":
28884
- console.error(t2("errors.configError", { message: error.message }));
28885
- console.error(t2("errors.checkConfig"));
28886
- break;
28887
- case "NETWORK_ERROR":
28888
- console.error(t2("errors.networkError", { message: error.message }));
28889
- console.error(t2("errors.checkConnection"));
28890
- break;
28891
- default:
28892
- console.error(`\u274C ${prefix}${error.message}`);
28856
+
28857
+ class InvalidArgumentError extends CommanderError {
28858
+ constructor(message) {
28859
+ super(1, "commander.invalidArgument", message);
28860
+ Error.captureStackTrace(this, this.constructor);
28861
+ this.name = this.constructor.name;
28893
28862
  }
28894
- process.exit(error.statusCode || 1);
28895
28863
  }
28896
- static handleGenericError(error, _context) {
28897
- console.error(t2("errors.unexpectedError", { message: error.message }));
28898
- if (true) {
28899
- console.error(t2("errors.stackTrace"), error.stack);
28864
+ exports.CommanderError = CommanderError;
28865
+ exports.InvalidArgumentError = InvalidArgumentError;
28866
+ });
28867
+
28868
+ // node_modules/commander/lib/argument.js
28869
+ var require_argument = __commonJS((exports) => {
28870
+ var { InvalidArgumentError } = require_error();
28871
+
28872
+ class Argument {
28873
+ constructor(name, description) {
28874
+ this.description = description || "";
28875
+ this.variadic = false;
28876
+ this.parseArg = undefined;
28877
+ this.defaultValue = undefined;
28878
+ this.defaultValueDescription = undefined;
28879
+ this.argChoices = undefined;
28880
+ switch (name[0]) {
28881
+ case "<":
28882
+ this.required = true;
28883
+ this._name = name.slice(1, -1);
28884
+ break;
28885
+ case "[":
28886
+ this.required = false;
28887
+ this._name = name.slice(1, -1);
28888
+ break;
28889
+ default:
28890
+ this.required = true;
28891
+ this._name = name;
28892
+ break;
28893
+ }
28894
+ if (this._name.endsWith("...")) {
28895
+ this.variadic = true;
28896
+ this._name = this._name.slice(0, -3);
28897
+ }
28900
28898
  }
28901
- process.exit(1);
28902
- }
28903
- static handleUnknownError(error, _context) {
28904
- console.error(t2("errors.unknownError"), error);
28905
- process.exit(1);
28906
- }
28907
- static async withErrorHandling(operation, context) {
28908
- try {
28909
- return await operation();
28910
- } catch (error) {
28911
- this.handle(error, context);
28912
- throw error;
28899
+ name() {
28900
+ return this._name;
28913
28901
  }
28914
- }
28915
- static fromApiResponse(response, endpoint) {
28916
- const statusCode = response.status || response.statusCode || 500;
28917
- const message = response.message || response.error || t2("api.unknownApiError");
28918
- switch (statusCode) {
28919
- case 401:
28920
- return new AuthenticationError(t2("api.invalidToken"));
28921
- case 403:
28922
- return new AuthenticationError("Access denied");
28923
- case 404:
28924
- return new NotFoundError(t2("api.resourceNotFound"), "unknown");
28925
- case 400:
28926
- return new ValidationError2(message);
28927
- case 429:
28928
- return new ApiError(t2("api.rateLimitExceeded"), statusCode, endpoint);
28929
- case 500:
28930
- return new ApiError(t2("api.internalServerError"), statusCode, endpoint);
28931
- default:
28932
- return new ApiError(message, statusCode, endpoint);
28902
+ _collectValue(value, previous) {
28903
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
28904
+ return [value];
28905
+ }
28906
+ previous.push(value);
28907
+ return previous;
28933
28908
  }
28934
- }
28935
- }
28936
- var TrelloCliError, AuthenticationError, ApiError, ValidationError2, NotFoundError;
28937
- var init_ErrorHandler = __esm(() => {
28938
- init_i18n();
28939
- TrelloCliError = class TrelloCliError extends Error {
28940
- code;
28941
- statusCode;
28942
- constructor(message, code, statusCode) {
28943
- super(message);
28944
- this.code = code;
28945
- this.statusCode = statusCode;
28946
- this.name = this.constructor.name;
28909
+ default(value, description) {
28910
+ this.defaultValue = value;
28911
+ this.defaultValueDescription = description;
28912
+ return this;
28947
28913
  }
28948
- };
28949
- AuthenticationError = class AuthenticationError extends TrelloCliError {
28950
- constructor(message = "Authentication failed") {
28951
- super(message, "AUTH_ERROR", 401);
28914
+ argParser(fn) {
28915
+ this.parseArg = fn;
28916
+ return this;
28952
28917
  }
28953
- };
28954
- ApiError = class ApiError extends TrelloCliError {
28955
- statusCode;
28956
- endpoint;
28957
- constructor(message, statusCode, endpoint) {
28958
- super(message, "API_ERROR", statusCode);
28959
- this.statusCode = statusCode;
28960
- this.endpoint = endpoint;
28918
+ choices(values) {
28919
+ this.argChoices = values.slice();
28920
+ this.parseArg = (arg, previous) => {
28921
+ if (!this.argChoices.includes(arg)) {
28922
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
28923
+ }
28924
+ if (this.variadic) {
28925
+ return this._collectValue(arg, previous);
28926
+ }
28927
+ return arg;
28928
+ };
28929
+ return this;
28961
28930
  }
28962
- };
28963
- ValidationError2 = class ValidationError2 extends TrelloCliError {
28964
- field;
28965
- constructor(message, field) {
28966
- super(message, "VALIDATION_ERROR", 400);
28967
- this.field = field;
28931
+ argRequired() {
28932
+ this.required = true;
28933
+ return this;
28968
28934
  }
28969
- };
28970
- NotFoundError = class NotFoundError extends TrelloCliError {
28971
- resourceType;
28972
- resourceId;
28973
- constructor(message, resourceType, resourceId) {
28974
- super(message, "NOT_FOUND_ERROR", 404);
28975
- this.resourceType = resourceType;
28976
- this.resourceId = resourceId;
28935
+ argOptional() {
28936
+ this.required = false;
28937
+ return this;
28977
28938
  }
28978
- };
28979
- });
28980
-
28981
- // src/shared/OutputFormatter.ts
28982
- class OutputFormatter {
28983
- format;
28984
- constructor(format = "table") {
28985
- this.format = format;
28986
28939
  }
28987
- setFormat(format) {
28988
- this.format = format;
28940
+ function humanReadableArgName(arg) {
28941
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
28942
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
28989
28943
  }
28990
- output(data, options) {
28991
- const format = options?.format || this.format;
28992
- switch (format) {
28993
- case "json":
28994
- this.outputJson(data);
28995
- break;
28996
- case "csv":
28997
- this.outputCsv(data, options);
28998
- break;
28999
- case "table":
29000
- default:
29001
- this.outputTable(data, options);
29002
- break;
29003
- }
29004
- }
29005
- outputJson(data) {
29006
- console.log(JSON.stringify(data, null, 2));
29007
- }
29008
- outputCsv(data, options) {
29009
- if (!Array.isArray(data) || data.length === 0) {
29010
- console.log(t2("common.noData"));
29011
- return;
29012
- }
29013
- const firstItem = data[0];
29014
- if (!firstItem) {
29015
- console.log(t2("common.noData"));
29016
- return;
29017
- }
29018
- const plainItem = this.toPlainObject(firstItem);
29019
- const fields = options?.fields || Object.keys(plainItem);
29020
- const headers = options?.headers || fields;
29021
- console.log(headers.join(","));
29022
- for (const item of data) {
29023
- const plainObject = this.toPlainObject(item);
29024
- const row = fields.map((field) => {
29025
- const value = plainObject[field];
29026
- const stringValue = String(value || "");
29027
- if (stringValue.includes(",") || stringValue.includes('"') || stringValue.includes(`
29028
- `)) {
29029
- return `"${stringValue.replace(/"/g, '""')}"`;
29030
- }
29031
- return stringValue;
29032
- });
29033
- console.log(row.join(","));
29034
- }
29035
- }
29036
- outputTable(data, options) {
29037
- if (!Array.isArray(data) || data.length === 0) {
29038
- console.log(t2("common.noData"));
29039
- return;
29040
- }
29041
- const firstItem = data[0];
29042
- if (!firstItem) {
29043
- console.log(t2("common.noData"));
29044
- return;
29045
- }
29046
- const plainItem = this.toPlainObject(firstItem);
29047
- const fields = options?.fields || Object.keys(plainItem);
29048
- const headers = options?.headers || fields;
29049
- const columnWidths = headers.map((header, index) => {
29050
- const field = fields[index];
29051
- const headerWidth = header.length;
29052
- const maxDataWidth = Math.max(...data.map((item) => {
29053
- const plainObject = this.toPlainObject(item);
29054
- return String(plainObject[field] || "").length;
29055
- }));
29056
- return Math.max(headerWidth, maxDataWidth);
29057
- });
29058
- const headerRow = headers.map((header, index) => header.padEnd(columnWidths[index])).join(" | ");
29059
- console.log(headerRow);
29060
- const separator = columnWidths.map((width) => "-".repeat(width)).join("-+-");
29061
- console.log(separator);
29062
- for (const item of data) {
29063
- const plainObject = this.toPlainObject(item);
29064
- const row = fields.map((field, index) => {
29065
- const value = String(plainObject[field] || "");
29066
- return value.padEnd(columnWidths[index]);
29067
- }).join(" | ");
29068
- console.log(row);
29069
- }
29070
- }
29071
- toPlainObject(obj) {
29072
- if (obj === null || obj === undefined) {
29073
- return {};
29074
- }
29075
- if (typeof obj === "object" && obj.constructor !== Object) {
29076
- const plain = {};
29077
- for (const key of Object.keys(obj)) {
29078
- plain[key] = obj[key];
29079
- }
29080
- return plain;
29081
- }
29082
- return obj;
29083
- }
29084
- message(message) {
29085
- console.log(message);
29086
- }
29087
- error(message) {
29088
- console.error(`\u274C ${message}`);
29089
- }
29090
- success(message) {
29091
- console.log(`\u2705 ${message}`);
29092
- }
29093
- warning(message) {
29094
- console.log(`\u26A0\uFE0F ${message}`);
29095
- }
29096
- info(message) {
29097
- console.log(`\u2139\uFE0F ${message}`);
29098
- }
29099
- }
29100
- var init_OutputFormatter = __esm(() => {
29101
- init_i18n();
29102
- });
29103
-
29104
- // src/shared/index.ts
29105
- var init_shared = __esm(() => {
29106
- init_ErrorHandler();
29107
- init_OutputFormatter();
29108
- init_types();
29109
- });
29110
-
29111
- // node_modules/commander/lib/error.js
29112
- var require_error = __commonJS((exports) => {
29113
- class CommanderError extends Error {
29114
- constructor(exitCode, code, message) {
29115
- super(message);
29116
- Error.captureStackTrace(this, this.constructor);
29117
- this.name = this.constructor.name;
29118
- this.code = code;
29119
- this.exitCode = exitCode;
29120
- this.nestedError = undefined;
29121
- }
29122
- }
29123
-
29124
- class InvalidArgumentError extends CommanderError {
29125
- constructor(message) {
29126
- super(1, "commander.invalidArgument", message);
29127
- Error.captureStackTrace(this, this.constructor);
29128
- this.name = this.constructor.name;
29129
- }
29130
- }
29131
- exports.CommanderError = CommanderError;
29132
- exports.InvalidArgumentError = InvalidArgumentError;
29133
- });
29134
-
29135
- // node_modules/commander/lib/argument.js
29136
- var require_argument = __commonJS((exports) => {
29137
- var { InvalidArgumentError } = require_error();
29138
-
29139
- class Argument {
29140
- constructor(name, description) {
29141
- this.description = description || "";
29142
- this.variadic = false;
29143
- this.parseArg = undefined;
29144
- this.defaultValue = undefined;
29145
- this.defaultValueDescription = undefined;
29146
- this.argChoices = undefined;
29147
- switch (name[0]) {
29148
- case "<":
29149
- this.required = true;
29150
- this._name = name.slice(1, -1);
29151
- break;
29152
- case "[":
29153
- this.required = false;
29154
- this._name = name.slice(1, -1);
29155
- break;
29156
- default:
29157
- this.required = true;
29158
- this._name = name;
29159
- break;
29160
- }
29161
- if (this._name.endsWith("...")) {
29162
- this.variadic = true;
29163
- this._name = this._name.slice(0, -3);
29164
- }
29165
- }
29166
- name() {
29167
- return this._name;
29168
- }
29169
- _collectValue(value, previous) {
29170
- if (previous === this.defaultValue || !Array.isArray(previous)) {
29171
- return [value];
29172
- }
29173
- previous.push(value);
29174
- return previous;
29175
- }
29176
- default(value, description) {
29177
- this.defaultValue = value;
29178
- this.defaultValueDescription = description;
29179
- return this;
29180
- }
29181
- argParser(fn) {
29182
- this.parseArg = fn;
29183
- return this;
29184
- }
29185
- choices(values) {
29186
- this.argChoices = values.slice();
29187
- this.parseArg = (arg, previous) => {
29188
- if (!this.argChoices.includes(arg)) {
29189
- throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
29190
- }
29191
- if (this.variadic) {
29192
- return this._collectValue(arg, previous);
29193
- }
29194
- return arg;
29195
- };
29196
- return this;
29197
- }
29198
- argRequired() {
29199
- this.required = true;
29200
- return this;
29201
- }
29202
- argOptional() {
29203
- this.required = false;
29204
- return this;
29205
- }
29206
- }
29207
- function humanReadableArgName(arg) {
29208
- const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
29209
- return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
29210
- }
29211
- exports.Argument = Argument;
29212
- exports.humanReadableArgName = humanReadableArgName;
29213
- });
29214
-
29215
- // node_modules/commander/lib/help.js
29216
- var require_help = __commonJS((exports) => {
29217
- var { humanReadableArgName } = require_argument();
29218
-
29219
- class Help {
29220
- constructor() {
29221
- this.helpWidth = undefined;
29222
- this.minWidthToWrap = 40;
29223
- this.sortSubcommands = false;
29224
- this.sortOptions = false;
29225
- this.showGlobalOptions = false;
28944
+ exports.Argument = Argument;
28945
+ exports.humanReadableArgName = humanReadableArgName;
28946
+ });
28947
+
28948
+ // node_modules/commander/lib/help.js
28949
+ var require_help = __commonJS((exports) => {
28950
+ var { humanReadableArgName } = require_argument();
28951
+
28952
+ class Help {
28953
+ constructor() {
28954
+ this.helpWidth = undefined;
28955
+ this.minWidthToWrap = 40;
28956
+ this.sortSubcommands = false;
28957
+ this.sortOptions = false;
28958
+ this.showGlobalOptions = false;
29226
28959
  }
29227
28960
  prepareContext(contextOptions) {
29228
28961
  this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
@@ -31046,192 +30779,447 @@ Expecting one of '${allowedValues.join("', '")}'`);
31046
30779
  };
31047
30780
  return { error, write, hasColors, helpWidth };
31048
30781
  }
31049
- outputHelp(contextOptions) {
31050
- let deprecatedCallback;
31051
- if (typeof contextOptions === "function") {
31052
- deprecatedCallback = contextOptions;
31053
- contextOptions = undefined;
31054
- }
31055
- const outputContext = this._getOutputContext(contextOptions);
31056
- const eventContext = {
31057
- error: outputContext.error,
31058
- write: outputContext.write,
31059
- command: this
31060
- };
31061
- this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
31062
- this.emit("beforeHelp", eventContext);
31063
- let helpInformation = this.helpInformation({ error: outputContext.error });
31064
- if (deprecatedCallback) {
31065
- helpInformation = deprecatedCallback(helpInformation);
31066
- if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
31067
- throw new Error("outputHelp callback must return a string or a Buffer");
31068
- }
31069
- }
31070
- outputContext.write(helpInformation);
31071
- if (this._getHelpOption()?.long) {
31072
- this.emit(this._getHelpOption().long);
31073
- }
31074
- this.emit("afterHelp", eventContext);
31075
- this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
30782
+ outputHelp(contextOptions) {
30783
+ let deprecatedCallback;
30784
+ if (typeof contextOptions === "function") {
30785
+ deprecatedCallback = contextOptions;
30786
+ contextOptions = undefined;
30787
+ }
30788
+ const outputContext = this._getOutputContext(contextOptions);
30789
+ const eventContext = {
30790
+ error: outputContext.error,
30791
+ write: outputContext.write,
30792
+ command: this
30793
+ };
30794
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
30795
+ this.emit("beforeHelp", eventContext);
30796
+ let helpInformation = this.helpInformation({ error: outputContext.error });
30797
+ if (deprecatedCallback) {
30798
+ helpInformation = deprecatedCallback(helpInformation);
30799
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
30800
+ throw new Error("outputHelp callback must return a string or a Buffer");
30801
+ }
30802
+ }
30803
+ outputContext.write(helpInformation);
30804
+ if (this._getHelpOption()?.long) {
30805
+ this.emit(this._getHelpOption().long);
30806
+ }
30807
+ this.emit("afterHelp", eventContext);
30808
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
30809
+ }
30810
+ helpOption(flags, description) {
30811
+ if (typeof flags === "boolean") {
30812
+ if (flags) {
30813
+ if (this._helpOption === null)
30814
+ this._helpOption = undefined;
30815
+ if (this._defaultOptionGroup) {
30816
+ this._initOptionGroup(this._getHelpOption());
30817
+ }
30818
+ } else {
30819
+ this._helpOption = null;
30820
+ }
30821
+ return this;
30822
+ }
30823
+ this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
30824
+ if (flags || description)
30825
+ this._initOptionGroup(this._helpOption);
30826
+ return this;
30827
+ }
30828
+ _getHelpOption() {
30829
+ if (this._helpOption === undefined) {
30830
+ this.helpOption(undefined, undefined);
30831
+ }
30832
+ return this._helpOption;
30833
+ }
30834
+ addHelpOption(option) {
30835
+ this._helpOption = option;
30836
+ this._initOptionGroup(option);
30837
+ return this;
30838
+ }
30839
+ help(contextOptions) {
30840
+ this.outputHelp(contextOptions);
30841
+ let exitCode = Number(process4.exitCode ?? 0);
30842
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
30843
+ exitCode = 1;
30844
+ }
30845
+ this._exit(exitCode, "commander.help", "(outputHelp)");
30846
+ }
30847
+ addHelpText(position, text) {
30848
+ const allowedValues = ["beforeAll", "before", "after", "afterAll"];
30849
+ if (!allowedValues.includes(position)) {
30850
+ throw new Error(`Unexpected value for position to addHelpText.
30851
+ Expecting one of '${allowedValues.join("', '")}'`);
30852
+ }
30853
+ const helpEvent = `${position}Help`;
30854
+ this.on(helpEvent, (context) => {
30855
+ let helpStr;
30856
+ if (typeof text === "function") {
30857
+ helpStr = text({ error: context.error, command: context.command });
30858
+ } else {
30859
+ helpStr = text;
30860
+ }
30861
+ if (helpStr) {
30862
+ context.write(`${helpStr}
30863
+ `);
30864
+ }
30865
+ });
30866
+ return this;
30867
+ }
30868
+ _outputHelpIfRequested(args) {
30869
+ const helpOption = this._getHelpOption();
30870
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
30871
+ if (helpRequested) {
30872
+ this.outputHelp();
30873
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
30874
+ }
30875
+ }
30876
+ }
30877
+ function incrementNodeInspectorPort(args) {
30878
+ return args.map((arg) => {
30879
+ if (!arg.startsWith("--inspect")) {
30880
+ return arg;
30881
+ }
30882
+ let debugOption;
30883
+ let debugHost = "127.0.0.1";
30884
+ let debugPort = "9229";
30885
+ let match;
30886
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
30887
+ debugOption = match[1];
30888
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
30889
+ debugOption = match[1];
30890
+ if (/^\d+$/.test(match[3])) {
30891
+ debugPort = match[3];
30892
+ } else {
30893
+ debugHost = match[3];
30894
+ }
30895
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
30896
+ debugOption = match[1];
30897
+ debugHost = match[3];
30898
+ debugPort = match[4];
30899
+ }
30900
+ if (debugOption && debugPort !== "0") {
30901
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
30902
+ }
30903
+ return arg;
30904
+ });
30905
+ }
30906
+ function useColor() {
30907
+ if (process4.env.NO_COLOR || process4.env.FORCE_COLOR === "0" || process4.env.FORCE_COLOR === "false")
30908
+ return false;
30909
+ if (process4.env.FORCE_COLOR || process4.env.CLICOLOR_FORCE !== undefined)
30910
+ return true;
30911
+ return;
30912
+ }
30913
+ exports.Command = Command;
30914
+ exports.useColor = useColor;
30915
+ });
30916
+
30917
+ // node_modules/commander/index.js
30918
+ var require_commander = __commonJS((exports) => {
30919
+ var { Argument } = require_argument();
30920
+ var { Command } = require_command();
30921
+ var { CommanderError, InvalidArgumentError } = require_error();
30922
+ var { Help } = require_help();
30923
+ var { Option } = require_option();
30924
+ exports.program = new Command;
30925
+ exports.createCommand = (name) => new Command(name);
30926
+ exports.createOption = (flags, description) => new Option(flags, description);
30927
+ exports.createArgument = (name, description) => new Argument(name, description);
30928
+ exports.Command = Command;
30929
+ exports.Option = Option;
30930
+ exports.Argument = Argument;
30931
+ exports.Help = Help;
30932
+ exports.CommanderError = CommanderError;
30933
+ exports.InvalidArgumentError = InvalidArgumentError;
30934
+ exports.InvalidOptionArgumentError = InvalidArgumentError;
30935
+ });
30936
+
30937
+ // node_modules/commander/esm.mjs
30938
+ var import__, program, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help;
30939
+ var init_esm17 = __esm(() => {
30940
+ import__ = __toESM(require_commander(), 1);
30941
+ ({
30942
+ program,
30943
+ createCommand,
30944
+ createArgument,
30945
+ createOption,
30946
+ CommanderError,
30947
+ InvalidArgumentError,
30948
+ InvalidOptionArgumentError,
30949
+ Command,
30950
+ Argument,
30951
+ Option,
30952
+ Help
30953
+ } = import__.default);
30954
+ });
30955
+
30956
+ // src/shared/ErrorHandler.ts
30957
+ class ErrorHandler {
30958
+ static handle(error, context) {
30959
+ if (error instanceof TrelloCliError) {
30960
+ this.handleTrelloError(error, context);
30961
+ } else if (error instanceof Error) {
30962
+ this.handleGenericError(error, context);
30963
+ } else {
30964
+ this.handleUnknownError(error, context);
30965
+ }
30966
+ }
30967
+ static handleTrelloError(error, context) {
30968
+ const prefix = context ? `[${context}] ` : "";
30969
+ switch (error.code) {
30970
+ case "AUTH_ERROR":
30971
+ console.error(t2("errors.authFailed", { message: error.message }));
30972
+ console.error(t2("errors.trySetup"));
30973
+ break;
30974
+ case "API_ERROR":
30975
+ console.error(t2("errors.apiError", { statusCode: error.statusCode, message: error.message }));
30976
+ if (error instanceof ApiError && error.endpoint) {
30977
+ console.error(t2("errors.endpoint", { endpoint: error.endpoint }));
30978
+ }
30979
+ break;
30980
+ case "VALIDATION_ERROR":
30981
+ console.error(t2("errors.validationError", { message: error.message }));
30982
+ if (error instanceof ValidationError2 && error.field) {
30983
+ console.error(t2("errors.field", { field: error.field }));
30984
+ }
30985
+ break;
30986
+ case "NOT_FOUND_ERROR":
30987
+ console.error(t2("errors.notFound", { message: error.message }));
30988
+ if (error instanceof NotFoundError) {
30989
+ if (error.resourceType) {
30990
+ console.error(t2("errors.resourceType", { resourceType: error.resourceType }));
30991
+ }
30992
+ if (error.resourceId) {
30993
+ console.error(t2("errors.resourceId", { resourceId: error.resourceId }));
30994
+ }
30995
+ }
30996
+ break;
30997
+ case "CONFIG_ERROR":
30998
+ console.error(t2("errors.configError", { message: error.message }));
30999
+ console.error(t2("errors.checkConfig"));
31000
+ break;
31001
+ case "NETWORK_ERROR":
31002
+ console.error(t2("errors.networkError", { message: error.message }));
31003
+ console.error(t2("errors.checkConnection"));
31004
+ break;
31005
+ default:
31006
+ console.error(`\u274C ${prefix}${error.message}`);
31007
+ }
31008
+ process.exit(error.statusCode || 1);
31009
+ }
31010
+ static handleGenericError(error, _context) {
31011
+ console.error(t2("errors.unexpectedError", { message: error.message }));
31012
+ if (true) {
31013
+ console.error(t2("errors.stackTrace"), error.stack);
31014
+ }
31015
+ process.exit(1);
31016
+ }
31017
+ static handleUnknownError(error, _context) {
31018
+ console.error(t2("errors.unknownError"), error);
31019
+ process.exit(1);
31020
+ }
31021
+ static async withErrorHandling(operation, context) {
31022
+ try {
31023
+ return await operation();
31024
+ } catch (error) {
31025
+ this.handle(error, context);
31026
+ throw error;
31027
+ }
31028
+ }
31029
+ static fromApiResponse(response, endpoint) {
31030
+ const statusCode = response.status || response.statusCode || 500;
31031
+ const message = response.message || response.error || t2("api.unknownApiError");
31032
+ switch (statusCode) {
31033
+ case 401:
31034
+ return new AuthenticationError(t2("api.invalidToken"));
31035
+ case 403:
31036
+ return new AuthenticationError("Access denied");
31037
+ case 404:
31038
+ return new NotFoundError(t2("api.resourceNotFound"), "unknown");
31039
+ case 400:
31040
+ return new ValidationError2(message);
31041
+ case 429:
31042
+ return new ApiError(t2("api.rateLimitExceeded"), statusCode, endpoint);
31043
+ case 500:
31044
+ return new ApiError(t2("api.internalServerError"), statusCode, endpoint);
31045
+ default:
31046
+ return new ApiError(message, statusCode, endpoint);
31047
+ }
31048
+ }
31049
+ }
31050
+ var TrelloCliError, AuthenticationError, ApiError, ValidationError2, NotFoundError;
31051
+ var init_ErrorHandler = __esm(() => {
31052
+ init_i18n();
31053
+ TrelloCliError = class TrelloCliError extends Error {
31054
+ code;
31055
+ statusCode;
31056
+ constructor(message, code, statusCode) {
31057
+ super(message);
31058
+ this.code = code;
31059
+ this.statusCode = statusCode;
31060
+ this.name = this.constructor.name;
31061
+ }
31062
+ };
31063
+ AuthenticationError = class AuthenticationError extends TrelloCliError {
31064
+ constructor(message = "Authentication failed") {
31065
+ super(message, "AUTH_ERROR", 401);
31066
+ }
31067
+ };
31068
+ ApiError = class ApiError extends TrelloCliError {
31069
+ statusCode;
31070
+ endpoint;
31071
+ constructor(message, statusCode, endpoint) {
31072
+ super(message, "API_ERROR", statusCode);
31073
+ this.statusCode = statusCode;
31074
+ this.endpoint = endpoint;
31075
+ }
31076
+ };
31077
+ ValidationError2 = class ValidationError2 extends TrelloCliError {
31078
+ field;
31079
+ constructor(message, field) {
31080
+ super(message, "VALIDATION_ERROR", 400);
31081
+ this.field = field;
31082
+ }
31083
+ };
31084
+ NotFoundError = class NotFoundError extends TrelloCliError {
31085
+ resourceType;
31086
+ resourceId;
31087
+ constructor(message, resourceType, resourceId) {
31088
+ super(message, "NOT_FOUND_ERROR", 404);
31089
+ this.resourceType = resourceType;
31090
+ this.resourceId = resourceId;
31091
+ }
31092
+ };
31093
+ });
31094
+
31095
+ // src/shared/OutputFormatter.ts
31096
+ class OutputFormatter {
31097
+ format;
31098
+ constructor(format = "table") {
31099
+ this.format = format;
31100
+ }
31101
+ setFormat(format) {
31102
+ this.format = format;
31103
+ }
31104
+ output(data, options) {
31105
+ const format = options?.format || this.format;
31106
+ switch (format) {
31107
+ case "json":
31108
+ this.outputJson(data);
31109
+ break;
31110
+ case "csv":
31111
+ this.outputCsv(data, options);
31112
+ break;
31113
+ case "table":
31114
+ default:
31115
+ this.outputTable(data, options);
31116
+ break;
31117
+ }
31118
+ }
31119
+ outputJson(data) {
31120
+ console.log(JSON.stringify(data, null, 2));
31121
+ }
31122
+ outputCsv(data, options) {
31123
+ if (!Array.isArray(data) || data.length === 0) {
31124
+ console.log(t2("common.noData"));
31125
+ return;
31076
31126
  }
31077
- helpOption(flags, description) {
31078
- if (typeof flags === "boolean") {
31079
- if (flags) {
31080
- if (this._helpOption === null)
31081
- this._helpOption = undefined;
31082
- if (this._defaultOptionGroup) {
31083
- this._initOptionGroup(this._getHelpOption());
31084
- }
31085
- } else {
31086
- this._helpOption = null;
31127
+ const firstItem = data[0];
31128
+ if (!firstItem) {
31129
+ console.log(t2("common.noData"));
31130
+ return;
31131
+ }
31132
+ const plainItem = this.toPlainObject(firstItem);
31133
+ const fields = options?.fields || Object.keys(plainItem);
31134
+ const headers = options?.headers || fields;
31135
+ console.log(headers.join(","));
31136
+ for (const item of data) {
31137
+ const plainObject = this.toPlainObject(item);
31138
+ const row = fields.map((field) => {
31139
+ const value = plainObject[field];
31140
+ const stringValue = String(value || "");
31141
+ if (stringValue.includes(",") || stringValue.includes('"') || stringValue.includes(`
31142
+ `)) {
31143
+ return `"${stringValue.replace(/"/g, '""')}"`;
31087
31144
  }
31088
- return this;
31089
- }
31090
- this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
31091
- if (flags || description)
31092
- this._initOptionGroup(this._helpOption);
31093
- return this;
31145
+ return stringValue;
31146
+ });
31147
+ console.log(row.join(","));
31094
31148
  }
31095
- _getHelpOption() {
31096
- if (this._helpOption === undefined) {
31097
- this.helpOption(undefined, undefined);
31098
- }
31099
- return this._helpOption;
31149
+ }
31150
+ outputTable(data, options) {
31151
+ if (!Array.isArray(data) || data.length === 0) {
31152
+ console.log(t2("common.noData"));
31153
+ return;
31100
31154
  }
31101
- addHelpOption(option) {
31102
- this._helpOption = option;
31103
- this._initOptionGroup(option);
31104
- return this;
31155
+ const firstItem = data[0];
31156
+ if (!firstItem) {
31157
+ console.log(t2("common.noData"));
31158
+ return;
31105
31159
  }
31106
- help(contextOptions) {
31107
- this.outputHelp(contextOptions);
31108
- let exitCode = Number(process4.exitCode ?? 0);
31109
- if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
31110
- exitCode = 1;
31111
- }
31112
- this._exit(exitCode, "commander.help", "(outputHelp)");
31160
+ const plainItem = this.toPlainObject(firstItem);
31161
+ const fields = options?.fields || Object.keys(plainItem);
31162
+ const headers = options?.headers || fields;
31163
+ const columnWidths = headers.map((header, index) => {
31164
+ const field = fields[index];
31165
+ const headerWidth = header.length;
31166
+ const maxDataWidth = Math.max(...data.map((item) => {
31167
+ const plainObject = this.toPlainObject(item);
31168
+ return String(plainObject[field] || "").length;
31169
+ }));
31170
+ return Math.max(headerWidth, maxDataWidth);
31171
+ });
31172
+ const headerRow = headers.map((header, index) => header.padEnd(columnWidths[index])).join(" | ");
31173
+ console.log(headerRow);
31174
+ const separator = columnWidths.map((width) => "-".repeat(width)).join("-+-");
31175
+ console.log(separator);
31176
+ for (const item of data) {
31177
+ const plainObject = this.toPlainObject(item);
31178
+ const row = fields.map((field, index) => {
31179
+ const value = String(plainObject[field] || "");
31180
+ return value.padEnd(columnWidths[index]);
31181
+ }).join(" | ");
31182
+ console.log(row);
31113
31183
  }
31114
- addHelpText(position, text) {
31115
- const allowedValues = ["beforeAll", "before", "after", "afterAll"];
31116
- if (!allowedValues.includes(position)) {
31117
- throw new Error(`Unexpected value for position to addHelpText.
31118
- Expecting one of '${allowedValues.join("', '")}'`);
31119
- }
31120
- const helpEvent = `${position}Help`;
31121
- this.on(helpEvent, (context) => {
31122
- let helpStr;
31123
- if (typeof text === "function") {
31124
- helpStr = text({ error: context.error, command: context.command });
31125
- } else {
31126
- helpStr = text;
31127
- }
31128
- if (helpStr) {
31129
- context.write(`${helpStr}
31130
- `);
31131
- }
31132
- });
31133
- return this;
31184
+ }
31185
+ toPlainObject(obj) {
31186
+ if (obj === null || obj === undefined) {
31187
+ return {};
31134
31188
  }
31135
- _outputHelpIfRequested(args) {
31136
- const helpOption = this._getHelpOption();
31137
- const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
31138
- if (helpRequested) {
31139
- this.outputHelp();
31140
- this._exit(0, "commander.helpDisplayed", "(outputHelp)");
31189
+ if (typeof obj === "object" && obj.constructor !== Object) {
31190
+ const plain = {};
31191
+ for (const key of Object.keys(obj)) {
31192
+ plain[key] = obj[key];
31141
31193
  }
31194
+ return plain;
31142
31195
  }
31196
+ return obj;
31143
31197
  }
31144
- function incrementNodeInspectorPort(args) {
31145
- return args.map((arg) => {
31146
- if (!arg.startsWith("--inspect")) {
31147
- return arg;
31148
- }
31149
- let debugOption;
31150
- let debugHost = "127.0.0.1";
31151
- let debugPort = "9229";
31152
- let match;
31153
- if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
31154
- debugOption = match[1];
31155
- } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
31156
- debugOption = match[1];
31157
- if (/^\d+$/.test(match[3])) {
31158
- debugPort = match[3];
31159
- } else {
31160
- debugHost = match[3];
31161
- }
31162
- } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
31163
- debugOption = match[1];
31164
- debugHost = match[3];
31165
- debugPort = match[4];
31166
- }
31167
- if (debugOption && debugPort !== "0") {
31168
- return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
31169
- }
31170
- return arg;
31171
- });
31198
+ message(message) {
31199
+ console.log(message);
31172
31200
  }
31173
- function useColor() {
31174
- if (process4.env.NO_COLOR || process4.env.FORCE_COLOR === "0" || process4.env.FORCE_COLOR === "false")
31175
- return false;
31176
- if (process4.env.FORCE_COLOR || process4.env.CLICOLOR_FORCE !== undefined)
31177
- return true;
31178
- return;
31201
+ error(message) {
31202
+ console.error(`\u274C ${message}`);
31179
31203
  }
31180
- exports.Command = Command;
31181
- exports.useColor = useColor;
31182
- });
31183
-
31184
- // node_modules/commander/index.js
31185
- var require_commander = __commonJS((exports) => {
31186
- var { Argument } = require_argument();
31187
- var { Command } = require_command();
31188
- var { CommanderError, InvalidArgumentError } = require_error();
31189
- var { Help } = require_help();
31190
- var { Option } = require_option();
31191
- exports.program = new Command;
31192
- exports.createCommand = (name) => new Command(name);
31193
- exports.createOption = (flags, description) => new Option(flags, description);
31194
- exports.createArgument = (name, description) => new Argument(name, description);
31195
- exports.Command = Command;
31196
- exports.Option = Option;
31197
- exports.Argument = Argument;
31198
- exports.Help = Help;
31199
- exports.CommanderError = CommanderError;
31200
- exports.InvalidArgumentError = InvalidArgumentError;
31201
- exports.InvalidOptionArgumentError = InvalidArgumentError;
31204
+ success(message) {
31205
+ console.log(`\u2705 ${message}`);
31206
+ }
31207
+ warning(message) {
31208
+ console.log(`\u26A0\uFE0F ${message}`);
31209
+ }
31210
+ info(message) {
31211
+ console.log(`\u2139\uFE0F ${message}`);
31212
+ }
31213
+ }
31214
+ var init_OutputFormatter = __esm(() => {
31215
+ init_i18n();
31202
31216
  });
31203
31217
 
31204
- // node_modules/commander/esm.mjs
31205
- var exports_esm = {};
31206
- __export(exports_esm, {
31207
- program: () => program,
31208
- createOption: () => createOption,
31209
- createCommand: () => createCommand,
31210
- createArgument: () => createArgument,
31211
- Option: () => Option,
31212
- InvalidOptionArgumentError: () => InvalidOptionArgumentError,
31213
- InvalidArgumentError: () => InvalidArgumentError,
31214
- Help: () => Help,
31215
- CommanderError: () => CommanderError,
31216
- Command: () => Command,
31217
- Argument: () => Argument
31218
- });
31219
- var import__, program, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help;
31220
- var init_esm17 = __esm(() => {
31221
- import__ = __toESM(require_commander(), 1);
31222
- ({
31223
- program,
31224
- createCommand,
31225
- createArgument,
31226
- createOption,
31227
- CommanderError,
31228
- InvalidArgumentError,
31229
- InvalidOptionArgumentError,
31230
- Command,
31231
- Argument,
31232
- Option,
31233
- Help
31234
- } = import__.default);
31218
+ // src/shared/index.ts
31219
+ var init_shared = __esm(() => {
31220
+ init_ErrorHandler();
31221
+ init_OutputFormatter();
31222
+ init_types();
31235
31223
  });
31236
31224
 
31237
31225
  // src/presentation/cli/TrelloCliController.ts
@@ -31295,8 +31283,7 @@ class CommandController {
31295
31283
  return;
31296
31284
  }
31297
31285
  try {
31298
- const { Command: Command2 } = await Promise.resolve().then(() => (init_esm17(), exports_esm));
31299
- this.program = new Command2;
31286
+ this.program = new Command;
31300
31287
  } catch (error) {
31301
31288
  console.error(t2("menu.errors.commanderInitError"), error);
31302
31289
  throw new Error(t2("menu.errors.commanderInitFailed"));
@@ -31317,11 +31304,13 @@ class CommandController {
31317
31304
  const packageJsonPath = join(process.cwd(), "package.json");
31318
31305
  const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
31319
31306
  const version = packageJson.version;
31320
- this.program.name("trello-cli-unofficial").description(t2("commands.description")).version(version).option("-f, --format <format>", t2("commands.formatOption"), "table").option("-v", t2("commands.versionOption")).on("option:format", (format) => {
31307
+ this.program.name("trello-cli-unofficial").description(t2("commands.description")).version(version).option("-f, --format <format>", t2("commands.formatOption"), "table").option("-v", t2("commands.versionOption")).option("--verbose", t2("commands.verboseOption")).on("option:format", (format) => {
31321
31308
  this.outputFormatter.setFormat(format);
31322
31309
  }).on("option:v", () => {
31323
31310
  console.log(version);
31324
31311
  process.exit(0);
31312
+ }).on("option:verbose", () => {
31313
+ process.env.VERBOSE_ERRORS = "true";
31325
31314
  });
31326
31315
  this.program.command("interactive").alias("i").description(t2("commands.interactive.description")).action(async () => {
31327
31316
  const configRepository = new FileConfigRepository;
@@ -31512,6 +31501,7 @@ class CommandController {
31512
31501
  var init_CommandController = __esm(() => {
31513
31502
  init_services();
31514
31503
  init_repositories();
31504
+ init_esm17();
31515
31505
  init_i18n();
31516
31506
  init_shared();
31517
31507
  init_cli();
@@ -31663,6 +31653,11 @@ async function main() {
31663
31653
  await commandController.run();
31664
31654
  } catch (error) {
31665
31655
  console.error(t2("errors.general", { message: error.message }), error.message);
31656
+ if (process.env.VERBOSE_ERRORS === "true") {
31657
+ console.error(`
31658
+ --- Stack Trace ---`);
31659
+ console.error(error.stack);
31660
+ }
31666
31661
  process.exit(1);
31667
31662
  }
31668
31663
  }
package/main.ts CHANGED
@@ -14,6 +14,13 @@ async function main() {
14
14
  t('errors.general', { message: (error as Error).message }),
15
15
  (error as Error).message,
16
16
  );
17
+
18
+ // Show stack trace in verbose mode
19
+ if (process.env.VERBOSE_ERRORS === 'true') {
20
+ console.error('\n--- Stack Trace ---');
21
+ console.error((error as Error).stack);
22
+ }
23
+
17
24
  process.exit(1);
18
25
  }
19
26
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trello-cli-unofficial",
3
3
  "type": "module",
4
- "version": "0.10.8",
4
+ "version": "0.11.1",
5
5
  "private": false,
6
6
  "description": "Unofficial Trello CLI using Power-Up authentication, built with Bun for maximum performance",
7
7
  "author": "Matheus Caiser <matheus.kaiser@gmail.com> (https://www.mrdeveloper.com.br/)",
@@ -169,6 +169,7 @@
169
169
  "description": "Unofficial Trello CLI using Power-Up authentication",
170
170
  "formatOption": "Output format: table, json, csv",
171
171
  "versionOption": "output the version number",
172
+ "verboseOption": "show detailed errors for debugging",
172
173
  "deprecated": {
173
174
  "boardsLegacyDescription": "[DEPRECATED] Use \"boards list\" instead",
174
175
  "boardsLegacyWarning": "⚠️ Warning: \"boards\" command is deprecated. Use \"boards list\" instead.",
@@ -169,6 +169,7 @@
169
169
  "description": "CLI não oficial do Trello usando autenticação Power-Up",
170
170
  "formatOption": "Formato de saída: table, json, csv",
171
171
  "versionOption": "exibe o número da versão",
172
+ "verboseOption": "mostra erros detalhados para debug",
172
173
  "deprecated": {
173
174
  "boardsLegacyDescription": "[DEPRECIADO] Use \"boards list\" ao invés disso",
174
175
  "boardsLegacyWarning": "⚠️ Aviso: comando \"boards\" está depreciado. Use \"boards list\" ao invés disso.",
@@ -1,4 +1,3 @@
1
- import type { Command } from 'commander';
2
1
  import type { OutputFormat } from '@/shared';
3
2
  import { readFileSync } from 'node:fs';
4
3
  import { join } from 'node:path';
@@ -8,6 +7,7 @@ import {
8
7
  FileConfigRepository,
9
8
  TrelloApiRepository,
10
9
  } from '@infrastructure/repositories';
10
+ import { Command } from 'commander';
11
11
 
12
12
  import { t } from '@/i18n';
13
13
  import { ErrorHandler, OutputFormatter } from '@/shared';
@@ -24,7 +24,7 @@ export class CommandController {
24
24
  const configRepository = new FileConfigRepository();
25
25
  this.authController = new AuthController(configRepository);
26
26
  this.outputFormatter = new OutputFormatter();
27
- // Commander will be initialized lazily in initializeProgram
27
+ // Commander will be initialized lazily in run()
28
28
  }
29
29
 
30
30
  private async initializeProgram(): Promise<void> {
@@ -33,7 +33,7 @@ export class CommandController {
33
33
  }
34
34
 
35
35
  try {
36
- const { Command } = await import('commander');
36
+ // Use static import - Commander is already imported at the top
37
37
  this.program = new Command();
38
38
  } catch (error) {
39
39
  console.error(t('menu.errors.commanderInitError'), error);
@@ -79,12 +79,17 @@ export class CommandController {
79
79
  .version(version)
80
80
  .option('-f, --format <format>', t('commands.formatOption'), 'table')
81
81
  .option('-v', t('commands.versionOption'))
82
+ .option('--verbose', t('commands.verboseOption'))
82
83
  .on('option:format', (format: string) => {
83
84
  this.outputFormatter.setFormat(format as OutputFormat);
84
85
  })
85
86
  .on('option:v', () => {
86
87
  console.log(version);
87
88
  process.exit(0);
89
+ })
90
+ .on('option:verbose', () => {
91
+ // Enable verbose error reporting
92
+ process.env.VERBOSE_ERRORS = 'true';
88
93
  });
89
94
 
90
95
  // Interactive mode