@metaobjectsdev/cli 1.0.0-rc.2 → 1.0.0-rc.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.
@@ -1,3 +1,4 @@
1
+ import { type OwnedComparison } from "../lib/owned-copy.js";
1
2
  /** Every ejectable name, in registry order (stable — matches `meta eject --list`). */
2
3
  export declare function ejectableNames(): string[];
3
4
  export interface EjectOptions {
@@ -29,9 +30,7 @@ export interface EjectResult {
29
30
  * green, because nothing compares an owned copy to anything. Reporting this is the
30
31
  * cheapest thing that makes that condition observable.
31
32
  */
32
- local?: "identical" | "differs" | undefined;
33
- /** Lines of the previous file that the reference does not have. Set only when it differs. */
34
- changedLines?: number | undefined;
33
+ comparison?: OwnedComparison | undefined;
35
34
  }
36
35
  /**
37
36
  * An ejected file is ordinary source in the adopter's repo, so its imports must be
@@ -1 +1 @@
1
- {"version":3,"file":"eject.d.ts","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"AA4DA,sFAAsF;AACtF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AA2CD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;sFACkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AA0BD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBvG;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2C7E;AAuDD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4F/E"}
1
+ {"version":3,"file":"eject.d.ts","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"AAcA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA+C9E,sFAAsF;AACtF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AA2CD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;sFACkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;CAC1C;AAoBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBvG;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsC7E;AAmED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4G/E"}
@@ -12,6 +12,7 @@ import * as tanstackTpl from "@metaobjectsdev/codegen-ts-tanstack";
12
12
  import { parseEjectArgs } from "../lib/args.js";
13
13
  import { log } from "../lib/log.js";
14
14
  import { declaredDependencyNames, readPackageManifest } from "../lib/package-manifest.js";
15
+ import { compareOwnedCopy } from "../lib/owned-copy.js";
15
16
  // Mirrors `OWNED_GENERATORS_DIR` in init.ts's `writeOwnedGenerators` — same directory,
16
17
  // same never-clobber-without-consent contract. Kept as its own local constant rather
17
18
  // than shared: eject is a standalone operation on ANY name, not a byproduct of init,
@@ -87,11 +88,6 @@ async function fileExists(p) {
87
88
  return false;
88
89
  }
89
90
  }
90
- /** Lines present in `a` and not in `b` — a cheap "how far apart" for a report line. */
91
- function changedLineCount(a, b) {
92
- const other = new Set(b.split("\n"));
93
- return a.split("\n").filter((l) => l.trim() !== "" && !other.has(l)).length;
94
- }
95
91
  /** The `@metaobjectsdev/*` packages an ejected template imports, read from the file
96
92
  * itself rather than from a per-name table — the template is the only thing that
97
93
  * knows, and a table would drift from it the moment a template gains an import. */
@@ -163,20 +159,16 @@ export async function ejectGenerator(opts) {
163
159
  dependencyNotes: notes,
164
160
  };
165
161
  const existing = (await fileExists(abs)) ? await readFile(abs, "utf8") : undefined;
166
- const local = existing === undefined ? undefined : existing === templateSource ? "identical" : "differs";
167
- const changedLines = local === "differs" && existing !== undefined
168
- ? changedLineCount(existing, templateSource)
169
- : undefined;
162
+ const comparison = existing === undefined ? undefined : await compareOwnedCopy(existing, templateSource);
170
163
  if (!opts.force && existing !== undefined) {
171
- return { ...common, status: "preserved", local, changedLines };
164
+ return { ...common, status: "preserved", comparison };
172
165
  }
173
166
  await mkdir(join(opts.cwd, OWNED_GENERATORS_DIR), { recursive: true });
174
167
  await writeFile(abs, templateSource, "utf8");
175
168
  return {
176
169
  ...common,
177
170
  status: existing === undefined ? "created" : "replaced",
178
- local,
179
- changedLines,
171
+ comparison,
180
172
  };
181
173
  }
