@elmeragroup/internal 0.2.0-canary.0 → 0.2.0-canary.2

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.
Files changed (2) hide show
  1. package/dist/release.mjs +211 -197
  2. package/package.json +8 -8
package/dist/release.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { createRequire } from "node:module";
3
3
  import { Duration, Effect, Result, Schedule, Schema } from "effect";
4
- import { isAbsolute, join, relative, resolve, sep } from "node:path";
4
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
6
6
  import { execFileSync, spawnSync } from "node:child_process";
7
7
  import { createHash } from "node:crypto";
@@ -50,157 +50,6 @@ function readJson(path, schema) {
50
50
  return decodeJson(readFileSync(path, "utf8"), schema, path);
51
51
  }
52
52
  //#endregion
53
- //#region ../release/dist/version.js
54
- const numericIdentifier = /^(?:0|[1-9]\d*)$/;
55
- const canaryMarker = "-canary.";
56
- function isNumericIdentifier(value) {
57
- return numericIdentifier.test(value);
58
- }
59
- function stableComponents(version) {
60
- const [major, minor, patch, ...rest] = version.split(".");
61
- if (major === void 0 || minor === void 0 || patch === void 0 || rest.length !== 0) return;
62
- if (!isNumericIdentifier(major) || !isNumericIdentifier(minor) || !isNumericIdentifier(patch)) return;
63
- return [
64
- major,
65
- minor,
66
- patch
67
- ];
68
- }
69
- function canaryComponents(version) {
70
- const marker = version.indexOf(canaryMarker);
71
- if (marker === -1) return void 0;
72
- const base = version.slice(0, marker);
73
- const suffix = version.slice(marker + 8);
74
- if (stableComponents(base) === void 0 || !isNumericIdentifier(suffix)) return void 0;
75
- return {
76
- base,
77
- suffix
78
- };
79
- }
80
- function isStableReleaseVersion(version) {
81
- return stableComponents(version) !== void 0;
82
- }
83
- function isCanaryReleaseVersion(version) {
84
- return canaryComponents(version) !== void 0;
85
- }
86
- function isSupportedReleaseVersion(version) {
87
- return isStableReleaseVersion(version) || isCanaryReleaseVersion(version);
88
- }
89
- function assertReleaseVersion(version) {
90
- if (!isSupportedReleaseVersion(version)) throw new Error(`Unsupported release version ${version}; expected x.y.z or x.y.z-canary.N without leading zeros`);
91
- return version;
92
- }
93
- function assertCanaryReleaseVersion(version) {
94
- assertReleaseVersion(version);
95
- if (!isCanaryReleaseVersion(version)) throw new Error(`Canary publication requires x.y.z-canary.N; received ${version}`);
96
- return version;
97
- }
98
- function assertStableReleaseVersion(version) {
99
- if (!isStableReleaseVersion(version)) throw new Error(`Expected a stable version; received ${version}`);
100
- return version;
101
- }
102
- function parseStableVersion(version) {
103
- const components = stableComponents(version);
104
- if (components === void 0) throw new Error(`Expected a stable version; received ${version}`);
105
- const [major, minor, patch] = components;
106
- return {
107
- major: BigInt(major),
108
- minor: BigInt(minor),
109
- patch: BigInt(patch)
110
- };
111
- }
112
- function parseCanaryVersion(version) {
113
- const components = canaryComponents(version);
114
- if (components === void 0) throw new Error(`Canary publication requires x.y.z-canary.N; received ${version}`);
115
- return {
116
- base: components.base,
117
- n: BigInt(components.suffix)
118
- };
119
- }
120
- function formatStableVersion(version) {
121
- return `${version.major}.${version.minor}.${version.patch}`;
122
- }
123
- function formatCanaryVersion(version) {
124
- return `${version.base}-canary.${version.n}`;
125
- }
126
- function compareParsedStableVersions(left, right) {
127
- if (left.major !== right.major) return left.major > right.major ? 1 : -1;
128
- if (left.minor !== right.minor) return left.minor > right.minor ? 1 : -1;
129
- if (left.patch !== right.patch) return left.patch > right.patch ? 1 : -1;
130
- return 0;
131
- }
132
- function compareStableVersions(left, right) {
133
- return compareParsedStableVersions(parseStableVersion(left), parseStableVersion(right));
134
- }
135
- function nextPatchVersion(version) {
136
- const parsed = parseStableVersion(version);
137
- return formatStableVersion({
138
- ...parsed,
139
- patch: parsed.patch + 1n
140
- });
141
- }
142
- function compareCanaryVersions(left, right) {
143
- const parsedLeft = parseCanaryVersion(left);
144
- const parsedRight = parseCanaryVersion(right);
145
- const baseOrder = compareStableVersions(parsedLeft.base, parsedRight.base);
146
- if (baseOrder !== 0) return baseOrder;
147
- return parsedLeft.n === parsedRight.n ? 0 : parsedLeft.n > parsedRight.n ? 1 : -1;
148
- }
149
- //#endregion
150
- //#region ../release/dist/intent.js
151
- const releaseRecordOwner = "elmera-release";
152
- /** Asset name of the recorded archive on its GitHub draft release. */
153
- const releaseArchiveName = "release.tgz";
154
- const canaryRecordPrefix = "canary-";
155
- const IntentDocument = Schema.Struct({
156
- schema: Schema.Literal(1),
157
- owner: Schema.optionalKey(Schema.Literal(releaseRecordOwner)),
158
- channel: Schema.Literals(["stable", "canary"]),
159
- version: Schema.String,
160
- commit: Schema.String
161
- });
162
- function isCommit(value) {
163
- return /^[a-f0-9]{40}$/.test(value);
164
- }
165
- function assertCommit(commit) {
166
- if (!isCommit(commit)) throw new Error(`Expected a full commit SHA; received ${commit}`);
167
- return commit;
168
- }
169
- /** Record tag for a canary release of `commit`. */
170
- function canaryRecordTag(commit) {
171
- return `${canaryRecordPrefix}${commit}`;
172
- }
173
- function releaseTag(intent) {
174
- return intent.channel === "stable" ? `v${intent.version}` : canaryRecordTag(intent.commit);
175
- }
176
- function isReleaseTag(tag) {
177
- if (tag.startsWith("v")) return isStableReleaseVersion(tag.slice(1));
178
- return tag.startsWith(canaryRecordPrefix) && isCommit(tag.slice(7));
179
- }
180
- function assertReleaseTag(tag) {
181
- if (!isReleaseTag(tag)) throw new Error("Expected a stable or canary release record tag");
182
- return tag;
183
- }
184
- function parseIntent(text) {
185
- const value = decodeJson(text, IntentDocument, "release intent");
186
- if (value.channel === "stable") assertStableReleaseVersion(value.version);
187
- else assertCanaryReleaseVersion(value.version);
188
- return {
189
- channel: value.channel,
190
- version: value.version,
191
- commit: assertCommit(value.commit)
192
- };
193
- }
194
- function serializeIntent(intent) {
195
- return JSON.stringify({
196
- schema: 1,
197
- owner: releaseRecordOwner,
198
- channel: intent.channel,
199
- version: intent.version,
200
- commit: intent.commit
201
- });
202
- }
203
- //#endregion
204
53
  //#region ../release/dist/archive.js
