trello-cli-unofficial 0.9.6 → 0.10.0

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,18 @@
1
+ # [0.10.0](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.9.6...v0.10.0) (2025-11-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * configure lint-staged to detect JSON issues without auto-fix ([31cf1f9](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/31cf1f9e22b767bb82bd1ba55969af6e9cfa5b55))
7
+ * correct lint-staged configuration and add pre-commit hook ([030b957](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/030b9575707e6062e826de225c5c7c7289807d98))
8
+ * remove dotenv verbose logging messages for cleaner CLI output ([ece06aa](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/ece06aa62bfd92b3a45e3c506c4b9c7829e99e9b))
9
+ * replace manual git hooks with husky ([18d3057](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/18d3057385756a4a75ba186a124b4d6a18f8cb83))
10
+
11
+
12
+ ### Features
13
+
14
+ * implement dynamic version display from package.json ([5d2c9e3](https://github.com/JaegerCaiser/trello-cli-unofficial/commit/5d2c9e30b0ed0dc44d65307e02ee84fbd694192f))
15
+
1
16
  ## [0.9.6](https://github.com/JaegerCaiser/trello-cli-unofficial/compare/v0.9.5...v0.9.6) (2025-11-14)
2
17
 
3
18
 
package/bun.lock CHANGED
@@ -8,7 +8,7 @@
8
8
  "@types/node": "^24.10.0",
9
9
  "bun": "^1.3.2",
10
10
  "commander": "^14.0.2",
11
- "dotenv": "^17.2.3",
11
+ "dotenv": "^15.0.1",
12
12
  "fs-extra": "^11.3.2",
13
13
  "i18next": "^25.6.1",
14
14
  "inquirer": "^12.10.0",
@@ -22,6 +22,7 @@
22
22
  "@types/inquirer": "^9.0.9",
23
23
  "eslint": "^9.39.1",
24
24
  "eslint-plugin-format": "^1.0.2",
25
+ "husky": "^9.1.7",
25
26
  "lint-staged": "^16.2.6",
26
27
  },
27
28
  "peerDependencies": {
@@ -372,7 +373,7 @@
372
373
 
373
374
  "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="],
374
375
 
375
- "dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
376
+ "dotenv": ["dotenv@15.0.1", "", {}, "sha512-4OnbwRfzR+xQThp7uq1xpUS9fmgZ//njexOtPjPSbK3yHGrSHSJnaJRsXderSSm2elfvVj+Y5awDC0I8Oy8rkA=="],
376
377
 
377
378
  "electron-to-chromium": ["electron-to-chromium@1.5.249", "", {}, "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg=="],
378
379
 
@@ -526,6 +527,8 @@
526
527
 
527
528
  "html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="],
528
529
 