182
174
  /**
@@ -210,20 +202,27 @@ async function listOutput(cwd) {
210
202
  continue;
211
203
  }
212
204
  const owned = await readFile(abs, "utf8");
213
- if (owned === ref) {
205
+ const cmp = await compareOwnedCopy(owned, ref);
206
+ if (cmp.verdict === "identical") {
214
207
  lines.push(` ${name} [owned — identical to the reference]`);
215
208
  }
209
+ else if (cmp.verdict === "reformatted") {
210
+ lines.push(` ${name} [owned — same content as the reference, your formatting]`);
211
+ }
216
212
  else {
217
213
  anyStale = true;
218
- lines.push(` ${name} [owned — DIFFERS from the reference by ` +
219
- `${changedLineCount(owned, ref)} line(s)]`);
214
+ lines.push(` ${name} [owned — DIFFERS: ${cmp.referenceOnly} line(s) behind, ` +
215
+ `${cmp.localOnly} line(s) of your own]`);
220
216
  }
221
217
  }
222
218
  lines.push("");
223
219
  }
224
220
  if (anyStale) {
225
- lines.push("A copy that DIFFERS is either your customization or upstream having moved on — " +
226
- "`meta eject <name>` prints the diff command that tells you which.");
221
+ lines.push("Both counts ignore formatting: each file is re-formatted and its lines sorted " +
222
+ "before comparing, so re-wrapping and import order never show up here.");
223
+ lines.push(" \"behind\" — lines the reference has that your copy does not. Upstream moved.");
224
+ lines.push(" \"of your own\" — lines your copy has that the reference does not. Your customization.");
225
+ lines.push("`meta eject <name>` prints the diff command that shows which lines they are.");
227
226
  lines.push("");
228
227
  }
229
228
  lines.push("Run: meta eject <name>");
@@ -253,13 +252,24 @@ export async function ejectCommand(args, cwd) {
253
252
  // question nobody has. What an owner needs to know is whether their copy still
254
253
  // matches what this CLI ships — the only way an owned generator's staleness is
255
254
  // ever observable, since no gate compares the two.
256
- if (result.local === "identical") {
255
+ if (result.comparison?.verdict === "identical") {
257
256
  log.info(`${result.path} already exists and is IDENTICAL to the ${result.packageName} ` +
258
257
  "reference template — nothing to do.");
259
258
  }
259
+ else if (result.comparison?.verdict === "reformatted") {
260
+ // Worth its own branch: this is the state a project that formats what it owns
261
+ // is in permanently, and calling it DIFFERS taught every one of them to ignore
262
+ // the line that is supposed to warn them.
263
+ log.info(`${result.path} already exists and has the SAME CONTENT as the ` +
264
+ `${result.packageName} reference template, in your own formatting — ` +
265
+ "nothing to do.");
266
+ }
260
267
  else {
261
268
  log.info(`${result.path} already exists and DIFFERS from the ${result.packageName} ` +
262
- `reference template (${result.changedLines} line(s) not in the reference) — left untouched.`);
269
+ `reference template (${result.comparison?.referenceOnly ?? 0} line(s) behind it, ` +
270
+ `${result.comparison?.localOnly ?? 0} line(s) of your own) — left untouched.`);
271
+ log.info(" Formatting is not counted: both files are re-formatted and their lines " +
272
+ "sorted before comparing, so re-wrapping and import order never show up.");
263
273
  log.info(" That difference is either YOUR customization or upstream having moved on. " +
264
274
  "See which, before deciding:");
265
275
  log.info(` diff -u node_modules/${result.packageName}/src/reference/${flags.name}.ts ${result.path}`);
@@ -273,9 +283,11 @@ export async function ejectCommand(args, cwd) {
273
283
  // destroys an adopter's customization, and the file's own header is often the
274
284
  // only record that the customization was deliberate.
275
285
  log.info(`Ejected "${flags.name}" -> ${result.path}, REPLACING the file that was there` +
276
- (result.local === "differs"
277
- ? ` and DISCARDING ${result.changedLines} line(s) it had that the reference does not.`
278
- : " (it was already identical to the reference)."));
286
+ (result.comparison?.verdict === "differs"
287
+ ? ` and DISCARDING ${result.comparison.localOnly} line(s) it had that the reference does not.`
288
+ : result.comparison?.verdict === "reformatted"
289
+ ? " (its content was already the reference's — only your formatting is gone)."
290
+ : " (it was already identical to the reference)."));
279
291
  }
280
292
  else {
281
293
  log.info(`Ejected "${flags.name}" -> ${result.path}. You own it now (ADR-0034 scaffold-and-own).`);
@@ -1 +1 @@
1
- {"version":3,"file":"eject.js","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eject.js","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,sFAAsF;AACtF,6FAA6F;AAC7F,wFAAwF;AACxF,uEAAuE;AACvE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,kCAAkC,CAAC;AAC7D,OAAO,KAAK,WAAW,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAwB,MAAM,sBAAsB,CAAC;AAE9E,uFAAuF;AACvF,qFAAqF;AACrF,qFAAqF;AACrF,uFAAuF;AACvF,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AASlD,uFAAuF;AACvF,0DAA0D;AAC1D,EAAE;AACF,uFAAuF;AACvF,uFAAuF;AACvF,wFAAwF;AACxF,uFAAuF;AACvF,oFAAoF;AACpF,wFAAwF;AACxF,oCAAoC;AACpC,MAAM,OAAO,GAAqB;IAChC;QACE,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE,OAAO,CAAC,yBAAyB;QACxC,IAAI,EAAE,OAAO,CAAC,oBAAoB;KACnC;IACD;QACE,WAAW,EAAE,kCAAkC;QAC/C,KAAK,EAAE,QAAQ,CAAC,yBAAyB;QACzC,IAAI,EAAE,QAAQ,CAAC,oBAAoB;KACpC;IACD;QACE,WAAW,EAAE,qCAAqC;QAClD,KAAK,EAAE,WAAW,CAAC,yBAAyB;QAC5C,IAAI,EAAE,WAAW,CAAC,oBAAoB;KACvC;CACF,CAAC;AAEF,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,oFAAoF;AACpF,sCAAsC;AACtC,wDAAwD;AACxD,sEAAsE;AACtE,qFAAqF;AACrF,qFAAqF;AACrF,qFAAqF;AACrF,iFAAiF;AACjF,+DAA+D;AAC/D,MAAM,gBAAgB,GAAG,8EAA8E,CAAC;AAExG;;oDAEoD;AACpD,SAAS,iBAAiB,CAAC,UAAkB,EAAE,IAAY;IACzD,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,qCAAqC,UAAU,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,cAAsB,EAAE,IAAY;IAC7D,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,wDAAwD;YACjF,yCAAyC,CAC5C,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAmCD;;oFAEoF;AACpF,SAAS,gBAAgB,CAAC,cAAsB;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,uFAAuF;IACvF,oFAAoF;IACpF,uFAAuF;IACvF,sFAAsF;IACtF,oFAAoF;IACpF,kFAAkF;IAClF,mBAAmB;IACnB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,oDAAoD,CAAC,EAAE,CAAC;QAC9F,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,GAAW,EAAE,cAAsB;IAClF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAClD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,+EAA+E;QAC/E,OAAO,CAAC,sBAAsB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,QAAQ,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,OAAO;QACL,4BAA4B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qCAAqC;YACnF,0EAA0E;QAC1E,cAAc,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;KACtE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAkB;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,CAAC,IAAI,4BAA4B,cAAc,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACxF,yDAAyD,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IACtF,MAAM,UAAU,GAAG,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,GAAG,oBAAoB,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,GAAG;QACT,UAAU;QACV,UAAU;QACV,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,eAAe,EAAE,KAAK;KACvB,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,MAAM,UAAU,GACd,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAExF,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO;QACL,GAAG,MAAM;QACT,MAAM,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;QACvD,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,UAAU,CAAC,GAAW;IACnC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;IAC5F,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,oBAAoB,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;YAC1D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;YAClE,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,WAAW,CAAC,CAAC;gBACjC,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/C,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,wCAAwC,CAAC,CAAC;YAChE,CAAC;iBAAM,IAAI,GAAG,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,4DAA4D,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,IAAI,CAAC;gBAChB,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,uBAAuB,GAAG,CAAC,aAAa,mBAAmB;oBAClE,GAAG,GAAG,CAAC,SAAS,uBAAuB,CAC1C,CAAC;YACJ,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CACR,gFAAgF;YAC9E,uEAAuE,CAC1E,CAAC;QACF,KAAK,CAAC,IAAI,CACR,uFAAuF,CACxF,CAAC;QACF,KAAK,CAAC,IAAI,CACR,2FAA2F,CAC5F,CAAC;QACF,KAAK,CAAC,IAAI,CACR,8EAA8E,CAC/E,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc,EAAE,GAAW;IAC5D,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,+EAA+E;YAC/E,+EAA+E;YAC/E,+EAA+E;YAC/E,mDAAmD;YACnD,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC/C,GAAG,CAAC,IAAI,CACN,GAAG,MAAM,CAAC,IAAI,2CAA2C,MAAM,CAAC,WAAW,GAAG;oBAC5E,qCAAqC,CACxC,CAAC;YACJ,CAAC;iBAAM,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,KAAK,aAAa,EAAE,CAAC;gBACxD,8EAA8E;gBAC9E,+EAA+E;gBAC/E,0CAA0C;gBAC1C,GAAG,CAAC,IAAI,CACN,GAAG,MAAM,CAAC,IAAI,kDAAkD;oBAC9D,GAAG,MAAM,CAAC,WAAW,gDAAgD;oBACrE,gBAAgB,CACnB,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CACN,GAAG,MAAM,CAAC,IAAI,wCAAwC,MAAM,CAAC,WAAW,GAAG;oBACzE,uBAAuB,MAAM,CAAC,UAAU,EAAE,aAAa,IAAI,CAAC,sBAAsB;oBAClF,GAAG,MAAM,CAAC,UAAU,EAAE,SAAS,IAAI,CAAC,yCAAyC,CAChF,CAAC;gBACF,GAAG,CAAC,IAAI,CACN,2EAA2E;oBACzE,yEAAyE,CAC5E,CAAC;gBACF,GAAG,CAAC,IAAI,CACN,8EAA8E;oBAC5E,6BAA6B,CAChC,CAAC;gBACF,GAAG,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,WAAW,kBAAkB,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzG,GAAG,CAAC,IAAI,CACN,iFAAiF;oBAC/E,+FAA+F;oBAC/F,gFAAgF,CACnF,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACxC,4EAA4E;YAC5E,8EAA8E;YAC9E,qDAAqD;YACrD,GAAG,CAAC,IAAI,CACN,YAAY,KAAK,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,qCAAqC;gBAC5E,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,KAAK,SAAS;oBACvC,CAAC,CAAC,mBAAmB,MAAM,CAAC,UAAU,CAAC,SAAS,8CAA8C;oBAC9F,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,KAAK,aAAa;wBAC5C,CAAC,CAAC,4EAA4E;wBAC9E,CAAC,CAAC,+CAA+C,CAAC,CACzD,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,QAAQ,MAAM,CAAC,IAAI,+CAA+C,CAAC,CAAC;QACrG,CAAC;QACD,qFAAqF;QACrF,iFAAiF;QACjF,oFAAoF;QACpF,oFAAoF;QACpF,gEAAgE;QAChE,EAAE;QACF,sFAAsF;QACtF,uFAAuF;QACvF,uFAAuF;QACvF,uFAAuF;QACvF,sEAAsE;QACtE,GAAG,CAAC,IAAI,CAAC,8BAA8B,MAAM,CAAC,UAAU,8BAA8B,CAAC,CAAC;QACxF,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACnC,GAAG,CAAC,IAAI,CACN,+BAA+B,MAAM,CAAC,WAAW,kCAAkC;YACnF,4EAA4E;YAC5E,oDAAoD,CACrD,CAAC;QACF,GAAG,CAAC,IAAI,CACN,6EAA6E;YAC7E,yDAAyD,CAC1D,CAAC;QACF,GAAG,CAAC,IAAI,CACN,UAAU,MAAM,CAAC,UAAU,wDAAwD;YACnF,gBAAgB,CACjB,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,eAAe;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ export type OwnedVerdict =
2
+ /** Byte-for-byte the reference. */
3
+ "identical"
4
+ /** Same content, different layout — a formatter ran over it, nothing else. */
5
+ | "reformatted"
6
+ /** Genuine content difference: your edits, upstream's, or both. */
7
+ | "differs";
8
+ export interface OwnedComparison {
9
+ verdict: OwnedVerdict;
10
+ /** Canonical lines the COPY has that the reference does not — your edits, and what
11
+ * `--force` would destroy. */
12
+ localOnly: number;
13
+ /** Canonical lines the REFERENCE has that the copy does not — how far behind it is. */
14
+ referenceOnly: number;
15
+ }
16
+ /** The canonical line multiset of one file, sorted. Exported for the tests that pin
17
+ * each formatter-insensitivity claim above against real reformatted input. */
18
+ export declare function canonicalLines(src: string): Promise<string[]>;
19
+ export declare function compareOwnedCopy(owned: string, reference: string): Promise<OwnedComparison>;
20
+ //# sourceMappingURL=owned-copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-copy.d.ts","sourceRoot":"","sources":["../../../src/lib/owned-copy.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,YAAY;AACtB,mCAAmC;AACjC,WAAW;AACb,8EAA8E;GAC5E,aAAa;AACf,mEAAmE;GACjE,SAAS,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB;mCAC+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC;CACvB;AAuBD;+EAC+E;AAC/E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnE;AAeD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAUjG"}
@@ -0,0 +1,107 @@
1
+ // How an OWNED generator copy compares to the reference template this CLI ships.
2
+ //
3
+ // ADR-0034 hands an adopter a file and then never speaks about it again, so `meta
4
+ // eject` and `meta eject --list` are the only places that condition is ever observable.
5
+ // The first version of this compared BYTES and counted lines the copy had that the
6
+ // reference did not. On a project that runs its own formatter over the code it owns —
7
+ // which is most of them, and it is the whole point that these are ordinary files in
8
+ // their repo — that answer is useless: every copy reads DIFFERS forever, and the count
9
+ // is dominated by re-wrapping and import sorting rather than by anything anyone wrote.
10
+ // One adopter estate had all of its owned copies reporting double-digit differences
11
+ // while being, in content, exactly the reference.
12
+ //
13
+ // So the comparison is made on a CANONICAL form instead, and the verdict grew a third
14
+ // value — `reformatted`, meaning "same content, your layout". The canonical form is
15
+ // produced by re-formatting both sides through the SAME formatter, deliberately at
16
+ // `lineWidth: 1` so every construct explodes onto its own line, then sorting those
17
+ // lines. That composition is what makes it survive each way a formatter rewrites a
18
+ // file without changing it:
19
+ //
20
+ // indentation, wrapping, quote style, semicolons → the formatter normalizes them
21
+ // trailing commas → `trailingCommas: "none"` + the
22
+ // per-line strip below (reordering
23
+ // a list moves which member is last)
24
+ // import statement AND specifier order → exploded one per line, then sorted
25
+ //
26
+ // The cost is deliberate and stated: sorting lines also makes the comparison blind to
27
+ // a pure REORDERING of real code. That is the right trade for a report line whose job
28
+ // is "have you fallen behind upstream" — a reorder with no content change is not
29
+ // staleness — and every message that carries this verdict also prints the `diff`
30
+ // command, which is not blind to anything.
31
+ //
32
+ // Fail-safe: if the formatter is unavailable or rejects the input (an adopter's copy is
33
+ // theirs and may not even parse), canonicalization degrades to trimmed raw lines. The
34
+ // verdict then reads `differs` where it might have read `reformatted` — the pre-existing
35
+ // behaviour, never a false `reformatted`.
36
+ import { Biome, Distribution } from "@biomejs/js-api";
37
+ // One instance, created lazily and shared. Cache the PROMISE so concurrent first calls
38
+ // (--list compares every owned copy) share one in-flight create rather than racing.
39
+ let _biome;
40
+ function getBiome() {
41
+ if (!_biome) {
42
+ _biome = Biome.create({ distribution: Distribution.NODE })
43
+ .then((biome) => {
44
+ biome.applyConfiguration({
45
+ formatter: { enabled: true, indentStyle: "space", indentWidth: 2, lineWidth: 1 },
46
+ javascript: { formatter: { quoteStyle: "double", semicolons: "always", trailingCommas: "none" } },
47
+ });
48
+ return biome;
49
+ })
50
+ // A comparison is a REPORT LINE. If the formatter cannot start, say less — never
51
+ // fail the command the adopter actually ran.
52
+ .catch(() => undefined);
53
+ }
54
+ return _biome;
55
+ }
56
+ /** The canonical line multiset of one file, sorted. Exported for the tests that pin
57
+ * each formatter-insensitivity claim above against real reformatted input. */
58
+ export async function canonicalLines(src) {
59
+ let text = src;
60
+ const biome = await getBiome();
61
+ if (biome !== undefined) {
62
+ try {
63
+ const result = biome.formatContent(src, { filePath: "in-memory.ts" });
64
+ if (result.diagnostics.length === 0)
65
+ text = result.content;
66
+ }
67
+ catch {
68
+ /* keep the raw text — see the fail-safe note above */
69
+ }
70
+ }
71
+ return text
72
+ .split("\n")
73
+ // The trailing-comma strip is per LINE and only meaningful because every construct
74
+ // is already on its own line: reordering an import list changes which specifier is
75
+ // last, and only the last one lacks a comma.
76
+ .map((l) => l.trim().replace(/,$/, ""))
77
+ .filter((l) => l !== "")
78
+ .sort();
79
+ }
80
+ /** How many members of `a` are not in `b`, counting duplicates. */
81
+ function countMissing(a, b) {
82
+ const remaining = new Map();
83
+ for (const l of b)
84
+ remaining.set(l, (remaining.get(l) ?? 0) + 1);
85
+ let missing = 0;
86
+ for (const l of a) {
87
+ const n = remaining.get(l) ?? 0;
88
+ if (n > 0)
89
+ remaining.set(l, n - 1);
90
+ else
91
+ missing++;
92
+ }
93
+ return missing;
94
+ }
95
+ export async function compareOwnedCopy(owned, reference) {
96
+ if (owned === reference)
97
+ return { verdict: "identical", localOnly: 0, referenceOnly: 0 };
98
+ const [a, b] = await Promise.all([canonicalLines(owned), canonicalLines(reference)]);
99
+ const localOnly = countMissing(a, b);
100
+ const referenceOnly = countMissing(b, a);
101
+ return {
102
+ verdict: localOnly === 0 && referenceOnly === 0 ? "reformatted" : "differs",
103
+ localOnly,
104
+ referenceOnly,
105
+ };
106
+ }
107
+ //# sourceMappingURL=owned-copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-copy.js","sourceRoot":"","sources":["../../../src/lib/owned-copy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/cli",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "CLI for MetaObjects: scaffold, codegen, migrate, and drift-detection commands.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -48,16 +48,18 @@
48
48
  "drift-detection"
