fireflyy 4.0.0-dev.4721ae4 → 4.0.0-dev.5022ada

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.
@@ -0,0 +1,74 @@
1
+ //#region src/core/environment/debug-flags.ts
2
+ /**
3
+ * Debug flags are environment variables prefixed with `FIREFLY_DEBUG_` that
4
+ * enable diagnostic features during development and troubleshooting.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * if (DebugFlags.showRawError) {
9
+ * logger.error(parseResult.error);
10
+ * }
11
+ * ```
12
+ */
13
+ var DebugFlags = class {
14
+ constructor() {}
15
+ /**
16
+ * When enabled, displays raw Zod validation errors for configuration parsing.
17
+ *
18
+ * Useful for debugging configuration schema issues and understanding
19
+ * why validation failed at a granular level.
20
+ */
21
+ static get showRawError() {
22
+ return Boolean(process.env.FIREFLY_DEBUG_SHOW_RAW_ERROR);
23
+ }
24
+ /**
25
+ * When enabled, logs the loaded configuration file contents.
26
+ *
27
+ * Useful for debugging configuration loading and understanding
28
+ * what values are being read from config files.
29
+ */
30
+ static get showFileConfig() {
31
+ return Boolean(process.env.FIREFLY_DEBUG_SHOW_FILE_CONFIG);
32
+ }
33
+ /**
34
+ * When enabled, displays task graph statistics during release execution.
35
+ *
36
+ * Shows information about task dependencies, execution order,
37
+ * and graph structure for debugging workflow issues.
38
+ */
39
+ static get showTaskGraphStats() {
40
+ return Boolean(process.env.FIREFLY_DEBUG_SHOW_TASK_GRAPH_STATS);
41
+ }
42
+ /**
43
+ * When enabled, prevents truncation of release notes in GitHub CLI logs.
44
+ *
45
+ * By default, release notes are truncated in logs to avoid pollution.
46
+ * Enable this flag to see full release notes content during debugging.
47
+ */
48
+ static get dontTruncateReleaseNotes() {
49
+ return Boolean(process.env.FIREFLY_DEBUG_DONT_TRUNCATE_RELEASE_NOTES?.trim());
50
+ }
51
+ /**
52
+ * When enabled, prevents redaction of sensitive GitHub CLI arguments in logs.
53
+ *
54
+ * By default, sensitive values (tokens, passwords, etc.) are redacted.
55
+ * Enable this flag to see full argument values during debugging.
56
+ *
57
+ * WARNING: Use with caution as this may expose sensitive information.
58
+ */
59
+ static get dontRedactGithubCliArgs() {
60
+ return Boolean(process.env.FIREFLY_DEBUG_DONT_REDACT_GITHUB_CLI_ARGS?.trim());
61
+ }
62
+ /**
63
+ * When enabled, logs verbose details for git commit operations.
64
+ *
65
+ * By default, the verbose log of the git show command is disabled to reduce noise, if commits are many.
66
+ * Enable this flag to see detailed commit information during debugging.
67
+ */
68
+ static get showVerboseGitCommitDetails() {
69
+ return Boolean(process.env.FIREFLY_DEBUG_SHOW_VERBOSE_GIT_COMMIT_DETAILS?.trim());
70
+ }
71
+ };
72
+
73
+ //#endregion
74
+ export { DebugFlags as t };
@@ -1,5 +1,5 @@
1
- import { t as logger } from "./main.js";
2
- import { i as FireflyOkAsync } from "./result.constructors-C9M1MP3_.js";
1
+ import { i as FireflyOkAsync } from "./result.constructors-DoAoYdfF.js";
2
+ import { t as logger } from "./logging-Bpk2RzGc.js";
3
3
 
4
4
  //#region src/infrastructure/dry-run/index.ts