530
+ "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="],
531
+
529
532
  "i18next": ["i18next@25.6.1", "", { "dependencies": { "@babel/runtime": "^7.27.6" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-yUWvdXtalZztmKrKw3yz/AvSP3yKyqIkVPx/wyvoYy9lkLmwzItLxp0iHZLG5hfVQ539Jor4XLO+U+NHIXg7pw=="],
530
533
 
531
534
  "iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
package/dist/main.js CHANGED
@@ -30,114 +30,12 @@ var __export = (target, all) => {
30
30
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
31
31
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
32
32
 
33
- // node_modules/dotenv/package.json
34
- var require_package = __commonJS((exports, module) => {
35
- module.exports = {
36
- name: "dotenv",
37
- version: "17.2.3",
38
- description: "Loads environment variables from .env file",
39
- main: "lib/main.js",
40
- types: "lib/main.d.ts",
41
- exports: {
42
- ".": {
43
- types: "./lib/main.d.ts",
44
- require: "./lib/main.js",
45
- default: "./lib/main.js"
46
- },
47
- "./config": "./config.js",
48
- "./config.js": "./config.js",
49
- "./lib/env-options": "./lib/env-options.js",
50
- "./lib/env-options.js": "./lib/env-options.js",
51
- "./lib/cli-options": "./lib/cli-options.js",
52
- "./lib/cli-options.js": "./lib/cli-options.js",
53
- "./package.json": "./package.json"
54
- },
55
- scripts: {
56
- "dts-check": "tsc --project tests/types/tsconfig.json",
57
- lint: "standard",
58
- pretest: "npm run lint && npm run dts-check",
59
- test: "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
60
- "test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
61
- prerelease: "npm test",
62
- release: "standard-version"
63
- },
64
- repository: {
65
- type: "git",
66
- url: "git://github.com/motdotla/dotenv.git"
67
- },
68
- homepage: "https://github.com/motdotla/dotenv#readme",
69
- funding: "https://dotenvx.com",
70
- keywords: [
71
- "dotenv",
72
- "env",
73
- ".env",
74
- "environment",
75
- "variables",
76
- "config",
77
- "settings"
78
- ],
79
- readmeFilename: "README.md",
80
- license: "BSD-2-Clause",
81
- devDependencies: {
82
- "@types/node": "^18.11.3",
83
- decache: "^4.6.2",
84
- sinon: "^14.0.1",
85
- standard: "^17.0.0",
86
- "standard-version": "^9.5.0",
87
- tap: "^19.2.0",
88
- typescript: "^4.8.4"
89
- },
90
- engines: {
91
- node: ">=12"
92
- },
93
- browser: {
94
- fs: false
95
- }
96
- };
97
- });
98
-
99
33
  // node_modules/dotenv/lib/main.js
100
34
  var require_main = __commonJS((exports, module) => {
101
35
  var fs = __require("fs");
102
36
  var path = __require("path");
103
37
  var os = __require("os");
104
- var crypto = __require("crypto");
105
- var packageJson = require_package();
106
- var version = packageJson.version;
107
- var TIPS = [
108
- "\uD83D\uDD10 encrypt with Dotenvx: https://dotenvx.com",
109
- "\uD83D\uDD10 prevent committing .env to code: https://dotenvx.com/precommit",
110
- "\uD83D\uDD10 prevent building .env in docker: https://dotenvx.com/prebuild",
111
- "\uD83D\uDCE1 add observability to secrets: https://dotenvx.com/ops",
112
- "\uD83D\uDC65 sync secrets across teammates & machines: https://dotenvx.com/ops",
113
- "\uD83D\uDDC2️ backup and recover secrets: https://dotenvx.com/ops",
114
- "✅ audit secrets and track compliance: https://dotenvx.com/ops",
115
- "\uD83D\uDD04 add secrets lifecycle management: https://dotenvx.com/ops",
116
- "\uD83D\uDD11 add access controls to secrets: https://dotenvx.com/ops",
117
- "\uD83D\uDEE0️ run anywhere with `dotenvx run -- yourcommand`",
118
- "⚙️ specify custom .env file path with { path: '/custom/path/.env' }",
119
- "⚙️ enable debug logging with { debug: true }",
120
- "⚙️ override existing env vars with { override: true }",
121
- "⚙️ suppress all logs with { quiet: true }",
122
- "⚙️ write to custom object with { processEnv: myObject }",
123
- "⚙️ load multiple .env files with { path: ['.env.local', '.env'] }"
124
- ];
125
- function _getRandomTip() {
126
- return TIPS[Math.floor(Math.random() * TIPS.length)];
127
- }
128
- function parseBoolean(value) {
129
- if (typeof value === "string") {
130
- return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
131
- }
132
- return Boolean(value);
133
- }
134
- function supportsAnsi() {
135
- return process.stdout.isTTY;
136
- }
137
- function dim(text) {
138
- return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
139
- }
140
- var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
38
+ var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
141
39
  function parse(src) {
142
40
  const obj = {};
143
41
  let lines = src.toString();
@@ -149,7 +47,7 @@ var require_main = __commonJS((exports, module) => {
149
47
  let value = match[2] || "";
150
48
  value = value.trim();
151
49
  const maybeQuote = value[0];
152
- value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
50
+ value = value.replace(/^(['"])([\s\S]*)\1$/mg, "$2");
153
51
  if (maybeQuote === '"') {
154
52
  value = value.replace(/\\n/g, `
155
53
  `);
@@ -159,269 +57,57 @@ var require_main = __commonJS((exports, module) => {
159
57
  }
160
58
  return obj;
161
59
  }
162
- function _parseVault(options) {
163
- options = options || {};
164
- const vaultPath = _vaultPath(options);
165
- options.path = vaultPath;
166
- const result = DotenvModule.configDotenv(options);
167
- if (!result.parsed) {
168
- const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
169
- err.code = "MISSING_DATA";
170
- throw err;
171
- }
172
- const keys = _dotenvKey(options).split(",");
173
- const length = keys.length;
174
- let decrypted;
175
- for (let i = 0;i < length; i++) {
176
- try {
177
- const key = keys[i].trim();
178
- const attrs = _instructions(result, key);
179
- decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
180
- break;
181
- } catch (error) {
182
- if (i + 1 >= length) {
183
- throw error;
184
- }
185
- }
186
- }
187
- return DotenvModule.parse(decrypted);
188
- }
189
- function _warn(message) {
190
- console.error(`[dotenv@${version}][WARN] ${message}`);
191
- }
192
- function _debug(message) {
193
- console.log(`[dotenv@${version}][DEBUG] ${message}`);
194
- }
195
60
  function _log(message) {
196
- console.log(`[dotenv@${version}] ${message}`);
197
- }
198
- function _dotenvKey(options) {
199
- if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
200
- return options.DOTENV_KEY;
201
- }
202
- if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
203
- return process.env.DOTENV_KEY;
204
- }
205
- return "";
206
- }
207
- function _instructions(result, dotenvKey) {
208
- let uri;
209
- try {
210
- uri = new URL(dotenvKey);
211
- } catch (error) {
212
- if (error.code === "ERR_INVALID_URL") {
213
- const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
214
- err.code = "INVALID_DOTENV_KEY";
215
- throw err;
216
- }
217
- throw error;
218
- }
219
- const key = uri.password;
220
- if (!key) {
221
- const err = new Error("INVALID_DOTENV_KEY: Missing key part");
222
- err.code = "INVALID_DOTENV_KEY";
223
- throw err;
224
- }
225
- const environment = uri.searchParams.get("environment");
226
- if (!environment) {
227
- const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
228
- err.code = "INVALID_DOTENV_KEY";
229
- throw err;
230
- }
231
- const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
232
- const ciphertext = result.parsed[environmentKey];
233
- if (!ciphertext) {
234
- const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
235
- err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
236
- throw err;
237
- }
238
- return { ciphertext, key };
239
- }
240
- function _vaultPath(options) {
241
- let possibleVaultPath = null;
242
- if (options && options.path && options.path.length > 0) {
243
- if (Array.isArray(options.path)) {
244
- for (const filepath of options.path) {
245
- if (fs.existsSync(filepath)) {
246
- possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
247
- }
248
- }
249
- } else {
250
- possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
251
- }
252
- } else {
253
- possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
254
- }
255
- if (fs.existsSync(possibleVaultPath)) {
256
- return possibleVaultPath;
257
- }
258
- return null;
61
+ console.log(`[dotenv][DEBUG] ${message}`);
259
62
  }
260
63
  function _resolveHome(envPath) {
261
64
  return envPath[0] === "~" ? path.join(os.homedir(), envPath.slice(1)) : envPath;
262
65
  }
263
- function _configVault(options) {
264
- const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
265
- const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
266
- if (debug || !quiet) {
267
- _log("Loading env from encrypted .env.vault");
268
- }
269
- const parsed = DotenvModule._parseVault(options);
270
- let processEnv = process.env;
271
- if (options && options.processEnv != null) {
272
- processEnv = options.processEnv;
273
- }
274
- DotenvModule.populate(processEnv, parsed, options);
275
- return { parsed };
276
- }
277
- function configDotenv(options) {
278
- const dotenvPath = path.resolve(process.cwd(), ".env");
66
+ function config(options) {
67
+ let dotenvPath = path.resolve(process.cwd(), ".env");
279
68
  let encoding = "utf8";
280
- let processEnv = process.env;
281
- if (options && options.processEnv != null) {
282
- processEnv = options.processEnv;
283
- }
284
- let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
285
- let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
286
- if (options && options.encoding) {
287
- encoding = options.encoding;
288
- } else {
289
- if (debug) {
290
- _debug("No encoding is specified. UTF-8 is used by default");
291
- }
292
- }
293
- let optionPaths = [dotenvPath];
294
- if (options && options.path) {
295
- if (!Array.isArray(options.path)) {
296
- optionPaths = [_resolveHome(options.path)];
297
- } else {
298
- optionPaths = [];
299
- for (const filepath of options.path) {
300
- optionPaths.push(_resolveHome(filepath));
301
- }
302
- }
303
- }
304
- let lastError;
305
- const parsedAll = {};
306
- for (const path2 of optionPaths) {
307
- try {
308
- const parsed = DotenvModule.parse(fs.readFileSync(path2, { encoding }));
309
- DotenvModule.populate(parsedAll, parsed, options);
310
- } catch (e) {
311
- if (debug) {
312
- _debug(`Failed to load ${path2} ${e.message}`);
313
- }
314
- lastError = e;
69
+ const debug = Boolean(options && options.debug);
70
+ const override = Boolean(options && options.override);
71
+ if (options) {
72
+ if (options.path != null) {
73
+ dotenvPath = _resolveHome(options.path);
315
74
  }
316
- }
317
- const populated = DotenvModule.populate(processEnv, parsedAll, options);
318
- debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
319
- quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
320
- if (debug || !quiet) {
321
- const keysCount = Object.keys(populated).length;
322
- const shortPaths = [];
323
- for (const filePath of optionPaths) {
324
- try {
325
- const relative = path.relative(process.cwd(), filePath);
326
- shortPaths.push(relative);
327
- } catch (e) {
328
- if (debug) {
329
- _debug(`Failed to load ${filePath} ${e.message}`);
330
- }
331
- lastError = e;
332
- }
75
+ if (options.encoding != null) {
76
+ encoding = options.encoding;
333
77
  }
334
- _log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
335
78
  }
336
- if (lastError) {
337
- return { parsed: parsedAll, error: lastError };
338
- } else {
339
- return { parsed: parsedAll };
340
- }
341
- }
342
- function config(options) {
343
- if (_dotenvKey(options).length === 0) {
344
- return DotenvModule.configDotenv(options);
345
- }
346
- const vaultPath = _vaultPath(options);
347
- if (!vaultPath) {
348
- _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
349
- return DotenvModule.configDotenv(options);
350
- }
351
- return DotenvModule._configVault(options);
352
- }
353
- function decrypt(encrypted, keyStr) {
354
- const key = Buffer.from(keyStr.slice(-64), "hex");
355
- let ciphertext = Buffer.from(encrypted, "base64");
356
- const nonce = ciphertext.subarray(0, 12);
357
- const authTag = ciphertext.subarray(-16);
358
- ciphertext = ciphertext.subarray(12, -16);
359
79
  try {
360
- const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
361
- aesgcm.setAuthTag(authTag);
362
- return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
363
- } catch (error) {
364
- const isRange = error instanceof RangeError;
365
- const invalidKeyLength = error.message === "Invalid key length";
366
- const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
367
- if (isRange || invalidKeyLength) {
368
- const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
369
- err.code = "INVALID_DOTENV_KEY";
370
- throw err;
371
- } else if (decryptionFailed) {
372
- const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
373
- err.code = "DECRYPTION_FAILED";
374
- throw err;
375
- } else {
376
- throw error;
377
- }
378
- }
379
- }
380
- function populate(processEnv, parsed, options = {}) {
381
- const debug = Boolean(options && options.debug);
382
- const override = Boolean(options && options.override);
383
- const populated = {};
384
- if (typeof parsed !== "object") {
385
- const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
386
- err.code = "OBJECT_REQUIRED";
387
- throw err;
388
- }
389
- for (const key of Object.keys(parsed)) {
390
- if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
391
- if (override === true) {
392
- processEnv[key] = parsed[key];
393
- populated[key] = parsed[key];
394
- }
395
- if (debug) {
80
+ const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }));
81
+ Object.keys(parsed).forEach(function(key) {
82
+ if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
83
+ process.env[key] = parsed[key];
84
+ } else {
396
85
  if (override === true) {
397
- _debug(`"${key}" is already defined and WAS overwritten`);
398
- } else {
399
- _debug(`"${key}" is already defined and was NOT overwritten`);
86
+ process.env[key] = parsed[key];
87
+ }
88
+ if (debug) {
89
+ if (override === true) {
90
+ _log(`"${key}" is already defined in \`process.env\` and WAS overwritten`);
91
+ } else {
92
+ _log(`"${key}" is already defined in \`process.env\` and was NOT overwritten`);
93
+ }
400
94
  }
401
95
  }
402
- } else {
403
- processEnv[key] = parsed[key];
404
- populated[key] = parsed[key];
96
+ });
97
+ return { parsed };
98
+ } catch (e) {
99
+ if (debug) {
100
+ _log(`Failed to load ${dotenvPath} ${e.message}`);
405
101
  }
102
+ return { error: e };
406
103
  }
407
- return populated;
408
104
  }
409
105
  var DotenvModule = {
410
- configDotenv,
411
- _configVault,
412
- _parseVault,
413
106
  config,
414
- decrypt,
415
- parse,
416
- populate
107
+ parse
417
108
  };
418
- exports.configDotenv = DotenvModule.configDotenv;
419
- exports._configVault = DotenvModule._configVault;
420
- exports._parseVault = DotenvModule._parseVault;
421
109
  exports.config = DotenvModule.config;
422
- exports.decrypt = DotenvModule.decrypt;
423
110
  exports.parse = DotenvModule.parse;
424
- exports.populate = DotenvModule.populate;
425
111
  module.exports = DotenvModule;
426
112
  });
427
113
 
@@ -2941,6 +2627,7 @@ var require_en = __commonJS((exports, module) => {
2941
2627
  commands: {
2942
2628
  description: "Unofficial Trello CLI using Power-Up authentication",
2943
2629
  formatOption: "Output format: table, json, csv",
2630
+ versionOption: "output the version number",
2944
2631
  deprecated: {
2945
2632
  boardsLegacyDescription: '[DEPRECATED] Use "boards list" instead',
2946
2633
  boardsLegacyWarning: '⚠️ Warning: "boards" command is deprecated. Use "boards list" instead.',
@@ -3211,6 +2898,7 @@ var require_pt_BR = __commonJS((exports, module) => {
3211
2898
  commands: {
3212
2899
  description: "CLI não oficial do Trello usando autenticação Power-Up",
3213
2900
  formatOption: "Formato de saída: table, json, csv",
2901
+ versionOption: "exibe o número da versão",
3214
2902
  deprecated: {
3215
2903
  boardsLegacyDescription: '[DEPRECIADO] Use "boards list" ao invés disso',
3216
2904
  boardsLegacyWarning: '⚠️ Aviso: comando "boards" está depreciado. Use "boards list" ao invés disso.',
@@ -31568,6 +31256,9 @@ var init_TrelloCliController = __esm(() => {
31568
31256
  });
31569
31257
 
31570
31258
  // src/presentation/cli/CommandController.ts
31259
+ import { readFileSync as readFileSync2 } from "node:fs";
31260
+ import { join } from "node:path";
31261
+
31571
31262
  class CommandController {
31572
31263
  authController;
31573
31264
  boardController;
@@ -31590,8 +31281,14 @@ class CommandController {
31590
31281
  this.cardController = new CardController(trelloRepository, this.boardController, this.outputFormatter);
31591
31282
  }
31592
31283
  setupCommands() {
31593
- this.program.name("trello-cli-unofficial").description(t3("commands.description")).version("1.0.0").option("-f, --format <format>", t3("commands.formatOption"), "table").on("option:format", (format) => {
31284
+ const packageJsonPath = join(process.cwd(), "package.json");
31285
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
31286
+ const version = packageJson.version;
31287
+ this.program.name("trello-cli-unofficial").description(t3("commands.description")).version(version).option("-f, --format <format>", t3("commands.formatOption"), "table").option("-v", t3("commands.versionOption")).on("option:format", (format) => {
31594
31288
  this.outputFormatter.setFormat(format);
31289
+ }).on("option:v", () => {
31290
+ console.log(version);
31291
+ process.exit(0);
31595
31292
  });
31596
31293
  this.program.command("interactive").alias("i").description(t3("commands.interactive.description")).action(async () => {
31597
31294
  const configRepository = new FileConfigRepository;
@@ -31768,12 +31465,11 @@ class CommandController {
31768
31465
  });
31769
31466
  }
31770
31467
  async run() {
31771
- if (process.argv.length === 2) {
31468
+ this.program.parse();
31469
+ if (!this.program.args.length && !this.program.opts().version) {
31772
31470
  const configRepository = new FileConfigRepository;
31773
31471
  const cli = new (await Promise.resolve().then(() => (init_TrelloCliController(), exports_TrelloCliController))).TrelloCliController(configRepository, this.outputFormatter);
31774
31472
  await cli.run();
31775
- } else {
31776
- this.program.parse();
31777
31473
  }
31778
31474
  }
31779
31475
  }
package/main.ts CHANGED
@@ -3,7 +3,6 @@ import { config } from 'dotenv';
3
3
  import { t } from './src/i18n';
4
4
  import { CommandController } from './src/presentation';
5
5
 
6
- // Load environment variables
7
6
  config();
8
7
 
9
8
  async function main() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trello-cli-unofficial",
3
3
  "type": "module",
4
- "version": "0.9.6",
4
+ "version": "0.10.0",
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/)",
@@ -70,7 +70,8 @@
70
70
  "version:patch": "bun version patch && git push --follow-tags",
71
71
  "version:minor": "bun version minor && git push --follow-tags",
72
72
  "version:major": "bun version major && git push --follow-tags",
73
- "prepublishOnly": "bun run validate && bun run build"
73
+ "prepublishOnly": "bun run validate && bun run build",
74
+ "prepare": "husky"
74
75
  },
75
76
  "peerDependencies": {
76
77
  "typescript": "^5"
@@ -79,7 +80,7 @@
79
80
  "@types/node": "^24.10.0",
80
81
  "bun": "^1.3.2",
81
82
  "commander": "^14.0.2",
82
- "dotenv": "^17.2.3",
83
+ "dotenv": "^15.0.1",
83
84
  "fs-extra": "^11.3.2",
84
85
  "i18next": "^25.6.1",
85
86
  "inquirer": "^12.10.0"
@@ -93,6 +94,7 @@
93
94
  "@types/inquirer": "^9.0.9",
94
95
  "eslint": "^9.39.1",
95
96
  "eslint-plugin-format": "^1.0.2",
97
+ "husky": "^9.1.7",
96
98
  "lint-staged": "^16.2.6"
97
99
  },
98
100
  "os": [
@@ -100,16 +102,12 @@
100
102
  "linux",
101
103
  "win32"
102
104
  ],
103
- "gitHooks": {
104
- "commit-msg": "bun run commitlint"
105
- },
106
105
  "lint-staged": {
107
106
  "*.{js,ts,tsx}": [
108
- "eslint --fix",
109
- "eslint --max-warnings 0"
107
+ "eslint --fix"
110
108
  ],
111
109
  "*.json": [
112
- "bun run lint:json"
110
+ "eslint"
113
111
  ]
114
112
  }
115
113
  }
@@ -165,6 +165,7 @@
165
165
  "commands": {
166
166
  "description": "Unofficial Trello CLI using Power-Up authentication",
167
167
  "formatOption": "Output format: table, json, csv",
168
+ "versionOption": "output the version number",
168
169
  "deprecated": {
169
170
  "boardsLegacyDescription": "[DEPRECATED] Use \"boards list\" instead",
170
171
  "boardsLegacyWarning": "⚠️ Warning: \"boards\" command is deprecated. Use \"boards list\" instead.",
@@ -165,6 +165,7 @@
165
165
  "commands": {
166
166
  "description": "CLI não oficial do Trello usando autenticação Power-Up",
167
167
  "formatOption": "Formato de saída: table, json, csv",
168
+ "versionOption": "exibe o número da versão",
168
169
  "deprecated": {
169
170
  "boardsLegacyDescription": "[DEPRECIADO] Use \"boards list\" ao invés disso",
170
171
  "boardsLegacyWarning": "⚠️ Aviso: comando \"boards\" está depreciado. Use \"boards list\" ao invés disso.",
@@ -1,4 +1,6 @@
1
1
  import type { OutputFormat } from '@/shared';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
2
4
 
3
5
  import { AuthenticationService } from '@domain/services';
4
6
  import {
@@ -48,13 +50,23 @@ export class CommandController {
48
50
  }
49
51
 
50
52
  private setupCommands(): void {
53
+ // Get version from package.json
54
+ const packageJsonPath = join(process.cwd(), 'package.json');
55
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
56
+ const version = packageJson.version;
57
+
51
58
  this.program
52
59
  .name('trello-cli-unofficial')
53
60
  .description(t('commands.description'))
54
- .version('1.0.0')
61
+ .version(version)
55
62
  .option('-f, --format <format>', t('commands.formatOption'), 'table')
63
+ .option('-v', t('commands.versionOption'))
56
64
  .on('option:format', (format) => {
57
65
  this.outputFormatter.setFormat(format as OutputFormat);
66
+ })
67
+ .on('option:v', () => {
68
+ console.log(version);
69
+ process.exit(0);
58
70
  });
59
71
 
60
72
  // Interactive mode
@@ -414,15 +426,16 @@ export class CommandController {
414
426
  }
415
427
 
416
428
  async run(): Promise<void> {
429
+ // Parse arguments first to handle global options like --version
430
+ this.program.parse();
431
+
417
432
  // Fallback to interactive mode if no command specified
418
- if (process.argv.length === 2) {
433
+ if (!this.program.args.length && !this.program.opts().version) {
419
434
  const configRepository = new FileConfigRepository();
420
435
  const cli = new (
421
436
  await import('./TrelloCliController')
422
437
  ).TrelloCliController(configRepository, this.outputFormatter);
423
438
  await cli.run();
424
- } else {
425
- this.program.parse();
426
439
  }
427
440
  }
428
441
  }