fireflyy 4.0.0-dev.644fea9 → 4.0.0-dev.988c93c

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/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.644fea9";
55
+ var version = "4.0.0-dev.988c93c";
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-CHc5t2Xm.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-Dqo9sQjU.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,6 +1,6 @@
1
- import { t as logger } from "./main.js";
2
- import { d as validationErrAsync, g as toFireflyError, i as FireflyOkAsync, u as validationErr } from "./result.constructors-C9M1MP3_.js";
3
- import { n as parseSchema } from "./schema.utilities-BGd9t1wm.js";
1
+ import { _ as toFireflyError, d as validationErrAsync, i as FireflyOkAsync, u as validationErr } from "./result.constructors-BMtOWD2-.js";
2
+ import { t as logger } from "./logging-BuIkRrn1.js";
3
+ import { n as parseSchema } from "./schema.utilities-BxiRR-GI.js";
4
4
  import { Result } from "neverthrow";
5
5
  import z$1 from "zod";
6
6
 
@@ -1,10 +1,11 @@
1
- import { n as RuntimeEnv, t as logger } from "./main.js";
2
- import { _ as validationError, a as conflictErrAsync, c as notFoundErrAsync, d as validationErrAsync, f as conflictError, h as notFoundError, i as FireflyOkAsync, l as timeoutErrAsync, m as failedError, n as FireflyErrAsync, r as FireflyOk, s as invalidErr, t as FireflyErr, u as validationErr, v as wrapErrorMessage } from "./result.constructors-C9M1MP3_.js";
3
- import { n as wrapPromise, r as zip3Async, t as ensureNotAsync } from "./result.utilities-DC5shlhT.js";
4
- import { n as parseSchema, t as formatZodErrors } from "./schema.utilities-BGd9t1wm.js";
1
+ import { t as RuntimeEnv } from "./main.js";
2
+ import { a as conflictErrAsync, c as notFoundErrAsync, d as validationErrAsync, f as conflictError, g as notFoundError, i as FireflyOkAsync, l as timeoutErrAsync, m as failedError, n as FireflyErrAsync, o as failedErrAsync, r as FireflyOk, s as invalidErr, t as FireflyErr, u as validationErr, v as validationError, y as wrapErrorMessage } from "./result.constructors-BMtOWD2-.js";
3
+ import { n as wrapPromise, t as ensureNotAsync } from "./result.utilities-BTVU-GsT.js";
4
+ import { t as logger } from "./logging-BuIkRrn1.js";
5
+ import { n as parseSchema, t as formatZodErrors } from "./schema.utilities-BxiRR-GI.js";
6
+ import { Command } from "commander";
5
7
  import { LogLevels } from "consola";
6
8
  import { colors } from "consola/utils";
7
- import { Command } from "commander";
8
9
  import { loadConfig } from "c12";
9
10
  import { Result, ResultAsync, err, ok } from "neverthrow";
10
11
  import z$1 from "zod";