205
54
  const PackedManifest = Schema.Struct({
206
55
  name: Schema.String,
@@ -210,6 +59,8 @@ const PackedManifest = Schema.Struct({
210
59
  channel: Schema.Literals(["canary", "stable"])
211
60
  })
212
61
  });
62
+ /** Scratch filename inside the scoped temp directory; unrelated to the record's asset name. */
63
+ const scratchArchiveName = "archive.tgz";
213
64
  /** Temporary directory removed when the surrounding Effect scope closes. Process kill is not covered. */
214
65
  function scratchDirectory() {
215
66
  return Effect.acquireRelease(lift(() => mkdtempSync(resolve(tmpdir(), "elmera-release-"))), (directory) => Effect.sync(() => rmSync(directory, {
@@ -225,7 +76,7 @@ function verifyReleaseArchive(intent, bytes, packageName) {
225
76
  return Effect.gen(function* () {
226
77
  const directory = yield* scratchDirectory();
227
78
  return yield* lift(() => {
228
- const archive = resolve(directory, releaseArchiveName);
79
+ const archive = resolve(directory, scratchArchiveName);
229
80
  writeFileSync(archive, bytes);
230
81
  const manifest = decodeJson(execFileSync("tar", [
231
82
  "-xOzf",
@@ -356,6 +207,103 @@ function createGitHubClient(environment) {
356
207
  };
357
208
  }
358
209
  //#endregion
210
+ //#region ../release/dist/version.js
211
+ const numericIdentifier = /^(?:0|[1-9]\d*)$/;
212
+ const canaryMarker = "-canary.";
213
+ function isNumericIdentifier(value) {
214
+ return numericIdentifier.test(value);
215
+ }
216
+ function stableComponents(version) {
217
+ const [major, minor, patch, ...rest] = version.split(".");
218
+ if (major === void 0 || minor === void 0 || patch === void 0 || rest.length !== 0) return;
219
+ if (!isNumericIdentifier(major) || !isNumericIdentifier(minor) || !isNumericIdentifier(patch)) return;
220
+ return [
221
+ major,
222
+ minor,
223
+ patch
224
+ ];
225
+ }
226
+ function canaryComponents(version) {
227
+ const marker = version.indexOf(canaryMarker);
228
+ if (marker === -1) return void 0;
229
+ const base = version.slice(0, marker);
230
+ const suffix = version.slice(marker + 8);
231
+ if (stableComponents(base) === void 0 || !isNumericIdentifier(suffix)) return void 0;
232
+ return {
233
+ base,
234
+ suffix
235
+ };
236
+ }
237
+ function isStableReleaseVersion(version) {
238
+ return stableComponents(version) !== void 0;
239
+ }
240
+ function isCanaryReleaseVersion(version) {
241
+ return canaryComponents(version) !== void 0;
242
+ }
243
+ function isSupportedReleaseVersion(version) {
244
+ return isStableReleaseVersion(version) || isCanaryReleaseVersion(version);
245
+ }
246
+ function assertReleaseVersion(version) {
247
+ if (!isSupportedReleaseVersion(version)) throw new Error(`Unsupported release version ${version}; expected x.y.z or x.y.z-canary.N without leading zeros`);
248
+ return version;
249
+ }
250
+ function assertCanaryReleaseVersion(version) {
251
+ assertReleaseVersion(version);
252
+ if (!isCanaryReleaseVersion(version)) throw new Error(`Canary publication requires x.y.z-canary.N; received ${version}`);
253
+ return version;
254
+ }
255
+ function assertStableReleaseVersion(version) {
256
+ if (!isStableReleaseVersion(version)) throw new Error(`Expected a stable version; received ${version}`);
257
+ return version;
258
+ }
259
+ function parseStableVersion(version) {
260
+ const components = stableComponents(version);
261
+ if (components === void 0) throw new Error(`Expected a stable version; received ${version}`);
262
+ const [major, minor, patch] = components;
263
+ return {
264
+ major: BigInt(major),
265
+ minor: BigInt(minor),
266
+ patch: BigInt(patch)
267
+ };
268
+ }
269
+ function parseCanaryVersion(version) {
270
+ const components = canaryComponents(version);
271
+ if (components === void 0) throw new Error(`Canary publication requires x.y.z-canary.N; received ${version}`);
272
+ return {
273
+ base: components.base,
274
+ n: BigInt(components.suffix)
275
+ };
276
+ }
277
+ function formatStableVersion(version) {
278
+ return `${version.major}.${version.minor}.${version.patch}`;
279
+ }
280
+ function formatCanaryVersion(version) {
281
+ return `${version.base}-canary.${version.n}`;
282
+ }
283
+ function compareParsedStableVersions(left, right) {
284
+ if (left.major !== right.major) return left.major > right.major ? 1 : -1;
285
+ if (left.minor !== right.minor) return left.minor > right.minor ? 1 : -1;
286
+ if (left.patch !== right.patch) return left.patch > right.patch ? 1 : -1;
287
+ return 0;
288
+ }
289
+ function compareStableVersions(left, right) {
290
+ return compareParsedStableVersions(parseStableVersion(left), parseStableVersion(right));
291
+ }
292
+ function nextPatchVersion(version) {
293
+ const parsed = parseStableVersion(version);
294
+ return formatStableVersion({
295
+ ...parsed,
296
+ patch: parsed.patch + 1n
297
+ });
298
+ }
299
+ function compareCanaryVersions(left, right) {
300
+ const parsedLeft = parseCanaryVersion(left);
301
+ const parsedRight = parseCanaryVersion(right);
302
+ const baseOrder = compareStableVersions(parsedLeft.base, parsedRight.base);
303
+ if (baseOrder !== 0) return baseOrder;
304
+ return parsedLeft.n === parsedRight.n ? 0 : parsedLeft.n > parsedRight.n ? 1 : -1;
305
+ }
306
+ //#endregion
359
307
  //#region ../release/dist/gate.js
360
308
  /** Reads the checked-out manifest's version and requires it to be a stable release version. */
361
309
  function readStableVersion(packageDirectory) {
@@ -393,6 +341,15 @@ function createStableReleaseGate(client, root, packageDirectory, trackedBranch)
393
341
  });
394
342
  }
395
343
  //#endregion
344
+ //#region ../release/dist/intent.js
345
+ function isCommit(value) {
346
+ return /^[a-f0-9]{40}$/.test(value);
347
+ }
348
+ function assertCommit(commit) {
349
+ if (!isCommit(commit)) throw new Error(`Expected a full commit SHA; received ${commit}`);
350
+ return commit;
351
+ }
352
+ //#endregion
396
353
  //#region ../release/dist/git.js
397
354
  function git(cwd, args) {
398
355
  return execFileSync("git", args, {
@@ -535,25 +492,23 @@ function trackedBranchOf(baseBranch) {
535
492
  /**
536
493
  * Asks Changesets which releases the pending changesets in `checkoutRoot` would produce.
537
494
  *
538
- * Two properties of the pinned CLI are load-bearing here. It writes `--output` with
539
- * `path.join(cwd, output)`, so the path must stay relative to the directory the CLI runs in; an
540
- * absolute path is concatenated onto that directory instead. It also resolves the configured
541
- * `baseBranch` through `git merge-base`, which is why `.changeset/config.json` names
542
- * `origin/<branch>` — the publisher runs in a detached checkout of one commit, where a bare branch
543
- * name does not resolve. Passing `--since` is not a substitute: it also filters out every changeset
544
- * added before that ref, which would silently plan the wrong version.
495
+ * The load-bearing property of the pinned CLI is that it resolves the configured `baseBranch`
496
+ * through `git merge-base`, which is why `.changeset/config.json` names `origin/<branch>` — the
497
+ * publisher runs in a detached checkout of one commit, where a bare branch name does not resolve.
498
+ * Passing `--since` is not a substitute: it also filters out every changeset added before that ref,
499
+ * which would silently plan the wrong version.
545
500
  *
546
501
  * The CLI binary is resolved from the consuming checkout, never from this package's location.
547
502
  */
548
503
  function readReleasePlan(checkoutRoot) {
549
504
  const planPath = resolve(checkoutRoot, planFileName);
550
- mkdirSync(resolve(checkoutRoot, ".artifacts"), { recursive: true });
505
+ mkdirSync(dirname(planPath), { recursive: true });
551
506
  try {
552
507
  execFileSync(process.execPath, [
553
508
  changesetBin(checkoutRoot),
554
509
  "status",
555
510
  "--output",
556
- planFileName
511
+ planPath
557
512
  ], {
558
513
  cwd: checkoutRoot,
559
514
  stdio: "pipe"
@@ -637,19 +592,25 @@ function canarySupersession(commit, base, registry, isAncestor, recordedVersion)
637
592
  if (highestStable !== void 0 && compareStableVersions(highestStable, base) >= 0) return "stable-superseded";
638
593
  return "owned";
639
594
  }
640
- /** Whether a fresh canary may be cut for this commit, or which published release already covers it. */
641
- function canaryEligibility(target, registry, isAncestor) {
642
- if (compareStableVersions(target.base, target.current) <= 0) throw new Error("The planned version must advance the stable version");
643
- return canarySupersession(target.commit, target.base, registry, isAncestor);
595
+ const skipReasons = {
596
+ "canary-superseded": "Skipping a commit superseded by a published canary",
597
+ "stable-superseded": "Skipping a commit superseded by a stable release",
598
+ "regressed-base": "Skipping a commit superseded by a canary on a newer base"
599
+ };
600
+ function skip(kind) {
601
+ return {
602
+ skip: kind,
603
+ reason: skipReasons[kind]
604
+ };
644
605
  }
645
606
  /**
646
- * Allocates the next canary number for `base`, or reports `undefined` when a published or reserved
647
- * canary already belongs to a newer base. A regressed base skips; it never blocks publication.
607
+ * Numbers the next canary for `base`, or reports `undefined` when a published or reserved canary
608
+ * already belongs to a newer base. A regressed base skips; it never blocks publication.
648
609
  */
649
- function allocateCanary(base, versions) {
610
+ function nextCanaryVersion(base, taken) {
650
611
  parseStableVersion(base);
651
612
  let highest = -1n;
652
- for (const version of versions) {
613
+ for (const version of taken) {
653
614
  if (!isCanaryReleaseVersion(version)) continue;
654
615
  const candidate = parseCanaryVersion(version);
655
616
  if (compareStableVersions(candidate.base, base) > 0) return void 0;
@@ -660,6 +621,19 @@ function allocateCanary(base, versions) {
660
621
  n: highest + 1n
661
622
  });
662
623
  }
624
+ /**
625
+ * Decides the canary for a checked main commit. Ancestry and the planned base settle whether the
626
+ * commit still owns the channel; published and reserved versions together settle the number, so a
627
+ * reservation is taken even when npm has not seen it yet.
628
+ */
629
+ function decideCanary(target, registry, reserved, isAncestor) {
630
+ if (compareStableVersions(target.base, target.current) <= 0) throw new Error("The planned version must advance the stable version");
631
+ const status = canarySupersession(target.commit, target.base, registry, isAncestor);
632
+ if (status !== "owned") return skip(status);
633
+ const version = nextCanaryVersion(target.base, [...registry.versions.keys(), ...reserved]);
634
+ if (version === void 0) return skip("regressed-base");
635
+ return { cut: version };
636
+ }
663
637
  /** Whether npm already carries this exact archive; a same-version mismatch is fatal. */
664
638
  function npmIdentity(release, registry) {
665
639
  const existing = registry.versions.get(release.version);
@@ -762,7 +736,52 @@ function publishVerifiedRelease(release, deps) {
762
736
  });
763
737
  }
764
738
  //#endregion
765
- //#region ../release/dist/ownership.js
739
+ //#region ../release/dist/record.js
740
+ const releaseRecordOwner = "elmera-release";
741
+ /** Asset name of the recorded archive on its GitHub draft release. */
742
+ const releaseArchiveName = "release.tgz";
743
+ const canaryRecordPrefix = "canary-";
744
+ const IntentDocument = Schema.Struct({
745
+ schema: Schema.Literal(1),
746
+ owner: Schema.optionalKey(Schema.Literal(releaseRecordOwner)),
747
+ channel: Schema.Literals(["stable", "canary"]),
748
+ version: Schema.String,
749
+ commit: Schema.String
750
+ });
751
+ /** Record tag for a canary release of `commit`. */
752
+ function canaryRecordTag(commit) {
753
+ return `${canaryRecordPrefix}${commit}`;
754
+ }
755
+ function releaseTag(intent) {
756
+ return intent.channel === "stable" ? `v${intent.version}` : canaryRecordTag(intent.commit);
757
+ }
758
+ function isReleaseTag(tag) {
759
+ if (tag.startsWith("v")) return isStableReleaseVersion(tag.slice(1));
760
+ return tag.startsWith(canaryRecordPrefix) && isCommit(tag.slice(7));
761
+ }
762
+ function assertReleaseTag(tag) {
763
+ if (!isReleaseTag(tag)) throw new Error("Expected a stable or canary release record tag");
764
+ return tag;
765
+ }
766
+ function parseIntent(text) {
767
+ const value = decodeJson(text, IntentDocument, "release intent");
768
+ if (value.channel === "stable") assertStableReleaseVersion(value.version);
769
+ else assertCanaryReleaseVersion(value.version);
770
+ return {
771
+ channel: value.channel,
772
+ version: value.version,
773
+ commit: assertCommit(value.commit)
774
+ };
775
+ }
776
+ function serializeIntent(intent) {
777
+ return JSON.stringify({
778
+ schema: 1,
779
+ owner: releaseRecordOwner,
780
+ channel: intent.channel,
781
+ version: intent.version,
782
+ commit: intent.commit
783
+ });
784
+ }
766
785
  const IntentProbe = Schema.Struct({
767
786
  schema: Schema.optionalKey(Schema.Json),
768
787
  owner: Schema.optionalKey(Schema.Json)
@@ -782,6 +801,10 @@ function intentMatchingTag(body, tag) {
782
801
  function clearlyForeignIdentity(parsed) {
783
802
  return parsed !== void 0 && parsed.owner !== void 0 && parsed.owner !== "elmera-release";
784
803
  }
804
+ /**
805
+ * Ownership is recognized before intent validation (ADR 0002). An owned or legacy record with an
806
+ * unreadable body throws so it is reported damaged rather than skipped as foreign.
807
+ */
785
808
  function classifyReleaseRecord(tag, body, assetNames) {
786
809
  if (!isReleaseTag(tag)) return { kind: "ignored" };
787
810
  const parsed = tryParseBody(body);
@@ -799,17 +822,6 @@ function classifyReleaseRecord(tag, body, assetNames) {
799
822
  };
800
823
  return { kind: "foreign" };
801
824
  }
802
- //#endregion
803
- //#region ../release/dist/store.js
804
- function assertSameIntent(saved, intended) {
805
- if (saved.commit !== intended.commit || saved.version !== intended.version || saved.channel !== intended.channel) throw new Error("Release intent differs from the saved release");
806
- }
807
- function releaseBodyText(value) {
808
- return value.body ?? "";
809
- }
810
- function assetNames(value) {
811
- return value.assets.map((asset) => asset.name);
812
- }
813
825
  /** `starterAllowed` records that an empty placeholder is only legal on a draft release. */
814
826
  function classifyReleaseAsset(starterAllowed, asset) {
815
827
  if (asset === void 0) return { state: "missing" };
@@ -827,6 +839,17 @@ function classifyReleaseAsset(starterAllowed, asset) {
827
839
  id: asset.id
828
840
  };
829
841
  }
842
+ //#endregion
843
+ //#region ../release/dist/store.js
844
+ function assertSameIntent(saved, intended) {
845
+ if (saved.commit !== intended.commit || saved.version !== intended.version || saved.channel !== intended.channel) throw new Error("Release intent differs from the saved release");
846
+ }
847
+ function releaseBodyText(value) {
848
+ return value.body ?? "";
849
+ }
850
+ function assetNames(value) {
851
+ return value.assets.map((asset) => asset.name);
852
+ }
830
853
  function savedReleaseFrom(value, intent) {
831
854
  const assets = value.assets.filter((asset) => asset.name === releaseArchiveName);
832
855
  if (assets.length > 1) throw new Error("Duplicate release archives");
@@ -995,10 +1018,6 @@ function createReleaseStore(client, packageName) {
995
1018
  }
996
1019
  //#endregion
997
1020
  //#region ../release/dist/engine.js
998
- function skipReason(status) {
999
- return status === "canary-superseded" ? "Skipping a commit superseded by a published canary" : "Skipping a commit superseded by a stable release";
1000
- }
1001
- const regressedBaseSkip = "Skipping a commit superseded by a canary on a newer base";
1002
1021
  /** Reserves the record, then packs, verifies, and uploads its archive. Resuming never repacks. */
1003
1022
  function recordRelease(intent, adapter, deps) {
1004
1023
  return Effect.gen(function* () {
@@ -1041,24 +1060,19 @@ function mainReleaseIntent(commit, deps) {
1041
1060
  if (recorded !== void 0) return recorded.intent;
1042
1061
  const base = yield* deps.plannedCanaryBase(line.current);
1043
1062
  const registry = yield* deps.readRegistry();
1044
- const status = yield* lift(() => canaryEligibility({
1063
+ const reserved = yield* deps.store.reservedCanaryVersions();
1064
+ const decision = yield* lift(() => decideCanary({
1045
1065
  commit,
1046
1066
  current: line.current,
1047
1067
  base
1048
- }, registry, deps.ancestry));
1049
- if (status !== "owned") {
1050
- deps.log(skipReason(status));
1051
- return;
1052
- }
1053
- const reserved = yield* deps.store.reservedCanaryVersions();
1054
- const version = yield* lift(() => allocateCanary(base, [...registry.versions.keys(), ...reserved]));
1055
- if (version === void 0) {
1056
- deps.log(regressedBaseSkip);
1068
+ }, registry, reserved, deps.ancestry));
1069
+ if ("skip" in decision) {
1070
+ deps.log(decision.reason);
1057
1071
  return;
1058
1072
  }
1059
1073
  return {
1060
1074
  channel: "canary",
1061
- version,
1075
+ version: decision.cut,
1062
1076
  commit
1063
1077
  };
1064
1078
  });
package/package.json CHANGED
@@ -3,22 +3,22 @@
3
3
  "type": "module",
4
4
  "license": "MIT",
5
5
  "dependencies": {
6
- "effect": "4.0.0-rc.111",
6
+ "effect": "4.0.0-rc.115",
7
7
  "typescript": "7.0.2",
8
- "@oxlint/plugins": "1.78.0"
8
+ "@oxlint/plugins": "1.82.0"
9
9
  },
10
10
  "devDependencies": {
11
11
  "@types/node": "25.9.5",
12
- "vitest": "4.1.10",
12
+ "vitest": "4.1.11",
13
13
  "tsdown": "0.23.0",
14
- "@elmeragroup/typescript-config": "0.0.0",
15
14
  "@elmeragroup/api-extractor": "0.0.0",
16
- "@elmeragroup/oxlint-plugin": "0.0.0",
15
+ "@elmeragroup/typescript-config": "0.0.0",
17
16
  "@elmeragroup/oxlint-plugin-anti-slop": "0.0.0",
17
+ "@elmeragroup/api-artifacts": "0.0.0",
18
18
  "@elmeragroup/release": "0.0.0",
19
- "@elmeragroup/api-artifacts": "0.0.0"
19
+ "@elmeragroup/oxlint-plugin": "0.0.0"
20
20
  },
21
- "version": "0.2.0-canary.0",
21
+ "version": "0.2.0-canary.2",
22
22
  "exports": {
23
23
  ".": {
24
24
  "types": "./dist/index.d.mts",
@@ -69,7 +69,7 @@
69
69
  },
70
70
  "sideEffects": false,
71
71
  "elmeraRelease": {
72
- "commit": "408e0d2a54342abfc6efc9492434a6e91a0eec93",
72
+ "commit": "f71523541c8c6ca1a937804a6defa1c518b2d001",
73
73
  "channel": "canary"
74
74
  },
75
75
  "scripts": {