@animus-ui/extract 0.1.7 → 0.1.8

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 +1 @@
1
- {"version":3,"file":"correlate-external-tokens.d.ts","sourceRoot":"","sources":["../pipeline/correlate-external-tokens.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAejE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,wBAAwB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA+D3B;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,WAAW,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IAC9C,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,yDAAyD;IACzD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACxC,GAAG,MAAM,EAAE,CAyBX;AAWD;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,WAAW,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IAC9C,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,wBAAwB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,IAAI,CAwBP"}
1
+ {"version":3,"file":"correlate-external-tokens.d.ts","sourceRoot":"","sources":["../pipeline/correlate-external-tokens.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAejE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,wBAAwB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA+D3B;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,WAAW,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IAC9C,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,yDAAyD;IACzD,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACxC,GAAG,MAAM,EAAE,CAyBX;AAWD;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,WAAW,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IAC9C,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,wBAAwB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpD,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,IAAI,CAwBP"}
@@ -12,6 +12,16 @@ export declare function findPackageRoot(absEntryPath: string): string;
12
12
  * repo path containing 'dist') must still have its sources discovered.
13
13
  */
14
14
  export declare const PACKAGE_SRC_EXCLUDES: string[];
15
+ /** True when a PACKAGE-RELATIVE path matches a package-source exclusion
16
+ * fragment (the "within the package" filter — see PACKAGE_SRC_EXCLUDES). */
17
+ export declare function isExcludedPackageRelativePath(rel: string): boolean;
18
+ /**
19
+ * THE package-source walk (guardrail G1 — one policy): shared discovery with
20
+ * no consumer patterns, then exclusion by package-relative path so fragments
21
+ * in the package's own location can't blank out its sources. Used by the
22
+ * collector, hosts' dirty-root rewalks, and watch-path classification alike.
23
+ */
24
+ export declare function walkPackageSources(packageDir: string, extensionsSet: ReadonlySet<string>): string[];
15
25
  /**
16
26
  * What one declared include specifier produced, so callers can tell a package
17
27
  * that contributed sources apart from one that silently contributed nothing.
@@ -38,6 +48,14 @@ export interface ExternalPackageOutcome {
38
48
  */
39
49
  fileCount: number;
40
50
  }
