fireflyy 4.0.0-dev.6b1dcb0 → 4.0.0-dev.a10ed44

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.
@@ -145,17 +145,14 @@
145
145
  },
146
146
  "releaseLatest": {
147
147
  "description": "Mark as latest release.",
148
- "default": true,
149
148
  "type": "boolean"
150
149
  },
151
150
  "releasePreRelease": {
152
151
  "description": "Mark as pre-release.",
153
- "default": false,
154
152
  "type": "boolean"
155
153
  },
156
154
  "releaseDraft": {
157
155
  "description": "Release as draft version.",
158
- "default": false,
159
156
  "type": "boolean"
160
157
  }
161
158
  }
@@ -1,6 +1,6 @@
1
- import { t as logger } from "./main.js";
2
- import { g as invalidError, i as FireflyOkAsync, r as FireflyOk, t as FireflyErr } from "./result.constructors-D9jmQ0uj.js";
3
- import { TRANSITION_KEYWORDS } from "./version-strategy.service-Ds4mvlDC.js";
1
+ import { h as invalidError, i as FireflyOkAsync, r as FireflyOk, t as FireflyErr } from "./result.constructors-BMtOWD2-.js";
2
+ import { t as logger } from "./logging-BuIkRrn1.js";
3
+ import { TRANSITION_KEYWORDS } from "./version-strategy.service-CmfeZLYC.js";
4
4
 
5
5
  //#region src/domain/commits/commit-types.ts
6
6
  /**
package/dist/config.d.ts CHANGED
@@ -1,7 +1,65 @@
1
1
  import z from "zod";
2
2
 
3
- //#region src/cli/config/config.schema.d.ts
3
+ //#region src/commands/release/release.config.d.ts
4
4
 
5
+ declare const ReleaseConfigSchema: z.ZodObject<{
6
+ name: z.ZodOptional<z.ZodString>;
7
+ scope: z.ZodOptional<z.ZodString>;
8
+ base: z.ZodDefault<z.ZodString>;
9
+ branch: z.ZodOptional<z.ZodString>;
10
+ changelogPath: z.ZodDefault<z.ZodString>;
11
+ bumpStrategy: z.ZodDefault<z.ZodUnion<[z.ZodEnum<{
12
+ auto: "auto";
13
+ manual: "manual";
14
+ }>, z.ZodLiteral<"">]>>;
15
+ releaseType: z.ZodOptional<z.ZodEnum<{
16
+ major: "major";
17
+ minor: "minor";
18
+ patch: "patch";
19
+ prerelease: "prerelease";
20
+ premajor: "premajor";
21
+ preminor: "preminor";
22
+ prepatch: "prepatch";
23
+ graduate: "graduate";
24
+ }>>;
25
+ preReleaseId: z.ZodOptional<z.ZodString>;
26
+ preReleaseBase: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"0">, z.ZodLiteral<"1">]>>;
27
+ releaseNotes: z.ZodDefault<z.ZodString>;
28
+ commitMessage: z.ZodDefault<z.ZodString>;
29
+ tagName: z.ZodDefault<z.ZodString>;
30
+ skipBump: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
31
+ skipChangelog: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
32
+ skipPush: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
33
+ skipGitHubRelease: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
34
+ skipGit: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
35
+ skipPreflightCheck: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
36
+ releaseTitle: z.ZodDefault<z.ZodString>;
37
+ releaseLatest: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
38
+ releasePreRelease: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
39
+ releaseDraft: z.ZodOptional<z.ZodCoercedBoolean<unknown>>;
40
+ }, z.core.$strip>;
41
+ type BaseRelease = z.infer<typeof ReleaseConfigSchema>;
42
+ type ReleaseFlagKeys = "releaseLatest" | "releasePreRelease" | "releaseDraft";
43
+ type ExclusiveReleaseFlags = {
44
+ releaseLatest: true;
45
+ releasePreRelease?: false | undefined;
46
+ releaseDraft?: false | undefined;
47
+ } | {
48
+ releasePreRelease: true;
49
+ releaseLatest?: false | undefined;
50
+ releaseDraft?: false | undefined;
51
+ } | {
52
+ releaseDraft: true;
53
+ releaseLatest?: false | undefined;
54
+ releasePreRelease?: false | undefined;
55
+ } | {
56
+ releaseLatest?: false | undefined;
57
+ releasePreRelease?: false | undefined;
58
+ releaseDraft?: false | undefined;
59
+ };
60
+ type ReleaseConfig = Omit<BaseRelease, ReleaseFlagKeys> & ExclusiveReleaseFlags;
61
+ //#endregion
62
+ //#region src/cli/config/config.schema.d.ts
5
63
  /**
6
64
  * Complete Firefly configuration schema.
7
65
  * Combines global options with command-specific configuration sections.
@@ -39,9 +97,9 @@ declare const FireflyConfigSchema: z.ZodObject<{
39
97
  skipGit: z.ZodOptional<z.ZodDefault<z.ZodCoercedBoolean<unknown>>>;
40
98
  skipPreflightCheck: z.ZodOptional<z.ZodDefault<z.ZodCoercedBoolean<unknown>>>;
41
99
  releaseTitle: z.ZodOptional<z.ZodDefault<z.ZodString>>;
42
- releaseLatest: z.ZodOptional<z.ZodDefault<z.ZodCoercedBoolean<unknown>>>;
43
- releasePreRelease: z.ZodOptional<z.ZodDefault<z.ZodCoercedBoolean<unknown>>>;
44
- releaseDraft: z.ZodOptional<z.ZodDefault<z.ZodCoercedBoolean<unknown>>>;
100
+ releaseLatest: z.ZodOptional<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
101
+ releasePreRelease: z.ZodOptional<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
102
+ releaseDraft: z.ZodOptional<z.ZodOptional<z.ZodCoercedBoolean<unknown>>>;
45
103
  }, z.core.$strip>>;
46
104
  cwd: z.ZodOptional<z.ZodOptional<z.ZodString>>;
47
105
  dryRun: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
@@ -52,7 +110,9 @@ declare const FireflyConfigSchema: z.ZodObject<{
52
110
  * TypeScript type for Firefly configuration.
53
111
  * Use this type when you need to reference the configuration shape without runtime validation.
54
112
  */