@@ -1003,9 +1004,10 @@ function createBumpExecutionGroup() {
1003
1004
  */
1004
1005
  function shouldSkipBumpStrategy(ctx) {
1005
1006
  const { skipBump, releaseType, bumpStrategy } = ctx.config;
1007
+ const { selectedReleaseType, selectedBumpStrategy } = ctx.data;
1006
1008
  if (skipBump) return true;
1007
- if (releaseType) return true;
1008
- if (!bumpStrategy) return true;
1009
+ if (releaseType || selectedReleaseType) return true;
1010
+ if (!Boolean(bumpStrategy || selectedBumpStrategy)) return true;
1009
1011
  return false;
1010
1012
  }
1011
1013
  /**
@@ -1013,9 +1015,11 @@ function shouldSkipBumpStrategy(ctx) {
1013
1015
  */
1014
1016
  function getSkipReason(ctx) {
1015
1017
  const { skipBump, releaseType, bumpStrategy } = ctx.config;
1018
+ const { selectedReleaseType, selectedBumpStrategy } = ctx.data;
1016
1019
  if (skipBump) return "skipBump is enabled";
1017
- if (releaseType) return `releaseType already set to '${releaseType}'`;
1018
- if (!bumpStrategy) return "no bumpStrategy configured";
1020
+ if (releaseType) return `releaseType already set to '${releaseType}' (config)`;
1021
+ if (selectedReleaseType) return `releaseType already set to '${selectedReleaseType}' (data)`;
1022
+ if (!Boolean(bumpStrategy || selectedBumpStrategy)) return "no bumpStrategy configured";
1019
1023
  return "unknown reason";
1020
1024
  }
1021
1025
  function createDelegateBumpStrategyTask() {
@@ -1034,7 +1038,10 @@ function createDelegateBumpStrategyTask() {
1034
1038
  //#endregion
1035
1039
  //#region src/commands/release/tasks/determine-automatic-bump.task.ts
1036
1040
  function createDetermineAutomaticBump() {
1037
- return TaskBuilder.create("determine-automatic-bump").description("Automatically determines the version bump from commit messages").dependsOn("delegate-bump-strategy").skipWhenWithReason((ctx) => ctx.config.skipBump || ctx.config.bumpStrategy !== BUMP_STRATEGY_AUTO, "Skipped: skipBump enabled or bumpStrategy is not 'auto'").execute((ctx) => {
1041
+ return TaskBuilder.create("determine-automatic-bump").description("Automatically determines the version bump from commit messages").dependsOn("delegate-bump-strategy").skipWhenWithReason((ctx) => {
1042
+ const bumpStrategy = ctx.data.selectedBumpStrategy ?? ctx.config.bumpStrategy;
1043
+ return ctx.config.skipBump || bumpStrategy !== BUMP_STRATEGY_AUTO;
1044
+ }, "Skipped: skipBump enabled or bumpStrategy is not 'auto'").execute((ctx) => {
1038
1045
  logger.info("determine-automatic-bump");
1039
1046
  return FireflyOkAsync(ctx);
1040
1047
  }).build();
@@ -1042,17 +1049,59 @@ function createDetermineAutomaticBump() {
1042
1049
 
1043
1050
  //#endregion
1044
1051
  //#region src/commands/release/tasks/prompt-bump-strategy.task.ts
1052
+ const BUMP_STRATEGIES = [{
1053
+ label: "Automatic Bump",
1054
+ value: BUMP_STRATEGY_AUTO,
1055
+ hint: "Determines the next version based on conventional commits history"
1056
+ }, {
1057
+ label: "Manual Bump",
1058
+ value: BUMP_STRATEGY_MANUAL,
1059
+ hint: "Manually specify the next version"
1060
+ }];
1061
+ const VALID_STRATEGY_VALUES = BUMP_STRATEGIES.map((s) => s.value);
1062
+ /**
1063
+ * Validates that the selected strategy is one of the allowed values.
1064
+ *
1065
+ * @param strategy The selected version bump strategy.
1066
+ * @returns A FireflyResult indicating success or failure of validation.
1067
+ */
1068
+ function validateStrategy(strategy) {
1069
+ if (!VALID_STRATEGY_VALUES.includes(strategy)) return invalidErr({ message: `Invalid version bump strategy: ${strategy}` });
1070
+ return FireflyOk(strategy);
1071
+ }
1072
+ /**
1073
+ * Prompts the user to select a bump strategy using the logger's prompt API.
1074
+ */
1075
+ function promptBumpStrategy() {
1076
+ const defaultStrategy = BUMP_STRATEGIES[0];
1077
+ if (!defaultStrategy) return notFoundErrAsync({ message: "No default version bump strategy found" });
1078
+ logger.verbose("PromptBumpStrategyTask: Prompting user for version bump strategy.");
1079
+ return wrapPromise(logger.prompt("Select version bump strategy", {
1080
+ type: "select",
1081
+ options: BUMP_STRATEGIES,
1082
+ initial: defaultStrategy.value,
1083
+ cancel: "undefined"
1084
+ })).andThen((selected) => {
1085
+ if (!selected || selected === "") return failedErrAsync({ message: "Operation cancelled by user" });
1086
+ if (logger.level === LogLevels.verbose) logger.log("");
1087
+ if (logger.level !== LogLevels.verbose) logger.log("");
1088
+ const validationResult = validateStrategy(selected);
1089
+ if (validationResult.isErr()) return FireflyErrAsync(validationResult.error);
1090
+ logger.verbose(`PromptBumpStrategyTask: Selected version bump strategy: '${selected}'`);
1091
+ return FireflyOkAsync(selected);
1092
+ });
1093
+ }
1045
1094
  function createPromptBumpStrategyTask() {
1046
- return TaskBuilder.create("prompt-bump-strategy").description("Prompts the user for a version bump strategy").dependsOn("initialize-release-version").skipWhenWithReason((ctx) => ctx.config.skipBump || Boolean(ctx.config.bumpStrategy) || Boolean(ctx.config.releaseType), "Skipped: skipBump enabled, or bumpStrategy/releaseType already specified").execute((ctx) => {
1047
- logger.info("prompt-bump-strategy");
1048
- return FireflyOkAsync(ctx);
1049
- }).build();
1095
+ return TaskBuilder.create("prompt-bump-strategy").description("Prompts the user for a version bump strategy").dependsOn("initialize-release-version").skipWhenWithReason((ctx) => ctx.config.skipBump || Boolean(ctx.config.bumpStrategy) || Boolean(ctx.config.releaseType), "Skipped: skipBump enabled, or bumpStrategy/releaseType already specified").execute((ctx) => promptBumpStrategy().andThen((strategy) => FireflyOkAsync(ctx.fork("selectedBumpStrategy", strategy)))).build();
1050
1096
  }
1051
1097
 
1052
1098
  //#endregion
1053
1099
  //#region src/commands/release/tasks/prompt-manual-bump.task.ts
1054
1100
  function createPromptManualVersionTask() {
1055
- return TaskBuilder.create("prompt-manual-version").description("Prompts the user for a manual version bump selections").dependsOn("delegate-bump-strategy").skipWhenWithReason((ctx) => ctx.config.skipBump || Boolean(ctx.config.bumpStrategy) || Boolean(ctx.config.releaseType), "Skipped: skipBump enabled, or bumpStrategy/releaseType already specified").execute((ctx) => {
1101
+ return TaskBuilder.create("prompt-manual-version").description("Prompts the user for a manual version bump selections").dependsOn("delegate-bump-strategy").skipWhenWithReason((ctx) => {
1102
+ const bumpStrategy = ctx.data.selectedBumpStrategy ?? ctx.config.bumpStrategy;
1103
+ return ctx.config.skipBump || bumpStrategy !== BUMP_STRATEGY_MANUAL;
1104
+ }, "Skipped: skipBump enabled or bumpStrategy is not 'manual'").execute((ctx) => {
1056
1105
  logger.info("prompt-manual-version");
1057
1106
  return FireflyOkAsync(ctx);
1058
1107
  }).build();
@@ -1130,6 +1179,12 @@ const SSH_REMOTE_REGEX = /git@[^:]+:([^/]+)\/([^/.]+)(?:\.git)?/;
1130
1179
  const SCOPED_PACKAGE_REGEX = /^@([^/]+)\/(.+)$/;
1131
1180
  const PRERELEASE_REGEX = /^\d+\.\d+\.\d+-([a-zA-Z]+)/;
1132
1181
  /**
1182
+ * Terminologies:
1183
+ *
1184
+ * Prepared: The value has been determined and set in the context.
1185
+ * Using: The value was explicitly provided in the config and is used as-is.
1186
+ */
1187
+ /**
1133
1188
  * Parses a git remote URL to extract owner and repository name.
1134
1189
  * Supports both HTTPS and SSH formats.
1135
1190
  *
@@ -1176,46 +1231,6 @@ function extractPreReleaseId(version) {
1176
1231
  return version.match(PRERELEASE_REGEX)?.[1];
1177
1232
  }
1178
1233
  /**
1179
- * Hydrates the repository field from git remote URL.
1180
- *
1181
- * Behavior:
1182
- * - If not inside a git repository, resolves to undefined.
1183
- * - If inside a repository, detect the repository URL
1184
- * using a fall-through strategy (upstream remote → origin → first remote).
1185
- * - Parses the URL and returns "owner/repo" when possible.
1186
- */
1187
- function hydrateRepository(ctx) {
1188
- return ctx.services.git.inferRepositoryUrl().map((url) => {
1189
- if (!url) return null;
1190
- const parsed = parseGitRemoteUrl(url);
1191
- if (parsed) return `${parsed.owner}/${parsed.repo}`;
1192
- return null;
1193
- }).map((val) => val ?? void 0).andTee((repository) => logger.verbose(`PrepareReleaseConfigTask: Prepared repository: ${repository}`));
1194
- }
1195
- /**
1196
- * Hydrates name, scope, and preReleaseId from package.json.
1197
- *
1198
- * Behavior:
1199
- * - If package.json does not exist, returns all values as undefined.
1200
- * - If it exists, reads package.json and returns parsed results for name, scope and preReleaseId.
1201
- */
1202
- function hydrateFromPackageJson(ctx) {
1203
- return ctx.services.fs.exists("package.json").andThen((exists) => {
1204
- if (!exists) return FireflyOkAsync({
1205
- name: void 0,
1206
- scope: void 0,
1207
- preReleaseId: void 0
1208
- });
1209
- return ctx.services.packageJson.read("package.json").andThen((pkg) => zip3Async(hydrateNameFromPackageJson(ctx, pkg), hydrateScopeFromPackageJson(ctx, pkg), hydratePreReleaseIdFromPackageJson(ctx, pkg)).map(([name, scope, preReleaseId]) => {
1210
- const result = {};
1211
- if (name) result.name = name;
1212
- if (scope) result.scope = scope;
1213
- if (preReleaseId) result.preReleaseId = preReleaseId;
1214
- return result;
1215
- }));
1216
- });
1217
- }
1218
- /**
1219
1234
  * Hydrates the `name` field from package.json when not provided in config.
1220
1235
  *
1221
1236
  * Cases:
@@ -1282,6 +1297,46 @@ function hydratePreReleaseIdFromPackageJson(ctx, packageJson) {
1282
1297
  return FireflyOkAsync("alpha");
1283
1298
  }
1284
1299
  /**
1300
+ * Hydrates name, scope, and preReleaseId from package.json.
1301
+ *
1302
+ * Behavior:
1303
+ * - If package.json does not exist, returns all values as undefined.
1304
+ * - If it exists, reads package.json and returns parsed results for name, scope and preReleaseId.
1305
+ */
1306
+ function hydrateFromPackageJson(ctx) {
1307
+ return ctx.services.fs.exists("package.json").andThen((exists) => {
1308
+ if (!exists) return FireflyOkAsync({
1309
+ name: void 0,
1310
+ scope: void 0,
1311
+ preReleaseId: void 0
1312
+ });
1313
+ return ctx.services.packageJson.read("package.json").andThen((pkg) => hydrateNameFromPackageJson(ctx, pkg).andThen((name) => hydrateScopeFromPackageJson(ctx, pkg).andThen((scope) => hydratePreReleaseIdFromPackageJson(ctx, pkg).map((preReleaseId) => {
1314
+ const result = {};
1315
+ if (name) result.name = name;
1316
+ if (scope) result.scope = scope;
1317
+ if (preReleaseId) result.preReleaseId = preReleaseId;
1318
+ return result;
1319
+ }))));
1320
+ });
1321
+ }
1322
+ /**
1323
+ * Hydrates the repository field from git remote URL.
1324
+ *
1325
+ * Behavior:
1326
+ * - If not inside a git repository, resolves to undefined.
1327
+ * - If inside a repository, detect the repository URL
1328
+ * using a fall-through strategy (upstream remote → origin → first remote).
1329
+ * - Parses the URL and returns "owner/repo" when possible.
1330
+ */
1331
+ function hydrateRepository(ctx) {
1332
+ return ctx.services.git.inferRepositoryUrl().andThen((url) => {
1333
+ if (!url) return validationErrAsync({ message: "Could not determine git remote URL to infer repository information" });
1334
+ const parsed = parseGitRemoteUrl(url);
1335
+ if (parsed) return FireflyOkAsync(`${parsed.owner}/${parsed.repo}`);
1336
+ return validationErrAsync({ message: `Could not parse repository information from git remote URL: ${url}` });
1337
+ }).andTee((repository) => logger.verbose(`PrepareReleaseConfigTask: Prepared repository: ${repository}`));
1338
+ }
1339
+ /**
1285
1340
  * Hydrates branch setting from git.
1286
1341
  *
1287
1342
  * Behavior:
@@ -1305,6 +1360,71 @@ function hydrateBranch(ctx) {
1305
1360
  });
1306
1361
  }
1307
1362
  /**
1363
+ * Hydrates repository and branch information from git.
1364
+ *
1365
+ * Behavior:
1366
+ * - If not inside a git repository, resolves both values to undefined.
1367
+ * - Otherwise it composes `hydrateRepository` and `hydrateBranch` and returns both values.
1368
+ */
1369
+ function hydrateFromGit(ctx) {
1370
+ return ctx.services.git.isInsideRepository().andThen((isRepo) => {
1371
+ if (!isRepo) return FireflyOkAsync({
1372
+ repository: void 0,
1373
+ branch: void 0
1374
+ });
1375
+ return hydrateRepository(ctx).andThen((repository) => hydrateBranch(ctx).map((branch) => {
1376
+ const result = {};
1377
+ if (repository) result.repository = repository;
1378
+ if (branch) result.branch = branch;
1379
+ return result;
1380
+ }));
1381
+ });
1382
+ }
1383
+ /**
1384
+ * Hydrates release flags (releaseLatest, releasePreRelease, releaseDraft).
1385
+ *
1386
+ * Behavior:
1387
+ * - If exactly one flag is explicitly set to true, use that and set others to false.
1388
+ * - If no flags are explicitly set, default to releaseLatest = true, others = false.
1389
+ * - Validation of exclusivity is handled by the schema, so we only need to determine defaults.
1390
+ */
1391
+ function hydrateReleaseFlags(ctx) {
1392
+ const { releaseLatest, releasePreRelease, releaseDraft } = ctx.config;
1393
+ const latestExplicit = releaseLatest === true;
1394
+ const preReleaseExplicit = releasePreRelease === true;
1395
+ const draftExplicit = releaseDraft === true;
1396
+ if (preReleaseExplicit) {
1397
+ logger.verbose(`PrepareReleaseConfigTask: Using "releasePreRelease" as it is explicitly set`);
1398
+ return FireflyOkAsync({
1399
+ releaseLatest: false,
1400
+ releasePreRelease: true,
1401
+ releaseDraft: false
1402
+ });
1403
+ }
1404
+ if (draftExplicit) {
1405
+ logger.verbose(`PrepareReleaseConfigTask: Using "releaseDraft" as it is explicitly set`);
1406
+ return FireflyOkAsync({
1407
+ releaseLatest: false,
1408
+ releasePreRelease: false,
1409
+ releaseDraft: true
1410
+ });
1411
+ }
1412
+ if (latestExplicit) {
1413
+ logger.verbose(`PrepareReleaseConfigTask: Using "releaseLatest" as it is explicitly set`);
1414
+ return FireflyOkAsync({
1415
+ releaseLatest: true,
1416
+ releasePreRelease: false,
1417
+ releaseDraft: false
1418
+ });
1419
+ }
1420
+ logger.verbose("PrepareReleaseConfigTask: Prepared releaseLatest as default since no flag was explicitly set");
1421
+ return FireflyOkAsync({
1422
+ releaseLatest: true,
1423
+ releasePreRelease: false,
1424
+ releaseDraft: false
1425
+ });
1426
+ }
1427
+ /**
1308
1428
  * Creates the Prepare Release Config Task.
1309
1429
  *
1310
1430
  * This task determines and hydrates configuration settings, by inferring values from the environment.
@@ -1314,17 +1434,24 @@ function hydrateBranch(ctx) {
1314
1434
  * 2. Extracts name and scope from package.json
1315
1435
  * 3. Extracts preReleaseId from package.json version
1316
1436
  * 4. Detects current git branch if not provided
1437
+ * 5. Determines release flags (latest, preRelease, draft) with proper defaults
1317
1438
  */
1318
1439
  function createPrepareReleaseConfigTask() {
1319
1440
  return TaskBuilder.create("prepare-release-config").description("Hydrate and prepare the release configuration").execute((ctx) => {
1320
1441
  const hydrated = {};
1321
- return zip3Async(hydrateRepository(ctx), hydrateFromPackageJson(ctx), hydrateBranch(ctx)).map(([repository, pkgData, branch]) => {
1322
- if (repository) hydrated.repository = repository;
1442
+ return hydrateFromGit(ctx).andThen((gitData) => {
1443
+ if (gitData.repository) hydrated.repository = gitData.repository;
1444
+ if (gitData.branch) hydrated.branch = gitData.branch;
1445
+ return hydrateFromPackageJson(ctx);
1446
+ }).andThen((pkgData) => {
1323
1447
  if (pkgData.name) hydrated.name = pkgData.name;
1324
1448
  if (pkgData.scope) hydrated.scope = pkgData.scope;
1325
1449
  if (pkgData.preReleaseId) hydrated.preReleaseId = pkgData.preReleaseId;
1326
- if (branch) hydrated.branch = branch;
1327
- logger.verbose(`PrepareReleaseConfigTask: Hydrated config: ${JSON.stringify(hydrated)}`);
1450
+ return hydrateReleaseFlags(ctx);
1451
+ }).map((releaseFlags) => {
1452
+ hydrated.releaseLatest = releaseFlags.releaseLatest;
1453
+ hydrated.releasePreRelease = releaseFlags.releasePreRelease;
1454
+ hydrated.releaseDraft = releaseFlags.releaseDraft;
1328
1455
  return ctx.fork("hydratedConfig", hydrated);
1329
1456
  });
1330
1457
  }).build();
@@ -1492,7 +1619,7 @@ function validateReleaseFlagExclusivity(ctx) {
1492
1619
  "releasePreRelease",
1493
1620
  "releaseDraft"
1494
1621
  ];
1495
- if (flagNames.filter((k) => ctx.value[k]).length > 1) ctx.issues.push({
1622
+ if (flagNames.filter((k) => ctx.value[k] === true).length > 1) ctx.issues.push({
1496
1623
  code: "custom",
1497
1624
  message: `Only one of ${flagNames.join(", ")} can be set to true.`,
1498
1625
  input: ctx.value,
@@ -1555,9 +1682,9 @@ const ReleaseConfigSchema = z$1.object({
1555
1682
  skipGit: z$1.coerce.boolean().default(false).describe("Skip all git-related steps."),
1556
1683
  skipPreflightCheck: z$1.coerce.boolean().default(false).describe("Skip preflight checks."),
1557
1684
  releaseTitle: z$1.string().default(RELEASE_TITLE_TEMPLATE).describe("GitHub release title with placeholders."),
1558
- releaseLatest: z$1.coerce.boolean().default(true).describe("Mark as latest release."),
1559
- releasePreRelease: z$1.coerce.boolean().default(false).describe("Mark as pre-release."),
1560
- releaseDraft: z$1.coerce.boolean().default(false).describe("Release as draft version.")
1685
+ releaseLatest: z$1.coerce.boolean().optional().describe("Mark as latest release."),
1686
+ releasePreRelease: z$1.coerce.boolean().optional().describe("Mark as pre-release."),
1687
+ releaseDraft: z$1.coerce.boolean().optional().describe("Release as draft version.")
1561
1688
  }).check((ctx) => {
1562
1689
  validateReleaseFlagExclusivity(ctx);
1563
1690
  validateSkipGitRedundancy(ctx);
@@ -1611,21 +1738,41 @@ function defineService(definition) {
1611
1738
  */
1612
1739
  const SERVICE_DEFINITIONS = {
1613
1740
  fs: defineService({ factory: async ({ basePath }) => {
1614
- const { createFileSystemService } = await import("./filesystem.service-9VHML130.js");
1741
+ const { createFileSystemService } = await import("./filesystem.service-B8qg87n-.js");
1615
1742
  return createFileSystemService(basePath);
1616
1743
  } }),
1617
1744
  packageJson: defineService({
1618
1745
  dependencies: ["fs"],
1619
1746
  factory: async ({ getService }) => {
1620
1747
  const fs = await getService("fs");
1621
- const { createPackageJsonService } = await import("./package-json.service-DACeZzRg.js");
1748
+ const { createPackageJsonService } = await import("./package-json.service-CHmtIoQQ.js");
1622
1749
  return createPackageJsonService(fs);
1623
1750
  }
1624
1751
  }),
1625
1752
  git: defineService({ factory: async ({ basePath }) => {
1626
- const { createGitService } = await import("./git.service-CACrfCW8.js");
1753
+ const { createGitService } = await import("./git.service-BBqDH7qx.js");
1627
1754
  return createGitService(basePath);
1628
- } })
1755
+ } }),
1756
+ versionBumper: defineService({ factory: async () => {
1757
+ const { createVersionBumperService } = await import("./version-bumper.service-DMYR0npB.js");
1758
+ return createVersionBumperService();
1759
+ } }),
1760
+ versionStrategy: defineService({
1761
+ dependencies: ["versionBumper"],
1762
+ factory: async ({ getService }) => {
1763
+ const versionBumper = await getService("versionBumper");
1764
+ const { createVersionStrategyService } = await import("./version-strategy.service-CmfeZLYC.js");
1765
+ return createVersionStrategyService(versionBumper);
1766
+ }
1767
+ }),
1768
+ commitAnalysis: defineService({
1769
+ dependencies: ["git"],
1770
+ factory: async ({ getService }) => {
1771
+ const git = await getService("git");
1772
+ const { createCommitAnalysisService } = await import("./commit-analysis.service-Ba6hLgsr.js");
1773
+ return createCommitAnalysisService(git);
1774
+ }
1775
+ })
1629
1776
  };
1630
1777
  /**
1631
1778
  * Array of all service keys for iteration
@@ -2264,7 +2411,11 @@ var WorkflowExecutor = class {
2264
2411
  const startTime = /* @__PURE__ */ new Date();
2265
2412
  const executedTaskIds = [];
2266
2413
  const skippedTaskIds = [];
2267
- if (this.options.dryRun) logger.warn("Workflow executing in DRY RUN mode - no actual changes will be made");
2414
+ if (this.options.dryRun) logger.warn("Running in DRY-RUN mode: No changes will be made.");
2415
+ const version = RuntimeEnv.version;
2416
+ const dashIndex = version.indexOf("-");
2417
+ if (dashIndex !== -1) if (dashIndex === version.length - 1 || version[dashIndex + 1] === "n") logger.warn(`You are running a DEVELOPMENT build of Firefly (${colors.dim(version)}). This is a 'next' build and may be unstable.`);
2418
+ else logger.warn(`You are running a PRE-RELEASE version of Firefly (${colors.dim(version)}). Unexpected behavior or bugs may occur.`);
2268
2419
  logger.verbose(`WorkflowExecutor: Starting execution of ${tasks.length} tasks`);
2269
2420
  return this.executeTasksSequentially(tasks, initialContext, executedTaskIds, skippedTaskIds).andThen(() => this.buildExecutionSuccessResult(startTime, executedTaskIds, skippedTaskIds)).orElse((error) => this.handleExecutionFailure({
2270
2421
  error,
@@ -2292,6 +2443,8 @@ var WorkflowExecutor = class {
2292
2443
  handleExecutionFailure(args) {
2293
2444
  const { error, startTime, executedTaskIds, skippedTaskIds, initialContext } = args;
2294
2445
  const endTime = /* @__PURE__ */ new Date();
2446
+ if (DebugFlags.showRawError) logger.error(error);
2447
+ else logger.error(error.message);
2295
2448
  if (this.options.enableRollback && this.executedTasks.length > 0) {
2296
2449
  logger.verbose(`WorkflowExecutor: Attempting rollback of ${this.executedTasks.length} tasks`);
2297
2450
  return this.rollback(initialContext).andThen((rollbackSuccess) => {
@@ -2367,9 +2520,6 @@ var WorkflowExecutor = class {
2367
2520
  executionLists.executedTaskIds.push(currentTask.meta.id);
2368
2521
  this.executedTasks.push(currentTask);
2369
2522
  return this.executeTasksSequentially(remainingTasks, updatedContext, executionLists.executedTaskIds, executionLists.skippedTaskIds);
2370
- }).mapErr((error) => {
2371
- logger.error(error.message);
2372
- return error;
2373
2523
  });
2374
2524
  }
2375
2525
  rollback(context) {
@@ -258,4 +258,4 @@ const invalidErr = (opts) => err(invalidError(opts));
258
258
  const timeoutErrAsync = (opts) => errAsync(timeoutError(opts));
259
259
 
260
260
  //#endregion
261
- export { validationError as _, conflictErrAsync as a, notFoundErrAsync as c, validationErrAsync as d, conflictError as f, toFireflyError as g, notFoundError as h, FireflyOkAsync as i, timeoutErrAsync as l, failedError as m, FireflyErrAsync as n, failedErrAsync as o, createFireflyError as p, FireflyOk as r, invalidErr as s, FireflyErr as t, validationErr as u, wrapErrorMessage as v };
261
+ export { toFireflyError as _, conflictErrAsync as a, notFoundErrAsync as c, validationErrAsync as d, conflictError as f, notFoundError as g, invalidError as h, FireflyOkAsync as i, timeoutErrAsync as l, failedError as m, FireflyErrAsync as n, failedErrAsync as o, createFireflyError as p, FireflyOk as r, invalidErr as s, FireflyErr as t, validationErr as u, validationError as v, wrapErrorMessage as y };
@@ -1,4 +1,4 @@
1
- import { d as validationErrAsync, g as toFireflyError, i as FireflyOkAsync, p as createFireflyError } from "./result.constructors-C9M1MP3_.js";
1
+ import { _ as toFireflyError, d as validationErrAsync, i as FireflyOkAsync, p as createFireflyError } from "./result.constructors-BMtOWD2-.js";
2
2
  import { ResultAsync } from "neverthrow";
3
3
 
4
4
  //#region src/core/result/result.utilities.ts
@@ -17,16 +17,6 @@ function wrapPromise(promise) {
17
17
  function ensureNotAsync(condition, errorOpts) {
18
18
  return condition ? validationErrAsync(errorOpts) : FireflyOkAsync(void 0);
19
19
  }
20
- /**
21
- * Async version of zip3.
22
- */
23
- function zip3Async(resultA, resultB, resultC) {
24
- return ResultAsync.combine([
25
- resultA,
26
- resultB,
27
- resultC
28
- ]);
29
- }
30
20
 
31
21
  //#endregion
32
- export { wrapPromise as n, zip3Async as r, ensureNotAsync as t };
22
+ export { wrapPromise as n, ensureNotAsync as t };
@@ -1,4 +1,4 @@
1
- import { g as toFireflyError, p as createFireflyError, r as FireflyOk, t as FireflyErr } from "./result.constructors-C9M1MP3_.js";
1
+ import { _ as toFireflyError, p as createFireflyError, r as FireflyOk, t as FireflyErr } from "./result.constructors-BMtOWD2-.js";
2
2
  import { ResultAsync } from "neverthrow";
3
3
  import z$1 from "zod";
4
4