vibe-splain 3.2.1 → 3.2.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/index.js +2138 -77
- package/dist/store/PointerStore.js +21 -5
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -247,8 +247,8 @@ async function collectFiles(dir, projectRoot, acc) {
|
|
|
247
247
|
if (entry.isDirectory()) {
|
|
248
248
|
await collectFiles(fullPath, projectRoot, acc);
|
|
249
249
|
} else if (entry.isFile()) {
|
|
250
|
-
const
|
|
251
|
-
if (!SUPPORTED_EXTENSIONS.has(
|
|
250
|
+
const ext2 = extname(entry.name);
|
|
251
|
+
if (!SUPPORTED_EXTENSIONS.has(ext2))
|
|
252
252
|
continue;
|
|
253
253
|
if (EXCLUDE_FILE_PATTERNS.some((p) => p.test(entry.name)))
|
|
254
254
|
continue;
|
|
@@ -1130,8 +1130,8 @@ async function runInventory(projectRoot) {
|
|
|
1130
1130
|
const work = [];
|
|
1131
1131
|
for (const file of abs) {
|
|
1132
1132
|
const rel = relative(projectRoot, file);
|
|
1133
|
-
const
|
|
1134
|
-
const lang = EXT_LANG[
|
|
1133
|
+
const ext2 = extname(file);
|
|
1134
|
+
const lang = EXT_LANG[ext2];
|
|
1135
1135
|
if (!lang)
|
|
1136
1136
|
continue;
|
|
1137
1137
|
let source;
|
|
@@ -1336,10 +1336,10 @@ var JS_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
|
1336
1336
|
function tryJsCandidates(base, projectRoot, fileSet) {
|
|
1337
1337
|
const candidates = [];
|
|
1338
1338
|
candidates.unshift(base);
|
|
1339
|
-
for (const
|
|
1340
|
-
candidates.push(base +
|
|
1341
|
-
for (const
|
|
1342
|
-
candidates.push(join3(base, "index" +
|
|
1339
|
+
for (const ext2 of JS_EXTS)
|
|
1340
|
+
candidates.push(base + ext2);
|
|
1341
|
+
for (const ext2 of JS_EXTS)
|
|
1342
|
+
candidates.push(join3(base, "index" + ext2));
|
|
1343
1343
|
for (const c of candidates) {
|
|
1344
1344
|
const rel = relative2(projectRoot, c);
|
|
1345
1345
|
if (fileSet.has(rel))
|
|
@@ -1584,32 +1584,32 @@ var ENTRYPOINT_ROLES = /* @__PURE__ */ new Set([
|
|
|
1584
1584
|
"trpc_api_route"
|
|
1585
1585
|
]);
|
|
1586
1586
|
function inferRiskTypesPass1(rel, frameworkRole, productDomain, sideEffectProfile, gravitySignals, smellKinds) {
|
|
1587
|
-
const
|
|
1587
|
+
const types2 = [];
|
|
1588
1588
|
const smThreshold = ["provider", "store"].includes(frameworkRole) ? 8 : 20;
|
|
1589
1589
|
if (gravitySignals.cyclomatic > smThreshold)
|
|
1590
|
-
|
|
1590
|
+
types2.push("state_machine");
|
|
1591
1591
|
if (smellKinds.has("god-file")) {
|
|
1592
1592
|
if (frameworkRole === "hook")
|
|
1593
|
-
|
|
1593
|
+
types2.push("god_hook");
|
|
1594
1594
|
else
|
|
1595
|
-
|
|
1595
|
+
types2.push("god_component");
|
|
1596
1596
|
}
|
|
1597
1597
|
if (sideEffectProfile.length > 3 && !sideEffectProfile.includes("none_detected")) {
|
|
1598
|
-
|
|
1598
|
+
types2.push("side_effect_coupling");
|
|
1599
1599
|
}
|
|
1600
1600
|
if (productDomain === "forms" && (gravitySignals.fanIn > 3 || gravitySignals.publicSurface > 5))
|
|
1601
|
-
|
|
1601
|
+
types2.push("registry_bottleneck");
|
|
1602
1602
|
if (sideEffectProfile.some((s) => ["booking_mutation", "payment_mutation", "auth_token_mutation"].includes(s)) && gravitySignals.cyclomatic > 10)
|
|
1603
|
-
|
|
1603
|
+
types2.push("mutation_orchestration");
|
|
1604
1604
|
if (ENTRYPOINT_ROLES.has(frameworkRole) && sideEffectProfile.includes("database_write")) {
|
|
1605
|
-
|
|
1605
|
+
types2.push("route_handler_write_path");
|
|
1606
1606
|
}
|
|
1607
1607
|
if (smellKinds.has("swallowed-catch"))
|
|
1608
|
-
|
|
1608
|
+
types2.push("error_swallowing");
|
|
1609
1609
|
if (sideEffectProfile.includes("local_storage") || sideEffectProfile.includes("indexed_db")) {
|
|
1610
|
-
|
|
1610
|
+
types2.push("storage_persistence_risk");
|
|
1611
1611
|
}
|
|
1612
|
-
return
|
|
1612
|
+
return types2;
|
|
1613
1613
|
}
|
|
1614
1614
|
var DOMAIN_SURFACE_PATTERNS = {
|
|
1615
1615
|
booking_creation: {
|
|
@@ -2052,16 +2052,16 @@ async function runClassification(projectRoot, inv, res) {
|
|
|
2052
2052
|
const gs = gravitySignalsByFile.get(w.rel);
|
|
2053
2053
|
const smellKinds = new Set(w.ast.smells.map((s) => s.kind));
|
|
2054
2054
|
const effects = sideEffectsByFile.get(w.rel);
|
|
2055
|
-
const
|
|
2056
|
-
riskTypesByFile.set(w.rel,
|
|
2055
|
+
const types2 = inferRiskTypesPass1(w.rel, w.frameworkRole, w.productDomain, effects, gs, smellKinds);
|
|
2056
|
+
riskTypesByFile.set(w.rel, types2);
|
|
2057
2057
|
}
|
|
2058
2058
|
for (const w of work) {
|
|
2059
2059
|
if (w.productDomain === "forms" && (w.frameworkRole === "component" || w.frameworkRole === "hook")) {
|
|
2060
2060
|
const importsResolved_w = importsResolved.get(w.rel) || /* @__PURE__ */ new Set();
|
|
2061
2061
|
const importsAny = [...importsResolved_w, ...w.importSpecs.filter((s) => s.startsWith("@"))];
|
|
2062
2062
|
const consumesBottleneck = importsAny.some((dep) => {
|
|
2063
|
-
const
|
|
2064
|
-
return
|
|
2063
|
+
const types3 = riskTypesByFile.get(dep);
|
|
2064
|
+
return types3?.includes("registry_bottleneck");
|
|
2065
2065
|
});
|
|
2066
2066
|
if (consumesBottleneck) {
|
|
2067
2067
|
const existing = riskTypesByFile.get(w.rel);
|
|
@@ -2074,9 +2074,9 @@ async function runClassification(projectRoot, inv, res) {
|
|
|
2074
2074
|
existing.splice(idx, 1);
|
|
2075
2075
|
}
|
|
2076
2076
|
}
|
|
2077
|
-
const
|
|
2078
|
-
if (
|
|
2079
|
-
|
|
2077
|
+
const types2 = riskTypesByFile.get(w.rel);
|
|
2078
|
+
if (types2.length === 0)
|
|
2079
|
+
types2.push("complexity_hotspot");
|
|
2080
2080
|
}
|
|
2081
2081
|
const classified = [];
|
|
2082
2082
|
for (const w of work) {
|
|
@@ -3035,8 +3035,8 @@ async function scanProject(projectRoot) {
|
|
|
3035
3035
|
return runPipeline(projectRoot);
|
|
3036
3036
|
}
|
|
3037
3037
|
async function getFileAnalysis(absPath) {
|
|
3038
|
-
const
|
|
3039
|
-
const lang = EXT_LANG[
|
|
3038
|
+
const ext2 = extname4(absPath);
|
|
3039
|
+
const lang = EXT_LANG[ext2];
|
|
3040
3040
|
if (!lang)
|
|
3041
3041
|
return null;
|
|
3042
3042
|
let source;
|
|
@@ -3118,10 +3118,10 @@ function validateMermaidNodeCount(diagram) {
|
|
|
3118
3118
|
const nodePattern = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*[\[({|>]/gm;
|
|
3119
3119
|
const statePattern = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:/gm;
|
|
3120
3120
|
const nodes = /* @__PURE__ */ new Set();
|
|
3121
|
-
for (const
|
|
3122
|
-
nodes.add(
|
|
3123
|
-
for (const
|
|
3124
|
-
nodes.add(
|
|
3121
|
+
for (const match2 of diagram.matchAll(nodePattern))
|
|
3122
|
+
nodes.add(match2[1]);
|
|
3123
|
+
for (const match2 of diagram.matchAll(statePattern))
|
|
3124
|
+
nodes.add(match2[1]);
|
|
3125
3125
|
if (diagram.includes("[*]"))
|
|
3126
3126
|
nodes.add("[*]");
|
|
3127
3127
|
return nodes.size <= 7;
|
|
@@ -3520,11 +3520,11 @@ ${viewModel.map.brief}
|
|
|
3520
3520
|
md += `## Tier 1: Critical Files & Risks
|
|
3521
3521
|
|
|
3522
3522
|
`;
|
|
3523
|
-
for (const
|
|
3524
|
-
const f = store.files[
|
|
3525
|
-
const card = uniqueDecisions.get(
|
|
3526
|
-
const recs = viewModel.recommendations[
|
|
3527
|
-
md += `### ${
|
|
3523
|
+
for (const path2 of tier1) {
|
|
3524
|
+
const f = store.files[path2];
|
|
3525
|
+
const card = uniqueDecisions.get(path2);
|
|
3526
|
+
const recs = viewModel.recommendations[path2] || [];
|
|
3527
|
+
md += `### ${path2}
|
|
3528
3528
|
`;
|
|
3529
3529
|
md += `- Gravity: ${Math.round(f.gravity)} | Heat: ${Math.round(f.heat)}
|
|
3530
3530
|
`;
|
|
@@ -3539,8 +3539,8 @@ ${viewModel.map.brief}
|
|
|
3539
3539
|
md += `**Narrative**: ${card.narrative}
|
|
3540
3540
|
`;
|
|
3541
3541
|
}
|
|
3542
|
-
if (this.bindings && this.bindings.files[
|
|
3543
|
-
const fileBinding = this.bindings.files[
|
|
3542
|
+
if (this.bindings && this.bindings.files[path2]) {
|
|
3543
|
+
const fileBinding = this.bindings.files[path2];
|
|
3544
3544
|
const criticalFunctions = fileBinding.functions.filter((fn) => fn.semanticActions.length > 0 || fn.isEntrypoint);
|
|
3545
3545
|
if (criticalFunctions.length > 0) {
|
|
3546
3546
|
md += `
|
|
@@ -3573,10 +3573,10 @@ ${viewModel.map.brief}
|
|
|
3573
3573
|
md += `## Tier 2: Important Files
|
|
3574
3574
|
|
|
3575
3575
|
`;
|
|
3576
|
-
for (const
|
|
3577
|
-
const f = store.files[
|
|
3578
|
-
const card = uniqueDecisions.get(
|
|
3579
|
-
md += `- **${
|
|
3576
|
+
for (const path2 of tier2) {
|
|
3577
|
+
const f = store.files[path2];
|
|
3578
|
+
const card = uniqueDecisions.get(path2);
|
|
3579
|
+
md += `- **${path2}** (Gravity: ${Math.round(f.gravity)})`;
|
|
3580
3580
|
if (card) {
|
|
3581
3581
|
md += ` \u2014 ${card.thesis}`;
|
|
3582
3582
|
}
|
|
@@ -3588,9 +3588,9 @@ ${viewModel.map.brief}
|
|
|
3588
3588
|
md += `## Tier 3: Index
|
|
3589
3589
|
|
|
3590
3590
|
`;
|
|
3591
|
-
for (const
|
|
3592
|
-
const f = store.files[
|
|
3593
|
-
md += `- ${
|
|
3591
|
+
for (const path2 of tier3) {
|
|
3592
|
+
const f = store.files[path2];
|
|
3593
|
+
md += `- ${path2} (Gravity: ${Math.round(f.gravity)})
|
|
3594
3594
|
`;
|
|
3595
3595
|
}
|
|
3596
3596
|
return [
|
|
@@ -3738,7 +3738,214 @@ async function hashFile(filePath) {
|
|
|
3738
3738
|
import Database from "better-sqlite3";
|
|
3739
3739
|
import { join as join13 } from "path";
|
|
3740
3740
|
import { mkdirSync } from "fs";
|
|
3741
|
-
|
|
3741
|
+
|
|
3742
|
+
// ../../node_modules/async-mutex/index.mjs
|
|
3743
|
+
var E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
|
|
3744
|
+
var E_ALREADY_LOCKED = new Error("mutex already locked");
|
|
3745
|
+
var E_CANCELED = new Error("request for lock canceled");
|
|
3746
|
+
var __awaiter$2 = function(thisArg, _arguments, P, generator) {
|
|
3747
|
+
function adopt(value) {
|
|
3748
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
3749
|
+
resolve(value);
|
|
3750
|
+
});
|
|
3751
|
+
}
|
|
3752
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
3753
|
+
function fulfilled(value) {
|
|
3754
|
+
try {
|
|
3755
|
+
step(generator.next(value));
|
|
3756
|
+
} catch (e) {
|
|
3757
|
+
reject(e);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
function rejected(value) {
|
|
3761
|
+
try {
|
|
3762
|
+
step(generator["throw"](value));
|
|
3763
|
+
} catch (e) {
|
|
3764
|
+
reject(e);
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
function step(result) {
|
|
3768
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
3769
|
+
}
|
|
3770
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
3771
|
+
});
|
|
3772
|
+
};
|
|
3773
|
+
var Semaphore = class {
|
|
3774
|
+
constructor(_value, _cancelError = E_CANCELED) {
|
|
3775
|
+
this._value = _value;
|
|
3776
|
+
this._cancelError = _cancelError;
|
|
3777
|
+
this._queue = [];
|
|
3778
|
+
this._weightedWaiters = [];
|
|
3779
|
+
}
|
|
3780
|
+
acquire(weight = 1, priority = 0) {
|
|
3781
|
+
if (weight <= 0)
|
|
3782
|
+
throw new Error(`invalid weight ${weight}: must be positive`);
|
|
3783
|
+
return new Promise((resolve, reject) => {
|
|
3784
|
+
const task = { resolve, reject, weight, priority };
|
|
3785
|
+
const i = findIndexFromEnd(this._queue, (other) => priority <= other.priority);
|
|
3786
|
+
if (i === -1 && weight <= this._value) {
|
|
3787
|
+
this._dispatchItem(task);
|
|
3788
|
+
} else {
|
|
3789
|
+
this._queue.splice(i + 1, 0, task);
|
|
3790
|
+
}
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3793
|
+
runExclusive(callback_1) {
|
|
3794
|
+
return __awaiter$2(this, arguments, void 0, function* (callback, weight = 1, priority = 0) {
|
|
3795
|
+
const [value, release] = yield this.acquire(weight, priority);
|
|
3796
|
+
try {
|
|
3797
|
+
return yield callback(value);
|
|
3798
|
+
} finally {
|
|
3799
|
+
release();
|
|
3800
|
+
}
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
waitForUnlock(weight = 1, priority = 0) {
|
|
3804
|
+
if (weight <= 0)
|
|
3805
|
+
throw new Error(`invalid weight ${weight}: must be positive`);
|
|
3806
|
+
if (this._couldLockImmediately(weight, priority)) {
|
|
3807
|
+
return Promise.resolve();
|
|
3808
|
+
} else {
|
|
3809
|
+
return new Promise((resolve) => {
|
|
3810
|
+
if (!this._weightedWaiters[weight - 1])
|
|
3811
|
+
this._weightedWaiters[weight - 1] = [];
|
|
3812
|
+
insertSorted(this._weightedWaiters[weight - 1], { resolve, priority });
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
isLocked() {
|
|
3817
|
+
return this._value <= 0;
|
|
3818
|
+
}
|
|
3819
|
+
getValue() {
|
|
3820
|
+
return this._value;
|
|
3821
|
+
}
|
|
3822
|
+
setValue(value) {
|
|
3823
|
+
this._value = value;
|
|
3824
|
+
this._dispatchQueue();
|
|
3825
|
+
}
|
|
3826
|
+
release(weight = 1) {
|
|
3827
|
+
if (weight <= 0)
|
|
3828
|
+
throw new Error(`invalid weight ${weight}: must be positive`);
|
|
3829
|
+
this._value += weight;
|
|
3830
|
+
this._dispatchQueue();
|
|
3831
|
+
}
|
|
3832
|
+
cancel() {
|
|
3833
|
+
this._queue.forEach((entry) => entry.reject(this._cancelError));
|
|
3834
|
+
this._queue = [];
|
|
3835
|
+
}
|
|
3836
|
+
_dispatchQueue() {
|
|
3837
|
+
this._drainUnlockWaiters();
|
|
3838
|
+
while (this._queue.length > 0 && this._queue[0].weight <= this._value) {
|
|
3839
|
+
this._dispatchItem(this._queue.shift());
|
|
3840
|
+
this._drainUnlockWaiters();
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
_dispatchItem(item) {
|
|
3844
|
+
const previousValue = this._value;
|
|
3845
|
+
this._value -= item.weight;
|
|
3846
|
+
item.resolve([previousValue, this._newReleaser(item.weight)]);
|
|
3847
|
+
}
|
|
3848
|
+
_newReleaser(weight) {
|
|
3849
|
+
let called = false;
|
|
3850
|
+
return () => {
|
|
3851
|
+
if (called)
|
|
3852
|
+
return;
|
|
3853
|
+
called = true;
|
|
3854
|
+
this.release(weight);
|
|
3855
|
+
};
|
|
3856
|
+
}
|
|
3857
|
+
_drainUnlockWaiters() {
|
|
3858
|
+
if (this._queue.length === 0) {
|
|
3859
|
+
for (let weight = this._value; weight > 0; weight--) {
|
|
3860
|
+
const waiters = this._weightedWaiters[weight - 1];
|
|
3861
|
+
if (!waiters)
|
|
3862
|
+
continue;
|
|
3863
|
+
waiters.forEach((waiter) => waiter.resolve());
|
|
3864
|
+
this._weightedWaiters[weight - 1] = [];
|
|
3865
|
+
}
|
|
3866
|
+
} else {
|
|
3867
|
+
const queuedPriority = this._queue[0].priority;
|
|
3868
|
+
for (let weight = this._value; weight > 0; weight--) {
|
|
3869
|
+
const waiters = this._weightedWaiters[weight - 1];
|
|
3870
|
+
if (!waiters)
|
|
3871
|
+
continue;
|
|
3872
|
+
const i = waiters.findIndex((waiter) => waiter.priority <= queuedPriority);
|
|
3873
|
+
(i === -1 ? waiters : waiters.splice(0, i)).forEach(((waiter) => waiter.resolve()));
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
_couldLockImmediately(weight, priority) {
|
|
3878
|
+
return (this._queue.length === 0 || this._queue[0].priority < priority) && weight <= this._value;
|
|
3879
|
+
}
|
|
3880
|
+
};
|
|
3881
|
+
function insertSorted(a, v) {
|
|
3882
|
+
const i = findIndexFromEnd(a, (other) => v.priority <= other.priority);
|
|
3883
|
+
a.splice(i + 1, 0, v);
|
|
3884
|
+
}
|
|
3885
|
+
function findIndexFromEnd(a, predicate) {
|
|
3886
|
+
for (let i = a.length - 1; i >= 0; i--) {
|
|
3887
|
+
if (predicate(a[i])) {
|
|
3888
|
+
return i;
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
return -1;
|
|
3892
|
+
}
|
|
3893
|
+
var __awaiter$1 = function(thisArg, _arguments, P, generator) {
|
|
3894
|
+
function adopt(value) {
|
|
3895
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
3896
|
+
resolve(value);
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
3900
|
+
function fulfilled(value) {
|
|
3901
|
+
try {
|
|
3902
|
+
step(generator.next(value));
|
|
3903
|
+
} catch (e) {
|
|
3904
|
+
reject(e);
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3907
|
+
function rejected(value) {
|
|
3908
|
+
try {
|
|
3909
|
+
step(generator["throw"](value));
|
|
3910
|
+
} catch (e) {
|
|
3911
|
+
reject(e);
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
function step(result) {
|
|
3915
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
3916
|
+
}
|
|
3917
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
3918
|
+
});
|
|
3919
|
+
};
|
|
3920
|
+
var Mutex = class {
|
|
3921
|
+
constructor(cancelError) {
|
|
3922
|
+
this._semaphore = new Semaphore(1, cancelError);
|
|
3923
|
+
}
|
|
3924
|
+
acquire() {
|
|
3925
|
+
return __awaiter$1(this, arguments, void 0, function* (priority = 0) {
|
|
3926
|
+
const [, releaser] = yield this._semaphore.acquire(1, priority);
|
|
3927
|
+
return releaser;
|
|
3928
|
+
});
|
|
3929
|
+
}
|
|
3930
|
+
runExclusive(callback, priority = 0) {
|
|
3931
|
+
return this._semaphore.runExclusive(() => callback(), 1, priority);
|
|
3932
|
+
}
|
|
3933
|
+
isLocked() {
|
|
3934
|
+
return this._semaphore.isLocked();
|
|
3935
|
+
}
|
|
3936
|
+
waitForUnlock(priority = 0) {
|
|
3937
|
+
return this._semaphore.waitForUnlock(1, priority);
|
|
3938
|
+
}
|
|
3939
|
+
release() {
|
|
3940
|
+
if (this._semaphore.isLocked())
|
|
3941
|
+
this._semaphore.release();
|
|
3942
|
+
}
|
|
3943
|
+
cancel() {
|
|
3944
|
+
return this._semaphore.cancel();
|
|
3945
|
+
}
|
|
3946
|
+
};
|
|
3947
|
+
|
|
3948
|
+
// dist/store/PointerStore.js
|
|
3742
3949
|
var instance = null;
|
|
3743
3950
|
var PointerStore = class _PointerStore {
|
|
3744
3951
|
db;
|
|
@@ -3746,10 +3953,25 @@ var PointerStore = class _PointerStore {
|
|
|
3746
3953
|
constructor(projectRoot) {
|
|
3747
3954
|
const dir = join13(projectRoot, ".vibe-splainer");
|
|
3748
3955
|
mkdirSync(dir, { recursive: true });
|
|
3749
|
-
this.db = new Database(join13(dir, "pointer_store.db"));
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3956
|
+
this.db = new Database(join13(dir, "pointer_store.db"), { timeout: 1e4 });
|
|
3957
|
+
let retries = 5;
|
|
3958
|
+
while (retries > 0) {
|
|
3959
|
+
try {
|
|
3960
|
+
this.db.pragma("journal_mode = WAL");
|
|
3961
|
+
this.db.pragma("foreign_keys = ON");
|
|
3962
|
+
break;
|
|
3963
|
+
} catch (e) {
|
|
3964
|
+
if (e.code === "SQLITE_BUSY" && retries > 1) {
|
|
3965
|
+
retries--;
|
|
3966
|
+
const delay = 100 + Math.random() * 200;
|
|
3967
|
+
const start = Date.now();
|
|
3968
|
+
while (Date.now() - start < delay) {
|
|
3969
|
+
}
|
|
3970
|
+
continue;
|
|
3971
|
+
}
|
|
3972
|
+
throw e;
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3753
3975
|
this._migrate();
|
|
3754
3976
|
}
|
|
3755
3977
|
static open(projectRoot) {
|
|
@@ -3870,8 +4092,54 @@ var PointerStore = class _PointerStore {
|
|
|
3870
4092
|
}
|
|
3871
4093
|
};
|
|
3872
4094
|
|
|
4095
|
+
// ../../node_modules/uuid/dist/esm-node/rng.js
|
|
4096
|
+
import crypto from "crypto";
|
|
4097
|
+
var rnds8Pool = new Uint8Array(256);
|
|
4098
|
+
var poolPtr = rnds8Pool.length;
|
|
4099
|
+
function rng() {
|
|
4100
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
4101
|
+
crypto.randomFillSync(rnds8Pool);
|
|
4102
|
+
poolPtr = 0;
|
|
4103
|
+
}
|
|
4104
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
4105
|
+
}
|
|
4106
|
+
|
|
4107
|
+
// ../../node_modules/uuid/dist/esm-node/stringify.js
|
|
4108
|
+
var byteToHex = [];
|
|
4109
|
+
for (let i = 0; i < 256; ++i) {
|
|
4110
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
4111
|
+
}
|
|
4112
|
+
function unsafeStringify(arr, offset = 0) {
|
|
4113
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
4114
|
+
}
|
|
4115
|
+
|
|
4116
|
+
// ../../node_modules/uuid/dist/esm-node/native.js
|
|
4117
|
+
import crypto2 from "crypto";
|
|
4118
|
+
var native_default = {
|
|
4119
|
+
randomUUID: crypto2.randomUUID
|
|
4120
|
+
};
|
|
4121
|
+
|
|
4122
|
+
// ../../node_modules/uuid/dist/esm-node/v4.js
|
|
4123
|
+
function v4(options, buf, offset) {
|
|
4124
|
+
if (native_default.randomUUID && !buf && !options) {
|
|
4125
|
+
return native_default.randomUUID();
|
|
4126
|
+
}
|
|
4127
|
+
options = options || {};
|
|
4128
|
+
const rnds = options.random || (options.rng || rng)();
|
|
4129
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
4130
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
4131
|
+
if (buf) {
|
|
4132
|
+
offset = offset || 0;
|
|
4133
|
+
for (let i = 0; i < 16; ++i) {
|
|
4134
|
+
buf[offset + i] = rnds[i];
|
|
4135
|
+
}
|
|
4136
|
+
return buf;
|
|
4137
|
+
}
|
|
4138
|
+
return unsafeStringify(rnds);
|
|
4139
|
+
}
|
|
4140
|
+
var v4_default = v4;
|
|
4141
|
+
|
|
3873
4142
|
// dist/export/ExportOrchestrator.js
|
|
3874
|
-
import { v4 as uuidv4 } from "uuid";
|
|
3875
4143
|
var ExportOrchestrator = class {
|
|
3876
4144
|
projectRoot;
|
|
3877
4145
|
constructor(projectRoot) {
|
|
@@ -3917,7 +4185,7 @@ var ExportOrchestrator = class {
|
|
|
3917
4185
|
for (const artifact of artifacts) {
|
|
3918
4186
|
const content = typeof artifact.content === "string" ? Buffer.from(artifact.content, "utf8") : artifact.content;
|
|
3919
4187
|
const { contentHash, blobPath } = await blobStore.writeAtomic(content);
|
|
3920
|
-
const pointerId = `ptr_${
|
|
4188
|
+
const pointerId = `ptr_${v4_default().replace(/-/g, "").slice(0, 16)}`;
|
|
3921
4189
|
await pointerStore.insertPointer({
|
|
3922
4190
|
pointerId,
|
|
3923
4191
|
scanId: effectiveScanId,
|
|
@@ -3950,7 +4218,7 @@ var ExportOrchestrator = class {
|
|
|
3950
4218
|
};
|
|
3951
4219
|
const indexContent = Buffer.from(JSON.stringify(analysisIndex, null, 2), "utf8");
|
|
3952
4220
|
const indexWrite = await blobStore.writeAtomic(indexContent);
|
|
3953
|
-
const indexPointerId = `ptr_${
|
|
4221
|
+
const indexPointerId = `ptr_${v4_default().replace(/-/g, "").slice(0, 16)}`;
|
|
3954
4222
|
await pointerStore.insertPointer({
|
|
3955
4223
|
pointerId: indexPointerId,
|
|
3956
4224
|
scanId: effectiveScanId,
|
|
@@ -4291,7 +4559,6 @@ async function handleGetFileContext(args) {
|
|
|
4291
4559
|
}
|
|
4292
4560
|
|
|
4293
4561
|
// dist/mcp/tools/write_decision_card.js
|
|
4294
|
-
import { v4 as uuidv42 } from "uuid";
|
|
4295
4562
|
import { createHash as createHash5 } from "crypto";
|
|
4296
4563
|
import { readFile as readFile12 } from "fs/promises";
|
|
4297
4564
|
import { join as join16 } from "path";
|
|
@@ -4396,7 +4663,7 @@ async function handleWriteDecisionCard(args, options = {}) {
|
|
|
4396
4663
|
}
|
|
4397
4664
|
const hash = createHash5("sha256").update(primaryContent).digest("hex");
|
|
4398
4665
|
const card = {
|
|
4399
|
-
id:
|
|
4666
|
+
id: v4_default(),
|
|
4400
4667
|
pillar,
|
|
4401
4668
|
title,
|
|
4402
4669
|
thesis,
|
|
@@ -4674,14 +4941,1815 @@ async function handleGetCallChain(args) {
|
|
|
4674
4941
|
import { readFile as readFile13 } from "fs/promises";
|
|
4675
4942
|
import { join as join17 } from "path";
|
|
4676
4943
|
|
|
4944
|
+
// ../../node_modules/balanced-match/dist/esm/index.js
|
|
4945
|
+
var balanced = (a, b, str) => {
|
|
4946
|
+
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
|
4947
|
+
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
|
4948
|
+
const r = ma !== null && mb != null && range(ma, mb, str);
|
|
4949
|
+
return r && {
|
|
4950
|
+
start: r[0],
|
|
4951
|
+
end: r[1],
|
|
4952
|
+
pre: str.slice(0, r[0]),
|
|
4953
|
+
body: str.slice(r[0] + ma.length, r[1]),
|
|
4954
|
+
post: str.slice(r[1] + mb.length)
|
|
4955
|
+
};
|
|
4956
|
+
};
|
|
4957
|
+
var maybeMatch = (reg, str) => {
|
|
4958
|
+
const m = str.match(reg);
|
|
4959
|
+
return m ? m[0] : null;
|
|
4960
|
+
};
|
|
4961
|
+
var range = (a, b, str) => {
|
|
4962
|
+
let begs, beg, left, right = void 0, result;
|
|
4963
|
+
let ai = str.indexOf(a);
|
|
4964
|
+
let bi = str.indexOf(b, ai + 1);
|
|
4965
|
+
let i = ai;
|
|
4966
|
+
if (ai >= 0 && bi > 0) {
|
|
4967
|
+
if (a === b) {
|
|
4968
|
+
return [ai, bi];
|
|
4969
|
+
}
|
|
4970
|
+
begs = [];
|
|
4971
|
+
left = str.length;
|
|
4972
|
+
while (i >= 0 && !result) {
|
|
4973
|
+
if (i === ai) {
|
|
4974
|
+
begs.push(i);
|
|
4975
|
+
ai = str.indexOf(a, i + 1);
|
|
4976
|
+
} else if (begs.length === 1) {
|
|
4977
|
+
const r = begs.pop();
|
|
4978
|
+
if (r !== void 0)
|
|
4979
|
+
result = [r, bi];
|
|
4980
|
+
} else {
|
|
4981
|
+
beg = begs.pop();
|
|
4982
|
+
if (beg !== void 0 && beg < left) {
|
|
4983
|
+
left = beg;
|
|
4984
|
+
right = bi;
|
|
4985
|
+
}
|
|
4986
|
+
bi = str.indexOf(b, i + 1);
|
|
4987
|
+
}
|
|
4988
|
+
i = ai < bi && ai >= 0 ? ai : bi;
|
|
4989
|
+
}
|
|
4990
|
+
if (begs.length && right !== void 0) {
|
|
4991
|
+
result = [left, right];
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
return result;
|
|
4995
|
+
};
|
|
4996
|
+
|
|
4997
|
+
// ../../node_modules/brace-expansion/dist/esm/index.js
|
|
4998
|
+
var escSlash = "\0SLASH" + Math.random() + "\0";
|
|
4999
|
+
var escOpen = "\0OPEN" + Math.random() + "\0";
|
|
5000
|
+
var escClose = "\0CLOSE" + Math.random() + "\0";
|
|
5001
|
+
var escComma = "\0COMMA" + Math.random() + "\0";
|
|
5002
|
+
var escPeriod = "\0PERIOD" + Math.random() + "\0";
|
|
5003
|
+
var escSlashPattern = new RegExp(escSlash, "g");
|
|
5004
|
+
var escOpenPattern = new RegExp(escOpen, "g");
|
|
5005
|
+
var escClosePattern = new RegExp(escClose, "g");
|
|
5006
|
+
var escCommaPattern = new RegExp(escComma, "g");
|
|
5007
|
+
var escPeriodPattern = new RegExp(escPeriod, "g");
|
|
5008
|
+
var slashPattern = /\\\\/g;
|
|
5009
|
+
var openPattern = /\\{/g;
|
|
5010
|
+
var closePattern = /\\}/g;
|
|
5011
|
+
var commaPattern = /\\,/g;
|
|
5012
|
+
var periodPattern = /\\\./g;
|
|
5013
|
+
var EXPANSION_MAX = 1e5;
|
|
5014
|
+
function numeric(str) {
|
|
5015
|
+
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
5016
|
+
}
|
|
5017
|
+
function escapeBraces(str) {
|
|
5018
|
+
return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
|
|
5019
|
+
}
|
|
5020
|
+
function unescapeBraces(str) {
|
|
5021
|
+
return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
|
|
5022
|
+
}
|
|
5023
|
+
function parseCommaParts(str) {
|
|
5024
|
+
if (!str) {
|
|
5025
|
+
return [""];
|
|
5026
|
+
}
|
|
5027
|
+
const parts = [];
|
|
5028
|
+
const m = balanced("{", "}", str);
|
|
5029
|
+
if (!m) {
|
|
5030
|
+
return str.split(",");
|
|
5031
|
+
}
|
|
5032
|
+
const { pre, body, post } = m;
|
|
5033
|
+
const p = pre.split(",");
|
|
5034
|
+
p[p.length - 1] += "{" + body + "}";
|
|
5035
|
+
const postParts = parseCommaParts(post);
|
|
5036
|
+
if (post.length) {
|
|
5037
|
+
;
|
|
5038
|
+
p[p.length - 1] += postParts.shift();
|
|
5039
|
+
p.push.apply(p, postParts);
|
|
5040
|
+
}
|
|
5041
|
+
parts.push.apply(parts, p);
|
|
5042
|
+
return parts;
|
|
5043
|
+
}
|
|
5044
|
+
function expand(str, options = {}) {
|
|
5045
|
+
if (!str) {
|
|
5046
|
+
return [];
|
|
5047
|
+
}
|
|
5048
|
+
const { max = EXPANSION_MAX } = options;
|
|
5049
|
+
if (str.slice(0, 2) === "{}") {
|
|
5050
|
+
str = "\\{\\}" + str.slice(2);
|
|
5051
|
+
}
|
|
5052
|
+
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
|
|
5053
|
+
}
|
|
5054
|
+
function embrace(str) {
|
|
5055
|
+
return "{" + str + "}";
|
|
5056
|
+
}
|
|
5057
|
+
function isPadded(el) {
|
|
5058
|
+
return /^-?0\d/.test(el);
|
|
5059
|
+
}
|
|
5060
|
+
function lte(i, y) {
|
|
5061
|
+
return i <= y;
|
|
5062
|
+
}
|
|
5063
|
+
function gte(i, y) {
|
|
5064
|
+
return i >= y;
|
|
5065
|
+
}
|
|
5066
|
+
function expand_(str, max, isTop) {
|
|
5067
|
+
const expansions = [];
|
|
5068
|
+
const m = balanced("{", "}", str);
|
|
5069
|
+
if (!m)
|
|
5070
|
+
return [str];
|
|
5071
|
+
const pre = m.pre;
|
|
5072
|
+
const post = m.post.length ? expand_(m.post, max, false) : [""];
|
|
5073
|
+
if (/\$$/.test(m.pre)) {
|
|
5074
|
+
for (let k = 0; k < post.length && k < max; k++) {
|
|
5075
|
+
const expansion = pre + "{" + m.body + "}" + post[k];
|
|
5076
|
+
expansions.push(expansion);
|
|
5077
|
+
}
|
|
5078
|
+
} else {
|
|
5079
|
+
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
5080
|
+
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
5081
|
+
const isSequence = isNumericSequence || isAlphaSequence;
|
|
5082
|
+
const isOptions = m.body.indexOf(",") >= 0;
|
|
5083
|
+
if (!isSequence && !isOptions) {
|
|
5084
|
+
if (m.post.match(/,(?!,).*\}/)) {
|
|
5085
|
+
str = m.pre + "{" + m.body + escClose + m.post;
|
|
5086
|
+
return expand_(str, max, true);
|
|
5087
|
+
}
|
|
5088
|
+
return [str];
|
|
5089
|
+
}
|
|
5090
|
+
let n;
|
|
5091
|
+
if (isSequence) {
|
|
5092
|
+
n = m.body.split(/\.\./);
|
|
5093
|
+
} else {
|
|
5094
|
+
n = parseCommaParts(m.body);
|
|
5095
|
+
if (n.length === 1 && n[0] !== void 0) {
|
|
5096
|
+
n = expand_(n[0], max, false).map(embrace);
|
|
5097
|
+
if (n.length === 1) {
|
|
5098
|
+
return post.map((p) => m.pre + n[0] + p);
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
let N;
|
|
5103
|
+
if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
|
|
5104
|
+
const x = numeric(n[0]);
|
|
5105
|
+
const y = numeric(n[1]);
|
|
5106
|
+
const width = Math.max(n[0].length, n[1].length);
|
|
5107
|
+
let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
|
|
5108
|
+
let test = lte;
|
|
5109
|
+
const reverse = y < x;
|
|
5110
|
+
if (reverse) {
|
|
5111
|
+
incr *= -1;
|
|
5112
|
+
test = gte;
|
|
5113
|
+
}
|
|
5114
|
+
const pad = n.some(isPadded);
|
|
5115
|
+
N = [];
|
|
5116
|
+
for (let i = x; test(i, y) && N.length < max; i += incr) {
|
|
5117
|
+
let c;
|
|
5118
|
+
if (isAlphaSequence) {
|
|
5119
|
+
c = String.fromCharCode(i);
|
|
5120
|
+
if (c === "\\") {
|
|
5121
|
+
c = "";
|
|
5122
|
+
}
|
|
5123
|
+
} else {
|
|
5124
|
+
c = String(i);
|
|
5125
|
+
if (pad) {
|
|
5126
|
+
const need = width - c.length;
|
|
5127
|
+
if (need > 0) {
|
|
5128
|
+
const z = new Array(need + 1).join("0");
|
|
5129
|
+
if (i < 0) {
|
|
5130
|
+
c = "-" + z + c.slice(1);
|
|
5131
|
+
} else {
|
|
5132
|
+
c = z + c;
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
}
|
|
5137
|
+
N.push(c);
|
|
5138
|
+
}
|
|
5139
|
+
} else {
|
|
5140
|
+
N = [];
|
|
5141
|
+
for (let j = 0; j < n.length; j++) {
|
|
5142
|
+
N.push.apply(N, expand_(n[j], max, false));
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
for (let j = 0; j < N.length; j++) {
|
|
5146
|
+
for (let k = 0; k < post.length && expansions.length < max; k++) {
|
|
5147
|
+
const expansion = pre + N[j] + post[k];
|
|
5148
|
+
if (!isTop || isSequence || expansion) {
|
|
5149
|
+
expansions.push(expansion);
|
|
5150
|
+
}
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
}
|
|
5154
|
+
return expansions;
|
|
5155
|
+
}
|
|
5156
|
+
|
|
5157
|
+
// ../../node_modules/minimatch/dist/esm/assert-valid-pattern.js
|
|
5158
|
+
var MAX_PATTERN_LENGTH = 1024 * 64;
|
|
5159
|
+
var assertValidPattern = (pattern) => {
|
|
5160
|
+
if (typeof pattern !== "string") {
|
|
5161
|
+
throw new TypeError("invalid pattern");
|
|
5162
|
+
}
|
|
5163
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
5164
|
+
throw new TypeError("pattern is too long");
|
|
5165
|
+
}
|
|
5166
|
+
};
|
|
5167
|
+
|
|
5168
|
+
// ../../node_modules/minimatch/dist/esm/brace-expressions.js
|
|
5169
|
+
var posixClasses = {
|
|
5170
|
+
"[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
|
|
5171
|
+
"[:alpha:]": ["\\p{L}\\p{Nl}", true],
|
|
5172
|
+
"[:ascii:]": ["\\x00-\\x7f", false],
|
|
5173
|
+
"[:blank:]": ["\\p{Zs}\\t", true],
|
|
5174
|
+
"[:cntrl:]": ["\\p{Cc}", true],
|
|
5175
|
+
"[:digit:]": ["\\p{Nd}", true],
|
|
5176
|
+
"[:graph:]": ["\\p{Z}\\p{C}", true, true],
|
|
5177
|
+
"[:lower:]": ["\\p{Ll}", true],
|
|
5178
|
+
"[:print:]": ["\\p{C}", true],
|
|
5179
|
+
"[:punct:]": ["\\p{P}", true],
|
|
5180
|
+
"[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", true],
|
|
5181
|
+
"[:upper:]": ["\\p{Lu}", true],
|
|
5182
|
+
"[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", true],
|
|
5183
|
+
"[:xdigit:]": ["A-Fa-f0-9", false]
|
|
5184
|
+
};
|
|
5185
|
+
var braceEscape = (s) => s.replace(/[[\]\\-]/g, "\\$&");
|
|
5186
|
+
var regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
5187
|
+
var rangesToString = (ranges) => ranges.join("");
|
|
5188
|
+
var parseClass = (glob, position) => {
|
|
5189
|
+
const pos = position;
|
|
5190
|
+
if (glob.charAt(pos) !== "[") {
|
|
5191
|
+
throw new Error("not in a brace expression");
|
|
5192
|
+
}
|
|
5193
|
+
const ranges = [];
|
|
5194
|
+
const negs = [];
|
|
5195
|
+
let i = pos + 1;
|
|
5196
|
+
let sawStart = false;
|
|
5197
|
+
let uflag = false;
|
|
5198
|
+
let escaping = false;
|
|
5199
|
+
let negate = false;
|
|
5200
|
+
let endPos = pos;
|
|
5201
|
+
let rangeStart = "";
|
|
5202
|
+
WHILE: while (i < glob.length) {
|
|
5203
|
+
const c = glob.charAt(i);
|
|
5204
|
+
if ((c === "!" || c === "^") && i === pos + 1) {
|
|
5205
|
+
negate = true;
|
|
5206
|
+
i++;
|
|
5207
|
+
continue;
|
|
5208
|
+
}
|
|
5209
|
+
if (c === "]" && sawStart && !escaping) {
|
|
5210
|
+
endPos = i + 1;
|
|
5211
|
+
break;
|
|
5212
|
+
}
|
|
5213
|
+
sawStart = true;
|
|
5214
|
+
if (c === "\\") {
|
|
5215
|
+
if (!escaping) {
|
|
5216
|
+
escaping = true;
|
|
5217
|
+
i++;
|
|
5218
|
+
continue;
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
if (c === "[" && !escaping) {
|
|
5222
|
+
for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
|
|
5223
|
+
if (glob.startsWith(cls, i)) {
|
|
5224
|
+
if (rangeStart) {
|
|
5225
|
+
return ["$.", false, glob.length - pos, true];
|
|
5226
|
+
}
|
|
5227
|
+
i += cls.length;
|
|
5228
|
+
if (neg)
|
|
5229
|
+
negs.push(unip);
|
|
5230
|
+
else
|
|
5231
|
+
ranges.push(unip);
|
|
5232
|
+
uflag = uflag || u;
|
|
5233
|
+
continue WHILE;
|
|
5234
|
+
}
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
escaping = false;
|
|
5238
|
+
if (rangeStart) {
|
|
5239
|
+
if (c > rangeStart) {
|
|
5240
|
+
ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c));
|
|
5241
|
+
} else if (c === rangeStart) {
|
|
5242
|
+
ranges.push(braceEscape(c));
|
|
5243
|
+
}
|
|
5244
|
+
rangeStart = "";
|
|
5245
|
+
i++;
|
|
5246
|
+
continue;
|
|
5247
|
+
}
|
|
5248
|
+
if (glob.startsWith("-]", i + 1)) {
|
|
5249
|
+
ranges.push(braceEscape(c + "-"));
|
|
5250
|
+
i += 2;
|
|
5251
|
+
continue;
|
|
5252
|
+
}
|
|
5253
|
+
if (glob.startsWith("-", i + 1)) {
|
|
5254
|
+
rangeStart = c;
|
|
5255
|
+
i += 2;
|
|
5256
|
+
continue;
|
|
5257
|
+
}
|
|
5258
|
+
ranges.push(braceEscape(c));
|
|
5259
|
+
i++;
|
|
5260
|
+
}
|
|
5261
|
+
if (endPos < i) {
|
|
5262
|
+
return ["", false, 0, false];
|
|
5263
|
+
}
|
|
5264
|
+
if (!ranges.length && !negs.length) {
|
|
5265
|
+
return ["$.", false, glob.length - pos, true];
|
|
5266
|
+
}
|
|
5267
|
+
if (negs.length === 0 && ranges.length === 1 && /^\\?.$/.test(ranges[0]) && !negate) {
|
|
5268
|
+
const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
|
|
5269
|
+
return [regexpEscape(r), false, endPos - pos, false];
|
|
5270
|
+
}
|
|
5271
|
+
const sranges = "[" + (negate ? "^" : "") + rangesToString(ranges) + "]";
|
|
5272
|
+
const snegs = "[" + (negate ? "" : "^") + rangesToString(negs) + "]";
|
|
5273
|
+
const comb = ranges.length && negs.length ? "(" + sranges + "|" + snegs + ")" : ranges.length ? sranges : snegs;
|
|
5274
|
+
return [comb, uflag, endPos - pos, true];
|
|
5275
|
+
};
|
|
5276
|
+
|
|
5277
|
+
// ../../node_modules/minimatch/dist/esm/unescape.js
|
|
5278
|
+
var unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
|
|
5279
|
+
if (magicalBraces) {
|
|
5280
|
+
return windowsPathsNoEscape ? s.replace(/\[([^/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^/\\])\]/g, "$1$2").replace(/\\([^/])/g, "$1");
|
|
5281
|
+
}
|
|
5282
|
+
return windowsPathsNoEscape ? s.replace(/\[([^/\\{}])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^/\\{}])\]/g, "$1$2").replace(/\\([^/{}])/g, "$1");
|
|
5283
|
+
};
|
|
5284
|
+
|
|
5285
|
+
// ../../node_modules/minimatch/dist/esm/ast.js
|
|
5286
|
+
var _a;
|
|
5287
|
+
var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
|
|
5288
|
+
var isExtglobType = (c) => types.has(c);
|
|
5289
|
+
var isExtglobAST = (c) => isExtglobType(c.type);
|
|
5290
|
+
var adoptionMap = /* @__PURE__ */ new Map([
|
|
5291
|
+
["!", ["@"]],
|
|
5292
|
+
["?", ["?", "@"]],
|
|
5293
|
+
["@", ["@"]],
|
|
5294
|
+
["*", ["*", "+", "?", "@"]],
|
|
5295
|
+
["+", ["+", "@"]]
|
|
5296
|
+
]);
|
|
5297
|
+
var adoptionWithSpaceMap = /* @__PURE__ */ new Map([
|
|
5298
|
+
["!", ["?"]],
|
|
5299
|
+
["@", ["?"]],
|
|
5300
|
+
["+", ["?", "*"]]
|
|
5301
|
+
]);
|
|
5302
|
+
var adoptionAnyMap = /* @__PURE__ */ new Map([
|
|
5303
|
+
["!", ["?", "@"]],
|
|
5304
|
+
["?", ["?", "@"]],
|
|
5305
|
+
["@", ["?", "@"]],
|
|
5306
|
+
["*", ["*", "+", "?", "@"]],
|
|
5307
|
+
["+", ["+", "@", "?", "*"]]
|
|
5308
|
+
]);
|
|
5309
|
+
var usurpMap = /* @__PURE__ */ new Map([
|
|
5310
|
+
["!", /* @__PURE__ */ new Map([["!", "@"]])],
|
|
5311
|
+
[
|
|
5312
|
+
"?",
|
|
5313
|
+
/* @__PURE__ */ new Map([
|
|
5314
|
+
["*", "*"],
|
|
5315
|
+
["+", "*"]
|
|
5316
|
+
])
|
|
5317
|
+
],
|
|
5318
|
+
[
|
|
5319
|
+
"@",
|
|
5320
|
+
/* @__PURE__ */ new Map([
|
|
5321
|
+
["!", "!"],
|
|
5322
|
+
["?", "?"],
|
|
5323
|
+
["@", "@"],
|
|
5324
|
+
["*", "*"],
|
|
5325
|
+
["+", "+"]
|
|
5326
|
+
])
|
|
5327
|
+
],
|
|
5328
|
+
[
|
|
5329
|
+
"+",
|
|
5330
|
+
/* @__PURE__ */ new Map([
|
|
5331
|
+
["?", "*"],
|
|
5332
|
+
["*", "*"]
|
|
5333
|
+
])
|
|
5334
|
+
]
|
|
5335
|
+
]);
|
|
5336
|
+
var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
|
|
5337
|
+
var startNoDot = "(?!\\.)";
|
|
5338
|
+
var addPatternStart = /* @__PURE__ */ new Set(["[", "."]);
|
|
5339
|
+
var justDots = /* @__PURE__ */ new Set(["..", "."]);
|
|
5340
|
+
var reSpecials = new Set("().*{}+?[]^$\\!");
|
|
5341
|
+
var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
5342
|
+
var qmark = "[^/]";
|
|
5343
|
+
var star = qmark + "*?";
|
|
5344
|
+
var starNoEmpty = qmark + "+?";
|
|
5345
|
+
var ID = 0;
|
|
5346
|
+
var AST = class {
|
|
5347
|
+
type;
|
|
5348
|
+
#root;
|
|
5349
|
+
#hasMagic;
|
|
5350
|
+
#uflag = false;
|
|
5351
|
+
#parts = [];
|
|
5352
|
+
#parent;
|
|
5353
|
+
#parentIndex;
|
|
5354
|
+
#negs;
|
|
5355
|
+
#filledNegs = false;
|
|
5356
|
+
#options;
|
|
5357
|
+
#toString;
|
|
5358
|
+
// set to true if it's an extglob with no children
|
|
5359
|
+
// (which really means one child of '')
|
|
5360
|
+
#emptyExt = false;
|
|
5361
|
+
id = ++ID;
|
|
5362
|
+
get depth() {
|
|
5363
|
+
return (this.#parent?.depth ?? -1) + 1;
|
|
5364
|
+
}
|
|
5365
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
5366
|
+
return {
|
|
5367
|
+
"@@type": "AST",
|
|
5368
|
+
id: this.id,
|
|
5369
|
+
type: this.type,
|
|
5370
|
+
root: this.#root.id,
|
|
5371
|
+
parent: this.#parent?.id,
|
|
5372
|
+
depth: this.depth,
|
|
5373
|
+
partsLength: this.#parts.length,
|
|
5374
|
+
parts: this.#parts
|
|
5375
|
+
};
|
|
5376
|
+
}
|
|
5377
|
+
constructor(type, parent, options = {}) {
|
|
5378
|
+
this.type = type;
|
|
5379
|
+
if (type)
|
|
5380
|
+
this.#hasMagic = true;
|
|
5381
|
+
this.#parent = parent;
|
|
5382
|
+
this.#root = this.#parent ? this.#parent.#root : this;
|
|
5383
|
+
this.#options = this.#root === this ? options : this.#root.#options;
|
|
5384
|
+
this.#negs = this.#root === this ? [] : this.#root.#negs;
|
|
5385
|
+
if (type === "!" && !this.#root.#filledNegs)
|
|
5386
|
+
this.#negs.push(this);
|
|
5387
|
+
this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
|
|
5388
|
+
}
|
|
5389
|
+
get hasMagic() {
|
|
5390
|
+
if (this.#hasMagic !== void 0)
|
|
5391
|
+
return this.#hasMagic;
|
|
5392
|
+
for (const p of this.#parts) {
|
|
5393
|
+
if (typeof p === "string")
|
|
5394
|
+
continue;
|
|
5395
|
+
if (p.type || p.hasMagic)
|
|
5396
|
+
return this.#hasMagic = true;
|
|
5397
|
+
}
|
|
5398
|
+
return this.#hasMagic;
|
|
5399
|
+
}
|
|
5400
|
+
// reconstructs the pattern
|
|
5401
|
+
toString() {
|
|
5402
|
+
return this.#toString !== void 0 ? this.#toString : !this.type ? this.#toString = this.#parts.map((p) => String(p)).join("") : this.#toString = this.type + "(" + this.#parts.map((p) => String(p)).join("|") + ")";
|
|
5403
|
+
}
|
|
5404
|
+
#fillNegs() {
|
|
5405
|
+
if (this !== this.#root)
|
|
5406
|
+
throw new Error("should only call on root");
|
|
5407
|
+
if (this.#filledNegs)
|
|
5408
|
+
return this;
|
|
5409
|
+
this.toString();
|
|
5410
|
+
this.#filledNegs = true;
|
|
5411
|
+
let n;
|
|
5412
|
+
while (n = this.#negs.pop()) {
|
|
5413
|
+
if (n.type !== "!")
|
|
5414
|
+
continue;
|
|
5415
|
+
let p = n;
|
|
5416
|
+
let pp = p.#parent;
|
|
5417
|
+
while (pp) {
|
|
5418
|
+
for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
|
|
5419
|
+
for (const part of n.#parts) {
|
|
5420
|
+
if (typeof part === "string") {
|
|
5421
|
+
throw new Error("string part in extglob AST??");
|
|
5422
|
+
}
|
|
5423
|
+
part.copyIn(pp.#parts[i]);
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
p = pp;
|
|
5427
|
+
pp = p.#parent;
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
return this;
|
|
5431
|
+
}
|
|
5432
|
+
push(...parts) {
|
|
5433
|
+
for (const p of parts) {
|
|
5434
|
+
if (p === "")
|
|
5435
|
+
continue;
|
|
5436
|
+
if (typeof p !== "string" && !(p instanceof _a && p.#parent === this)) {
|
|
5437
|
+
throw new Error("invalid part: " + p);
|
|
5438
|
+
}
|
|
5439
|
+
this.#parts.push(p);
|
|
5440
|
+
}
|
|
5441
|
+
}
|
|
5442
|
+
toJSON() {
|
|
5443
|
+
const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
|
|
5444
|
+
if (this.isStart() && !this.type)
|
|
5445
|
+
ret.unshift([]);
|
|
5446
|
+
if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && this.#parent?.type === "!")) {
|
|
5447
|
+
ret.push({});
|
|
5448
|
+
}
|
|
5449
|
+
return ret;
|
|
5450
|
+
}
|
|
5451
|
+
isStart() {
|
|
5452
|
+
if (this.#root === this)
|
|
5453
|
+
return true;
|
|
5454
|
+
if (!this.#parent?.isStart())
|
|
5455
|
+
return false;
|
|
5456
|
+
if (this.#parentIndex === 0)
|
|
5457
|
+
return true;
|
|
5458
|
+
const p = this.#parent;
|
|
5459
|
+
for (let i = 0; i < this.#parentIndex; i++) {
|
|
5460
|
+
const pp = p.#parts[i];
|
|
5461
|
+
if (!(pp instanceof _a && pp.type === "!")) {
|
|
5462
|
+
return false;
|
|
5463
|
+
}
|
|
5464
|
+
}
|
|
5465
|
+
return true;
|
|
5466
|
+
}
|
|
5467
|
+
isEnd() {
|
|
5468
|
+
if (this.#root === this)
|
|
5469
|
+
return true;
|
|
5470
|
+
if (this.#parent?.type === "!")
|
|
5471
|
+
return true;
|
|
5472
|
+
if (!this.#parent?.isEnd())
|
|
5473
|
+
return false;
|
|
5474
|
+
if (!this.type)
|
|
5475
|
+
return this.#parent?.isEnd();
|
|
5476
|
+
const pl = this.#parent ? this.#parent.#parts.length : 0;
|
|
5477
|
+
return this.#parentIndex === pl - 1;
|
|
5478
|
+
}
|
|
5479
|
+
copyIn(part) {
|
|
5480
|
+
if (typeof part === "string")
|
|
5481
|
+
this.push(part);
|
|
5482
|
+
else
|
|
5483
|
+
this.push(part.clone(this));
|
|
5484
|
+
}
|
|
5485
|
+
clone(parent) {
|
|
5486
|
+
const c = new _a(this.type, parent);
|
|
5487
|
+
for (const p of this.#parts) {
|
|
5488
|
+
c.copyIn(p);
|
|
5489
|
+
}
|
|
5490
|
+
return c;
|
|
5491
|
+
}
|
|
5492
|
+
static #parseAST(str, ast, pos, opt, extDepth) {
|
|
5493
|
+
const maxDepth = opt.maxExtglobRecursion ?? 2;
|
|
5494
|
+
let escaping = false;
|
|
5495
|
+
let inBrace = false;
|
|
5496
|
+
let braceStart = -1;
|
|
5497
|
+
let braceNeg = false;
|
|
5498
|
+
if (ast.type === null) {
|
|
5499
|
+
let i2 = pos;
|
|
5500
|
+
let acc2 = "";
|
|
5501
|
+
while (i2 < str.length) {
|
|
5502
|
+
const c = str.charAt(i2++);
|
|
5503
|
+
if (escaping || c === "\\") {
|
|
5504
|
+
escaping = !escaping;
|
|
5505
|
+
acc2 += c;
|
|
5506
|
+
continue;
|
|
5507
|
+
}
|
|
5508
|
+
if (inBrace) {
|
|
5509
|
+
if (i2 === braceStart + 1) {
|
|
5510
|
+
if (c === "^" || c === "!") {
|
|
5511
|
+
braceNeg = true;
|
|
5512
|
+
}
|
|
5513
|
+
} else if (c === "]" && !(i2 === braceStart + 2 && braceNeg)) {
|
|
5514
|
+
inBrace = false;
|
|
5515
|
+
}
|
|
5516
|
+
acc2 += c;
|
|
5517
|
+
continue;
|
|
5518
|
+
} else if (c === "[") {
|
|
5519
|
+
inBrace = true;
|
|
5520
|
+
braceStart = i2;
|
|
5521
|
+
braceNeg = false;
|
|
5522
|
+
acc2 += c;
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5525
|
+
const doRecurse = !opt.noext && isExtglobType(c) && str.charAt(i2) === "(" && extDepth <= maxDepth;
|
|
5526
|
+
if (doRecurse) {
|
|
5527
|
+
ast.push(acc2);
|
|
5528
|
+
acc2 = "";
|
|
5529
|
+
const ext2 = new _a(c, ast);
|
|
5530
|
+
i2 = _a.#parseAST(str, ext2, i2, opt, extDepth + 1);
|
|
5531
|
+
ast.push(ext2);
|
|
5532
|
+
continue;
|
|
5533
|
+
}
|
|
5534
|
+
acc2 += c;
|
|
5535
|
+
}
|
|
5536
|
+
ast.push(acc2);
|
|
5537
|
+
return i2;
|
|
5538
|
+
}
|
|
5539
|
+
let i = pos + 1;
|
|
5540
|
+
let part = new _a(null, ast);
|
|
5541
|
+
const parts = [];
|
|
5542
|
+
let acc = "";
|
|
5543
|
+
while (i < str.length) {
|
|
5544
|
+
const c = str.charAt(i++);
|
|
5545
|
+
if (escaping || c === "\\") {
|
|
5546
|
+
escaping = !escaping;
|
|
5547
|
+
acc += c;
|
|
5548
|
+
continue;
|
|
5549
|
+
}
|
|
5550
|
+
if (inBrace) {
|
|
5551
|
+
if (i === braceStart + 1) {
|
|
5552
|
+
if (c === "^" || c === "!") {
|
|
5553
|
+
braceNeg = true;
|
|
5554
|
+
}
|
|
5555
|
+
} else if (c === "]" && !(i === braceStart + 2 && braceNeg)) {
|
|
5556
|
+
inBrace = false;
|
|
5557
|
+
}
|
|
5558
|
+
acc += c;
|
|
5559
|
+
continue;
|
|
5560
|
+
} else if (c === "[") {
|
|
5561
|
+
inBrace = true;
|
|
5562
|
+
braceStart = i;
|
|
5563
|
+
braceNeg = false;
|
|
5564
|
+
acc += c;
|
|
5565
|
+
continue;
|
|
5566
|
+
}
|
|
5567
|
+
const doRecurse = !opt.noext && isExtglobType(c) && str.charAt(i) === "(" && /* c8 ignore start - the maxDepth is sufficient here */
|
|
5568
|
+
(extDepth <= maxDepth || ast && ast.#canAdoptType(c));
|
|
5569
|
+
if (doRecurse) {
|
|
5570
|
+
const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
|
|
5571
|
+
part.push(acc);
|
|
5572
|
+
acc = "";
|
|
5573
|
+
const ext2 = new _a(c, part);
|
|
5574
|
+
part.push(ext2);
|
|
5575
|
+
i = _a.#parseAST(str, ext2, i, opt, extDepth + depthAdd);
|
|
5576
|
+
continue;
|
|
5577
|
+
}
|
|
5578
|
+
if (c === "|") {
|
|
5579
|
+
part.push(acc);
|
|
5580
|
+
acc = "";
|
|
5581
|
+
parts.push(part);
|
|
5582
|
+
part = new _a(null, ast);
|
|
5583
|
+
continue;
|
|
5584
|
+
}
|
|
5585
|
+
if (c === ")") {
|
|
5586
|
+
if (acc === "" && ast.#parts.length === 0) {
|
|
5587
|
+
ast.#emptyExt = true;
|
|
5588
|
+
}
|
|
5589
|
+
part.push(acc);
|
|
5590
|
+
acc = "";
|
|
5591
|
+
ast.push(...parts, part);
|
|
5592
|
+
return i;
|
|
5593
|
+
}
|
|
5594
|
+
acc += c;
|
|
5595
|
+
}
|
|
5596
|
+
ast.type = null;
|
|
5597
|
+
ast.#hasMagic = void 0;
|
|
5598
|
+
ast.#parts = [str.substring(pos - 1)];
|
|
5599
|
+
return i;
|
|
5600
|
+
}
|
|
5601
|
+
#canAdoptWithSpace(child) {
|
|
5602
|
+
return this.#canAdopt(child, adoptionWithSpaceMap);
|
|
5603
|
+
}
|
|
5604
|
+
#canAdopt(child, map = adoptionMap) {
|
|
5605
|
+
if (!child || typeof child !== "object" || child.type !== null || child.#parts.length !== 1 || this.type === null) {
|
|
5606
|
+
return false;
|
|
5607
|
+
}
|
|
5608
|
+
const gc = child.#parts[0];
|
|
5609
|
+
if (!gc || typeof gc !== "object" || gc.type === null) {
|
|
5610
|
+
return false;
|
|
5611
|
+
}
|
|
5612
|
+
return this.#canAdoptType(gc.type, map);
|
|
5613
|
+
}
|
|
5614
|
+
#canAdoptType(c, map = adoptionAnyMap) {
|
|
5615
|
+
return !!map.get(this.type)?.includes(c);
|
|
5616
|
+
}
|
|
5617
|
+
#adoptWithSpace(child, index) {
|
|
5618
|
+
const gc = child.#parts[0];
|
|
5619
|
+
const blank = new _a(null, gc, this.options);
|
|
5620
|
+
blank.#parts.push("");
|
|
5621
|
+
gc.push(blank);
|
|
5622
|
+
this.#adopt(child, index);
|
|
5623
|
+
}
|
|
5624
|
+
#adopt(child, index) {
|
|
5625
|
+
const gc = child.#parts[0];
|
|
5626
|
+
this.#parts.splice(index, 1, ...gc.#parts);
|
|
5627
|
+
for (const p of gc.#parts) {
|
|
5628
|
+
if (typeof p === "object")
|
|
5629
|
+
p.#parent = this;
|
|
5630
|
+
}
|
|
5631
|
+
this.#toString = void 0;
|
|
5632
|
+
}
|
|
5633
|
+
#canUsurpType(c) {
|
|
5634
|
+
const m = usurpMap.get(this.type);
|
|
5635
|
+
return !!m?.has(c);
|
|
5636
|
+
}
|
|
5637
|
+
#canUsurp(child) {
|
|
5638
|
+
if (!child || typeof child !== "object" || child.type !== null || child.#parts.length !== 1 || this.type === null || this.#parts.length !== 1) {
|
|
5639
|
+
return false;
|
|
5640
|
+
}
|
|
5641
|
+
const gc = child.#parts[0];
|
|
5642
|
+
if (!gc || typeof gc !== "object" || gc.type === null) {
|
|
5643
|
+
return false;
|
|
5644
|
+
}
|
|
5645
|
+
return this.#canUsurpType(gc.type);
|
|
5646
|
+
}
|
|
5647
|
+
#usurp(child) {
|
|
5648
|
+
const m = usurpMap.get(this.type);
|
|
5649
|
+
const gc = child.#parts[0];
|
|
5650
|
+
const nt = m?.get(gc.type);
|
|
5651
|
+
if (!nt)
|
|
5652
|
+
return false;
|
|
5653
|
+
this.#parts = gc.#parts;
|
|
5654
|
+
for (const p of this.#parts) {
|
|
5655
|
+
if (typeof p === "object") {
|
|
5656
|
+
p.#parent = this;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
this.type = nt;
|
|
5660
|
+
this.#toString = void 0;
|
|
5661
|
+
this.#emptyExt = false;
|
|
5662
|
+
}
|
|
5663
|
+
static fromGlob(pattern, options = {}) {
|
|
5664
|
+
const ast = new _a(null, void 0, options);
|
|
5665
|
+
_a.#parseAST(pattern, ast, 0, options, 0);
|
|
5666
|
+
return ast;
|
|
5667
|
+
}
|
|
5668
|
+
// returns the regular expression if there's magic, or the unescaped
|
|
5669
|
+
// string if not.
|
|
5670
|
+
toMMPattern() {
|
|
5671
|
+
if (this !== this.#root)
|
|
5672
|
+
return this.#root.toMMPattern();
|
|
5673
|
+
const glob = this.toString();
|
|
5674
|
+
const [re, body, hasMagic, uflag] = this.toRegExpSource();
|
|
5675
|
+
const anyMagic = hasMagic || this.#hasMagic || this.#options.nocase && !this.#options.nocaseMagicOnly && glob.toUpperCase() !== glob.toLowerCase();
|
|
5676
|
+
if (!anyMagic) {
|
|
5677
|
+
return body;
|
|
5678
|
+
}
|
|
5679
|
+
const flags = (this.#options.nocase ? "i" : "") + (uflag ? "u" : "");
|
|
5680
|
+
return Object.assign(new RegExp(`^${re}$`, flags), {
|
|
5681
|
+
_src: re,
|
|
5682
|
+
_glob: glob
|
|
5683
|
+
});
|
|
5684
|
+
}
|
|
5685
|
+
get options() {
|
|
5686
|
+
return this.#options;
|
|
5687
|
+
}
|
|
5688
|
+
// returns the string match, the regexp source, whether there's magic
|
|
5689
|
+
// in the regexp (so a regular expression is required) and whether or
|
|
5690
|
+
// not the uflag is needed for the regular expression (for posix classes)
|
|
5691
|
+
// TODO: instead of injecting the start/end at this point, just return
|
|
5692
|
+
// the BODY of the regexp, along with the start/end portions suitable
|
|
5693
|
+
// for binding the start/end in either a joined full-path makeRe context
|
|
5694
|
+
// (where we bind to (^|/), or a standalone matchPart context (where
|
|
5695
|
+
// we bind to ^, and not /). Otherwise slashes get duped!
|
|
5696
|
+
//
|
|
5697
|
+
// In part-matching mode, the start is:
|
|
5698
|
+
// - if not isStart: nothing
|
|
5699
|
+
// - if traversal possible, but not allowed: ^(?!\.\.?$)
|
|
5700
|
+
// - if dots allowed or not possible: ^
|
|
5701
|
+
// - if dots possible and not allowed: ^(?!\.)
|
|
5702
|
+
// end is:
|
|
5703
|
+
// - if not isEnd(): nothing
|
|
5704
|
+
// - else: $
|
|
5705
|
+
//
|
|
5706
|
+
// In full-path matching mode, we put the slash at the START of the
|
|
5707
|
+
// pattern, so start is:
|
|
5708
|
+
// - if first pattern: same as part-matching mode
|
|
5709
|
+
// - if not isStart(): nothing
|
|
5710
|
+
// - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
|
|
5711
|
+
// - if dots allowed or not possible: /
|
|
5712
|
+
// - if dots possible and not allowed: /(?!\.)
|
|
5713
|
+
// end is:
|
|
5714
|
+
// - if last pattern, same as part-matching mode
|
|
5715
|
+
// - else nothing
|
|
5716
|
+
//
|
|
5717
|
+
// Always put the (?:$|/) on negated tails, though, because that has to be
|
|
5718
|
+
// there to bind the end of the negated pattern portion, and it's easier to
|
|
5719
|
+
// just stick it in now rather than try to inject it later in the middle of
|
|
5720
|
+
// the pattern.
|
|
5721
|
+
//
|
|
5722
|
+
// We can just always return the same end, and leave it up to the caller
|
|
5723
|
+
// to know whether it's going to be used joined or in parts.
|
|
5724
|
+
// And, if the start is adjusted slightly, can do the same there:
|
|
5725
|
+
// - if not isStart: nothing
|
|
5726
|
+
// - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
|
|
5727
|
+
// - if dots allowed or not possible: (?:/|^)
|
|
5728
|
+
// - if dots possible and not allowed: (?:/|^)(?!\.)
|
|
5729
|
+
//
|
|
5730
|
+
// But it's better to have a simpler binding without a conditional, for
|
|
5731
|
+
// performance, so probably better to return both start options.
|
|
5732
|
+
//
|
|
5733
|
+
// Then the caller just ignores the end if it's not the first pattern,
|
|
5734
|
+
// and the start always gets applied.
|
|
5735
|
+
//
|
|
5736
|
+
// But that's always going to be $ if it's the ending pattern, or nothing,
|
|
5737
|
+
// so the caller can just attach $ at the end of the pattern when building.
|
|
5738
|
+
//
|
|
5739
|
+
// So the todo is:
|
|
5740
|
+
// - better detect what kind of start is needed
|
|
5741
|
+
// - return both flavors of starting pattern
|
|
5742
|
+
// - attach $ at the end of the pattern when creating the actual RegExp
|
|
5743
|
+
//
|
|
5744
|
+
// Ah, but wait, no, that all only applies to the root when the first pattern
|
|
5745
|
+
// is not an extglob. If the first pattern IS an extglob, then we need all
|
|
5746
|
+
// that dot prevention biz to live in the extglob portions, because eg
|
|
5747
|
+
// +(*|.x*) can match .xy but not .yx.
|
|
5748
|
+
//
|
|
5749
|
+
// So, return the two flavors if it's #root and the first child is not an
|
|
5750
|
+
// AST, otherwise leave it to the child AST to handle it, and there,
|
|
5751
|
+
// use the (?:^|/) style of start binding.
|
|
5752
|
+
//
|
|
5753
|
+
// Even simplified further:
|
|
5754
|
+
// - Since the start for a join is eg /(?!\.) and the start for a part
|
|
5755
|
+
// is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
|
|
5756
|
+
// or start or whatever) and prepend ^ or / at the Regexp construction.
|
|
5757
|
+
toRegExpSource(allowDot) {
|
|
5758
|
+
const dot = allowDot ?? !!this.#options.dot;
|
|
5759
|
+
if (this.#root === this) {
|
|
5760
|
+
this.#flatten();
|
|
5761
|
+
this.#fillNegs();
|
|
5762
|
+
}
|
|
5763
|
+
if (!isExtglobAST(this)) {
|
|
5764
|
+
const noEmpty = this.isStart() && this.isEnd() && !this.#parts.some((s) => typeof s !== "string");
|
|
5765
|
+
const src = this.#parts.map((p) => {
|
|
5766
|
+
const [re, _, hasMagic, uflag] = typeof p === "string" ? _a.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
|
|
5767
|
+
this.#hasMagic = this.#hasMagic || hasMagic;
|
|
5768
|
+
this.#uflag = this.#uflag || uflag;
|
|
5769
|
+
return re;
|
|
5770
|
+
}).join("");
|
|
5771
|
+
let start2 = "";
|
|
5772
|
+
if (this.isStart()) {
|
|
5773
|
+
if (typeof this.#parts[0] === "string") {
|
|
5774
|
+
const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
|
|
5775
|
+
if (!dotTravAllowed) {
|
|
5776
|
+
const aps = addPatternStart;
|
|
5777
|
+
const needNoTrav = (
|
|
5778
|
+
// dots are allowed, and the pattern starts with [ or .
|
|
5779
|
+
dot && aps.has(src.charAt(0)) || // the pattern starts with \., and then [ or .
|
|
5780
|
+
src.startsWith("\\.") && aps.has(src.charAt(2)) || // the pattern starts with \.\., and then [ or .
|
|
5781
|
+
src.startsWith("\\.\\.") && aps.has(src.charAt(4))
|
|
5782
|
+
);
|
|
5783
|
+
const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
|
|
5784
|
+
start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "";
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
}
|
|
5788
|
+
let end = "";
|
|
5789
|
+
if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") {
|
|
5790
|
+
end = "(?:$|\\/)";
|
|
5791
|
+
}
|
|
5792
|
+
const final2 = start2 + src + end;
|
|
5793
|
+
return [
|
|
5794
|
+
final2,
|
|
5795
|
+
unescape(src),
|
|
5796
|
+
this.#hasMagic = !!this.#hasMagic,
|
|
5797
|
+
this.#uflag
|
|
5798
|
+
];
|
|
5799
|
+
}
|
|
5800
|
+
const repeated = this.type === "*" || this.type === "+";
|
|
5801
|
+
const start = this.type === "!" ? "(?:(?!(?:" : "(?:";
|
|
5802
|
+
let body = this.#partsToRegExp(dot);
|
|
5803
|
+
if (this.isStart() && this.isEnd() && !body && this.type !== "!") {
|
|
5804
|
+
const s = this.toString();
|
|
5805
|
+
const me = this;
|
|
5806
|
+
me.#parts = [s];
|
|
5807
|
+
me.type = null;
|
|
5808
|
+
me.#hasMagic = void 0;
|
|
5809
|
+
return [s, unescape(this.toString()), false, false];
|
|
5810
|
+
}
|
|
5811
|
+
let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
|
|
5812
|
+
if (bodyDotAllowed === body) {
|
|
5813
|
+
bodyDotAllowed = "";
|
|
5814
|
+
}
|
|
5815
|
+
if (bodyDotAllowed) {
|
|
5816
|
+
body = `(?:${body})(?:${bodyDotAllowed})*?`;
|
|
5817
|
+
}
|
|
5818
|
+
let final = "";
|
|
5819
|
+
if (this.type === "!" && this.#emptyExt) {
|
|
5820
|
+
final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty;
|
|
5821
|
+
} else {
|
|
5822
|
+
const close = this.type === "!" ? (
|
|
5823
|
+
// !() must match something,but !(x) can match ''
|
|
5824
|
+
"))" + (this.isStart() && !dot && !allowDot ? startNoDot : "") + star + ")"
|
|
5825
|
+
) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && bodyDotAllowed ? ")" : this.type === "*" && bodyDotAllowed ? `)?` : `)${this.type}`;
|
|
5826
|
+
final = start + body + close;
|
|
5827
|
+
}
|
|
5828
|
+
return [
|
|
5829
|
+
final,
|
|
5830
|
+
unescape(body),
|
|
5831
|
+
this.#hasMagic = !!this.#hasMagic,
|
|
5832
|
+
this.#uflag
|
|
5833
|
+
];
|
|
5834
|
+
}
|
|
5835
|
+
#flatten() {
|
|
5836
|
+
if (!isExtglobAST(this)) {
|
|
5837
|
+
for (const p of this.#parts) {
|
|
5838
|
+
if (typeof p === "object") {
|
|
5839
|
+
p.#flatten();
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
} else {
|
|
5843
|
+
let iterations = 0;
|
|
5844
|
+
let done = false;
|
|
5845
|
+
do {
|
|
5846
|
+
done = true;
|
|
5847
|
+
for (let i = 0; i < this.#parts.length; i++) {
|
|
5848
|
+
const c = this.#parts[i];
|
|
5849
|
+
if (typeof c === "object") {
|
|
5850
|
+
c.#flatten();
|
|
5851
|
+
if (this.#canAdopt(c)) {
|
|
5852
|
+
done = false;
|
|
5853
|
+
this.#adopt(c, i);
|
|
5854
|
+
} else if (this.#canAdoptWithSpace(c)) {
|
|
5855
|
+
done = false;
|
|
5856
|
+
this.#adoptWithSpace(c, i);
|
|
5857
|
+
} else if (this.#canUsurp(c)) {
|
|
5858
|
+
done = false;
|
|
5859
|
+
this.#usurp(c);
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
} while (!done && ++iterations < 10);
|
|
5864
|
+
}
|
|
5865
|
+
this.#toString = void 0;
|
|
5866
|
+
}
|
|
5867
|
+
#partsToRegExp(dot) {
|
|
5868
|
+
return this.#parts.map((p) => {
|
|
5869
|
+
if (typeof p === "string") {
|
|
5870
|
+
throw new Error("string type in extglob ast??");
|
|
5871
|
+
}
|
|
5872
|
+
const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
|
|
5873
|
+
this.#uflag = this.#uflag || uflag;
|
|
5874
|
+
return re;
|
|
5875
|
+
}).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
|
|
5876
|
+
}
|
|
5877
|
+
static #parseGlob(glob, hasMagic, noEmpty = false) {
|
|
5878
|
+
let escaping = false;
|
|
5879
|
+
let re = "";
|
|
5880
|
+
let uflag = false;
|
|
5881
|
+
let inStar = false;
|
|
5882
|
+
for (let i = 0; i < glob.length; i++) {
|
|
5883
|
+
const c = glob.charAt(i);
|
|
5884
|
+
if (escaping) {
|
|
5885
|
+
escaping = false;
|
|
5886
|
+
re += (reSpecials.has(c) ? "\\" : "") + c;
|
|
5887
|
+
continue;
|
|
5888
|
+
}
|
|
5889
|
+
if (c === "*") {
|
|
5890
|
+
if (inStar)
|
|
5891
|
+
continue;
|
|
5892
|
+
inStar = true;
|
|
5893
|
+
re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star;
|
|
5894
|
+
hasMagic = true;
|
|
5895
|
+
continue;
|
|
5896
|
+
} else {
|
|
5897
|
+
inStar = false;
|
|
5898
|
+
}
|
|
5899
|
+
if (c === "\\") {
|
|
5900
|
+
if (i === glob.length - 1) {
|
|
5901
|
+
re += "\\\\";
|
|
5902
|
+
} else {
|
|
5903
|
+
escaping = true;
|
|
5904
|
+
}
|
|
5905
|
+
continue;
|
|
5906
|
+
}
|
|
5907
|
+
if (c === "[") {
|
|
5908
|
+
const [src, needUflag, consumed, magic] = parseClass(glob, i);
|
|
5909
|
+
if (consumed) {
|
|
5910
|
+
re += src;
|
|
5911
|
+
uflag = uflag || needUflag;
|
|
5912
|
+
i += consumed - 1;
|
|
5913
|
+
hasMagic = hasMagic || magic;
|
|
5914
|
+
continue;
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
if (c === "?") {
|
|
5918
|
+
re += qmark;
|
|
5919
|
+
hasMagic = true;
|
|
5920
|
+
continue;
|
|
5921
|
+
}
|
|
5922
|
+
re += regExpEscape(c);
|
|
5923
|
+
}
|
|
5924
|
+
return [re, unescape(glob), !!hasMagic, uflag];
|
|
5925
|
+
}
|
|
5926
|
+
};
|
|
5927
|
+
_a = AST;
|
|
5928
|
+
|
|
5929
|
+
// ../../node_modules/minimatch/dist/esm/escape.js
|
|
5930
|
+
var escape = (s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
|
|
5931
|
+
if (magicalBraces) {
|
|
5932
|
+
return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
|
|
5933
|
+
}
|
|
5934
|
+
return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
|
|
5935
|
+
};
|
|
5936
|
+
|
|
5937
|
+
// ../../node_modules/minimatch/dist/esm/index.js
|
|
5938
|
+
var minimatch = (p, pattern, options = {}) => {
|
|
5939
|
+
assertValidPattern(pattern);
|
|
5940
|
+
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|
5941
|
+
return false;
|
|
5942
|
+
}
|
|
5943
|
+
return new Minimatch(pattern, options).match(p);
|
|
5944
|
+
};
|
|
5945
|
+
var starDotExtRE = /^\*+([^+@!?*[(]*)$/;
|
|
5946
|
+
var starDotExtTest = (ext2) => (f) => !f.startsWith(".") && f.endsWith(ext2);
|
|
5947
|
+
var starDotExtTestDot = (ext2) => (f) => f.endsWith(ext2);
|
|
5948
|
+
var starDotExtTestNocase = (ext2) => {
|
|
5949
|
+
ext2 = ext2.toLowerCase();
|
|
5950
|
+
return (f) => !f.startsWith(".") && f.toLowerCase().endsWith(ext2);
|
|
5951
|
+
};
|
|
5952
|
+
var starDotExtTestNocaseDot = (ext2) => {
|
|
5953
|
+
ext2 = ext2.toLowerCase();
|
|
5954
|
+
return (f) => f.toLowerCase().endsWith(ext2);
|
|
5955
|
+
};
|
|
5956
|
+
var starDotStarRE = /^\*+\.\*+$/;
|
|
5957
|
+
var starDotStarTest = (f) => !f.startsWith(".") && f.includes(".");
|
|
5958
|
+
var starDotStarTestDot = (f) => f !== "." && f !== ".." && f.includes(".");
|
|
5959
|
+
var dotStarRE = /^\.\*+$/;
|
|
5960
|
+
var dotStarTest = (f) => f !== "." && f !== ".." && f.startsWith(".");
|
|
5961
|
+
var starRE = /^\*+$/;
|
|
5962
|
+
var starTest = (f) => f.length !== 0 && !f.startsWith(".");
|
|
5963
|
+
var starTestDot = (f) => f.length !== 0 && f !== "." && f !== "..";
|
|
5964
|
+
var qmarksRE = /^\?+([^+@!?*[(]*)?$/;
|
|
5965
|
+
var qmarksTestNocase = ([$0, ext2 = ""]) => {
|
|
5966
|
+
const noext = qmarksTestNoExt([$0]);
|
|
5967
|
+
if (!ext2)
|
|
5968
|
+
return noext;
|
|
5969
|
+
ext2 = ext2.toLowerCase();
|
|
5970
|
+
return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
|
|
5971
|
+
};
|
|
5972
|
+
var qmarksTestNocaseDot = ([$0, ext2 = ""]) => {
|
|
5973
|
+
const noext = qmarksTestNoExtDot([$0]);
|
|
5974
|
+
if (!ext2)
|
|
5975
|
+
return noext;
|
|
5976
|
+
ext2 = ext2.toLowerCase();
|
|
5977
|
+
return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
|
|
5978
|
+
};
|
|
5979
|
+
var qmarksTestDot = ([$0, ext2 = ""]) => {
|
|
5980
|
+
const noext = qmarksTestNoExtDot([$0]);
|
|
5981
|
+
return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
|
|
5982
|
+
};
|
|
5983
|
+
var qmarksTest = ([$0, ext2 = ""]) => {
|
|
5984
|
+
const noext = qmarksTestNoExt([$0]);
|
|
5985
|
+
return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
|
|
5986
|
+
};
|
|
5987
|
+
var qmarksTestNoExt = ([$0]) => {
|
|
5988
|
+
const len = $0.length;
|
|
5989
|
+
return (f) => f.length === len && !f.startsWith(".");
|
|
5990
|
+
};
|
|
5991
|
+
var qmarksTestNoExtDot = ([$0]) => {
|
|
5992
|
+
const len = $0.length;
|
|
5993
|
+
return (f) => f.length === len && f !== "." && f !== "..";
|
|
5994
|
+
};
|
|
5995
|
+
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
5996
|
+
var path = {
|
|
5997
|
+
win32: { sep: "\\" },
|
|
5998
|
+
posix: { sep: "/" }
|
|
5999
|
+
};
|
|
6000
|
+
var sep4 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
|
|
6001
|
+
minimatch.sep = sep4;
|
|
6002
|
+
var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
6003
|
+
minimatch.GLOBSTAR = GLOBSTAR;
|
|
6004
|
+
var qmark2 = "[^/]";
|
|
6005
|
+
var star2 = qmark2 + "*?";
|
|
6006
|
+
var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
|
|
6007
|
+
var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
|
|
6008
|
+
var filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
|
|
6009
|
+
minimatch.filter = filter;
|
|
6010
|
+
var ext = (a, b = {}) => Object.assign({}, a, b);
|
|
6011
|
+
var defaults = (def) => {
|
|
6012
|
+
if (!def || typeof def !== "object" || !Object.keys(def).length) {
|
|
6013
|
+
return minimatch;
|
|
6014
|
+
}
|
|
6015
|
+
const orig = minimatch;
|
|
6016
|
+
const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
|
|
6017
|
+
return Object.assign(m, {
|
|
6018
|
+
Minimatch: class Minimatch extends orig.Minimatch {
|
|
6019
|
+
constructor(pattern, options = {}) {
|
|
6020
|
+
super(pattern, ext(def, options));
|
|
6021
|
+
}
|
|
6022
|
+
static defaults(options) {
|
|
6023
|
+
return orig.defaults(ext(def, options)).Minimatch;
|
|
6024
|
+
}
|
|
6025
|
+
},
|
|
6026
|
+
AST: class AST extends orig.AST {
|
|
6027
|
+
/* c8 ignore start */
|
|
6028
|
+
constructor(type, parent, options = {}) {
|
|
6029
|
+
super(type, parent, ext(def, options));
|
|
6030
|
+
}
|
|
6031
|
+
/* c8 ignore stop */
|
|
6032
|
+
static fromGlob(pattern, options = {}) {
|
|
6033
|
+
return orig.AST.fromGlob(pattern, ext(def, options));
|
|
6034
|
+
}
|
|
6035
|
+
},
|
|
6036
|
+
unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
|
|
6037
|
+
escape: (s, options = {}) => orig.escape(s, ext(def, options)),
|
|
6038
|
+
filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
|
|
6039
|
+
defaults: (options) => orig.defaults(ext(def, options)),
|
|
6040
|
+
makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
|
|
6041
|
+
braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
|
|
6042
|
+
match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
|
|
6043
|
+
sep: orig.sep,
|
|
6044
|
+
GLOBSTAR
|
|
6045
|
+
});
|
|
6046
|
+
};
|
|
6047
|
+
minimatch.defaults = defaults;
|
|
6048
|
+
var braceExpand = (pattern, options = {}) => {
|
|
6049
|
+
assertValidPattern(pattern);
|
|
6050
|
+
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
|
|
6051
|
+
return [pattern];
|
|
6052
|
+
}
|
|
6053
|
+
return expand(pattern, { max: options.braceExpandMax });
|
|
6054
|
+
};
|
|
6055
|
+
minimatch.braceExpand = braceExpand;
|
|
6056
|
+
var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
|
|
6057
|
+
minimatch.makeRe = makeRe;
|
|
6058
|
+
var match = (list, pattern, options = {}) => {
|
|
6059
|
+
const mm = new Minimatch(pattern, options);
|
|
6060
|
+
list = list.filter((f) => mm.match(f));
|
|
6061
|
+
if (mm.options.nonull && !list.length) {
|
|
6062
|
+
list.push(pattern);
|
|
6063
|
+
}
|
|
6064
|
+
return list;
|
|
6065
|
+
};
|
|
6066
|
+
minimatch.match = match;
|
|
6067
|
+
var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
|
|
6068
|
+
var regExpEscape2 = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
6069
|
+
var Minimatch = class {
|
|
6070
|
+
options;
|
|
6071
|
+
set;
|
|
6072
|
+
pattern;
|
|
6073
|
+
windowsPathsNoEscape;
|
|
6074
|
+
nonegate;
|
|
6075
|
+
negate;
|
|
6076
|
+
comment;
|
|
6077
|
+
empty;
|
|
6078
|
+
preserveMultipleSlashes;
|
|
6079
|
+
partial;
|
|
6080
|
+
globSet;
|
|
6081
|
+
globParts;
|
|
6082
|
+
nocase;
|
|
6083
|
+
isWindows;
|
|
6084
|
+
platform;
|
|
6085
|
+
windowsNoMagicRoot;
|
|
6086
|
+
maxGlobstarRecursion;
|
|
6087
|
+
regexp;
|
|
6088
|
+
constructor(pattern, options = {}) {
|
|
6089
|
+
assertValidPattern(pattern);
|
|
6090
|
+
options = options || {};
|
|
6091
|
+
this.options = options;
|
|
6092
|
+
this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
|
|
6093
|
+
this.pattern = pattern;
|
|
6094
|
+
this.platform = options.platform || defaultPlatform;
|
|
6095
|
+
this.isWindows = this.platform === "win32";
|
|
6096
|
+
const awe = "allowWindowsEscape";
|
|
6097
|
+
this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options[awe] === false;
|
|
6098
|
+
if (this.windowsPathsNoEscape) {
|
|
6099
|
+
this.pattern = this.pattern.replace(/\\/g, "/");
|
|
6100
|
+
}
|
|
6101
|
+
this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
|
|
6102
|
+
this.regexp = null;
|
|
6103
|
+
this.negate = false;
|
|
6104
|
+
this.nonegate = !!options.nonegate;
|
|
6105
|
+
this.comment = false;
|
|
6106
|
+
this.empty = false;
|
|
6107
|
+
this.partial = !!options.partial;
|
|
6108
|
+
this.nocase = !!this.options.nocase;
|
|
6109
|
+
this.windowsNoMagicRoot = options.windowsNoMagicRoot !== void 0 ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase);
|
|
6110
|
+
this.globSet = [];
|
|
6111
|
+
this.globParts = [];
|
|
6112
|
+
this.set = [];
|
|
6113
|
+
this.make();
|
|
6114
|
+
}
|
|
6115
|
+
hasMagic() {
|
|
6116
|
+
if (this.options.magicalBraces && this.set.length > 1) {
|
|
6117
|
+
return true;
|
|
6118
|
+
}
|
|
6119
|
+
for (const pattern of this.set) {
|
|
6120
|
+
for (const part of pattern) {
|
|
6121
|
+
if (typeof part !== "string")
|
|
6122
|
+
return true;
|
|
6123
|
+
}
|
|
6124
|
+
}
|
|
6125
|
+
return false;
|
|
6126
|
+
}
|
|
6127
|
+
debug(..._) {
|
|
6128
|
+
}
|
|
6129
|
+
make() {
|
|
6130
|
+
const pattern = this.pattern;
|
|
6131
|
+
const options = this.options;
|
|
6132
|
+
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|
6133
|
+
this.comment = true;
|
|
6134
|
+
return;
|
|
6135
|
+
}
|
|
6136
|
+
if (!pattern) {
|
|
6137
|
+
this.empty = true;
|
|
6138
|
+
return;
|
|
6139
|
+
}
|
|
6140
|
+
this.parseNegate();
|
|
6141
|
+
this.globSet = [...new Set(this.braceExpand())];
|
|
6142
|
+
if (options.debug) {
|
|
6143
|
+
this.debug = (...args) => console.error(...args);
|
|
6144
|
+
}
|
|
6145
|
+
this.debug(this.pattern, this.globSet);
|
|
6146
|
+
const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
|
|
6147
|
+
this.globParts = this.preprocess(rawGlobParts);
|
|
6148
|
+
this.debug(this.pattern, this.globParts);
|
|
6149
|
+
let set = this.globParts.map((s, _, __) => {
|
|
6150
|
+
if (this.isWindows && this.windowsNoMagicRoot) {
|
|
6151
|
+
const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
|
|
6152
|
+
const isDrive = /^[a-z]:/i.test(s[0]);
|
|
6153
|
+
if (isUNC) {
|
|
6154
|
+
return [
|
|
6155
|
+
...s.slice(0, 4),
|
|
6156
|
+
...s.slice(4).map((ss) => this.parse(ss))
|
|
6157
|
+
];
|
|
6158
|
+
} else if (isDrive) {
|
|
6159
|
+
return [s[0], ...s.slice(1).map((ss) => this.parse(ss))];
|
|
6160
|
+
}
|
|
6161
|
+
}
|
|
6162
|
+
return s.map((ss) => this.parse(ss));
|
|
6163
|
+
});
|
|
6164
|
+
this.debug(this.pattern, set);
|
|
6165
|
+
this.set = set.filter((s) => s.indexOf(false) === -1);
|
|
6166
|
+
if (this.isWindows) {
|
|
6167
|
+
for (let i = 0; i < this.set.length; i++) {
|
|
6168
|
+
const p = this.set[i];
|
|
6169
|
+
if (p[0] === "" && p[1] === "" && this.globParts[i][2] === "?" && typeof p[3] === "string" && /^[a-z]:$/i.test(p[3])) {
|
|
6170
|
+
p[2] = "?";
|
|
6171
|
+
}
|
|
6172
|
+
}
|
|
6173
|
+
}
|
|
6174
|
+
this.debug(this.pattern, this.set);
|
|
6175
|
+
}
|
|
6176
|
+
// various transforms to equivalent pattern sets that are
|
|
6177
|
+
// faster to process in a filesystem walk. The goal is to
|
|
6178
|
+
// eliminate what we can, and push all ** patterns as far
|
|
6179
|
+
// to the right as possible, even if it increases the number
|
|
6180
|
+
// of patterns that we have to process.
|
|
6181
|
+
preprocess(globParts) {
|
|
6182
|
+
if (this.options.noglobstar) {
|
|
6183
|
+
for (const partset of globParts) {
|
|
6184
|
+
for (let j = 0; j < partset.length; j++) {
|
|
6185
|
+
if (partset[j] === "**") {
|
|
6186
|
+
partset[j] = "*";
|
|
6187
|
+
}
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6190
|
+
}
|
|
6191
|
+
const { optimizationLevel = 1 } = this.options;
|
|
6192
|
+
if (optimizationLevel >= 2) {
|
|
6193
|
+
globParts = this.firstPhasePreProcess(globParts);
|
|
6194
|
+
globParts = this.secondPhasePreProcess(globParts);
|
|
6195
|
+
} else if (optimizationLevel >= 1) {
|
|
6196
|
+
globParts = this.levelOneOptimize(globParts);
|
|
6197
|
+
} else {
|
|
6198
|
+
globParts = this.adjascentGlobstarOptimize(globParts);
|
|
6199
|
+
}
|
|
6200
|
+
return globParts;
|
|
6201
|
+
}
|
|
6202
|
+
// just get rid of adjascent ** portions
|
|
6203
|
+
adjascentGlobstarOptimize(globParts) {
|
|
6204
|
+
return globParts.map((parts) => {
|
|
6205
|
+
let gs = -1;
|
|
6206
|
+
while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
|
|
6207
|
+
let i = gs;
|
|
6208
|
+
while (parts[i + 1] === "**") {
|
|
6209
|
+
i++;
|
|
6210
|
+
}
|
|
6211
|
+
if (i !== gs) {
|
|
6212
|
+
parts.splice(gs, i - gs);
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
return parts;
|
|
6216
|
+
});
|
|
6217
|
+
}
|
|
6218
|
+
// get rid of adjascent ** and resolve .. portions
|
|
6219
|
+
levelOneOptimize(globParts) {
|
|
6220
|
+
return globParts.map((parts) => {
|
|
6221
|
+
parts = parts.reduce((set, part) => {
|
|
6222
|
+
const prev = set[set.length - 1];
|
|
6223
|
+
if (part === "**" && prev === "**") {
|
|
6224
|
+
return set;
|
|
6225
|
+
}
|
|
6226
|
+
if (part === "..") {
|
|
6227
|
+
if (prev && prev !== ".." && prev !== "." && prev !== "**") {
|
|
6228
|
+
set.pop();
|
|
6229
|
+
return set;
|
|
6230
|
+
}
|
|
6231
|
+
}
|
|
6232
|
+
set.push(part);
|
|
6233
|
+
return set;
|
|
6234
|
+
}, []);
|
|
6235
|
+
return parts.length === 0 ? [""] : parts;
|
|
6236
|
+
});
|
|
6237
|
+
}
|
|
6238
|
+
levelTwoFileOptimize(parts) {
|
|
6239
|
+
if (!Array.isArray(parts)) {
|
|
6240
|
+
parts = this.slashSplit(parts);
|
|
6241
|
+
}
|
|
6242
|
+
let didSomething = false;
|
|
6243
|
+
do {
|
|
6244
|
+
didSomething = false;
|
|
6245
|
+
if (!this.preserveMultipleSlashes) {
|
|
6246
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
6247
|
+
const p = parts[i];
|
|
6248
|
+
if (i === 1 && p === "" && parts[0] === "")
|
|
6249
|
+
continue;
|
|
6250
|
+
if (p === "." || p === "") {
|
|
6251
|
+
didSomething = true;
|
|
6252
|
+
parts.splice(i, 1);
|
|
6253
|
+
i--;
|
|
6254
|
+
}
|
|
6255
|
+
}
|
|
6256
|
+
if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
|
|
6257
|
+
didSomething = true;
|
|
6258
|
+
parts.pop();
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6261
|
+
let dd = 0;
|
|
6262
|
+
while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
|
|
6263
|
+
const p = parts[dd - 1];
|
|
6264
|
+
if (p && p !== "." && p !== ".." && p !== "**" && !(this.isWindows && /^[a-z]:$/i.test(p))) {
|
|
6265
|
+
didSomething = true;
|
|
6266
|
+
parts.splice(dd - 1, 2);
|
|
6267
|
+
dd -= 2;
|
|
6268
|
+
}
|
|
6269
|
+
}
|
|
6270
|
+
} while (didSomething);
|
|
6271
|
+
return parts.length === 0 ? [""] : parts;
|
|
6272
|
+
}
|
|
6273
|
+
// First phase: single-pattern processing
|
|
6274
|
+
// <pre> is 1 or more portions
|
|
6275
|
+
// <rest> is 1 or more portions
|
|
6276
|
+
// <p> is any portion other than ., .., '', or **
|
|
6277
|
+
// <e> is . or ''
|
|
6278
|
+
//
|
|
6279
|
+
// **/.. is *brutal* for filesystem walking performance, because
|
|
6280
|
+
// it effectively resets the recursive walk each time it occurs,
|
|
6281
|
+
// and ** cannot be reduced out by a .. pattern part like a regexp
|
|
6282
|
+
// or most strings (other than .., ., and '') can be.
|
|
6283
|
+
//
|
|
6284
|
+
// <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
|
|
6285
|
+
// <pre>/<e>/<rest> -> <pre>/<rest>
|
|
6286
|
+
// <pre>/<p>/../<rest> -> <pre>/<rest>
|
|
6287
|
+
// **/**/<rest> -> **/<rest>
|
|
6288
|
+
//
|
|
6289
|
+
// **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow
|
|
6290
|
+
// this WOULD be allowed if ** did follow symlinks, or * didn't
|
|
6291
|
+
firstPhasePreProcess(globParts) {
|
|
6292
|
+
let didSomething = false;
|
|
6293
|
+
do {
|
|
6294
|
+
didSomething = false;
|
|
6295
|
+
for (let parts of globParts) {
|
|
6296
|
+
let gs = -1;
|
|
6297
|
+
while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
|
|
6298
|
+
let gss = gs;
|
|
6299
|
+
while (parts[gss + 1] === "**") {
|
|
6300
|
+
gss++;
|
|
6301
|
+
}
|
|
6302
|
+
if (gss > gs) {
|
|
6303
|
+
parts.splice(gs + 1, gss - gs);
|
|
6304
|
+
}
|
|
6305
|
+
let next = parts[gs + 1];
|
|
6306
|
+
const p = parts[gs + 2];
|
|
6307
|
+
const p2 = parts[gs + 3];
|
|
6308
|
+
if (next !== "..")
|
|
6309
|
+
continue;
|
|
6310
|
+
if (!p || p === "." || p === ".." || !p2 || p2 === "." || p2 === "..") {
|
|
6311
|
+
continue;
|
|
6312
|
+
}
|
|
6313
|
+
didSomething = true;
|
|
6314
|
+
parts.splice(gs, 1);
|
|
6315
|
+
const other = parts.slice(0);
|
|
6316
|
+
other[gs] = "**";
|
|
6317
|
+
globParts.push(other);
|
|
6318
|
+
gs--;
|
|
6319
|
+
}
|
|
6320
|
+
if (!this.preserveMultipleSlashes) {
|
|
6321
|
+
for (let i = 1; i < parts.length - 1; i++) {
|
|
6322
|
+
const p = parts[i];
|
|
6323
|
+
if (i === 1 && p === "" && parts[0] === "")
|
|
6324
|
+
continue;
|
|
6325
|
+
if (p === "." || p === "") {
|
|
6326
|
+
didSomething = true;
|
|
6327
|
+
parts.splice(i, 1);
|
|
6328
|
+
i--;
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
|
|
6332
|
+
didSomething = true;
|
|
6333
|
+
parts.pop();
|
|
6334
|
+
}
|
|
6335
|
+
}
|
|
6336
|
+
let dd = 0;
|
|
6337
|
+
while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
|
|
6338
|
+
const p = parts[dd - 1];
|
|
6339
|
+
if (p && p !== "." && p !== ".." && p !== "**") {
|
|
6340
|
+
didSomething = true;
|
|
6341
|
+
const needDot = dd === 1 && parts[dd + 1] === "**";
|
|
6342
|
+
const splin = needDot ? ["."] : [];
|
|
6343
|
+
parts.splice(dd - 1, 2, ...splin);
|
|
6344
|
+
if (parts.length === 0)
|
|
6345
|
+
parts.push("");
|
|
6346
|
+
dd -= 2;
|
|
6347
|
+
}
|
|
6348
|
+
}
|
|
6349
|
+
}
|
|
6350
|
+
} while (didSomething);
|
|
6351
|
+
return globParts;
|
|
6352
|
+
}
|
|
6353
|
+
// second phase: multi-pattern dedupes
|
|
6354
|
+
// {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>
|
|
6355
|
+
// {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>
|
|
6356
|
+
// {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>
|
|
6357
|
+
//
|
|
6358
|
+
// {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>
|
|
6359
|
+
// ^-- not valid because ** doens't follow symlinks
|
|
6360
|
+
secondPhasePreProcess(globParts) {
|
|
6361
|
+
for (let i = 0; i < globParts.length - 1; i++) {
|
|
6362
|
+
for (let j = i + 1; j < globParts.length; j++) {
|
|
6363
|
+
const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
|
|
6364
|
+
if (matched) {
|
|
6365
|
+
globParts[i] = [];
|
|
6366
|
+
globParts[j] = matched;
|
|
6367
|
+
break;
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
}
|
|
6371
|
+
return globParts.filter((gs) => gs.length);
|
|
6372
|
+
}
|
|
6373
|
+
partsMatch(a, b, emptyGSMatch = false) {
|
|
6374
|
+
let ai = 0;
|
|
6375
|
+
let bi = 0;
|
|
6376
|
+
let result = [];
|
|
6377
|
+
let which = "";
|
|
6378
|
+
while (ai < a.length && bi < b.length) {
|
|
6379
|
+
if (a[ai] === b[bi]) {
|
|
6380
|
+
result.push(which === "b" ? b[bi] : a[ai]);
|
|
6381
|
+
ai++;
|
|
6382
|
+
bi++;
|
|
6383
|
+
} else if (emptyGSMatch && a[ai] === "**" && b[bi] === a[ai + 1]) {
|
|
6384
|
+
result.push(a[ai]);
|
|
6385
|
+
ai++;
|
|
6386
|
+
} else if (emptyGSMatch && b[bi] === "**" && a[ai] === b[bi + 1]) {
|
|
6387
|
+
result.push(b[bi]);
|
|
6388
|
+
bi++;
|
|
6389
|
+
} else if (a[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
|
|
6390
|
+
if (which === "b")
|
|
6391
|
+
return false;
|
|
6392
|
+
which = "a";
|
|
6393
|
+
result.push(a[ai]);
|
|
6394
|
+
ai++;
|
|
6395
|
+
bi++;
|
|
6396
|
+
} else if (b[bi] === "*" && a[ai] && (this.options.dot || !a[ai].startsWith(".")) && a[ai] !== "**") {
|
|
6397
|
+
if (which === "a")
|
|
6398
|
+
return false;
|
|
6399
|
+
which = "b";
|
|
6400
|
+
result.push(b[bi]);
|
|
6401
|
+
ai++;
|
|
6402
|
+
bi++;
|
|
6403
|
+
} else {
|
|
6404
|
+
return false;
|
|
6405
|
+
}
|
|
6406
|
+
}
|
|
6407
|
+
return a.length === b.length && result;
|
|
6408
|
+
}
|
|
6409
|
+
parseNegate() {
|
|
6410
|
+
if (this.nonegate)
|
|
6411
|
+
return;
|
|
6412
|
+
const pattern = this.pattern;
|
|
6413
|
+
let negate = false;
|
|
6414
|
+
let negateOffset = 0;
|
|
6415
|
+
for (let i = 0; i < pattern.length && pattern.charAt(i) === "!"; i++) {
|
|
6416
|
+
negate = !negate;
|
|
6417
|
+
negateOffset++;
|
|
6418
|
+
}
|
|
6419
|
+
if (negateOffset)
|
|
6420
|
+
this.pattern = pattern.slice(negateOffset);
|
|
6421
|
+
this.negate = negate;
|
|
6422
|
+
}
|
|
6423
|
+
// set partial to true to test if, for example,
|
|
6424
|
+
// "/a/b" matches the start of "/*/b/*/d"
|
|
6425
|
+
// Partial means, if you run out of file before you run
|
|
6426
|
+
// out of pattern, then that's fine, as long as all
|
|
6427
|
+
// the parts match.
|
|
6428
|
+
matchOne(file, pattern, partial = false) {
|
|
6429
|
+
let fileStartIndex = 0;
|
|
6430
|
+
let patternStartIndex = 0;
|
|
6431
|
+
if (this.isWindows) {
|
|
6432
|
+
const fileDrive = typeof file[0] === "string" && /^[a-z]:$/i.test(file[0]);
|
|
6433
|
+
const fileUNC = !fileDrive && file[0] === "" && file[1] === "" && file[2] === "?" && /^[a-z]:$/i.test(file[3]);
|
|
6434
|
+
const patternDrive = typeof pattern[0] === "string" && /^[a-z]:$/i.test(pattern[0]);
|
|
6435
|
+
const patternUNC = !patternDrive && pattern[0] === "" && pattern[1] === "" && pattern[2] === "?" && typeof pattern[3] === "string" && /^[a-z]:$/i.test(pattern[3]);
|
|
6436
|
+
const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0;
|
|
6437
|
+
const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0;
|
|
6438
|
+
if (typeof fdi === "number" && typeof pdi === "number") {
|
|
6439
|
+
const [fd, pd] = [
|
|
6440
|
+
file[fdi],
|
|
6441
|
+
pattern[pdi]
|
|
6442
|
+
];
|
|
6443
|
+
if (fd.toLowerCase() === pd.toLowerCase()) {
|
|
6444
|
+
pattern[pdi] = fd;
|
|
6445
|
+
patternStartIndex = pdi;
|
|
6446
|
+
fileStartIndex = fdi;
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
}
|
|
6450
|
+
const { optimizationLevel = 1 } = this.options;
|
|
6451
|
+
if (optimizationLevel >= 2) {
|
|
6452
|
+
file = this.levelTwoFileOptimize(file);
|
|
6453
|
+
}
|
|
6454
|
+
if (pattern.includes(GLOBSTAR)) {
|
|
6455
|
+
return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
6456
|
+
}
|
|
6457
|
+
return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
|
|
6458
|
+
}
|
|
6459
|
+
#matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
|
|
6460
|
+
const firstgs = pattern.indexOf(GLOBSTAR, patternIndex);
|
|
6461
|
+
const lastgs = pattern.lastIndexOf(GLOBSTAR);
|
|
6462
|
+
const [head, body, tail] = partial ? [
|
|
6463
|
+
pattern.slice(patternIndex, firstgs),
|
|
6464
|
+
pattern.slice(firstgs + 1),
|
|
6465
|
+
[]
|
|
6466
|
+
] : [
|
|
6467
|
+
pattern.slice(patternIndex, firstgs),
|
|
6468
|
+
pattern.slice(firstgs + 1, lastgs),
|
|
6469
|
+
pattern.slice(lastgs + 1)
|
|
6470
|
+
];
|
|
6471
|
+
if (head.length) {
|
|
6472
|
+
const fileHead = file.slice(fileIndex, fileIndex + head.length);
|
|
6473
|
+
if (!this.#matchOne(fileHead, head, partial, 0, 0)) {
|
|
6474
|
+
return false;
|
|
6475
|
+
}
|
|
6476
|
+
fileIndex += head.length;
|
|
6477
|
+
patternIndex += head.length;
|
|
6478
|
+
}
|
|
6479
|
+
let fileTailMatch = 0;
|
|
6480
|
+
if (tail.length) {
|
|
6481
|
+
if (tail.length + fileIndex > file.length)
|
|
6482
|
+
return false;
|
|
6483
|
+
let tailStart = file.length - tail.length;
|
|
6484
|
+
if (this.#matchOne(file, tail, partial, tailStart, 0)) {
|
|
6485
|
+
fileTailMatch = tail.length;
|
|
6486
|
+
} else {
|
|
6487
|
+
if (file[file.length - 1] !== "" || fileIndex + tail.length === file.length) {
|
|
6488
|
+
return false;
|
|
6489
|
+
}
|
|
6490
|
+
tailStart--;
|
|
6491
|
+
if (!this.#matchOne(file, tail, partial, tailStart, 0)) {
|
|
6492
|
+
return false;
|
|
6493
|
+
}
|
|
6494
|
+
fileTailMatch = tail.length + 1;
|
|
6495
|
+
}
|
|
6496
|
+
}
|
|
6497
|
+
if (!body.length) {
|
|
6498
|
+
let sawSome = !!fileTailMatch;
|
|
6499
|
+
for (let i2 = fileIndex; i2 < file.length - fileTailMatch; i2++) {
|
|
6500
|
+
const f = String(file[i2]);
|
|
6501
|
+
sawSome = true;
|
|
6502
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
6503
|
+
return false;
|
|
6504
|
+
}
|
|
6505
|
+
}
|
|
6506
|
+
return partial || sawSome;
|
|
6507
|
+
}
|
|
6508
|
+
const bodySegments = [[[], 0]];
|
|
6509
|
+
let currentBody = bodySegments[0];
|
|
6510
|
+
let nonGsParts = 0;
|
|
6511
|
+
const nonGsPartsSums = [0];
|
|
6512
|
+
for (const b of body) {
|
|
6513
|
+
if (b === GLOBSTAR) {
|
|
6514
|
+
nonGsPartsSums.push(nonGsParts);
|
|
6515
|
+
currentBody = [[], 0];
|
|
6516
|
+
bodySegments.push(currentBody);
|
|
6517
|
+
} else {
|
|
6518
|
+
currentBody[0].push(b);
|
|
6519
|
+
nonGsParts++;
|
|
6520
|
+
}
|
|
6521
|
+
}
|
|
6522
|
+
let i = bodySegments.length - 1;
|
|
6523
|
+
const fileLength = file.length - fileTailMatch;
|
|
6524
|
+
for (const b of bodySegments) {
|
|
6525
|
+
b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
|
|
6526
|
+
}
|
|
6527
|
+
return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
|
|
6528
|
+
}
|
|
6529
|
+
// return false for "nope, not matching"
|
|
6530
|
+
// return null for "not matching, cannot keep trying"
|
|
6531
|
+
#matchGlobStarBodySections(file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
|
|
6532
|
+
const bs = bodySegments[bodyIndex];
|
|
6533
|
+
if (!bs) {
|
|
6534
|
+
for (let i = fileIndex; i < file.length; i++) {
|
|
6535
|
+
sawTail = true;
|
|
6536
|
+
const f = file[i];
|
|
6537
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
6538
|
+
return false;
|
|
6539
|
+
}
|
|
6540
|
+
}
|
|
6541
|
+
return sawTail;
|
|
6542
|
+
}
|
|
6543
|
+
const [body, after] = bs;
|
|
6544
|
+
while (fileIndex <= after) {
|
|
6545
|
+
const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
|
|
6546
|
+
if (m && globStarDepth < this.maxGlobstarRecursion) {
|
|
6547
|
+
const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
|
|
6548
|
+
if (sub !== false) {
|
|
6549
|
+
return sub;
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
const f = file[fileIndex];
|
|
6553
|
+
if (f === "." || f === ".." || !this.options.dot && f.startsWith(".")) {
|
|
6554
|
+
return false;
|
|
6555
|
+
}
|
|
6556
|
+
fileIndex++;
|
|
6557
|
+
}
|
|
6558
|
+
return partial || null;
|
|
6559
|
+
}
|
|
6560
|
+
#matchOne(file, pattern, partial, fileIndex, patternIndex) {
|
|
6561
|
+
let fi;
|
|
6562
|
+
let pi;
|
|
6563
|
+
let pl;
|
|
6564
|
+
let fl;
|
|
6565
|
+
for (fi = fileIndex, pi = patternIndex, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
|
|
6566
|
+
this.debug("matchOne loop");
|
|
6567
|
+
let p = pattern[pi];
|
|
6568
|
+
let f = file[fi];
|
|
6569
|
+
this.debug(pattern, p, f);
|
|
6570
|
+
if (p === false || p === GLOBSTAR) {
|
|
6571
|
+
return false;
|
|
6572
|
+
}
|
|
6573
|
+
let hit;
|
|
6574
|
+
if (typeof p === "string") {
|
|
6575
|
+
hit = f === p;
|
|
6576
|
+
this.debug("string match", p, f, hit);
|
|
6577
|
+
} else {
|
|
6578
|
+
hit = p.test(f);
|
|
6579
|
+
this.debug("pattern match", p, f, hit);
|
|
6580
|
+
}
|
|
6581
|
+
if (!hit)
|
|
6582
|
+
return false;
|
|
6583
|
+
}
|
|
6584
|
+
if (fi === fl && pi === pl) {
|
|
6585
|
+
return true;
|
|
6586
|
+
} else if (fi === fl) {
|
|
6587
|
+
return partial;
|
|
6588
|
+
} else if (pi === pl) {
|
|
6589
|
+
return fi === fl - 1 && file[fi] === "";
|
|
6590
|
+
} else {
|
|
6591
|
+
throw new Error("wtf?");
|
|
6592
|
+
}
|
|
6593
|
+
}
|
|
6594
|
+
braceExpand() {
|
|
6595
|
+
return braceExpand(this.pattern, this.options);
|
|
6596
|
+
}
|
|
6597
|
+
parse(pattern) {
|
|
6598
|
+
assertValidPattern(pattern);
|
|
6599
|
+
const options = this.options;
|
|
6600
|
+
if (pattern === "**")
|
|
6601
|
+
return GLOBSTAR;
|
|
6602
|
+
if (pattern === "")
|
|
6603
|
+
return "";
|
|
6604
|
+
let m;
|
|
6605
|
+
let fastTest = null;
|
|
6606
|
+
if (m = pattern.match(starRE)) {
|
|
6607
|
+
fastTest = options.dot ? starTestDot : starTest;
|
|
6608
|
+
} else if (m = pattern.match(starDotExtRE)) {
|
|
6609
|
+
fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]);
|
|
6610
|
+
} else if (m = pattern.match(qmarksRE)) {
|
|
6611
|
+
fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m);
|
|
6612
|
+
} else if (m = pattern.match(starDotStarRE)) {
|
|
6613
|
+
fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
|
|
6614
|
+
} else if (m = pattern.match(dotStarRE)) {
|
|
6615
|
+
fastTest = dotStarTest;
|
|
6616
|
+
}
|
|
6617
|
+
const re = AST.fromGlob(pattern, this.options).toMMPattern();
|
|
6618
|
+
if (fastTest && typeof re === "object") {
|
|
6619
|
+
Reflect.defineProperty(re, "test", { value: fastTest });
|
|
6620
|
+
}
|
|
6621
|
+
return re;
|
|
6622
|
+
}
|
|
6623
|
+
makeRe() {
|
|
6624
|
+
if (this.regexp || this.regexp === false)
|
|
6625
|
+
return this.regexp;
|
|
6626
|
+
const set = this.set;
|
|
6627
|
+
if (!set.length) {
|
|
6628
|
+
this.regexp = false;
|
|
6629
|
+
return this.regexp;
|
|
6630
|
+
}
|
|
6631
|
+
const options = this.options;
|
|
6632
|
+
const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot;
|
|
6633
|
+
const flags = new Set(options.nocase ? ["i"] : []);
|
|
6634
|
+
let re = set.map((pattern) => {
|
|
6635
|
+
const pp = pattern.map((p) => {
|
|
6636
|
+
if (p instanceof RegExp) {
|
|
6637
|
+
for (const f of p.flags.split(""))
|
|
6638
|
+
flags.add(f);
|
|
6639
|
+
}
|
|
6640
|
+
return typeof p === "string" ? regExpEscape2(p) : p === GLOBSTAR ? GLOBSTAR : p._src;
|
|
6641
|
+
});
|
|
6642
|
+
pp.forEach((p, i) => {
|
|
6643
|
+
const next = pp[i + 1];
|
|
6644
|
+
const prev = pp[i - 1];
|
|
6645
|
+
if (p !== GLOBSTAR || prev === GLOBSTAR) {
|
|
6646
|
+
return;
|
|
6647
|
+
}
|
|
6648
|
+
if (prev === void 0) {
|
|
6649
|
+
if (next !== void 0 && next !== GLOBSTAR) {
|
|
6650
|
+
pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next;
|
|
6651
|
+
} else {
|
|
6652
|
+
pp[i] = twoStar;
|
|
6653
|
+
}
|
|
6654
|
+
} else if (next === void 0) {
|
|
6655
|
+
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
|
|
6656
|
+
} else if (next !== GLOBSTAR) {
|
|
6657
|
+
pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
|
|
6658
|
+
pp[i + 1] = GLOBSTAR;
|
|
6659
|
+
}
|
|
6660
|
+
});
|
|
6661
|
+
const filtered = pp.filter((p) => p !== GLOBSTAR);
|
|
6662
|
+
if (this.partial && filtered.length >= 1) {
|
|
6663
|
+
const prefixes = [];
|
|
6664
|
+
for (let i = 1; i <= filtered.length; i++) {
|
|
6665
|
+
prefixes.push(filtered.slice(0, i).join("/"));
|
|
6666
|
+
}
|
|
6667
|
+
return "(?:" + prefixes.join("|") + ")";
|
|
6668
|
+
}
|
|
6669
|
+
return filtered.join("/");
|
|
6670
|
+
}).join("|");
|
|
6671
|
+
const [open2, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
|
|
6672
|
+
re = "^" + open2 + re + close + "$";
|
|
6673
|
+
if (this.partial) {
|
|
6674
|
+
re = "^(?:\\/|" + open2 + re.slice(1, -1) + close + ")$";
|
|
6675
|
+
}
|
|
6676
|
+
if (this.negate)
|
|
6677
|
+
re = "^(?!" + re + ").+$";
|
|
6678
|
+
try {
|
|
6679
|
+
this.regexp = new RegExp(re, [...flags].join(""));
|
|
6680
|
+
} catch {
|
|
6681
|
+
this.regexp = false;
|
|
6682
|
+
}
|
|
6683
|
+
return this.regexp;
|
|
6684
|
+
}
|
|
6685
|
+
slashSplit(p) {
|
|
6686
|
+
if (this.preserveMultipleSlashes) {
|
|
6687
|
+
return p.split("/");
|
|
6688
|
+
} else if (this.isWindows && /^\/\/[^/]+/.test(p)) {
|
|
6689
|
+
return ["", ...p.split(/\/+/)];
|
|
6690
|
+
} else {
|
|
6691
|
+
return p.split(/\/+/);
|
|
6692
|
+
}
|
|
6693
|
+
}
|
|
6694
|
+
match(f, partial = this.partial) {
|
|
6695
|
+
this.debug("match", f, this.pattern);
|
|
6696
|
+
if (this.comment) {
|
|
6697
|
+
return false;
|
|
6698
|
+
}
|
|
6699
|
+
if (this.empty) {
|
|
6700
|
+
return f === "";
|
|
6701
|
+
}
|
|
6702
|
+
if (f === "/" && partial) {
|
|
6703
|
+
return true;
|
|
6704
|
+
}
|
|
6705
|
+
const options = this.options;
|
|
6706
|
+
if (this.isWindows) {
|
|
6707
|
+
f = f.split("\\").join("/");
|
|
6708
|
+
}
|
|
6709
|
+
const ff = this.slashSplit(f);
|
|
6710
|
+
this.debug(this.pattern, "split", ff);
|
|
6711
|
+
const set = this.set;
|
|
6712
|
+
this.debug(this.pattern, "set", set);
|
|
6713
|
+
let filename = ff[ff.length - 1];
|
|
6714
|
+
if (!filename) {
|
|
6715
|
+
for (let i = ff.length - 2; !filename && i >= 0; i--) {
|
|
6716
|
+
filename = ff[i];
|
|
6717
|
+
}
|
|
6718
|
+
}
|
|
6719
|
+
for (const pattern of set) {
|
|
6720
|
+
let file = ff;
|
|
6721
|
+
if (options.matchBase && pattern.length === 1) {
|
|
6722
|
+
file = [filename];
|
|
6723
|
+
}
|
|
6724
|
+
const hit = this.matchOne(file, pattern, partial);
|
|
6725
|
+
if (hit) {
|
|
6726
|
+
if (options.flipNegate) {
|
|
6727
|
+
return true;
|
|
6728
|
+
}
|
|
6729
|
+
return !this.negate;
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6732
|
+
if (options.flipNegate) {
|
|
6733
|
+
return false;
|
|
6734
|
+
}
|
|
6735
|
+
return this.negate;
|
|
6736
|
+
}
|
|
6737
|
+
static defaults(def) {
|
|
6738
|
+
return minimatch.defaults(def).Minimatch;
|
|
6739
|
+
}
|
|
6740
|
+
};
|
|
6741
|
+
minimatch.AST = AST;
|
|
6742
|
+
minimatch.Minimatch = Minimatch;
|
|
6743
|
+
minimatch.escape = escape;
|
|
6744
|
+
minimatch.unescape = unescape;
|
|
6745
|
+
|
|
4677
6746
|
// dist/mcp/SessionScope.js
|
|
4678
|
-
import { minimatch } from "minimatch";
|
|
4679
6747
|
var ScopeViolation = class extends Error {
|
|
4680
6748
|
path;
|
|
4681
6749
|
workOrderId;
|
|
4682
|
-
constructor(
|
|
4683
|
-
super(`ScopeViolation [${workOrderId}]: ${reason} \u2014 path: ${
|
|
4684
|
-
this.path =
|
|
6750
|
+
constructor(path2, workOrderId, reason) {
|
|
6751
|
+
super(`ScopeViolation [${workOrderId}]: ${reason} \u2014 path: ${path2}`);
|
|
6752
|
+
this.path = path2;
|
|
4685
6753
|
this.workOrderId = workOrderId;
|
|
4686
6754
|
this.name = "ScopeViolation";
|
|
4687
6755
|
}
|
|
@@ -4729,7 +6797,6 @@ var SessionScope = {
|
|
|
4729
6797
|
};
|
|
4730
6798
|
|
|
4731
6799
|
// dist/mcp/BudgetGuard.js
|
|
4732
|
-
import { v4 as uuidv43 } from "uuid";
|
|
4733
6800
|
var BUDGET_CHARS = 8e3;
|
|
4734
6801
|
async function applyBudgetGuard(projectRoot, scanId, artifactName, output) {
|
|
4735
6802
|
const serialized = JSON.stringify(output, null, 2);
|
|
@@ -4738,7 +6805,7 @@ async function applyBudgetGuard(projectRoot, scanId, artifactName, output) {
|
|
|
4738
6805
|
const blobStore = new BlobStore(projectRoot);
|
|
4739
6806
|
const pointerStore = PointerStore.open(projectRoot);
|
|
4740
6807
|
const { contentHash, blobPath } = await blobStore.writeAtomic(serialized);
|
|
4741
|
-
const pointerId = `ptr_${
|
|
6808
|
+
const pointerId = `ptr_${v4_default().replace(/-/g, "").slice(0, 16)}`;
|
|
4742
6809
|
await pointerStore.insertPointer({
|
|
4743
6810
|
pointerId,
|
|
4744
6811
|
scanId,
|
|
@@ -4781,7 +6848,6 @@ async function hydratePointer(projectRoot, pointerId) {
|
|
|
4781
6848
|
}
|
|
4782
6849
|
|
|
4783
6850
|
// dist/mcp/tools/get_file_skeleton.js
|
|
4784
|
-
import { v4 as uuidv44 } from "uuid";
|
|
4785
6851
|
var getFileSkeletonTool = {
|
|
4786
6852
|
name: "get_file_skeleton",
|
|
4787
6853
|
description: "Returns a content-addressed skeleton view of a source file (function signatures, class names, exported symbols). Enforces active workOrder scope. Results are content-addressed \u2014 repeated calls on unchanged files return cached pointers.",
|
|
@@ -4840,7 +6906,7 @@ async function handleGetFileSkeleton(args) {
|
|
|
4840
6906
|
const blobStore = new BlobStore(projectRoot);
|
|
4841
6907
|
const serialized = JSON.stringify(skeletonPayload, null, 2);
|
|
4842
6908
|
const { contentHash: skeletonHash, blobPath } = await blobStore.writeAtomic(serialized);
|
|
4843
|
-
const pointerId = `ptr_skel_${
|
|
6909
|
+
const pointerId = `ptr_skel_${v4_default().replace(/-/g, "").slice(0, 12)}`;
|
|
4844
6910
|
await pointerStore.insertPointer({
|
|
4845
6911
|
pointerId,
|
|
4846
6912
|
scanId,
|
|
@@ -4863,9 +6929,9 @@ async function handleGetFileSkeleton(args) {
|
|
|
4863
6929
|
function extractSkeleton(source, filePath) {
|
|
4864
6930
|
const lines = source.split("\n");
|
|
4865
6931
|
const skeleton = [];
|
|
4866
|
-
const
|
|
4867
|
-
const isTS = ["ts", "tsx"].includes(
|
|
4868
|
-
const isJS = ["js", "jsx", "mjs", "cjs"].includes(
|
|
6932
|
+
const ext2 = filePath.split(".").pop() ?? "";
|
|
6933
|
+
const isTS = ["ts", "tsx"].includes(ext2);
|
|
6934
|
+
const isJS = ["js", "jsx", "mjs", "cjs"].includes(ext2);
|
|
4869
6935
|
if (isTS || isJS) {
|
|
4870
6936
|
for (let i = 0; i < lines.length; i++) {
|
|
4871
6937
|
const line = lines[i].trim();
|
|
@@ -4882,7 +6948,6 @@ function extractSkeleton(source, filePath) {
|
|
|
4882
6948
|
// dist/mcp/tools/read_file.js
|
|
4883
6949
|
import { readFile as readFile14 } from "fs/promises";
|
|
4884
6950
|
import { join as join18 } from "path";
|
|
4885
|
-
import { v4 as uuidv45 } from "uuid";
|
|
4886
6951
|
var readFileTool = {
|
|
4887
6952
|
name: "read_file",
|
|
4888
6953
|
description: "Reads a file within the active workOrder scope. Enforces allowedFiles/allowedGlobs/deniedGlobs. Records content hash. Output is budgeted.",
|
|
@@ -4933,7 +6998,7 @@ async function handleReadFile(args) {
|
|
|
4933
6998
|
const blobStore = new BlobStore(projectRoot);
|
|
4934
6999
|
const pointerStore = PointerStore.open(projectRoot);
|
|
4935
7000
|
const { blobPath } = await blobStore.writeAtomic(content);
|
|
4936
|
-
const pointerId = `ptr_file_${
|
|
7001
|
+
const pointerId = `ptr_file_${v4_default().replace(/-/g, "").slice(0, 12)}`;
|
|
4937
7002
|
await pointerStore.insertPointer({
|
|
4938
7003
|
pointerId,
|
|
4939
7004
|
scanId,
|
|
@@ -4958,7 +7023,6 @@ async function handleReadFile(args) {
|
|
|
4958
7023
|
// dist/mcp/tools/apply_patch.js
|
|
4959
7024
|
import { writeFile as writeFile9, rename as rename3, mkdir as mkdir8 } from "fs/promises";
|
|
4960
7025
|
import { join as join19, dirname as dirname4 } from "path";
|
|
4961
|
-
import { v4 as uuidv46 } from "uuid";
|
|
4962
7026
|
var StalePatchError = class extends Error {
|
|
4963
7027
|
filePath;
|
|
4964
7028
|
expectedHash;
|
|
@@ -5024,7 +7088,7 @@ async function handleApplyPatch(args) {
|
|
|
5024
7088
|
const blobStore = new BlobStore(projectRoot);
|
|
5025
7089
|
const pointerStore = PointerStore.open(projectRoot);
|
|
5026
7090
|
const { blobPath } = await blobStore.writeAtomic(newContent);
|
|
5027
|
-
const pointerId = `ptr_patch_${
|
|
7091
|
+
const pointerId = `ptr_patch_${v4_default().replace(/-/g, "").slice(0, 12)}`;
|
|
5028
7092
|
await pointerStore.insertPointer({
|
|
5029
7093
|
pointerId,
|
|
5030
7094
|
scanId,
|
|
@@ -5047,7 +7111,6 @@ async function handleApplyPatch(args) {
|
|
|
5047
7111
|
}
|
|
5048
7112
|
|
|
5049
7113
|
// dist/mcp/tools/work_orders.js
|
|
5050
|
-
import { v4 as uuidv47 } from "uuid";
|
|
5051
7114
|
var createWorkOrderTool = {
|
|
5052
7115
|
name: "create_work_order",
|
|
5053
7116
|
description: "Creates a new Work Order defining intent, allowed file scope, and required verifiable proof. Returns the workOrderId and a manifestPointer for use with spawn_worker.",
|
|
@@ -5098,7 +7161,7 @@ async function handleCreateWorkOrder(args) {
|
|
|
5098
7161
|
if (!projectRoot || !intent) {
|
|
5099
7162
|
throw new Error("projectRoot and intent are required");
|
|
5100
7163
|
}
|
|
5101
|
-
const workOrderId = `wo_${
|
|
7164
|
+
const workOrderId = `wo_${v4_default().replace(/-/g, "").slice(0, 16)}`;
|
|
5102
7165
|
const pointerStore = PointerStore.open(projectRoot);
|
|
5103
7166
|
await pointerStore.insertWorkOrder({
|
|
5104
7167
|
workOrderId,
|
|
@@ -5174,8 +7237,6 @@ async function handleSpawnWorker(args) {
|
|
|
5174
7237
|
|
|
5175
7238
|
// dist/mcp/tools/submit_receipt.js
|
|
5176
7239
|
import { join as join20 } from "path";
|
|
5177
|
-
import { minimatch as minimatch2 } from "minimatch";
|
|
5178
|
-
import { v4 as uuidv48 } from "uuid";
|
|
5179
7240
|
var submitReceiptTool = {
|
|
5180
7241
|
name: "submit_receipt",
|
|
5181
7242
|
description: "Worker submits a WorkerReceipt for a completed Work Order. The ProofValidator checks all 8 proof conditions. Returns accept/reject with detailed errors.",
|
|
@@ -5241,11 +7302,11 @@ async function handleSubmitReceipt(args) {
|
|
|
5241
7302
|
const blobDir = join20(projectRoot, ".vibe-splainer", "blobs");
|
|
5242
7303
|
const isAllowedFile = (filePath) => {
|
|
5243
7304
|
const inExplicit = allowedFiles.some((f) => filePath === f || filePath.endsWith("/" + f) || filePath.endsWith(f));
|
|
5244
|
-
const inGlobs = allowedGlobs.some((g) =>
|
|
7305
|
+
const inGlobs = allowedGlobs.some((g) => minimatch(filePath, g, { matchBase: true }));
|
|
5245
7306
|
return inExplicit || inGlobs;
|
|
5246
7307
|
};
|
|
5247
7308
|
const validation = await ProofValidator.validate(receipt, requiredProof, isAllowedFile, blobDir);
|
|
5248
|
-
const receiptId = `rcpt_${
|
|
7309
|
+
const receiptId = `rcpt_${v4_default().replace(/-/g, "").slice(0, 16)}`;
|
|
5249
7310
|
const finalStatus = validation.valid ? receipt.status : "failed";
|
|
5250
7311
|
await pointerStore.insertReceipt({
|
|
5251
7312
|
receiptId,
|