55
- type FireflyConfig = z.infer<typeof FireflyConfigSchema>;
113
+ type FireflyConfig = z.infer<typeof FireflyConfigSchema> & {
114
+ release?: Partial<Omit<ReleaseConfig, ReleaseFlagKeys>> & ExclusiveReleaseFlags;
115
+ };
56
116
  //#endregion
57
117
  //#region src/config/index.d.ts
58
118
  /**
@@ -1,5 +1,5 @@
1
- import { t as logger } from "./main.js";
2
- import { i as FireflyOkAsync } from "./result.constructors-D9jmQ0uj.js";
1
+ import { i as FireflyOkAsync } from "./result.constructors-BMtOWD2-.js";
2
+ import { t as logger } from "./logging-BuIkRrn1.js";
3
3
 
4
4
  //#region src/infrastructure/dry-run/index.ts
5
5
  /**
@@ -1,7 +1,7 @@
1
- import { t as logger } from "./main.js";
2
- import { l as notFoundErrAsync } from "./result.constructors-D9jmQ0uj.js";
3
- import { n as wrapPromise } from "./result.utilities-CdBL5noX.js";
4
- import { t as withDryRun } from "./dry-run-BeuzUufT.js";
1
+ import { c as notFoundErrAsync } from "./result.constructors-BMtOWD2-.js";
2
+ import { n as wrapPromise } from "./result.utilities-BTVU-GsT.js";
3
+ import { t as logger } from "./logging-BuIkRrn1.js";
4
+ import { t as withDryRun } from "./dry-run-Cdg-c0EP.js";
5
5
 
6
6
  //#region src/services/implementations/filesystem.service.ts
7
7
  /**
@@ -1,6 +1,6 @@
1
- import { t as logger } from "./main.js";
2
- import { h as failedError, i as FireflyOkAsync, o as failedErrAsync } from "./result.constructors-D9jmQ0uj.js";
3
- import { t as withDryRun } from "./dry-run-BeuzUufT.js";
1
+ import { i as FireflyOkAsync, m as failedError, o as failedErrAsync } from "./result.constructors-BMtOWD2-.js";
2
+ import { t as logger } from "./logging-BuIkRrn1.js";
3
+ import { t as withDryRun } from "./dry-run-Cdg-c0EP.js";
4
4
  import { ResultAsync } from "neverthrow";
5
5
  import { z } from "zod";
6
6
 
@@ -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.6b1dcb0";
55
+ var version = "4.0.0-dev.a10ed44";
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-BVc78BFb.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 validationErr, f as validationErrAsync, i as FireflyOkAsync, v as toFireflyError } from "./result.constructors-D9jmQ0uj.js";
3
- import { n as parseSchema } from "./schema.utilities-BOJqWEey.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 notFoundError, a as conflictErrAsync, b as wrapErrorMessage, c as invalidErrAsync, d as validationErr, f as validationErrAsync, h as failedError, i as FireflyOkAsync, l as notFoundErrAsync, n as FireflyErrAsync, p as conflictError, r as FireflyOk, s as invalidErr, t as FireflyErr, u as timeoutErrAsync, y as validationError } from "./result.constructors-D9jmQ0uj.js";
3
- import { n as wrapPromise, r as zip3Async, t as ensureNotAsync } from "./result.utilities-CdBL5noX.js";
4
- import { n as parseSchema, t as formatZodErrors } from "./schema.utilities-BOJqWEey.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";
@@ -1075,17 +1076,15 @@ function promptBumpStrategy() {
1075
1076
  const defaultStrategy = BUMP_STRATEGIES[0];
1076
1077
  if (!defaultStrategy) return notFoundErrAsync({ message: "No default version bump strategy found" });
1077
1078
  logger.verbose("PromptBumpStrategyTask: Prompting user for version bump strategy.");
1078
- const prompt = logger.prompt("Select version bump strategy", {
1079
+ return wrapPromise(logger.prompt("Select version bump strategy", {
1079
1080
  type: "select",
1080
1081
  options: BUMP_STRATEGIES,
1081
1082
  initial: defaultStrategy.value,
1082
- cancel: "reject"
1083
- });
1084
- if (logger.level !== LogLevels.verbose) logger.log("");
1085
- return wrapPromise(prompt).andTee(() => {
1083
+ cancel: "undefined"
1084
+ })).andThen((selected) => {
1085
+ if (!selected || selected === "") return failedErrAsync({ message: "Operation cancelled by user" });
1086
1086
  if (logger.level === LogLevels.verbose) logger.log("");
1087
- }).andThen((selected) => {
1088
- if (!selected || selected === "") return invalidErrAsync({ message: "No version bump strategy selected" });
1087
+ if (logger.level !== LogLevels.verbose) logger.log("");
1089
1088
  const validationResult = validateStrategy(selected);
1090
1089
  if (validationResult.isErr()) return FireflyErrAsync(validationResult.error);
1091
1090
  logger.verbose(`PromptBumpStrategyTask: Selected version bump strategy: '${selected}'`);
@@ -1180,6 +1179,12 @@ const SSH_REMOTE_REGEX = /git@[^:]+:([^/]+)\/([^/.]+)(?:\.git)?/;
1180
1179
  const SCOPED_PACKAGE_REGEX = /^@([^/]+)\/(.+)$/;
1181
1180
  const PRERELEASE_REGEX = /^\d+\.\d+\.\d+-([a-zA-Z]+)/;
1182
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
+ /**
1183
1188
  * Parses a git remote URL to extract owner and repository name.
1184
1189
  * Supports both HTTPS and SSH formats.
1185
1190
  *
@@ -1226,46 +1231,6 @@ function extractPreReleaseId(version) {
1226
1231
  return version.match(PRERELEASE_REGEX)?.[1];
1227
1232
  }
1228
1233
  /**
1229
- * Hydrates the repository field from git remote URL.
1230
- *
1231
- * Behavior:
1232
- * - If not inside a git repository, resolves to undefined.
1233
- * - If inside a repository, detect the repository URL
1234
- * using a fall-through strategy (upstream remote → origin → first remote).
1235
- * - Parses the URL and returns "owner/repo" when possible.
1236
- */
1237
- function hydrateRepository(ctx) {
1238
- return ctx.services.git.inferRepositoryUrl().map((url) => {
1239
- if (!url) return null;
1240
- const parsed = parseGitRemoteUrl(url);
1241
- if (parsed) return `${parsed.owner}/${parsed.repo}`;
1242
- return null;
1243
- }).map((val) => val ?? void 0).andTee((repository) => logger.verbose(`PrepareReleaseConfigTask: Prepared repository: ${repository}`));
1244
- }
1245
- /**
1246
- * Hydrates name, scope, and preReleaseId from package.json.
1247
- *
1248
- * Behavior:
1249
- * - If package.json does not exist, returns all values as undefined.
1250
- * - If it exists, reads package.json and returns parsed results for name, scope and preReleaseId.
1251
- */
1252
- function hydrateFromPackageJson(ctx) {
1253
- return ctx.services.fs.exists("package.json").andThen((exists) => {
1254
- if (!exists) return FireflyOkAsync({
1255
- name: void 0,
1256
- scope: void 0,
1257
- preReleaseId: void 0
1258
- });
1259
- return ctx.services.packageJson.read("package.json").andThen((pkg) => zip3Async(hydrateNameFromPackageJson(ctx, pkg), hydrateScopeFromPackageJson(ctx, pkg), hydratePreReleaseIdFromPackageJson(ctx, pkg)).map(([name, scope, preReleaseId]) => {
1260
- const result = {};
1261
- if (name) result.name = name;
1262
- if (scope) result.scope = scope;
1263
- if (preReleaseId) result.preReleaseId = preReleaseId;
1264
- return result;
1265
- }));
1266
- });
1267
- }
1268
- /**
1269
1234
  * Hydrates the `name` field from package.json when not provided in config.
1270
1235
  *
1271
1236
  * Cases:
@@ -1332,6 +1297,46 @@ function hydratePreReleaseIdFromPackageJson(ctx, packageJson) {
1332
1297
  return FireflyOkAsync("alpha");
1333
1298
  }
1334
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
+ /**
1335
1340
  * Hydrates branch setting from git.
1336
1341
  *
1337
1342
  * Behavior:
@@ -1355,6 +1360,71 @@ function hydrateBranch(ctx) {
1355
1360
  });
1356
1361
  }
1357
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
+ /**
1358
1428
  * Creates the Prepare Release Config Task.
1359
1429
  *
1360
1430
  * This task determines and hydrates configuration settings, by inferring values from the environment.
@@ -1364,17 +1434,24 @@ function hydrateBranch(ctx) {
1364
1434
  * 2. Extracts name and scope from package.json
1365
1435
  * 3. Extracts preReleaseId from package.json version
1366
1436
  * 4. Detects current git branch if not provided
1437
+ * 5. Determines release flags (latest, preRelease, draft) with proper defaults
1367
1438
  */