49
49
  ],
50
50
  "dependencies": {
51
+ "@biomejs/js-api": "^0.7.0",
52
+ "@biomejs/wasm-nodejs": "^1.9.4",
51
53
  "@libsql/kysely-libsql": "^0.4.0",
52
- "@metaobjectsdev/codegen-ts": "1.0.0-rc.2",
53
- "@metaobjectsdev/codegen-ts-react": "1.0.0-rc.2",
54
- "@metaobjectsdev/codegen-ts-tanstack": "1.0.0-rc.2",
55
- "@metaobjectsdev/docs-site": "1.0.0-rc.2",
56
- "@metaobjectsdev/metadata": "1.0.0-rc.2",
57
- "@metaobjectsdev/migrate-ts": "1.0.0-rc.2",
58
- "@metaobjectsdev/render": "1.0.0-rc.2",
59
- "@metaobjectsdev/runtime-ts": "1.0.0-rc.2",
60
- "@metaobjectsdev/sdk": "1.0.0-rc.2",
54
+ "@metaobjectsdev/codegen-ts": "1.0.0-rc.3",
55
+ "@metaobjectsdev/codegen-ts-react": "1.0.0-rc.3",
56
+ "@metaobjectsdev/codegen-ts-tanstack": "1.0.0-rc.3",
57
+ "@metaobjectsdev/docs-site": "1.0.0-rc.3",
58
+ "@metaobjectsdev/metadata": "1.0.0-rc.3",
59
+ "@metaobjectsdev/migrate-ts": "1.0.0-rc.3",
60
+ "@metaobjectsdev/render": "1.0.0-rc.3",
61
+ "@metaobjectsdev/runtime-ts": "1.0.0-rc.3",
62
+ "@metaobjectsdev/sdk": "1.0.0-rc.3",
61
63
  "@toon-format/toon": "^2.3.0",
62
64
  "jiti": "^2.4.0"
63
65
  },
