@karmaniverous/stan-cli 0.12.1 → 0.12.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.
- package/dist/cli/stan.js +81 -93
- package/package.json +1 -1
package/dist/cli/stan.js
CHANGED
|
@@ -32022,27 +32022,28 @@ const isSubtreePattern = (s) => {
|
|
|
32022
32022
|
const p = posix(s.trim());
|
|
32023
32023
|
return p.endsWith('/**') || p.endsWith('/*');
|
|
32024
32024
|
};
|
|
32025
|
-
/** Extract the "tail" (after last '/') from a glob (e.g., '**\/*.test.ts' -\> '*.test.ts'). */
|
|
32026
|
-
const globTail = (s) => {
|
|
32027
|
-
const p = posix(s.trim());
|
|
32028
|
-
const idx = p.lastIndexOf('/');
|
|
32029
|
-
return idx >= 0 ? p.slice(idx + 1) : p;
|
|
32030
|
-
};
|
|
32031
32025
|
/** Normalize subtree roots from a list of exclude patterns. */
|
|
32032
32026
|
const collectSubtreeRoots = (patterns) => (patterns ?? [])
|
|
32033
32027
|
.filter((p) => isSubtreePattern(p))
|
|
32034
32028
|
.map(stripGlobTail)
|
|
32035
32029
|
.filter((r) => r.length > 0);
|
|
32036
|
-
/** Collect leaf‑glob tails (e.g., '**\/*.test.ts' -\> '*.test.ts') from a list of exclude patterns. */
|
|
32037
|
-
const collectLeafGlobTails = (patterns) => (patterns ?? [])
|
|
32038
|
-
.filter((p) => !isSubtreePattern(p))
|
|
32039
|
-
.map(globTail)
|
|
32040
|
-
.filter((t) => t.length > 0);
|
|
32041
32030
|
const isUnder = (childRel, root) => {
|
|
32042
32031
|
const c = posix(childRel);
|
|
32043
32032
|
const r = posix(root);
|
|
32044
32033
|
return c === r || c.startsWith(r.length ? r + '/' : '');
|
|
32045
32034
|
};
|
|
32035
|
+
const toSubtreeGlob = (root) => `${posix(root)}/**`;
|
|
32036
|
+
const segmentUnderRoot = (root, p) => {
|
|
32037
|
+
const r = posix(root);
|
|
32038
|
+
const full = posix(p);
|
|
32039
|
+
if (!isUnder(full, r))
|
|
32040
|
+
return null;
|
|
32041
|
+
const rest = full.slice(r.length).replace(/^\/+/, '');
|
|
32042
|
+
if (!rest.length)
|
|
32043
|
+
return null;
|
|
32044
|
+
const first = rest.split('/')[0];
|
|
32045
|
+
return first && first.length ? first : null;
|
|
32046
|
+
};
|
|
32046
32047
|
const readFacetMeta = async (cwd, stanPath) => {
|
|
32047
32048
|
const abs = toAbs(cwd, path.join(stanPath, 'system', 'facet.meta.json'));
|
|
32048
32049
|
const meta = await safeReadJson(abs);
|
|
@@ -32096,14 +32097,10 @@ const computeFacetOverlay = async (input) => {
|
|
|
32096
32097
|
const anchorsOverlaySet = new Set();
|
|
32097
32098
|
// Final excludes overlay entries (subtree roots only; leaf-globs are not propagated here).
|
|
32098
32099
|
const excludesOverlayArr = [];
|
|
32099
|
-
// Track subtree-root entries for enabled-wins filtering.
|
|
32100
|
-
const excludesOverlayRoots = [];
|
|
32101
32100
|
const autosuspended = [];
|
|
32102
32101
|
const anchorsKeptCounts = {};
|
|
32103
32102
|
// Track per-facet inactive subtree roots for overlap-kept diagnostics.
|
|
32104
32103
|
const inactiveEntries = [];
|
|
32105
|
-
// Collect leaf‑glob tails from active facets (protected patterns).
|
|
32106
|
-
const activeLeafTails = new Set();
|
|
32107
32104
|
// Precompute active subtree roots across all facets (for tie-breakers and scoped anchors).
|
|
32108
32105
|
const activeRoots = new Set();
|
|
32109
32106
|
for (const name of facetNames) {
|
|
@@ -32112,15 +32109,7 @@ const computeFacetOverlay = async (input) => {
|
|
|
32112
32109
|
if (isActive)
|
|
32113
32110
|
for (const r of exRoots)
|
|
32114
32111
|
activeRoots.add(posix(r));
|
|
32115
|
-
// Also collect leaf‑glob tails for active facets so they can be protected
|
|
32116
|
-
// under inactive subtree roots (enabled‑wins across leaf‑glob vs subtree).
|
|
32117
|
-
if (isActive) {
|
|
32118
|
-
for (const tail of collectLeafGlobTails(meta[name].exclude))
|
|
32119
|
-
activeLeafTails.add(tail);
|
|
32120
|
-
}
|
|
32121
32112
|
}
|
|
32122
|
-
// Collect leaf-glob tails from inactive facets (for scoped anchors under active roots).
|
|
32123
|
-
const inactiveLeafTails = new Set();
|
|
32124
32113
|
// Always include all anchors (keep docs breadcrumbs visible even when overlay off)
|
|
32125
32114
|
for (const name of facetNames) {
|
|
32126
32115
|
const def = defOf(name);
|
|
@@ -32177,7 +32166,6 @@ const computeFacetOverlay = async (input) => {
|
|
|
32177
32166
|
.filter(isSubtreePattern)
|
|
32178
32167
|
.map(stripGlobTail)
|
|
32179
32168
|
.filter(Boolean);
|
|
32180
|
-
const leafGlobs = excludes.filter((p) => !isSubtreePattern(p));
|
|
32181
32169
|
const inc = Array.isArray(def.include) ? def.include.map(posix) : [];
|
|
32182
32170
|
// Count anchors present on disk (for metadata)
|
|
32183
32171
|
anchorsKeptCounts[name] = inc.filter((a) => existsSync(toAbs(cwd, a))).length;
|
|
@@ -32205,75 +32193,80 @@ const computeFacetOverlay = async (input) => {
|
|
|
32205
32193
|
if (!root)
|
|
32206
32194
|
continue;
|
|
32207
32195
|
inactiveEntries.push({ facet: name, root });
|
|
32208
|
-
excludesOverlayRoots.push(root.endsWith('/') ? root : root);
|
|
32209
|
-
}
|
|
32210
|
-
// Collect leaf-glob tails for scoped re-inclusions under active roots.
|
|
32211
|
-
for (const g of leafGlobs) {
|
|
32212
|
-
const tail = globTail(g);
|
|
32213
|
-
if (tail)
|
|
32214
|
-
inactiveLeafTails.add(tail);
|
|
32215
32196
|
}
|
|
32216
32197
|
}
|
|
32217
|
-
//
|
|
32198
|
+
// Nested structural facets: carve-out inactive roots that contain active descendant roots.
|
|
32199
|
+
// - Keep exact-match "enabled wins" behavior (drop inactive root when the same root is active).
|
|
32200
|
+
// - If an inactive root contains one or more active descendant subtree roots, exclude all
|
|
32201
|
+
// immediate children under the inactive root that are NOT ancestors of any active root.
|
|
32202
|
+
// This expresses "B on, rest of A off" without using anchors as filter machinery.
|
|
32218
32203
|
const overlapKeptCounts = {};
|
|
32219
|
-
|
|
32220
|
-
|
|
32221
|
-
const
|
|
32222
|
-
|
|
32223
|
-
|
|
32224
|
-
|
|
32225
|
-
|
|
32226
|
-
|
|
32227
|
-
|
|
32228
|
-
|
|
32229
|
-
|
|
32230
|
-
}
|
|
32231
|
-
//
|
|
32232
|
-
|
|
32233
|
-
|
|
32234
|
-
|
|
32235
|
-
for (const { facet } of keptEntries) {
|
|
32236
|
-
overlapKeptCounts[facet] = (overlapKeptCounts[facet] ?? 0) + 1;
|
|
32237
|
-
}
|
|
32238
|
-
}
|
|
32239
|
-
else {
|
|
32240
|
-
// No filtering occurred (no active roots or no excludes); consider all inactive entries as kept.
|
|
32241
|
-
for (const { facet } of inactiveEntries) {
|
|
32242
|
-
overlapKeptCounts[facet] = (overlapKeptCounts[facet] ?? 0) + 1;
|
|
32243
|
-
}
|
|
32244
|
-
// Append the raw subtree roots only.
|
|
32245
|
-
const uniq = Array.from(new Set(excludesOverlayRoots));
|
|
32246
|
-
excludesOverlayArr.length = 0;
|
|
32247
|
-
excludesOverlayArr.push(...uniq);
|
|
32248
|
-
}
|
|
32249
|
-
// Enabled‑wins for leaf‑glob patterns: protect ACTIVE facets' leaf‑glob tails
|
|
32250
|
-
// under any remaining inactive subtree roots by adding scoped anchors
|
|
32251
|
-
// "<inactiveRoot>/**/<tail>" so those files remain visible.
|
|
32252
|
-
if (activeLeafTails.size > 0 && excludesOverlayArr.length > 0) {
|
|
32204
|
+
const activeRootsArr = Array.from(activeRoots);
|
|
32205
|
+
const carveOutOrExcludeRoot = async (root) => {
|
|
32206
|
+
const protectedRoots = activeRootsArr.filter((ar) => ar !== root && isUnder(ar, root));
|
|
32207
|
+
if (protectedRoots.length === 0)
|
|
32208
|
+
return [toSubtreeGlob(root)];
|
|
32209
|
+
// Compute which immediate child entries are "keepers".
|
|
32210
|
+
const keep = new Set();
|
|
32211
|
+
for (const pr of protectedRoots) {
|
|
32212
|
+
const seg = segmentUnderRoot(root, pr);
|
|
32213
|
+
if (seg)
|
|
32214
|
+
keep.add(seg);
|
|
32215
|
+
}
|
|
32216
|
+
// Enumerate immediate children under the inactive root and exclude everything
|
|
32217
|
+
// except the keeper segments. Keep deterministic output ordering.
|
|
32218
|
+
const abs = toAbs(cwd, root);
|
|
32219
|
+
let dirents = null;
|
|
32253
32220
|
try {
|
|
32254
|
-
|
|
32255
|
-
for (const tail of activeLeafTails) {
|
|
32256
|
-
const scoped = posix(`${root}/**/${tail}`);
|
|
32257
|
-
anchorsOverlaySet.add(scoped);
|
|
32258
|
-
}
|
|
32259
|
-
}
|
|
32221
|
+
dirents = (await readdir(abs, { withFileTypes: true }));
|
|
32260
32222
|
}
|
|
32261
32223
|
catch {
|
|
32262
|
-
|
|
32224
|
+
dirents = null;
|
|
32263
32225
|
}
|
|
32264
|
-
|
|
32265
|
-
|
|
32266
|
-
|
|
32267
|
-
|
|
32268
|
-
|
|
32269
|
-
const
|
|
32270
|
-
|
|
32226
|
+
// If we can't enumerate, fall back to excluding the full root and
|
|
32227
|
+
// anchor-rescuing the protected roots. This preserves correctness without
|
|
32228
|
+
// reintroducing leaf-glob anchor tricks.
|
|
32229
|
+
if (!dirents) {
|
|
32230
|
+
try {
|
|
32231
|
+
for (const pr of protectedRoots)
|
|
32232
|
+
anchorsOverlaySet.add(toSubtreeGlob(pr));
|
|
32271
32233
|
}
|
|
32234
|
+
catch {
|
|
32235
|
+
/* best-effort */
|
|
32236
|
+
}
|
|
32237
|
+
return [toSubtreeGlob(root)];
|
|
32238
|
+
}
|
|
32239
|
+
const entries = dirents
|
|
32240
|
+
.map((d) => ({ name: d.name, isDir: d.isDirectory() }))
|
|
32241
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
32242
|
+
const out = [];
|
|
32243
|
+
for (const e of entries) {
|
|
32244
|
+
if (keep.has(e.name))
|
|
32245
|
+
continue;
|
|
32246
|
+
const rel = posix(path.join(root, e.name));
|
|
32247
|
+
out.push(e.isDir ? toSubtreeGlob(rel) : rel);
|
|
32272
32248
|
}
|
|
32249
|
+
return out;
|
|
32250
|
+
};
|
|
32251
|
+
if (inactiveEntries.length > 0) {
|
|
32252
|
+
const patterns = new Set();
|
|
32253
|
+
for (const entry of inactiveEntries) {
|
|
32254
|
+
const r = entry.root;
|
|
32255
|
+
// Enabled-wins (exact match only): if the same subtree root is active, do not apply the inactive drop.
|
|
32256
|
+
if (activeRoots.has(r))
|
|
32257
|
+
continue;
|
|
32258
|
+
overlapKeptCounts[entry.facet] =
|
|
32259
|
+
(overlapKeptCounts[entry.facet] ?? 0) + 1;
|
|
32260
|
+
const ps = await carveOutOrExcludeRoot(r);
|
|
32261
|
+
for (const p of ps)
|
|
32262
|
+
patterns.add(posix(p));
|
|
32263
|
+
}
|
|
32264
|
+
excludesOverlayArr.length = 0;
|
|
32265
|
+
excludesOverlayArr.push(...Array.from(patterns).sort((a, b) => a.localeCompare(b)));
|
|
32273
32266
|
}
|
|
32274
32267
|
// Deduplicate anchors overlay
|
|
32275
32268
|
const anchorsOverlay = Array.from(anchorsOverlaySet);
|
|
32276
|
-
// Excludes overlay contains subtree
|
|
32269
|
+
// Excludes overlay contains engine-ready patterns (subtree globs and/or exact paths).
|
|
32277
32270
|
return {
|
|
32278
32271
|
enabled: true,
|
|
32279
32272
|
excludesOverlay: excludesOverlayArr,
|
|
@@ -32285,11 +32278,6 @@ const computeFacetOverlay = async (input) => {
|
|
|
32285
32278
|
};
|
|
32286
32279
|
};
|
|
32287
32280
|
|
|
32288
|
-
const hasGlob = (s) => s.includes('*') || s.includes('?') || s.includes('[');
|
|
32289
|
-
const ensureSubtreeGlob = (p) => {
|
|
32290
|
-
const s = p.replace(/\/+$/, '');
|
|
32291
|
-
return hasGlob(s) ? s : `${s}/**`;
|
|
32292
|
-
};
|
|
32293
32281
|
const toPosix = (p) => p.replace(/\\+/g, '/');
|
|
32294
32282
|
const buildOverlayInputs = async (args) => {
|
|
32295
32283
|
const { cwd, stanPath, enabled, activateNames, deactivateNames } = args;
|
|
@@ -32317,12 +32305,9 @@ const buildOverlayInputs = async (args) => {
|
|
|
32317
32305
|
};
|
|
32318
32306
|
}
|
|
32319
32307
|
const shouldMap = enabled;
|
|
32320
|
-
//
|
|
32321
|
-
|
|
32322
|
-
//
|
|
32323
|
-
const overlayExcludesRaw = shouldMap ? overlay.excludesOverlay : [];
|
|
32324
|
-
const overlayExcludes = overlayExcludesRaw.map(ensureSubtreeGlob);
|
|
32325
|
-
// Also include leaf-glob excludes from inactive facets (e.g., "**/*.test.ts").
|
|
32308
|
+
// Overlay structural excludes are already engine-ready patterns (subtree globs and/or exact paths).
|
|
32309
|
+
const overlayExcludes = shouldMap ? overlay.excludesOverlay : [];
|
|
32310
|
+
// Also include leaf‑glob excludes from inactive facets (e.g., "**/*.test.ts").
|
|
32326
32311
|
// Read facet.meta.json directly and derive leaf-globs for facets that are
|
|
32327
32312
|
// currently inactive per overlay.effective.
|
|
32328
32313
|
const leafGlobs = [];
|
|
@@ -32350,7 +32335,10 @@ const buildOverlayInputs = async (args) => {
|
|
|
32350
32335
|
catch {
|
|
32351
32336
|
/* best-effort only */
|
|
32352
32337
|
}
|
|
32353
|
-
const engineExcludes = Array.from(new Set([
|
|
32338
|
+
const engineExcludes = Array.from(new Set([
|
|
32339
|
+
...overlayExcludes.map(toPosix),
|
|
32340
|
+
...leafGlobs.map(toPosix),
|
|
32341
|
+
]));
|
|
32354
32342
|
// Facet view lines for plan (same as before; keep compact)
|
|
32355
32343
|
const overlayPlan = (() => {
|
|
32356
32344
|
const lines = [];
|
package/package.json
CHANGED