1368
1439
  function createPrepareReleaseConfigTask() {
1369
1440
  return TaskBuilder.create("prepare-release-config").description("Hydrate and prepare the release configuration").execute((ctx) => {
1370
1441
  const hydrated = {};
1371
- return zip3Async(hydrateRepository(ctx), hydrateFromPackageJson(ctx), hydrateBranch(ctx)).map(([repository, pkgData, branch]) => {
1372
- 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) => {
1373
1447
  if (pkgData.name) hydrated.name = pkgData.name;
1374
1448
  if (pkgData.scope) hydrated.scope = pkgData.scope;
1375
1449
  if (pkgData.preReleaseId) hydrated.preReleaseId = pkgData.preReleaseId;
1376
- if (branch) hydrated.branch = branch;
1377
- 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;
1378
1455
  return ctx.fork("hydratedConfig", hydrated);
1379
1456
  });
1380
1457
  }).build();
@@ -1542,7 +1619,7 @@ function validateReleaseFlagExclusivity(ctx) {
1542
1619
  "releasePreRelease",
1543
1620
  "releaseDraft"
1544
1621
  ];
1545
- 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({
1546
1623
  code: "custom",
1547
1624
  message: `Only one of ${flagNames.join(", ")} can be set to true.`,
1548
1625
  input: ctx.value,
@@ -1605,9 +1682,9 @@ const ReleaseConfigSchema = z$1.object({
1605
1682
  skipGit: z$1.coerce.boolean().default(false).describe("Skip all git-related steps."),
1606
1683
  skipPreflightCheck: z$1.coerce.boolean().default(false).describe("Skip preflight checks."),
1607
1684
  releaseTitle: z$1.string().default(RELEASE_TITLE_TEMPLATE).describe("GitHub release title with placeholders."),
1608
- releaseLatest: z$1.coerce.boolean().default(true).describe("Mark as latest release."),
1609
- releasePreRelease: z$1.coerce.boolean().default(false).describe("Mark as pre-release."),
1610
- 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.")
1611
1688
  }).check((ctx) => {
1612
1689
  validateReleaseFlagExclusivity(ctx);
1613
1690
  validateSkipGitRedundancy(ctx);
@@ -1661,30 +1738,30 @@ function defineService(definition) {
1661
1738
  */
1662
1739
  const SERVICE_DEFINITIONS = {
1663
1740
  fs: defineService({ factory: async ({ basePath }) => {
1664
- const { createFileSystemService } = await import("./filesystem.service-Bl5h9T_0.js");
1741
+ const { createFileSystemService } = await import("./filesystem.service-B8qg87n-.js");
1665
1742
  return createFileSystemService(basePath);
1666
1743
  } }),
1667
1744
  packageJson: defineService({
1668
1745
  dependencies: ["fs"],
1669
1746
  factory: async ({ getService }) => {
1670
1747
  const fs = await getService("fs");
1671
- const { createPackageJsonService } = await import("./package-json.service-B6ultpL4.js");
1748
+ const { createPackageJsonService } = await import("./package-json.service-CHmtIoQQ.js");
1672
1749
  return createPackageJsonService(fs);
1673
1750
  }
1674
1751
  }),
1675
1752
  git: defineService({ factory: async ({ basePath }) => {
1676
- const { createGitService } = await import("./git.service-C0qRXy1s.js");
1753
+ const { createGitService } = await import("./git.service-BBqDH7qx.js");
1677
1754
  return createGitService(basePath);
1678
1755
  } }),
1679
1756
  versionBumper: defineService({ factory: async () => {
1680
- const { createVersionBumperService } = await import("./version-bumper.service-BYsIFCpv.js");
1757
+ const { createVersionBumperService } = await import("./version-bumper.service-DMYR0npB.js");
1681
1758
  return createVersionBumperService();
1682
1759
  } }),
1683
1760
  versionStrategy: defineService({
1684
1761
  dependencies: ["versionBumper"],
1685
1762
  factory: async ({ getService }) => {
1686
1763
  const versionBumper = await getService("versionBumper");
1687
- const { createVersionStrategyService } = await import("./version-strategy.service-Ds4mvlDC.js");
1764
+ const { createVersionStrategyService } = await import("./version-strategy.service-CmfeZLYC.js");
1688
1765
  return createVersionStrategyService(versionBumper);
1689
1766
  }
1690
1767
  }),
@@ -1692,7 +1769,7 @@ const SERVICE_DEFINITIONS = {
1692
1769
  dependencies: ["git"],
1693
1770
  factory: async ({ getService }) => {
1694
1771
  const git = await getService("git");
1695
- const { createCommitAnalysisService } = await import("./commit-analysis.service-BNlHyyhC.js");
1772
+ const { createCommitAnalysisService } = await import("./commit-analysis.service-Ba6hLgsr.js");
1696
1773
  return createCommitAnalysisService(git);
1697
1774
  }
1698
1775
  })
@@ -2366,6 +2443,8 @@ var WorkflowExecutor = class {
2366
2443
  handleExecutionFailure(args) {
2367
2444
  const { error, startTime, executedTaskIds, skippedTaskIds, initialContext } = args;
2368
2445
  const endTime = /* @__PURE__ */ new Date();
2446
+ if (DebugFlags.showRawError) logger.error(error);
2447
+ else logger.error(error.message);
2369
2448
  if (this.options.enableRollback && this.executedTasks.length > 0) {
2370
2449
  logger.verbose(`WorkflowExecutor: Attempting rollback of ${this.executedTasks.length} tasks`);
2371
2450
  return this.rollback(initialContext).andThen((rollbackSuccess) => {
@@ -2441,9 +2520,6 @@ var WorkflowExecutor = class {
2441
2520
  executionLists.executedTaskIds.push(currentTask.meta.id);
2442
2521
  this.executedTasks.push(currentTask);
2443
2522
  return this.executeTasksSequentially(remainingTasks, updatedContext, executionLists.executedTaskIds, executionLists.skippedTaskIds);
2444
- }).mapErr((error) => {
2445
- logger.error(error.message);
2446
- return error;
2447
2523
  });
2448
2524
  }
2449
2525
  rollback(context) {
@@ -253,13 +253,9 @@ const failedErrAsync = (opts) => errAsync(failedError(opts));
253
253
  */
254
254
  const invalidErr = (opts) => err(invalidError(opts));
255
255
  /**
256
- * Creates an async invalid error result.
257
- */
258
- const invalidErrAsync = (opts) => errAsync(invalidError(opts));
259
- /**
260
256
  * Creates an async timeout error result.
261
257
  */
262
258
  const timeoutErrAsync = (opts) => errAsync(timeoutError(opts));
263
259
 
264
260
  //#endregion
265
- export { notFoundError as _, conflictErrAsync as a, wrapErrorMessage as b, invalidErrAsync as c, validationErr as d, validationErrAsync as f, invalidError as g, failedError as h, FireflyOkAsync as i, notFoundErrAsync as l, createFireflyError as m, FireflyErrAsync as n, failedErrAsync as o, conflictError as p, FireflyOk as r, invalidErr as s, FireflyErr as t, timeoutErrAsync as u, toFireflyError as v, validationError as y };
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 { f as validationErrAsync, i as FireflyOkAsync, m as createFireflyError, v as toFireflyError } from "./result.constructors-D9jmQ0uj.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 { m as createFireflyError, r as FireflyOk, t as FireflyErr, v as toFireflyError } from "./result.constructors-D9jmQ0uj.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
 
@@ -1,4 +1,4 @@
1
- import { r as FireflyOk, s as invalidErr, t as FireflyErr } from "./result.constructors-D9jmQ0uj.js";
1
+ import { r as FireflyOk, s as invalidErr, t as FireflyErr } from "./result.constructors-BMtOWD2-.js";
2
2
  import semver from "semver";
3
3
 
4
4
  //#region src/domain/semver/version.ts
@@ -1,5 +1,5 @@
1
- import { t as logger } from "./main.js";
2
- import { g as invalidError, r as FireflyOk, t as FireflyErr } from "./result.constructors-D9jmQ0uj.js";
1
+ import { h as invalidError, r as FireflyOk, t as FireflyErr } from "./result.constructors-BMtOWD2-.js";
2
+ import { t as logger } from "./logging-BuIkRrn1.js";
3
3
  import { Result } from "neverthrow";
4
4
 
5
5
  //#region src/services/implementations/version-strategy.service.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fireflyy",
3
- "version": "4.0.0-dev.6b1dcb0",
3
+ "version": "4.0.0-dev.a10ed44",
4
4
  "description": " CLI orchestrator for automatic semantic versioning, changelog generation, and creating releases. Built for my own use cases.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -67,7 +67,7 @@
67
67
  "@types/semver": "^7.7.1",
68
68
  "tsdown": "^0.17.0-beta.6",
69
69
  "typescript": "^5.9.3",
70
- "ultracite": "6.3.8"
70
+ "ultracite": "6.3.9"
71
71
  },
72
72
  "keywords": [
73
73
  "cli",