51
+ /**
52
+ * Resolve an absolute-path specifier (a relative `includes` entry already
53
+ * resolved against the system file) without a bundler: the path itself when it
54
+ * is a file, otherwise the extension and directory-index candidates built from
55
+ * the caller's extension set. Used only as a fallback — a bundler resolver that
56
+ * answers first still wins, since it also knows aliases and `.js`→`.ts` mapping.
57
+ */
58
+ export declare function resolveAbsolutePathSpecifier(absSpecifier: string, extensionsSet: ReadonlySet<string>): string | null;
41
59
  export interface CollectedExternalPackages {
42
60
  /** New file entries (rootDir-relative, preprocessed) for the analysis set. */
43
61
  entries: Array<{
@@ -48,10 +66,20 @@ export interface CollectedExternalPackages {
48
66
  packageMap: Record<string, string>;
49
67
  /** specifier → absolute src/index.ts path, only for packages with one. */
50
68
  sourceEntries: Map<string, string>;
69
+ /** specifier → absolute entry to scan for branded `Keyframes` collections —
70
+ * one per admitted specifier, whatever the package's shape: the redirected
71
+ * source entry when src/ serves it, the resolved (dist) entry otherwise.
72
+ * Keyed separately from `sourceEntries` because that map doubles as the
73
+ * hosts' module-resolution redirect and stays src-only by contract. */
74
+ keyframesScanEntries: Map<string, string>;
51
75
  /** Absolute directories for bundler loader allowlisting (src/ or dist entry dir). */
52
76
  packageDirs: string[];
53
- /** Absolute package dir → owning specifier (cross-source correlation). */
54
- dirOwners: Record<string, string>;
77
+ /** Absolute package dir → EVERY declared specifier that claimed it, in
78
+ * declaration order (set-valued ownership — openspec:
79
+ * external-source-watch-ingestion, design D2). The first-wins
80
+ * single-value view correlation consumers key on derives via
81
+ * `firstOwners`. */
82
+ dirOwnerSets: Record<string, string[]>;
55
83
  /** rootDir-relative file path → owning specifier, for files THIS collection
56
84
  * pushed (first-contributing specifier wins; files the caller's own set
57
85
  * already supplied stay unattributed — they are consumer-owned). */
@@ -95,7 +123,27 @@ export declare function collectExternalPackageSources(opts: {
95
123
  } | null>;
96
124
  /** Called when a discovered file cannot be read; the file is skipped. */
97
125
  onUnreadable: (relPath: string, error: unknown) => void;
126
+ /**
127
+ * Called once per specifier immediately after its package dir is derived
128
+ * and BEFORE that package's sources are walked (openspec:
129
+ * external-source-watch-ingestion, design D4 — a host can open its
130
+ * watcher with no blind gap between scan and watch).
131
+ */
132
+ onPackageResolved?: (specifier: string, packageDir: string) => void;
98
133
  }): Promise<CollectedExternalPackages>;
134
+ /** First-declared specifier per package dir — the single-value ownership
135
+ * view correlation consumers key on, derived from `dirOwnerSets`. */
136
+ export declare function firstOwners(dirOwnerSets: Record<string, string[]>): Record<string, string>;
137
+ /**
138
+ * Excise a set of rejected specifiers from a collection result ATOMICALLY
139
+ * (openspec: external-source-watch-ingestion, design D5): the returned copy
140
+ * carries no entries, package-map targets, source entries, package dirs, or
141
+ * ownership for the rejected packages — a package dir is removed only when
142
+ * EVERY specifier that claimed it is rejected (a dir-level rejection, such
143
+ * as the cross-volume gate, always rejects them together). Outcome records
144
+ * are reporting inputs, not membership, and pass through untouched.
145
+ */
146
+ export declare function excludeCollectedPackages(collected: CollectedExternalPackages, rejectedSpecifiers: ReadonlySet<string>, rootDir: string): CollectedExternalPackages;
99
147
  /**
100
148
  * Extract external DS package names from inheritance declarations in the
101
149
  * system file.
@@ -1 +1 @@
1
- {"version":3,"file":"discover-packages.d.ts","sourceRoot":"","sources":["../pipeline/discover-packages.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAKhC,CAAC;AAWF;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,OAAO,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,YAAY,CAAC;IAC9D;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAqFD,MAAM,WAAW,yBAAyB;IACxC,8EAA8E;IAC9E,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0EAA0E;IAC1E,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,qFAAqF;IACrF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;yEAEqE;IACrE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,+DAA+D;IAC/D,QAAQ,EAAE,sBAAsB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iFAAiF;IACjF,gBAAgB,EAAE,CAChB,SAAS,EAAE,MAAM,KACd,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC;;;OAGG;IACH,cAAc,EAAE,CACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACzD,yEAAyE;IACzE,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzD,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAyMrC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,sBAAsB,EAAE,GACjC,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,sBAAsB,EAAE,GACjC,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAoN1E"}
1
+ {"version":3,"file":"discover-packages.d.ts","sourceRoot":"","sources":["../pipeline/discover-packages.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAKhC,CAAC;AAEF;6EAC6E;AAC7E,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,GACjC,MAAM,EAAE,CAIV;AAWD;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,OAAO,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,YAAY,CAAC;IAC9D;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,GACjC,MAAM,GAAG,IAAI,CAOf;AAyDD,MAAM,WAAW,yBAAyB;IACxC,8EAA8E;IAC9E,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0EAA0E;IAC1E,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;;;4EAIwE;IACxE,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,qFAAqF;IACrF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;yBAIqB;IACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC;;yEAEqE;IACrE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,+DAA+D;IAC/D,QAAQ,EAAE,sBAAsB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iFAAiF;IACjF,gBAAgB,EAAE,CAChB,SAAS,EAAE,MAAM,KACd,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC;;;OAGG;IACH,cAAc,EAAE,CACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACzD,yEAAyE;IACzE,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA+MrC;AAED;sEACsE;AACtE,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,yBAAyB,EACpC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,EACvC,OAAO,EAAE,MAAM,GACd,yBAAyB,CAsD3B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,sBAAsB,EAAE,GACjC,MAAM,GAAG,IAAI,CAMf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,sBAAsB,EAAE,GACjC,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAoN1E"}
package/dist/index.cjs CHANGED
@@ -24,13 +24,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  let crypto = require("crypto");
25
25
  let fs = require("fs");
26
26
  let path = require("path");
27
+ let node_fs = require("node:fs");
28
+ let node_path = require("node:path");
29
+ node_path = __toESM(node_path);
27
30
  let module$1 = require("module");
28
31
  let browserslist = require("browserslist");
29
32
  browserslist = __toESM(browserslist);
30
33
  let lightningcss = require("lightningcss");
31
34
  let _animus_ui_properties = require("@animus-ui/properties");
32
- let node_fs = require("node:fs");
33
- let node_path = require("node:path");
34
35
  //#region pipeline/assemble-stylesheet.ts
35
36
  /**
36
37
  * The 7 Animus cascade layers. Always prefixed with `anm-` to avoid
@@ -337,6 +338,126 @@ function discoverFiles(dir, rootDir, excludePatterns, extensionsSet) {
337
338
  return results;
338
339
  }
339
340
  //#endregion
341
+ //#region pipeline/source-identity.ts
342
+ /**
343
+ * SourceId derivation authority + allowlist membership (openspec:
344
+ * external-source-watch-ingestion, design D1/D2/D5).
345
+ *
346
+ * One shared derivation produces the canonical source identity consumed by
347
+ * discovery, watch ingestion, ownership, deletion pruning, and diagnostics
348
+ * — raw event paths are lookup INPUTS only, so event spelling (symlink
349
+ * alias vs canonical, lexical vs realpath) can never fork identity.
350
+ *
351
+ * The containment and volume helpers are pure and path-API-injectable so
352
+ * Windows semantics are unit-testable via `path.win32` on any host; runtime
353
+ * callers use the ambient platform implementation.
354
+ */
355
+ /**
356
+ * Structural containment: `target` is the root itself or a descendant of it,
357
+ * decided by `relative()` shape — never by string prefixing, so `/ui` can
358
+ * never claim `/ui-old`, and a cross-drive win32 target (whose relative()
359
+ * result is absolute) is never contained.
360
+ */
361
+ function isPathWithinRoot(root, target, pathApi = node_path.default) {
362
+ const rel = pathApi.relative(root, target);
363
+ return rel === "" || !pathApi.isAbsolute(rel) && rel !== ".." && !rel.startsWith(".." + pathApi.sep);
364
+ }
365
+ /**
366
+ * Cross-volume gate (design D5): two paths share a platform path root
367
+ * (win32 drive letter or UNC share; always true on posix). Compared
368
+ * case-insensitively — win32 drive letters are case-insensitive.
369
+ */
370
+ function sharesVolumeRoot(a, b, pathApi = node_path.default) {
371
+ const volumeOf = (p) => pathApi.parse(pathApi.resolve(p)).root.toLowerCase();
372
+ return volumeOf(a) === volumeOf(b);
373
+ }
374
+ function canonicalize(p) {
375
+ try {
376
+ return (0, node_fs.realpathSync)(p);
377
+ } catch {
378
+ return null;
379
+ }
380
+ }
381
+ function createSourceIdentity(rootDir) {
382
+ const normalizedRootDir = node_path.default.normalize(rootDir);
383
+ const canonicalRootDir = canonicalize(normalizedRootDir) ?? normalizedRootDir;
384
+ const roots = [];
385
+ const aliases = /* @__PURE__ */ new Map();
386
+ const owningRecord = (canonicalPath) => {
387
+ let owner = null;
388
+ for (const record of roots) {
389
+ if (!isPathWithinRoot(record.canonical, canonicalPath)) continue;
390
+ if (!owner || record.canonical.length > owner.canonical.length) owner = record;
391
+ }
392
+ return owner;
393
+ };
394
+ return {
395
+ rootDir: normalizedRootDir,
396
+ canonicalRootDir,
397
+ registerExternalRoot(root) {
398
+ const asRegistered = node_path.default.normalize(root);
399
+ const canonical = canonicalize(asRegistered) ?? asRegistered;
400
+ const existing = roots.find((record) => record.canonical === canonical);
401
+ if (existing) return existing.canonical;
402
+ roots.push({
403
+ asRegistered,
404
+ canonical
405
+ });
406
+ return canonical;
407
+ },
408
+ externalRoots() {
409
+ return roots.map((record) => record.canonical);
410
+ },
411
+ resolveSourceId(inputPath) {
412
+ const lexical = node_path.default.normalize(inputPath);
413
+ const canonical = canonicalize(lexical);
414
+ if (canonical === null) return null;
415
+ const owner = owningRecord(canonical);
416
+ const ownedBy = (record) => {
417
+ const pathInRoot = node_path.default.relative(record.canonical, canonical);
418
+ return {
419
+ sourceKey: node_path.default.relative(normalizedRootDir, node_path.default.join(record.asRegistered, pathInRoot)),
420
+ owningRoot: record.canonical,
421
+ pathInRoot
422
+ };
423
+ };
424
+ const ownerIsMoreSpecific = owner !== null && owner.canonical.length > canonicalRootDir.length;
425
+ let resolved;
426
+ if (!ownerIsMoreSpecific && isPathWithinRoot(canonicalRootDir, canonical)) {
427
+ const key = node_path.default.relative(canonicalRootDir, canonical);
428
+ resolved = {
429
+ sourceKey: key,
430
+ owningRoot: null,
431
+ pathInRoot: key
432
+ };
433
+ } else if (owner) resolved = ownedBy(owner);
434
+ else return null;
435
+ aliases.set(lexical, resolved);
436
+ aliases.set(canonical, resolved);
437
+ return resolved;
438
+ },
439
+ resolveDeletedSourceId(inputPath) {
440
+ return aliases.get(node_path.default.normalize(inputPath)) ?? null;
441
+ },
442
+ containingExternalRoot(inputPath) {
443
+ const lexical = node_path.default.normalize(inputPath);
444
+ let owner = null;
445
+ for (const record of roots) {
446
+ if (!(isPathWithinRoot(record.canonical, lexical) || isPathWithinRoot(record.asRegistered, lexical))) continue;
447
+ if (!owner || record.canonical.length > owner.canonical.length) owner = record;
448
+ }
449
+ if (owner) return owner.canonical;
450
+ const canonical = canonicalize(lexical);
451
+ if (canonical === null) return null;
452
+ for (const record of roots) {
453
+ if (!isPathWithinRoot(record.canonical, canonical)) continue;
454
+ if (!owner || record.canonical.length > owner.canonical.length) owner = record;
455
+ }
456
+ return owner?.canonical ?? null;
457
+ }
458
+ };
459
+ }
460
+ //#endregion
340
461
  //#region pipeline/discover-packages.ts
341
462
  /**
342
463
  * Walk up from a resolved package entry file to the nearest directory
@@ -361,6 +482,20 @@ const PACKAGE_SRC_EXCLUDES = [
361
482
  ".test.",
362
483
  ".spec."
363
484
  ];
485
+ /** True when a PACKAGE-RELATIVE path matches a package-source exclusion
486
+ * fragment (the "within the package" filter — see PACKAGE_SRC_EXCLUDES). */
487
+ function isExcludedPackageRelativePath(rel) {
488
+ return PACKAGE_SRC_EXCLUDES.some((pattern) => rel.includes(pattern));
489
+ }
490
+ /**
491
+ * THE package-source walk (guardrail G1 — one policy): shared discovery with
492
+ * no consumer patterns, then exclusion by package-relative path so fragments
493
+ * in the package's own location can't blank out its sources. Used by the
494
+ * collector, hosts' dirty-root rewalks, and watch-path classification alike.
495
+ */
496
+ function walkPackageSources(packageDir, extensionsSet) {
497
+ return discoverFiles(packageDir, packageDir, [], extensionsSet).filter((absPath) => !isExcludedPackageRelativePath((0, path.relative)(packageDir, absPath)));
498
+ }
364
499
  /** Exclusions for the compiled-output fallback when a package does not ship src/. */
365
500
  const PACKAGE_OUTPUT_EXCLUDES = [
366
501
  "node_modules",
@@ -369,9 +504,9 @@ const PACKAGE_OUTPUT_EXCLUDES = [
369
504
  ".d.ts",
370
505
  ".map"
371
506
  ];
372
- const isFile = (path$2) => {
507
+ const isFile = (path$3) => {
373
508
  try {
374
- return (0, fs.statSync)(path$2).isFile();
509
+ return (0, fs.statSync)(path$3).isFile();
375
510
  } catch {
376
511
  return false;
377
512
  }
@@ -399,7 +534,7 @@ function sourceEntryForSpecifier(specifier, srcDir, extensionsSet) {
399
534
  if ((0, path.isAbsolute)(specifier)) {
400
535
  const resolved = resolveAbsolutePathSpecifier(specifier, extensionsSet);
401
536
  if (!resolved) return null;
402
- return !(0, path.relative)(srcDir, resolved).startsWith("..") ? resolved : null;
537
+ return isPathWithinRoot(srcDir, resolved) ? resolved : null;
403
538
  }
404
539
  const packageName = bareSpecifierPackageName(specifier);
405
540
  return resolveAbsolutePathSpecifier((0, path.join)(srcDir, specifier.slice(packageName.length + 1) || "index"), extensionsSet);
@@ -413,7 +548,7 @@ function sourceEntryForSpecifier(specifier, srcDir, extensionsSet) {
413
548
  * file's mtime is readable. Detection only — reporting is the caller's policy.
414
549
  */
415
550
  function distEntryIsStale(absEntry, srcDir, srcFiles) {
416
- if (!(0, path.relative)(srcDir, absEntry).startsWith("..")) return false;
551
+ if (isPathWithinRoot(srcDir, absEntry)) return false;
417
552
  let distMtime;
418
553
  try {
419
554
  distMtime = (0, fs.statSync)(absEntry).mtimeMs;
@@ -445,15 +580,19 @@ function distEntryIsStale(absEntry, srcDir, srcFiles) {
445
580
  * them — any warning or gate is the caller's policy.
446
581
  */
447
582
  async function collectExternalPackageSources(opts) {
448
- const { specifiers, resolveSpecifier, rootDir, extensionsSet, hasEntry, preprocessFile, onUnreadable } = opts;
583
+ const { specifiers, resolveSpecifier, rootDir, extensionsSet, hasEntry, preprocessFile, onUnreadable, onPackageResolved } = opts;
449
584
  const entries = [];
450
585
  const pushed = /* @__PURE__ */ new Set();
451
586
  const packageMap = {};
452
587
  const sourceEntries = /* @__PURE__ */ new Map();
588
+ const keyframesScanEntries = /* @__PURE__ */ new Map();
453
589
  const packageDirs = [];
454
- const dirOwners = {};
590
+ const dirOwnerSets = {};
455
591
  const fileOwners = {};
456
592
  const outcomes = [];
593
+ const claimDir = (dir, specifier) => {
594
+ (dirOwnerSets[dir] ??= []).push(specifier);
595
+ };
457
596
  const alreadyIngested = (relPath) => hasEntry(relPath) || pushed.has(relPath);
458
597
  for (const specifier of specifiers) {
459
598
  let absEntry;
@@ -476,12 +615,14 @@ async function collectExternalPackageSources(opts) {
476
615
  let staleDist = false;
477
616
  if ((0, fs.existsSync)(srcDir)) {
478
617
  packageDirs.push(srcDir);
479
- dirOwners[srcDir] ??= specifier;
618
+ claimDir(srcDir, specifier);
619
+ onPackageResolved?.(specifier, srcDir);
480
620
  const srcEntry = sourceEntryForSpecifier(specifier, srcDir, extensionsSet);
481
621
  if (srcEntry) {
482
622
  packageMap[specifier] = (0, path.relative)(rootDir, srcEntry);
483
623
  sourceEntries.set(specifier, srcEntry);
484
624
  } else packageMap[specifier] = (0, path.relative)(rootDir, absEntry);
625
+ keyframesScanEntries.set(specifier, srcEntry ?? absEntry);
485
626
  if (!(0, path.isAbsolute)(specifier)) {
486
627
  const packageName = bareSpecifierPackageName(specifier);
487
628
  if (packageName !== specifier && !(packageName in packageMap)) {
@@ -489,13 +630,11 @@ async function collectExternalPackageSources(opts) {
489
630
  if (rootEntry) {
490
631
  packageMap[packageName] = (0, path.relative)(rootDir, rootEntry);
491
632
  sourceEntries.set(packageName, rootEntry);
633
+ keyframesScanEntries.set(packageName, rootEntry);
492
634
  }
493
635
  }
494
636
  }
495
- const pkgFiles = discoverFiles(srcDir, srcDir, [], extensionsSet).filter((absPath) => {
496
- const inPkg = (0, path.relative)(srcDir, absPath);
497
- return !PACKAGE_SRC_EXCLUDES.some((pattern) => inPkg.includes(pattern));
498
- });
637
+ const pkgFiles = walkPackageSources(srcDir, extensionsSet);
499
638
  staleDist = distEntryIsStale(absEntry, srcDir, pkgFiles);
500
639
  for (const pkgFile of pkgFiles) {
501
640
  const relPath = (0, path.relative)(rootDir, pkgFile);
@@ -523,8 +662,10 @@ async function collectExternalPackageSources(opts) {
523
662
  } else {
524
663
  const outputDir = (0, path.dirname)(absEntry);
525
664
  packageDirs.push(outputDir);
526
- dirOwners[outputDir] ??= specifier;
665
+ claimDir(outputDir, specifier);
666
+ onPackageResolved?.(specifier, outputDir);
527
667
  packageMap[specifier] = (0, path.relative)(rootDir, absEntry);
668
+ keyframesScanEntries.set(specifier, absEntry);
528
669
  const outputExtensions = new Set(extensionsSet);
529
670
  outputExtensions.add((0, path.extname)(absEntry));
530
671
  const outputFiles = discoverFiles(outputDir, outputDir, [], outputExtensions).filter((file) => {
@@ -566,12 +707,71 @@ async function collectExternalPackageSources(opts) {
566
707
  entries,
567
708
  packageMap,
568
709
  sourceEntries,
710
+ keyframesScanEntries,
569
711
  packageDirs,
570
- dirOwners,
712
+ dirOwnerSets,
571
713
  fileOwners,
572
714
  outcomes
573
715
  };
574
716
  }
717
+ /** First-declared specifier per package dir — the single-value ownership
718
+ * view correlation consumers key on, derived from `dirOwnerSets`. */
719
+ function firstOwners(dirOwnerSets) {
720
+ const owners = {};
721
+ for (const [dir, specifiers] of Object.entries(dirOwnerSets)) if (specifiers.length > 0) owners[dir] = specifiers[0];
722
+ return owners;
723
+ }
724
+ /**
725
+ * Excise a set of rejected specifiers from a collection result ATOMICALLY
726
+ * (openspec: external-source-watch-ingestion, design D5): the returned copy
727
+ * carries no entries, package-map targets, source entries, package dirs, or
728
+ * ownership for the rejected packages — a package dir is removed only when
729
+ * EVERY specifier that claimed it is rejected (a dir-level rejection, such
730
+ * as the cross-volume gate, always rejects them together). Outcome records
731
+ * are reporting inputs, not membership, and pass through untouched.
732
+ */
733
+ function excludeCollectedPackages(collected, rejectedSpecifiers, rootDir) {
734
+ if (rejectedSpecifiers.size === 0) return collected;
735
+ const rejectedDirs = Object.entries(collected.dirOwnerSets).filter(([, specs]) => specs.every((s) => rejectedSpecifiers.has(s))).map(([dir]) => dir);
736
+ const underRejectedDir = (absPath) => rejectedDirs.some((dir) => isPathWithinRoot(dir, absPath));
737
+ const targetRejected = (specifier, absTarget) => rejectedSpecifiers.has(specifier) || underRejectedDir(absTarget);
738
+ const packageMap = {};
739
+ for (const [specifier, relTarget] of Object.entries(collected.packageMap)) {
740
+ if (targetRejected(specifier, (0, path.resolve)(rootDir, relTarget))) continue;
741
+ packageMap[specifier] = relTarget;
742
+ }
743
+ const sourceEntries = /* @__PURE__ */ new Map();
744
+ for (const [specifier, absEntry] of collected.sourceEntries) {
745
+ if (targetRejected(specifier, absEntry)) continue;
746
+ sourceEntries.set(specifier, absEntry);
747
+ }
748
+ const keyframesScanEntries = /* @__PURE__ */ new Map();
749
+ for (const [specifier, absEntry] of collected.keyframesScanEntries) {
750
+ if (targetRejected(specifier, absEntry)) continue;
751
+ keyframesScanEntries.set(specifier, absEntry);
752
+ }
753
+ const dirOwnerSets = {};
754
+ for (const [dir, specs] of Object.entries(collected.dirOwnerSets)) {
755
+ const kept = specs.filter((s) => !rejectedSpecifiers.has(s));
756
+ if (kept.length === 0) continue;
757
+ dirOwnerSets[dir] = kept;
758
+ }
759
+ const fileOwners = {};
760
+ for (const [relPath, owner] of Object.entries(collected.fileOwners)) {
761
+ if (rejectedSpecifiers.has(owner)) continue;
762
+ fileOwners[relPath] = owner;
763
+ }
764
+ return {
765
+ entries: collected.entries.filter((entry) => !rejectedSpecifiers.has(collected.fileOwners[entry.path])),
766
+ packageMap,
767
+ sourceEntries,
768
+ keyframesScanEntries,
769
+ packageDirs: collected.packageDirs.filter((dir) => !rejectedDirs.includes(dir)),
770
+ dirOwnerSets,
771
+ fileOwners,
772
+ outcomes: collected.outcomes
773
+ };
774
+ }
575
775
  /**
576
776
  * Extract external DS package names from inheritance declarations in the
577
777
  * system file.
@@ -941,7 +1141,7 @@ function buildSourceTokenIndex(opts) {
941
1141
  if ((0, fs.existsSync)((0, path.join)(packageRoot, "package.json"))) addOwnerDir(packageRoot, specifier);
942
1142
  }
943
1143
  for (const [modulePath, exports] of Object.entries(manifests)) {
944
- const owner = realDirOwners.find(({ dir }) => modulePath === dir || modulePath.startsWith(dir + path.sep));
1144
+ const owner = realDirOwners.find(({ dir }) => isPathWithinRoot(dir, modulePath));
945
1145
  if (!owner) continue;
946
1146
  let tokens = index.get(owner.specifier);
947
1147
  if (!tokens) {
@@ -1082,16 +1282,42 @@ function postProcessCss(css, opts) {
1082
1282
  /** Stable code for selector forms with no substitutable subject.
1083
1283
  * Mirrors the Rust constant in `extract-v2/src/eval.rs`. */
1084
1284
  const SELECTOR_UNSUPPORTED_SUBJECT = "animus.selector.unsupported-subject";
1285
+ /** Unresolved-parent chain-drop message (mirrors the Rust diagnostic in
1286
+ * `extract-v2` — the ONE encoding of this message shape; consumers match
1287
+ * through the helpers below, never their own regex copies). */
1288
+ const UNRESOLVED_PARENT_RE = /chain dropped: could not resolve parent component '([^']+)'/;
1289
+ /** True when the diagnostic reports a chain dropped for an unresolved
1290
+ * parent component. */
1291
+ function isUnresolvedParentDrop(diagnostic) {
1292
+ return typeof diagnostic?.message === "string" && UNRESOLVED_PARENT_RE.test(diagnostic.message);
1293
+ }
1294
+ /** The parent binding named by an unresolved-parent drop, or null when the
1295
+ * diagnostic is not one. */
1296
+ function unresolvedParentName(diagnostic) {
1297
+ if (typeof diagnostic?.message !== "string") return null;
1298
+ return UNRESOLVED_PARENT_RE.exec(diagnostic.message)?.[1] ?? null;
1299
+ }
1085
1300
  /** True when the selector string carries at least one substitutable `&`
1086
1301
  * subject outside quoted text (mirrors the Rust `selector_subject` walk —
1087
1302
  * ancestor, leading, and repeated subjects all count; a `&` inside a
1088
1303
  * quoted attribute value does not). */
1089
1304
  function hasSelectorSubject(value) {
1090
1305
  let quote = null;
1091
- for (const c of value) if (quote !== null) {
1092
- if (c === quote) quote = null;
1093
- } else if (c === "\"" || c === "'") quote = c;
1094
- else if (c === "&") return true;
1306
+ let escaped = false;
1307
+ for (const c of value) {
1308
+ if (escaped) {
1309
+ escaped = false;
1310
+ continue;
1311
+ }
1312
+ if (c === "\\") {
1313
+ escaped = true;
1314
+ continue;
1315
+ }
1316
+ if (quote !== null) {
1317
+ if (c === quote) quote = null;
1318
+ } else if (c === "\"" || c === "'") quote = c;
1319
+ else if (c === "&") return true;
1320
+ }
1095
1321
  return false;
1096
1322
  }
1097
1323
  /**
@@ -1509,17 +1735,17 @@ function stripJsonc(text) {
1509
1735
  }
1510
1736
  return out.replace(/,(\s*[}\]])/g, "$1");
1511
1737
  }
1512
- function readConfig(path$1) {
1738
+ function readConfig(path$2) {
1513
1739
  let raw;
1514
1740
  try {
1515
- raw = (0, fs.readFileSync)(path$1, "utf-8");
1741
+ raw = (0, fs.readFileSync)(path$2, "utf-8");
1516
1742
  } catch {
1517
1743
  return null;
1518
1744
  }
1519
1745
  try {
1520
1746
  const json = JSON.parse(stripJsonc(raw));
1521
1747
  return {
1522
- dir: (0, path.dirname)(path$1),
1748
+ dir: (0, path.dirname)(path$2),
1523
1749
  compilerOptions: json.compilerOptions ?? {},
1524
1750
  extends: json.extends
1525
1751
  };
@@ -1664,6 +1890,79 @@ async function preprocessMdx(source, filename) {
1664
1890
  }
1665
1891
  }
1666
1892
  //#endregion
1893
+ //#region pipeline/replacement-plans.ts
1894
+ const snapshotByManifest = /* @__PURE__ */ new WeakMap();
1895
+ function snapshotFilePlans(manifest) {
1896
+ const memoKey = manifest !== null && typeof manifest === "object" ? manifest : null;
1897
+ if (memoKey) {
1898
+ const cached = snapshotByManifest.get(memoKey);
1899
+ if (cached) return cached;
1900
+ }
1901
+ const entriesByFile = /* @__PURE__ */ new Map();
1902
+ for (const [id, desc] of Object.entries(manifest?.components ?? {})) {
1903
+ const file = desc.file;
1904
+ if (!file) continue;
1905
+ const list = entriesByFile.get(file) ?? [];
1906
+ list.push([id, desc.replacement ?? ""]);
1907
+ entriesByFile.set(file, list);
1908
+ }
1909
+ const snapshot = /* @__PURE__ */ new Map();
1910
+ for (const [file, entries] of entriesByFile) {
1911
+ entries.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1912
+ snapshot.set(file, JSON.stringify(entries));
1913
+ }
1914
+ if (memoKey) snapshotByManifest.set(memoKey, snapshot);
1915
+ return snapshot;
1916
+ }
1917
+ /**
1918
+ * Rel paths whose plan changed between two snapshots: absent→present,
1919
+ * present→absent, and any change to membership or replacement content.
1920
+ * `exclude` drops one path (the changed file itself on the edit path — its
1921
+ * own modules are already in the update set).
1922
+ */
1923
+ function diffFilePlans(prev, next, opts) {
1924
+ const changed = /* @__PURE__ */ new Set();
1925
+ for (const [file, plan] of next) if (prev.get(file) !== plan) changed.add(file);
1926
+ for (const file of prev.keys()) if (!next.has(file)) changed.add(file);
1927
+ if (opts?.exclude) changed.delete(opts.exclude);
1928
+ return [...changed].sort();
1929
+ }
1930
+ /** Domain prefix keeping the epoch hash disjoint from every other
1931
+ * contentHash use in the pipeline (design D5). */
1932
+ const REPLACEMENT_PLANS_DOMAIN = "animus-replacement-plans-v1\0";
1933
+ /** Section marker for the served-dependency witness. Leads with NUL: every
1934
+ * plan entry ends `…\0` and neither file paths nor plan JSON contain NUL,
1935
+ * so `\0\0` is unreachable from entry serialization alone — a snapshot can
1936
+ * never forge the witness section. */
1937
+ const SERVED_DEPENDENCY_DOMAIN = "\0animus-served-dependency-v1\0";
1938
+ /**
1939
+ * Canonical replacement epoch: contentHash over the domain-prefixed, sorted
1940
+ * canonical serialization of a file-plan snapshot — each entry contributes
1941
+ * `file + '\0' + plan + '\0'` (unambiguous: neither file paths nor the
1942
+ * JSON plan strings contain NUL). Byte-identical plans → identical epoch;
1943
+ * any membership/replacement/absent↔present change moves it.
1944
+ *
1945
+ * `servedDependencyWitness` extends the epoch to content the plans cannot
1946
+ * see but restored modules depend on: transformed modules import the
1947
+ * session's served system-props artifact, so a consumer passes that
1948
+ * artifact's content here and an offline change to it moves the epoch —
1949
+ * invalidating persistent-cache snapshots that reference the old epoch
1950
+ * artifact. Absence and empty-string are distinct values.
1951
+ *
1952
+ * This is THE epoch definition — integrations consume this hash (or the
1953
+ * snapshot diff) and never define their own. Epoch values compare only for
1954
+ * equality (a moved value invalidates), so the serialization is free to
1955
+ * evolve with a domain bump: sessions running different serializations
1956
+ * simply disagree once and rebuild.
1957
+ */
1958
+ function hashReplacementPlans(snapshot, servedDependencyWitness) {
1959
+ const entries = [...snapshot.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1960
+ let serialized = REPLACEMENT_PLANS_DOMAIN;
1961
+ for (const [file, plan] of entries) serialized += file + "\0" + plan + "\0";
1962
+ if (servedDependencyWitness !== void 0) serialized += SERVED_DEPENDENCY_DOMAIN + servedDependencyWitness;
1963
+ return contentHash(serialized);
1964
+ }
1965
+ //#endregion
1667
1966
  //#region pipeline/utils.ts
1668
1967
  /** Convert camelCase CSS property names to kebab-case. */
1669
1968
  function camelToKebab(str) {
@@ -1733,27 +2032,40 @@ exports.camelToKebab = camelToKebab;
1733
2032
  exports.clearEngineCache = clearEngineCache;
1734
2033
  exports.collectExternalPackageSources = collectExternalPackageSources;
1735
2034
  exports.contentHash = contentHash;
2035
+ exports.createSourceIdentity = createSourceIdentity;
1736
2036
  exports.createV2EngineApi = createV2EngineApi;
2037
+ exports.diffFilePlans = diffFilePlans;
1737
2038
  exports.discoverFiles = discoverFiles;
1738
2039
  exports.enforceExternalTokenContracts = enforceExternalTokenContracts;
2040
+ exports.excludeCollectedPackages = excludeCollectedPackages;
1739
2041
  exports.extractSystemFilePackages = extractSystemFilePackages;
1740
2042
  exports.findAssetSpecifiers = findAssetSpecifiers;
1741
2043
  exports.findPackageRoot = findPackageRoot;
2044
+ exports.firstOwners = firstOwners;
1742
2045
  exports.formatRustTimingWaterfall = formatRustTimingWaterfall;
2046
+ exports.hashReplacementPlans = hashReplacementPlans;
2047
+ exports.isExcludedPackageRelativePath = isExcludedPackageRelativePath;
2048
+ exports.isPathWithinRoot = isPathWithinRoot;
2049
+ exports.isUnresolvedParentDrop = isUnresolvedParentDrop;
1743
2050
  exports.loadSystemConfig = loadSystemConfig;
1744
2051
  exports.mergeExternalKeyframes = mergeExternalKeyframes;
1745
2052
  exports.postProcessCss = postProcessCss;
1746
2053
  exports.preprocessMdx = preprocessMdx;
1747
2054
  exports.readTsconfigAliasPairs = readTsconfigAliasPairs;
2055
+ exports.resolveAbsolutePathSpecifier = resolveAbsolutePathSpecifier;
1748
2056
  exports.resolveAssetFile = resolveAssetFile;
1749
2057
  exports.resolveLightningTargets = resolveLightningTargets;
1750
2058
  exports.resolveThroughPathAliases = resolveThroughPathAliases;
1751
2059
  exports.runProjectAnalysis = runProjectAnalysis;
1752
2060
  exports.serializeStaticCss = serializeStaticCss;
2061
+ exports.sharesVolumeRoot = sharesVolumeRoot;
2062
+ exports.snapshotFilePlans = snapshotFilePlans;
1753
2063
  exports.staleDistIncludesMessage = staleDistIncludesMessage;
1754
2064
  exports.stripLeadingLayerDeclaration = stripLeadingLayerDeclaration;
1755
2065
  exports.substituteAssetPlaceholders = substituteAssetPlaceholders;
1756
2066
  exports.surfaceManifestDiagnostics = surfaceManifestDiagnostics;
1757
2067
  exports.toWatchKeys = toWatchKeys;
1758
2068
  exports.unresolvableIncludesMessage = unresolvableIncludesMessage;
2069
+ exports.unresolvedParentName = unresolvedParentName;
1759
2070
  exports.validateLayerOrder = validateLayerOrder;
2071
+ exports.walkPackageSources = walkPackageSources;
package/dist/index.d.ts CHANGED
@@ -10,7 +10,9 @@ export { KEYFRAMES_EXPORT_COLLISION, KEYFRAMES_EXTERNAL_ENTRY_FAILED, mergeExter
10
10
  export type { ExternalKeyframesMerge } from './external-keyframes';
11
11
  export { discoverFiles } from './discover-files';
12
12
  export type { CollectedExternalPackages, ExternalPackageOutcome, } from './discover-packages';
13
- export { collectExternalPackageSources, extractSystemFilePackages, findPackageRoot, staleDistIncludesMessage, unresolvableIncludesMessage, } from './discover-packages';
13
+ export { collectExternalPackageSources, excludeCollectedPackages, extractSystemFilePackages, findPackageRoot, firstOwners, isExcludedPackageRelativePath, resolveAbsolutePathSpecifier, staleDistIncludesMessage, unresolvableIncludesMessage, walkPackageSources, } from './discover-packages';
14
+ export type { ResolvedSourceId, SourceIdentity } from './source-identity';
15
+ export { createSourceIdentity, isPathWithinRoot, sharesVolumeRoot, } from './source-identity';
14
16
  export { findAssetSpecifiers, substituteAssetPlaceholders, } from './asset-placeholders';
15
17
  export { resolveAssetFile, resolveThroughPathAliases } from './resolve-asset';
16
18
  export { enforceExternalTokenContracts } from './correlate-external-tokens';
@@ -29,10 +31,12 @@ export { readTsconfigAliasPairs } from './tsconfig-paths';
29
31
  export type { DynamicPropConfigEntry, DynamicPropMeta, } from './dynamic-prop-config';
30
32
  export { buildDynamicPropConfig } from './dynamic-prop-config';
31
33
  export type { ManifestDiagnostic } from './manifest-diagnostics';
32
- export { surfaceManifestDiagnostics } from './manifest-diagnostics';
34
+ export { isUnresolvedParentDrop, surfaceManifestDiagnostics, unresolvedParentName, } from './manifest-diagnostics';
33
35
  export type { DefaultExtension, PreprocessMdxResult } from './mdx-preprocessor';
34
36
  export { DEFAULT_EXTENSIONS, preprocessMdx } from './mdx-preprocessor';
35
37
  export { applyPrefix } from './prefix';
38
+ export type { FilePlanSnapshot } from './replacement-plans';
39
+ export { diffFilePlans, hashReplacementPlans, snapshotFilePlans, } from './replacement-plans';
36
40
  export { applyUnitFallback } from './unit-fallback';
37
41
  export { camelToKebab } from './utils';
38
42
  export { toWatchKeys } from './watch-keys';