@@ -12,6 +12,7 @@ import * as tanstackTpl from "@metaobjectsdev/codegen-ts-tanstack";
12
12
  import { parseEjectArgs } from "../lib/args.js";
13
13
  import { log } from "../lib/log.js";
14
14
  import { declaredDependencyNames, readPackageManifest } from "../lib/package-manifest.js";
15
+ import { compareOwnedCopy, type OwnedComparison } from "../lib/owned-copy.js";
15
16
 
16
17
  // Mirrors `OWNED_GENERATORS_DIR` in init.ts's `writeOwnedGenerators` — same directory,
17
18
  // same never-clobber-without-consent contract. Kept as its own local constant rather
@@ -134,15 +135,7 @@ export interface EjectResult {
134
135
  * green, because nothing compares an owned copy to anything. Reporting this is the
135
136
  * cheapest thing that makes that condition observable.
136
137
  */
137
- local?: "identical" | "differs" | undefined;
138
- /** Lines of the previous file that the reference does not have. Set only when it differs. */
139
- changedLines?: number | undefined;
140
- }
141
-
142
- /** Lines present in `a` and not in `b` — a cheap "how far apart" for a report line. */
143
- function changedLineCount(a: string, b: string): number {
144
- const other = new Set(b.split("\n"));
145
- return a.split("\n").filter((l) => l.trim() !== "" && !other.has(l)).length;
138
+ comparison?: OwnedComparison | undefined;
146
139
  }