5
5
  /**
@@ -1,6 +1,7 @@
1
- import { c as notFoundErrAsync } from "./result.constructors-C9M1MP3_.js";
2
- import { n as wrapPromise } from "./result.utilities-DC5shlhT.js";
3
- import { t as withDryRun } from "./dry-run-BfYCtldz.js";
1
+ import { l as notFoundErrAsync } from "./result.constructors-DoAoYdfF.js";
2
+ import { n as wrapPromise } from "./result.utilities-DXSJU70_.js";
3
+ import { t as logger } from "./logging-Bpk2RzGc.js";
4
+ import { t as withDryRun } from "./dry-run-C7RaPEq8.js";
4
5
 
5
6
  //#region src/services/implementations/filesystem.service.ts
6
7
  /**
@@ -29,21 +30,18 @@ var DefaultFileSystemService = class {
29
30
  }
30
31
  exists(path) {
31
32
  const resolved = this.resolvePath(path);
32
- return wrapPromise(Bun.file(resolved).exists());
33
+ return wrapPromise(Bun.file(resolved).exists()).andTee(() => logger.verbose(`DefaultFileSystemService: Checked existence of file: ${resolved}`));
33
34
  }
34
35
  read(path) {
35
36
  const resolved = this.resolvePath(path);
36
37
  const file = Bun.file(resolved);
37
38
  return wrapPromise(file.exists()).andThen((fileExists) => {
38
- if (!fileExists) return notFoundErrAsync({
39
- message: `File not found: ${resolved}`,
40
- source: "FileSystemService.read"
41
- });
42
- return wrapPromise(file.text());
39
+ if (!fileExists) return notFoundErrAsync({ message: `File not found: ${resolved}` });
40
+ return wrapPromise(file.text()).andTee(() => logger.verbose(`DefaultFileSystemService: Read file: ${resolved}`));
43
41
  });
44
42
  }
45
43
  write(path, content, options) {
46
- return withDryRun(options, `Writing to ${this.resolvePath(path)}`, () => wrapPromise(Bun.write(this.resolvePath(path), content).then(() => {})));
44
+ return withDryRun(options, `Writing to ${this.resolvePath(path)}`, () => wrapPromise(Bun.write(this.resolvePath(path), content).then(() => {})).andTee(() => logger.verbose(`DefaultFileSystemService: Wrote file: ${this.resolvePath(path)}`)));
47
45
  }
48
46
  };
49
47
  /**
@@ -1,6 +1,7 @@
1
- import { t as logger } from "./main.js";
2
- import { i as FireflyOkAsync, m as failedError, o as failedErrAsync } from "./result.constructors-C9M1MP3_.js";
3
- import { t as withDryRun } from "./dry-run-BfYCtldz.js";
1
+ import { t as DebugFlags } from "./debug-flags-K3yK5B6O.js";
2
+ import { h as failedError, i as FireflyOkAsync, o as failedErrAsync } from "./result.constructors-DoAoYdfF.js";
3
+ import { t as logger } from "./logging-Bpk2RzGc.js";
4
+ import { t as withDryRun } from "./dry-run-C7RaPEq8.js";
4
5
  import { ResultAsync } from "neverthrow";
5
6
  import { z } from "zod";
6
7
 
@@ -257,7 +258,7 @@ var DefaultGitService = class {
257
258
  return this.git(["rev-parse", "--is-inside-work-tree"]).map(() => true).orElse(() => FireflyOkAsync(false));
258
259
  }
259
260
  getRepositoryRoot() {
260
- return this.git(["rev-parse", "--show-toplevel"]).map((output) => output.trim());
261
+ return this.git(["rev-parse", "--show-toplevel"]).andTee(() => logger.verbose("DefaultGitService: Resolving repository root")).map((output) => output.trim()).andTee(() => logger.verbose("DefaultGitService: Repository root resolved"));
261
262
  }
262
263
  getRemoteUrl(remote) {
263
264
  const remoteName = remote ?? "origin";
@@ -280,12 +281,14 @@ var DefaultGitService = class {
280
281
  else if (index !== " " && index !== "?") hasStaged = true;
281
282
  if (workTree !== " " && workTree !== "?") hasUnstaged = true;
282
283
  }
283
- return {
284
+ const status = {
284
285
  hasStaged,
285
286
  hasUnstaged,
286
287
  hasUntracked,
287
288
  isClean: lines.length === 0
288
289
  };
290
+ logger.verbose(`DefaultGitService: Git status: staged=${status.hasStaged},unstaged=${status.hasUnstaged},untracked=${status.hasUntracked},clean=${status.isClean}`);
291
+ return status;
289
292
  });
290
293
  }
291
294
  isWorkingTreeClean() {
@@ -312,7 +315,7 @@ var DefaultGitService = class {
312
315
  const includeStaged = filter?.staged ?? true;
313
316
  const includeUnstaged = filter?.unstaged ?? true;
314
317
  return this.git(["status", "--porcelain"]).map((output) => {
315
- return this.parseStatusOutput(output).filter((file) => {
318
+ const filtered = this.parseStatusOutput(output).filter((file) => {
316
319
  const isStaged = file.indexStatus !== " " && file.indexStatus !== "?";
317
320
  const isUnstaged = file.workTreeStatus !== " " && file.workTreeStatus !== "?";
318
321
  if (includeStaged && includeUnstaged) return isStaged || isUnstaged;
@@ -320,6 +323,8 @@ var DefaultGitService = class {
320
323
  if (includeUnstaged) return isUnstaged;
321
324
  return false;
322
325
  });
326
+ logger.verbose(`DefaultGitService: Found ${filtered.length} file(s) for filter staged=${includeStaged} unstaged=${includeUnstaged}`);
327
+ return filtered;
323
328
  });
324
329
  }
325
330
  getFileNames(filter) {
@@ -344,11 +349,13 @@ var DefaultGitService = class {
344
349
  const isRemote = line.includes("remotes/");
345
350
  let branchName = line.replace(CURRENT_BRANCH_MARKER_REGEX, "").trim();
346
351
  if (isRemote) branchName = branchName.replace(REMOTES_PREFIX_REGEX, "");
347
- return {
352
+ const branch = {
348
353
  name: branchName,
349
354
  isCurrent,
350
355
  isRemote
351
356
  };
357
+ logger.verbose(`DefaultGitService: Parsed branch: ${branch.name} current=${branch.isCurrent} remote=${branch.isRemote}`);
358
+ return branch;
352
359
  }
353
360
  listBranches(includeRemote) {
354
361
  const args = ["branch"];
@@ -359,7 +366,7 @@ var DefaultGitService = class {
359
366
  }
360
367
  createCommit(message, options) {
361
368
  if (options?.dryRun) {
362
- logger.verbose("GitService: Dry run, skipping commit");
369
+ logger.verbose("DefaultGitService: Dry run, skipping commit");
363
370
  return FireflyOkAsync({ sha: "dry-run-sha" });
364
371
  }
365
372
  const args = [
@@ -391,7 +398,7 @@ var DefaultGitService = class {
391
398
  "--no-patch",
392
399
  `--format=${format}`,
393
400
  hash
394
- ]);
401
+ ], { verbose: DebugFlags.showVerboseGitCommitDetails });
395
402
  }
396
403
  getUnpushedCommits() {
397
404
  return this.getCurrentBranch().andThen((branch) => {
@@ -402,6 +409,7 @@ var DefaultGitService = class {
402
409
  `${upstream}..HEAD`
403
410
  ]).map((output) => {
404
411
  const count = Number.parseInt(output.trim(), 10) || 0;
412
+ logger.verbose(`DefaultGitService: Unpushed commits count for ${upstream}: ${count}`);
405
413
  return {
406
414
  hasUnpushed: count > 0,
407
415
  count
@@ -413,6 +421,7 @@ var DefaultGitService = class {
413
421
  "HEAD"
414
422
  ]).map((output) => {
415
423
  const count = Number.parseInt(output.trim(), 10) || 0;
424
+ logger.verbose(`DefaultGitService: Total commit count: ${count}`);
416
425
  return {
417
426
  hasUnpushed: count > 0,
418
427
  count
@@ -426,7 +435,7 @@ var DefaultGitService = class {
426
435
  }
427
436
  createTag(name, options) {
428
437
  if (options?.dryRun) {
429
- logger.verbose(`GitService: Dry run, skipping tag creation: ${name}`);
438
+ logger.verbose(`DefaultGitService: Dry run, skipping tag creation: ${name}`);
430
439
  return FireflyOkAsync(void 0);
431
440
  }
432
441
  const args = ["tag"];
@@ -439,7 +448,7 @@ var DefaultGitService = class {
439
448
  const scope = options?.scope ?? "local";
440
449
  const remote = options?.remote ?? "origin";
441
450
  if (options?.dryRun) {
442
- logger.verbose(`GitService: Dry run, skipping tag deletion (${scope}): ${name}`);
451
+ logger.verbose(`DefaultGitService: Dry run, skipping tag deletion (${scope}): ${name}`);
443
452
  return FireflyOkAsync(void 0);
444
453
  }
445
454
  if (scope === "local") return this.git([
@@ -447,11 +456,15 @@ var DefaultGitService = class {
447
456
  "-d",
448
457
  name
449
458
  ]).map(() => void 0);
450
- if (scope === "remote") return this.git([
451
- "push",
452
- remote,
453
- `:refs/tags/${name}`
454
- ]).map(() => void 0);
459
+ if (scope === "remote") {
460
+ logger.verbose(`DefaultGitService: Deleting remote tag: ${name} on ${remote}`);
461
+ return this.git([
462
+ "push",
463
+ remote,
464
+ `:refs/tags/${name}`
465
+ ]).andTee(() => logger.verbose(`DefaultGitService: Remote tag deleted: ${name} on ${remote}`)).map(() => void 0);
466
+ }
467
+ logger.verbose(`DefaultGitService: Deleting tag locally and remotely: ${name} on ${remote}`);
455
468
  return this.git([
456
469
  "tag",
457
470
  "-d",
@@ -460,17 +473,21 @@ var DefaultGitService = class {
460
473
  "push",
461
474
  remote,
462
475
  `:refs/tags/${name}`
463
- ])).map(() => void 0);
476
+ ])).andTee(() => logger.verbose(`DefaultGitService: Local and remote tag deleted: ${name} on ${remote}`)).map(() => void 0);
464
477
  }
465
478
  hasTag(name) {
466
479
  return this.git([
467
480
  "tag",
468
481
  "--list",
469
482
  name
470
- ]).map((output) => output.trim() === name);
483
+ ]).map((output) => {
484
+ const exists = output.trim() === name;
485
+ logger.verbose(`DefaultGitService: Tag ${name} exists=${exists}`);
486
+ return exists;
487
+ });
471
488
  }
472
489
  hasAnyTags() {
473
- return this.getLatestTag().map((tag) => tag !== null);
490
+ return this.getLatestTag().andTee(() => logger.verbose("DefaultGitService: Checking if any tags exist")).map((tag) => tag !== null);
474
491
  }
475
492
  listTags() {
476
493
  return this.git(["tag", "--list"]).map((output) => output.split("\n").map((tag) => tag.trim()).filter((tag) => tag.length > 0));
@@ -494,25 +511,28 @@ var DefaultGitService = class {
494
511
  "--format=%(contents)",
495
512
  name
496
513
  ]).map((output) => {
497
- return output.trim() || null;
514
+ const message = output.trim();
515
+ logger.verbose(`DefaultGitService: Tag message for ${name}: ${message?.substring(0, 60) ?? "(none)"}`);
516
+ return message || null;
498
517
  }).orElse(() => FireflyOkAsync(null));
499
518
  }
500
519
  stage(paths) {
501
520
  const pathArray = Array.isArray(paths) ? paths : [paths];
502
- return this.git(["add", ...pathArray]).map(() => void 0);
521
+ return this.git(["add", ...pathArray]).andTee(() => logger.verbose(`DefaultGitService: Staged paths: ${pathArray.join(", ")}`)).map(() => void 0);
503
522
  }
504
523
  unstage(paths) {
505
524
  const pathArray = Array.isArray(paths) ? paths : [paths];
525
+ logger.verbose(`DefaultGitService: Unstaging paths: ${pathArray.join(", ")}`);
506
526
  return this.git([
507
527
  "reset",
508
528
  "HEAD",
509
529
  "--",
510
530
  ...pathArray
511
- ]).map(() => void 0);
531
+ ]).andTee(() => logger.verbose(`DefaultGitService: Unstaged paths: ${pathArray.join(", ")}`)).map(() => void 0);
512
532
  }
513
533
  push(options) {
514
534
  if (options?.dryRun) {
515
- logger.verbose("GitService: Dry run, skipping push");
535
+ logger.verbose("DefaultGitService: Dry run, skipping push");
516
536
  return FireflyOkAsync(void 0);
517
537
  }
518
538
  const args = ["push"];
@@ -550,9 +570,10 @@ var DefaultGitService = class {
550
570
  inferRepositoryUrl() {
551
571
  return this.getUpstreamRemote().andThen((upstreamRemote) => {
552
572
  if (upstreamRemote) {
553
- logger.verbose(`GitService: Inferring repository URL from upstream remote: ${upstreamRemote}`);
573
+ logger.verbose(`DefaultGitService: Inferring repository URL from upstream remote: ${upstreamRemote}`);
554
574
  return this.getRemoteUrl(upstreamRemote).map((url) => url).orElse(() => this.tryOriginOrFirstRemote());
555
575
  }
576
+ logger.verbose("DefaultGitService: No upstream remote; falling back to origin or first remote");
556
577
  return this.tryOriginOrFirstRemote();
557
578
  });
558
579
  }
@@ -561,16 +582,16 @@ var DefaultGitService = class {
561
582
  */
