@biffo/cli 0.244.2 → 0.244.3

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/index.js CHANGED
@@ -2709,11 +2709,15 @@ function applyMigrationCarry(instanceDir, plan) {
2709
2709
  const written = [];
2710
2710
  for (const e of plan.entries) {
2711
2711
  const abs = join7(instanceDir, e.path);
2712
- if (existsSync7(abs)) {
2713
- throw new Error(`Refusing to overwrite an existing migration: ${e.path}`);
2714
- }
2715
2712
  mkdirSync2(dirname4(abs), { recursive: true });
2716
- writeFileSync3(abs, e.content);
2713
+ try {
2714
+ writeFileSync3(abs, e.content, { flag: "wx" });
2715
+ } catch (err) {
2716
+ if (err.code === "EEXIST") {
2717
+ throw new Error(`Refusing to overwrite an existing migration: ${e.path}`);
2718
+ }
2719
+ throw err;
2720
+ }
2717
2721
  written.push(e.path);
2718
2722
  }
2719
2723
  return written;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.244.2",
3
+ "version": "0.244.3",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -147,6 +147,14 @@ export function slugify(text) {
147
147
  * Refuses to overwrite an existing file: a collision means the slug needs to
148
148
  * be more specific, not that the earlier entry should be silently replaced.
149
149
  *
150
+ * The refusal is an atomic `wx` create, not an `existsSync` check followed by
151
+ * a write (#1222). This corpus has concurrent writers BY DESIGN — several
152
+ * agent sessions run against this estate at once — so the window between a
153
+ * check and a write is not theoretical here: two sessions writing the same
154
+ * `date-slug` is the exact case the guard exists for, and the check-then-write
155
+ * form lost the earlier entry rather than refusing. `EEXIST` is translated
156
+ * back into the same message, so nothing else changes.
157
+ *
150
158
  * @param {Record<string, any>} row
151
159
  * @param {{dir?: string, date?: string, slug?: string}} [opts]
152
160
  * @returns {string} the path written, relative to `opts.dir`'s base
@@ -158,10 +166,14 @@ export function writeEvidenceEntry(row, opts = {}) {
158
166
  mkdirSync(dir, { recursive: true })
159
167
  const file = `${date}-${slug || 'entry'}.json`
160
168
  const path = join(dir, file)
161
- if (existsSync(path)) {
162
- throw new Error(`${path} already exists choose a more specific slug or date`)
169
+ try {
170
+ writeFileSync(path, `${JSON.stringify({ ...row, date }, null, 2)}\n`, { flag: 'wx' })
171
+ } catch (err) {
172
+ if (err && err.code === 'EEXIST') {
173
+ throw new Error(`${path} already exists — choose a more specific slug or date`)
174
+ }
175
+ throw err
163
176
  }
164
- writeFileSync(path, `${JSON.stringify({ ...row, date }, null, 2)}\n`)
165
177
  return path
166
178
  }
167
179