147
140
 
148
141
  /** The `@metaobjectsdev/*` packages an ejected template imports, read from the file
@@ -221,15 +214,11 @@ export async function ejectGenerator(opts: EjectOptions): Promise<EjectResult> {
221
214
  };
222
215
 
223
216
  const existing = (await fileExists(abs)) ? await readFile(abs, "utf8") : undefined;
224
- const local =
225
- existing === undefined ? undefined : existing === templateSource ? "identical" : "differs";
226
- const changedLines =
227
- local === "differs" && existing !== undefined
228
- ? changedLineCount(existing, templateSource)
229
- : undefined;
217
+ const comparison =
218
+ existing === undefined ? undefined : await compareOwnedCopy(existing, templateSource);
230
219
 
231
220
  if (!opts.force && existing !== undefined) {
232
- return { ...common, status: "preserved", local, changedLines };
221
+ return { ...common, status: "preserved", comparison };
233
222
  }
234
223
 
235
224
  await mkdir(join(opts.cwd, OWNED_GENERATORS_DIR), { recursive: true });
@@ -237,8 +226,7 @@ export async function ejectGenerator(opts: EjectOptions): Promise<EjectResult> {
237
226
  return {
238
227
  ...common,
239
228
  status: existing === undefined ? "created" : "replaced",
240
- local,
241
- changedLines,
229
+ comparison,
242
230
  };
243
231
  }
244
232
 
@@ -272,13 +260,16 @@ async function listOutput(cwd: string): Promise<string> {
272
260
  continue;
273
261
  }
274
262
  const owned = await readFile(abs, "utf8");
275
- if (owned === ref) {
263
+ const cmp = await compareOwnedCopy(owned, ref);
264
+ if (cmp.verdict === "identical") {
276
265
  lines.push(` ${name} [owned — identical to the reference]`);
266
+ } else if (cmp.verdict === "reformatted") {
267
+ lines.push(` ${name} [owned — same content as the reference, your formatting]`);
277
268
  } else {
278
269
  anyStale = true;
279
270
  lines.push(
280
- ` ${name} [owned — DIFFERS from the reference by ` +
281
- `${changedLineCount(owned, ref)} line(s)]`,
271
+ ` ${name} [owned — DIFFERS: ${cmp.referenceOnly} line(s) behind, ` +
272
+ `${cmp.localOnly} line(s) of your own]`,
282
273
  );
283
274
  }
284
275
  }
@@ -286,8 +277,17 @@ async function listOutput(cwd: string): Promise<string> {
286
277
  }
287
278
  if (anyStale) {
288
279
  lines.push(
289
- "A copy that DIFFERS is either your customization or upstream having moved on — " +
290
- "`meta eject <name>` prints the diff command that tells you which.",
280
+ "Both counts ignore formatting: each file is re-formatted and its lines sorted " +
281
+ "before comparing, so re-wrapping and import order never show up here.",
282
+ );
283
+ lines.push(
284
+ " \"behind\" — lines the reference has that your copy does not. Upstream moved.",
285
+ );
286
+ lines.push(
287
+ " \"of your own\" — lines your copy has that the reference does not. Your customization.",
288
+ );
289
+ lines.push(
290
+ "`meta eject <name>` prints the diff command that shows which lines they are.",
291
291
  );
292
292
  lines.push("");
293
293
  }
@@ -321,15 +321,29 @@ export async function ejectCommand(args: string[], cwd: string): Promise<number>
321
321
  // question nobody has. What an owner needs to know is whether their copy still
322
322
  // matches what this CLI ships — the only way an owned generator's staleness is
323
323
  // ever observable, since no gate compares the two.
324
- if (result.local === "identical") {
324
+ if (result.comparison?.verdict === "identical") {
325
325
  log.info(
326
326
  `${result.path} already exists and is IDENTICAL to the ${result.packageName} ` +
327
327
  "reference template — nothing to do.",
328
328
  );
329
+ } else if (result.comparison?.verdict === "reformatted") {
330
+ // Worth its own branch: this is the state a project that formats what it owns
331
+ // is in permanently, and calling it DIFFERS taught every one of them to ignore
332
+ // the line that is supposed to warn them.
333
+ log.info(
334
+ `${result.path} already exists and has the SAME CONTENT as the ` +
335
+ `${result.packageName} reference template, in your own formatting — ` +
336
+ "nothing to do.",
337
+ );
329
338
  } else {
330
339
  log.info(
331
340
  `${result.path} already exists and DIFFERS from the ${result.packageName} ` +
332
- `reference template (${result.changedLines} line(s) not in the reference) — left untouched.`,
341
+ `reference template (${result.comparison?.referenceOnly ?? 0} line(s) behind it, ` +
342
+ `${result.comparison?.localOnly ?? 0} line(s) of your own) — left untouched.`,
343
+ );
344
+ log.info(
345
+ " Formatting is not counted: both files are re-formatted and their lines " +
346
+ "sorted before comparing, so re-wrapping and import order never show up.",
333
347
  );
334
348
  log.info(
335
349
  " That difference is either YOUR customization or upstream having moved on. " +
@@ -348,9 +362,11 @@ export async function ejectCommand(args: string[], cwd: string): Promise<number>
348
362
  // only record that the customization was deliberate.
349
363
  log.info(
350
364
  `Ejected "${flags.name}" -> ${result.path}, REPLACING the file that was there` +
351
- (result.local === "differs"
352
- ? ` and DISCARDING ${result.changedLines} line(s) it had that the reference does not.`
353
- : " (it was already identical to the reference)."),
365
+ (result.comparison?.verdict === "differs"
366
+ ? ` and DISCARDING ${result.comparison.localOnly} line(s) it had that the reference does not.`
367
+ : result.comparison?.verdict === "reformatted"
368
+ ? " (its content was already the reference's — only your formatting is gone)."
369
+ : " (it was already identical to the reference)."),
354
370
  );
355
371
  } else {
356
372
  log.info(`Ejected "${flags.name}" -> ${result.path}. You own it now (ADR-0034 scaffold-and-own).`);
@@ -0,0 +1,122 @@
1
+ // How an OWNED generator copy compares to the reference template this CLI ships.
2
+ //
3
+ // ADR-0034 hands an adopter a file and then never speaks about it again, so `meta
4
+ // eject` and `meta eject --list` are the only places that condition is ever observable.
5
+ // The first version of this compared BYTES and counted lines the copy had that the
6
+ // reference did not. On a project that runs its own formatter over the code it owns —
7
+ // which is most of them, and it is the whole point that these are ordinary files in
8
+ // their repo — that answer is useless: every copy reads DIFFERS forever, and the count
9
+ // is dominated by re-wrapping and import sorting rather than by anything anyone wrote.
10
+ // One adopter estate had all of its owned copies reporting double-digit differences
11
+ // while being, in content, exactly the reference.
12
+ //
13
+ // So the comparison is made on a CANONICAL form instead, and the verdict grew a third
14
+ // value — `reformatted`, meaning "same content, your layout". The canonical form is
15
+ // produced by re-formatting both sides through the SAME formatter, deliberately at
16
+ // `lineWidth: 1` so every construct explodes onto its own line, then sorting those
17
+ // lines. That composition is what makes it survive each way a formatter rewrites a
18
+ // file without changing it:
19
+ //
20
+ // indentation, wrapping, quote style, semicolons → the formatter normalizes them
21
+ // trailing commas → `trailingCommas: "none"` + the
22
+ // per-line strip below (reordering
23
+ // a list moves which member is last)
24
+ // import statement AND specifier order → exploded one per line, then sorted
25
+ //
26
+ // The cost is deliberate and stated: sorting lines also makes the comparison blind to
27
+ // a pure REORDERING of real code. That is the right trade for a report line whose job
28
+ // is "have you fallen behind upstream" — a reorder with no content change is not
29
+ // staleness — and every message that carries this verdict also prints the `diff`
30
+ // command, which is not blind to anything.
31
+ //
32
+ // Fail-safe: if the formatter is unavailable or rejects the input (an adopter's copy is
33
+ // theirs and may not even parse), canonicalization degrades to trimmed raw lines. The
34
+ // verdict then reads `differs` where it might have read `reformatted` — the pre-existing
35
+ // behaviour, never a false `reformatted`.
36
+ import { Biome, Distribution } from "@biomejs/js-api";
37
+
38
+ export type OwnedVerdict =
39
+ /** Byte-for-byte the reference. */
40
+ | "identical"
41
+ /** Same content, different layout — a formatter ran over it, nothing else. */
42
+ | "reformatted"
43
+ /** Genuine content difference: your edits, upstream's, or both. */
44
+ | "differs";
45
+
46
+ export interface OwnedComparison {
47
+ verdict: OwnedVerdict;
48
+ /** Canonical lines the COPY has that the reference does not — your edits, and what
49
+ * `--force` would destroy. */
50
+ localOnly: number;
51
+ /** Canonical lines the REFERENCE has that the copy does not — how far behind it is. */
52
+ referenceOnly: number;
53
+ }
54
+
55
+ // One instance, created lazily and shared. Cache the PROMISE so concurrent first calls
56
+ // (--list compares every owned copy) share one in-flight create rather than racing.
57
+ let _biome: Promise<Biome | undefined> | undefined;
58
+
59
+ function getBiome(): Promise<Biome | undefined> {
60
+ if (!_biome) {
61
+ _biome = Biome.create({ distribution: Distribution.NODE })
62
+ .then((biome) => {
63
+ biome.applyConfiguration({
64
+ formatter: { enabled: true, indentStyle: "space", indentWidth: 2, lineWidth: 1 },
65
+ javascript: { formatter: { quoteStyle: "double", semicolons: "always", trailingCommas: "none" } },
66
+ });
67
+ return biome;
68
+ })
69
+ // A comparison is a REPORT LINE. If the formatter cannot start, say less — never
70
+ // fail the command the adopter actually ran.
71
+ .catch(() => undefined);
72
+ }
73
+ return _biome;
74
+ }
75
+
76
+ /** The canonical line multiset of one file, sorted. Exported for the tests that pin
77
+ * each formatter-insensitivity claim above against real reformatted input. */
78
+ export async function canonicalLines(src: string): Promise<string[]> {
79
+ let text = src;
80
+ const biome = await getBiome();
81
+ if (biome !== undefined) {
82
+ try {
83
+ const result = biome.formatContent(src, { filePath: "in-memory.ts" });
84
+ if (result.diagnostics.length === 0) text = result.content;
85
+ } catch {
86
+ /* keep the raw text — see the fail-safe note above */
87
+ }
88
+ }
89
+ return text
90
+ .split("\n")
91
+ // The trailing-comma strip is per LINE and only meaningful because every construct
92
+ // is already on its own line: reordering an import list changes which specifier is
93
+ // last, and only the last one lacks a comma.
94
+ .map((l) => l.trim().replace(/,$/, ""))
95
+ .filter((l) => l !== "")
96
+ .sort();
97
+ }
98
+
99
+ /** How many members of `a` are not in `b`, counting duplicates. */
100
+ function countMissing(a: string[], b: string[]): number {
101
+ const remaining = new Map<string, number>();
102
+ for (const l of b) remaining.set(l, (remaining.get(l) ?? 0) + 1);
103
+ let missing = 0;
104
+ for (const l of a) {
105
+ const n = remaining.get(l) ?? 0;
106
+ if (n > 0) remaining.set(l, n - 1);
107
+ else missing++;
108
+ }
109
+ return missing;
110
+ }
111
+
112
+ export async function compareOwnedCopy(owned: string, reference: string): Promise<OwnedComparison> {
113
+ if (owned === reference) return { verdict: "identical", localOnly: 0, referenceOnly: 0 };
114
+ const [a, b] = await Promise.all([canonicalLines(owned), canonicalLines(reference)]);
115
+ const localOnly = countMissing(a, b);
116
+ const referenceOnly = countMissing(b, a);
117
+ return {
118
+ verdict: localOnly === 0 && referenceOnly === 0 ? "reformatted" : "differs",
119
+ localOnly,
120
+ referenceOnly,
121
+ };
122
+ }