562
583
  tryOriginOrFirstRemote() {
563
584
  return this.getRemoteUrl("origin").map((url) => {
564
- logger.verbose("GitService: Inferring repository URL from origin remote");
585
+ logger.verbose("DefaultGitService: Inferring repository URL from origin remote");
565
586
  return url;
566
587
  }).orElse(() => {
567
588
  return this.listRemotes().andThen((remotes) => {
568
589
  if (remotes.length === 0) {
569
- logger.verbose("GitService: No remotes configured, cannot infer repository URL");
590
+ logger.verbose("DefaultGitService: No remotes configured, cannot infer repository URL");
570
591
  return FireflyOkAsync(null);
571
592
  }
572
593
  const firstRemote = remotes[0];
573
- logger.verbose(`GitService: Inferring repository URL from first remote: ${firstRemote}`);
594
+ logger.verbose(`DefaultGitService: Inferring repository URL from first remote: ${firstRemote}`);
574
595
  return this.getRemoteUrl(firstRemote).map((url) => url).orElse(() => FireflyOkAsync(null));
575
596
  });
576
597
  });
@@ -0,0 +1,20 @@
1
+ import { createConsola } from "consola";
2
+ import { colors } from "consola/utils";
3
+
4
+ //#region src/infrastructure/logging/index.ts
5
+ const opts = {
6
+ date: false,
7
+ compact: true,
8
+ columns: 0
9
+ };
10
+ const _logger = createConsola({ formatOptions: opts });
11
+ const logger = createConsola({
12
+ formatOptions: opts,
13
+ reporters: [{ log(logObj) {
14
+ if (logObj.type === "verbose") console.log(colors.gray(logObj.args.join(" ")));
15
+ else _logger.log(logObj);
16
+ } }]
17
+ });
18
+
19
+ //#endregion
20
+ export { logger as t };
package/dist/main.js CHANGED
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env bun
2
- import { createConsola } from "consola";
3
- import { colors } from "consola/utils";
4
-
5
2
  //#region src/core/environment/runtime-env.ts
6
3
  /**
7
4
  * These are set during CLI initialization in main.ts and provide
@@ -53,25 +50,9 @@ var RuntimeEnv = class {
53
50
  }
54
51
  };
55
52
 
56
- //#endregion
57
- //#region src/infrastructure/logging/index.ts
58
- const opts = {
59
- date: false,
60
- compact: true,
61
- columns: 0
62
- };
63
- const _logger = createConsola({ formatOptions: opts });
64
- const logger = createConsola({
65
- formatOptions: opts,
66
- reporters: [{ log(logObj) {
67
- if (logObj.type === "verbose") console.log(colors.gray(logObj.args.join(" ")));
68
- else _logger.log(logObj);
69
- } }]
70
- });
71
-
72
53
  //#endregion
73
54
  //#region package.json
74
- var version = "4.0.0-dev.4721ae4";
55
+ var version = "4.0.0-dev.5022ada";
75
56
  var description = " CLI orchestrator for automatic semantic versioning, changelog generation, and creating releases. Built for my own use cases.";
76
57
  var dependencies = {
77
58
  "c12": "^3.3.2",
@@ -99,13 +80,10 @@ async function main() {
99
80
  description,
100
81
  gitCliffVersion: dependencies["git-cliff"]?.replace("^", "") || "unknown"
101
82
  });
102
- const { createFireflyCLI } = await import("./program-Cw3A_k7R.js");
103
- createFireflyCLI().parseAsync(process.argv).catch((error) => {
104
- logger.error("Fatal error:", error);
105
- process.exit(1);
106
- });
83
+ const { createFireflyCLI } = await import("./program-BBUBg7D4.js");
84
+ createFireflyCLI().parseAsync(process.argv).catch(() => process.exit(1));
107
85
  }
108
86
  main();
109
87
 
110
88
  //#endregion
111
- export { RuntimeEnv as n, logger as t };
89
+ export { RuntimeEnv as t };
@@ -1,5 +1,6 @@
1
- import { d as validationErrAsync, g as toFireflyError, i as FireflyOkAsync, u as validationErr } from "./result.constructors-C9M1MP3_.js";
2
- import { n as parseSchema } from "./schema.utilities-BGd9t1wm.js";
1
+ import { d as validationErr, f as validationErrAsync, i as FireflyOkAsync, v as toFireflyError } from "./result.constructors-DoAoYdfF.js";
2
+ import { t as logger } from "./logging-Bpk2RzGc.js";
3
+ import { n as parseSchema } from "./schema.utilities-C1yimTtB.js";
3
4
  import { Result } from "neverthrow";
4
5
  import z$1 from "zod";
5
6
 
@@ -28,7 +29,7 @@ var DefaultPackageJsonService = class DefaultPackageJsonService {
28
29
  return this.fs.read(path).map((content) => this.replaceVersionInContent(content, newVersion)).andThen((updatedContent) => this.fs.write(path, updatedContent)).andThen(() => this.read(path).andThen((pkg) => {
29
30
  if (pkg.version !== newVersion) return validationErrAsync({ message: `Failed to verify updated version in package.json at path: ${path}` });
30
31
  return FireflyOkAsync(void 0);
31
- }));
32
+ })).andTee(() => logger.verbose(`DefaultPackageJsonService: Updated version in package.json at path: ${path} to ${newVersion}`));
32
33
  }
33
34
  /**
34
35
  * Replaces the version string in the package.json content.