@massa-ai/mcp-client 1.9.0 → 1.9.1
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/config-cli.js +174 -14
- package/dist/index.js +174 -14
- package/package.json +3 -3
package/dist/config-cli.js
CHANGED
|
@@ -837,6 +837,20 @@ function validateCapturePolicyConfig(raw2) {
|
|
|
837
837
|
...p.maxIgnorePatterns !== undefined && { maxIgnorePatterns: p.maxIgnorePatterns }
|
|
838
838
|
};
|
|
839
839
|
}
|
|
840
|
+
function validateAllowedExtensionsConfig(raw2) {
|
|
841
|
+
if (!Array.isArray(raw2)) {
|
|
842
|
+
throw new TypeError("security.allowedExtensions must be an array of strings");
|
|
843
|
+
}
|
|
844
|
+
if (raw2.length === 0) {
|
|
845
|
+
throw new TypeError("security.allowedExtensions must not be empty \u2014 an empty allow-list indexes nothing; omit the key to use the defaults");
|
|
846
|
+
}
|
|
847
|
+
for (const ext of raw2) {
|
|
848
|
+
if (typeof ext !== "string" || !ext.startsWith(".") || ext.length < 2) {
|
|
849
|
+
throw new TypeError(`security.allowedExtensions[] must be dot-prefixed extensions (got ${JSON.stringify(ext)})`);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
return [...raw2];
|
|
853
|
+
}
|
|
840
854
|
function getGlobalDataDir() {
|
|
841
855
|
const envOverride = process.env.MASSA_AI_DATA_DIR;
|
|
842
856
|
if (envOverride && envOverride.trim())
|
|
@@ -1132,7 +1146,7 @@ var init_config = __esm(() => {
|
|
|
1132
1146
|
sanitizeInputs: process.env.SANITIZE_INPUTS !== "false",
|
|
1133
1147
|
maxIndexSize: 1e5,
|
|
1134
1148
|
maxFileSize: 1024 * 1024,
|
|
1135
|
-
allowedExtensions: [...DEFAULT_ALLOWED_EXTENSIONS],
|
|
1149
|
+
allowedExtensions: fileConfig.security?.allowedExtensions ? validateAllowedExtensionsConfig(fileConfig.security.allowedExtensions) : [...DEFAULT_ALLOWED_EXTENSIONS],
|
|
1136
1150
|
excludePatterns: [
|
|
1137
1151
|
"node_modules/**",
|
|
1138
1152
|
".git/**",
|
|
@@ -107584,14 +107598,140 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
107584
107598
|
});
|
|
107585
107599
|
|
|
107586
107600
|
// ../../packages/core/dist/services/search/capture-policy.js
|
|
107587
|
-
|
|
107601
|
+
function globToRegex(pattern) {
|
|
107602
|
+
let re = "^";
|
|
107603
|
+
let i = 0;
|
|
107604
|
+
while (i < pattern.length) {
|
|
107605
|
+
const ch = pattern[i];
|
|
107606
|
+
if (ch === "*") {
|
|
107607
|
+
if (pattern[i + 1] === "*") {
|
|
107608
|
+
re += ".*";
|
|
107609
|
+
i += 2;
|
|
107610
|
+
if (pattern[i] === "/")
|
|
107611
|
+
i += 1;
|
|
107612
|
+
} else {
|
|
107613
|
+
re += "[^/]*";
|
|
107614
|
+
i += 1;
|
|
107615
|
+
}
|
|
107616
|
+
} else if (ch === "?") {
|
|
107617
|
+
re += "[^/]";
|
|
107618
|
+
i += 1;
|
|
107619
|
+
} else if (ch === ".") {
|
|
107620
|
+
re += "\\.";
|
|
107621
|
+
i += 1;
|
|
107622
|
+
} else if ("+()^${}|[]\\".includes(ch)) {
|
|
107623
|
+
re += "\\" + ch;
|
|
107624
|
+
i += 1;
|
|
107625
|
+
} else {
|
|
107626
|
+
re += ch;
|
|
107627
|
+
i += 1;
|
|
107628
|
+
}
|
|
107629
|
+
}
|
|
107630
|
+
re += "$";
|
|
107631
|
+
return new RegExp(re);
|
|
107632
|
+
}
|
|
107633
|
+
function validatePolicy(policy, opts = {}) {
|
|
107634
|
+
if (!policy || typeof policy !== "object")
|
|
107635
|
+
throw new TypeError("policy must be an object");
|
|
107636
|
+
const p = policy;
|
|
107637
|
+
const allowedKeys = new Set(["rules", "maxMatchWork", "maxIgnorePatterns"]);
|
|
107638
|
+
if (opts.denyUnknownFields) {
|
|
107639
|
+
for (const key of Object.keys(p)) {
|
|
107640
|
+
if (!allowedKeys.has(key)) {
|
|
107641
|
+
throw new TypeError(`policy: unknown field "${key}" (denyUnknownFields=true)`);
|
|
107642
|
+
}
|
|
107643
|
+
}
|
|
107644
|
+
}
|
|
107645
|
+
if (!Array.isArray(p.rules))
|
|
107646
|
+
throw new TypeError("policy.rules must be an array");
|
|
107647
|
+
const dropCount = p.rules.filter((r) => r?.disposition === "Drop").length;
|
|
107648
|
+
const maxIgnore = typeof p.maxIgnorePatterns === "number" ? p.maxIgnorePatterns : MAX_IGNORE_PATTERNS2;
|
|
107649
|
+
if (dropCount > maxIgnore) {
|
|
107650
|
+
throw new TypeError(`policy: ${dropCount} Drop rules exceed maxIgnorePatterns=${maxIgnore}`);
|
|
107651
|
+
}
|
|
107652
|
+
if (p.maxMatchWork !== undefined) {
|
|
107653
|
+
if (typeof p.maxMatchWork !== "number" || p.maxMatchWork < 0) {
|
|
107654
|
+
throw new TypeError("policy.maxMatchWork must be a non-negative number");
|
|
107655
|
+
}
|
|
107656
|
+
}
|
|
107657
|
+
}
|
|
107658
|
+
function matchesGlob(path7, pattern) {
|
|
107659
|
+
let re = regexCache.get(pattern);
|
|
107660
|
+
if (!re) {
|
|
107661
|
+
re = globToRegex(pattern);
|
|
107662
|
+
regexCache.set(pattern, re);
|
|
107663
|
+
}
|
|
107664
|
+
return re.test(path7);
|
|
107665
|
+
}
|
|
107666
|
+
var MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS2 = 1024, DEFAULT_POLICY, applyPolicy = (filePath, policy) => {
|
|
107667
|
+
const normalized = filePath.trim();
|
|
107668
|
+
for (const rule of policy.rules) {
|
|
107669
|
+
if (matchesGlob(normalized, rule.pattern))
|
|
107670
|
+
return rule.disposition;
|
|
107671
|
+
}
|
|
107672
|
+
return "Keep";
|
|
107673
|
+
}, regexCache;
|
|
107588
107674
|
var init_capture_policy = __esm(() => {
|
|
107675
|
+
DEFAULT_POLICY = {
|
|
107676
|
+
rules: [
|
|
107677
|
+
{ pattern: "**/node_modules/**", disposition: "Drop" },
|
|
107678
|
+
{ pattern: "**/.git/**", disposition: "Drop" },
|
|
107679
|
+
{ pattern: "**/dist/**", disposition: "Drop" },
|
|
107680
|
+
{ pattern: "**/build/**", disposition: "Drop" },
|
|
107681
|
+
{ pattern: "**/coverage/**", disposition: "Drop" },
|
|
107682
|
+
{ pattern: ".env", disposition: "Drop" },
|
|
107683
|
+
{ pattern: ".env.*", disposition: "Drop" },
|
|
107684
|
+
{ pattern: "**/generated/**", disposition: "Drop" },
|
|
107685
|
+
{ pattern: "**/*.generated.*", disposition: "Drop" },
|
|
107686
|
+
{ pattern: "**/*.d.ts", disposition: "Drop" },
|
|
107687
|
+
{ pattern: "**/__tests__/**", disposition: "Drop" },
|
|
107688
|
+
{ pattern: "**/tests/**", disposition: "Drop" },
|
|
107689
|
+
{ pattern: "**/*.test.ts", disposition: "Drop" },
|
|
107690
|
+
{ pattern: "**/*.test.tsx", disposition: "Drop" },
|
|
107691
|
+
{ pattern: "**/*.test.js", disposition: "Drop" },
|
|
107692
|
+
{ pattern: "**/*.test.jsx", disposition: "Drop" },
|
|
107693
|
+
{ pattern: "**/*.spec.ts", disposition: "Drop" },
|
|
107694
|
+
{ pattern: "**/*.spec.tsx", disposition: "Drop" },
|
|
107695
|
+
{ pattern: "**/*.spec.js", disposition: "Drop" },
|
|
107696
|
+
{ pattern: "**/*.spec.jsx", disposition: "Drop" },
|
|
107697
|
+
{ pattern: "**/benchmarks/**", disposition: "Drop" },
|
|
107698
|
+
{ pattern: "**/fixtures/**", disposition: "Drop" },
|
|
107699
|
+
{ pattern: "**/*.wasm*", disposition: "Drop" },
|
|
107700
|
+
{ pattern: "**/*.min.*", disposition: "Drop" },
|
|
107701
|
+
{ pattern: "**/*.map", disposition: "Drop" },
|
|
107702
|
+
{ pattern: "**/lock.yaml", disposition: "Drop" },
|
|
107703
|
+
{ pattern: "**/pnpm-lock.yaml", disposition: "Drop" },
|
|
107704
|
+
{ pattern: "**/package-lock.json", disposition: "Drop" },
|
|
107705
|
+
{ pattern: "**/bun.lockb", disposition: "Drop" },
|
|
107706
|
+
{ pattern: "**/yarn.lock", disposition: "Drop" }
|
|
107707
|
+
],
|
|
107708
|
+
maxMatchWork: MAX_MATCH_WORK,
|
|
107709
|
+
maxIgnorePatterns: MAX_IGNORE_PATTERNS2
|
|
107710
|
+
};
|
|
107589
107711
|
regexCache = new Map;
|
|
107590
107712
|
});
|
|
107591
107713
|
|
|
107592
107714
|
// ../../packages/core/dist/services/search/ignore-patterns.js
|
|
107593
107715
|
import fs2 from "fs/promises";
|
|
107594
107716
|
import path7 from "path";
|
|
107717
|
+
function buildExtensionGlob(extensions) {
|
|
107718
|
+
return extensions.map((ext2) => `**/*${ext2}`);
|
|
107719
|
+
}
|
|
107720
|
+
function getActivePolicy() {
|
|
107721
|
+
if (cachedPolicy)
|
|
107722
|
+
return cachedPolicy;
|
|
107723
|
+
const fromConfig = config.get("capturePolicy");
|
|
107724
|
+
if (!fromConfig) {
|
|
107725
|
+
cachedPolicy = DEFAULT_POLICY;
|
|
107726
|
+
return cachedPolicy;
|
|
107727
|
+
}
|
|
107728
|
+
validatePolicy(fromConfig, { denyUnknownFields: true });
|
|
107729
|
+
cachedPolicy = fromConfig;
|
|
107730
|
+
return cachedPolicy;
|
|
107731
|
+
}
|
|
107732
|
+
function getActiveCapturePolicy() {
|
|
107733
|
+
return getActivePolicy();
|
|
107734
|
+
}
|
|
107595
107735
|
async function loadProjectIgnore(projectPath) {
|
|
107596
107736
|
const ig = ignore();
|
|
107597
107737
|
ig.add(DEFAULT_IGNORES);
|
|
@@ -107610,7 +107750,7 @@ async function loadProjectIgnore(projectPath) {
|
|
|
107610
107750
|
}
|
|
107611
107751
|
return ig;
|
|
107612
107752
|
}
|
|
107613
|
-
var import_ignore3, ignore, DEFAULT_EXTENSIONS, DEFAULT_IGNORES;
|
|
107753
|
+
var import_ignore3, ignore, DEFAULT_EXTENSIONS, DEFAULT_IGNORES, cachedPolicy;
|
|
107614
107754
|
var init_ignore_patterns = __esm(() => {
|
|
107615
107755
|
init_dist();
|
|
107616
107756
|
init_capture_policy();
|
|
@@ -107935,9 +108075,9 @@ class IndexManager {
|
|
|
107935
108075
|
try {
|
|
107936
108076
|
const securityConfig = config.get("security");
|
|
107937
108077
|
const allowedExtensions = securityConfig.allowedExtensions || DEFAULT_ALLOWED_EXTENSIONS;
|
|
107938
|
-
const
|
|
108078
|
+
const patterns = buildExtensionGlob(allowedExtensions);
|
|
107939
108079
|
const ig = await this.loadGitignore(projectPath);
|
|
107940
|
-
const matches = await globAsync(
|
|
108080
|
+
const matches = await globAsync(patterns, {
|
|
107941
108081
|
cwd: projectPath,
|
|
107942
108082
|
nodir: true,
|
|
107943
108083
|
dot: false
|
|
@@ -112242,7 +112382,7 @@ async function _indexProjectInternalImpl(rlm, projectPath, projectId, options =
|
|
|
112242
112382
|
];
|
|
112243
112383
|
try {
|
|
112244
112384
|
const ig = await loadGitignoreImpl(projectPath);
|
|
112245
|
-
const files = await globAsync2(
|
|
112385
|
+
const files = await globAsync2(buildExtensionGlob(allowedExtensions), {
|
|
112246
112386
|
cwd: projectPath,
|
|
112247
112387
|
absolute: true,
|
|
112248
112388
|
nodir: true,
|
|
@@ -112694,6 +112834,9 @@ class MemoryRepositoryPg {
|
|
|
112694
112834
|
if (filters.types && filters.types.length > 0) {
|
|
112695
112835
|
conditions.push(import_prisma2.Prisma.sql`type = ANY(${filters.types}::text[])`);
|
|
112696
112836
|
}
|
|
112837
|
+
if (filters.includePersistent === false) {
|
|
112838
|
+
conditions.push(import_prisma2.Prisma.sql`level <> ${MemoryLevel.PERSISTENT}`);
|
|
112839
|
+
}
|
|
112697
112840
|
const whereClause = import_prisma2.Prisma.sql`WHERE ${import_prisma2.Prisma.join(conditions, " AND ")}`;
|
|
112698
112841
|
const rows = await this.prisma.$queryRaw`
|
|
112699
112842
|
SELECT id, content, type, level,
|
|
@@ -112728,6 +112871,8 @@ class MemoryRepositoryPg {
|
|
|
112728
112871
|
conditions.push(import_prisma2.Prisma.sql`importance >= ${filters.minImportance}`);
|
|
112729
112872
|
if (filters?.types && filters.types.length > 0)
|
|
112730
112873
|
conditions.push(import_prisma2.Prisma.sql`type = ANY(${filters.types}::text[])`);
|
|
112874
|
+
if (filters?.includePersistent === false)
|
|
112875
|
+
conditions.push(import_prisma2.Prisma.sql`level <> ${MemoryLevel.PERSISTENT}`);
|
|
112731
112876
|
const whereClause = import_prisma2.Prisma.sql`WHERE ${import_prisma2.Prisma.join(conditions, " AND ")}
|
|
112732
112877
|
AND NOT EXISTS (
|
|
112733
112878
|
SELECT 1 FROM memory_edges me
|
|
@@ -125339,20 +125484,21 @@ class DiscoverStage {
|
|
|
125339
125484
|
payload: { projectId: ctx.projectId, projectPath: ctx.projectPath },
|
|
125340
125485
|
timestamp: Date.now()
|
|
125341
125486
|
});
|
|
125342
|
-
const
|
|
125487
|
+
const includeTests = opts.includeTests ?? false;
|
|
125488
|
+
const ig = await this.loadIgnore(ctx.projectPath, includeTests);
|
|
125489
|
+
const policy = this.loadPolicy(includeTests);
|
|
125343
125490
|
const allowedExts = config.get("security").allowedExtensions ?? DEFAULT_EXTENSIONS;
|
|
125344
125491
|
let relPaths;
|
|
125345
125492
|
if (opts.filesToProcess && opts.filesToProcess.length > 0) {
|
|
125346
125493
|
relPaths = opts.filesToProcess;
|
|
125347
125494
|
} else {
|
|
125348
|
-
const
|
|
125349
|
-
const found = await glob(pattern, {
|
|
125495
|
+
const found = await glob(buildExtensionGlob(allowedExts), {
|
|
125350
125496
|
cwd: ctx.projectPath,
|
|
125351
125497
|
nodir: true,
|
|
125352
125498
|
dot: false,
|
|
125353
125499
|
absolute: false
|
|
125354
125500
|
});
|
|
125355
|
-
relPaths = found.map((p) => path13.isAbsolute(p) ? path13.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p));
|
|
125501
|
+
relPaths = found.map((p) => path13.isAbsolute(p) ? path13.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
|
|
125356
125502
|
}
|
|
125357
125503
|
if (ctx.resumeCursor?.path) {
|
|
125358
125504
|
const cursorPath = ctx.resumeCursor.path;
|
|
@@ -125438,6 +125584,15 @@ class DiscoverStage {
|
|
|
125438
125584
|
throw new Error(`required_file_unreadable:${relativePath}:${err.message}`);
|
|
125439
125585
|
}
|
|
125440
125586
|
}
|
|
125587
|
+
loadPolicy(includeTests) {
|
|
125588
|
+
const policy = getActiveCapturePolicy();
|
|
125589
|
+
if (!includeTests)
|
|
125590
|
+
return policy;
|
|
125591
|
+
return {
|
|
125592
|
+
...policy,
|
|
125593
|
+
rules: policy.rules.filter((rule) => !(rule.disposition === "Drop" && TEST_IGNORE_PATTERNS.has(rule.pattern)))
|
|
125594
|
+
};
|
|
125595
|
+
}
|
|
125441
125596
|
async loadIgnore(projectPath, includeTests) {
|
|
125442
125597
|
if (!includeTests)
|
|
125443
125598
|
return loadProjectIgnore(projectPath);
|
|
@@ -125463,6 +125618,7 @@ var init_discover = __esm(() => {
|
|
|
125463
125618
|
init_dist();
|
|
125464
125619
|
init_symbol_repository_factory();
|
|
125465
125620
|
init_ignore_patterns();
|
|
125621
|
+
init_capture_policy();
|
|
125466
125622
|
import_ignore4 = __toESM(require_ignore(), 1);
|
|
125467
125623
|
ignore2 = import_ignore4.default.default ?? import_ignore4.default;
|
|
125468
125624
|
TEST_IGNORE_PATTERNS = new Set([
|
|
@@ -128292,19 +128448,22 @@ class StructuralResolverRegistry {
|
|
|
128292
128448
|
return resolver;
|
|
128293
128449
|
}
|
|
128294
128450
|
}
|
|
128451
|
+
function declarationGroupKey(file2, qualifiedName) {
|
|
128452
|
+
return `${file2}\x00${qualifiedName}`;
|
|
128453
|
+
}
|
|
128295
128454
|
function buildStructuralResolverDefinitions(documents) {
|
|
128296
128455
|
const groups = new Map;
|
|
128297
128456
|
const exportedRoots = new Set;
|
|
128298
128457
|
for (const document2 of documents)
|
|
128299
128458
|
for (const symbol27 of document2.structure.symbols) {
|
|
128300
|
-
const key =
|
|
128459
|
+
const key = declarationGroupKey(document2.file, symbol27.qualifiedName);
|
|
128301
128460
|
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
128302
128461
|
if (symbol27.exported && symbol27.qualifiedName === symbol27.name) {
|
|
128303
128462
|
exportedRoots.add(`${document2.file}\x00${symbol27.qualifiedName.split(".")[0]}`);
|
|
128304
128463
|
}
|
|
128305
128464
|
}
|
|
128306
128465
|
return Object.freeze(documents.flatMap((document2) => document2.structure.symbols.map((symbol27) => {
|
|
128307
|
-
const key =
|
|
128466
|
+
const key = declarationGroupKey(document2.file, symbol27.qualifiedName);
|
|
128308
128467
|
const visibleNested = document2.dialect === "java" ? symbol27.signatureMaterial.modifiers.includes("public") && (["class", "interface", "enum"].includes(symbol27.kind) || symbol27.signatureMaterial.modifiers.includes("static")) : !symbol27.signatureMaterial.modifiers.includes("private");
|
|
128309
128468
|
const isExportMarker = symbol27.kind === "export";
|
|
128310
128469
|
return Object.freeze({
|
|
@@ -131481,7 +131640,7 @@ class MemoryController {
|
|
|
131481
131640
|
types: types6,
|
|
131482
131641
|
minImportance = 0.3,
|
|
131483
131642
|
limit = 10,
|
|
131484
|
-
includePersistent
|
|
131643
|
+
includePersistent = true,
|
|
131485
131644
|
includeRelated = false
|
|
131486
131645
|
} = input;
|
|
131487
131646
|
logger.info("Searching memories", {
|
|
@@ -131499,7 +131658,8 @@ class MemoryController {
|
|
|
131499
131658
|
projectId,
|
|
131500
131659
|
agentId,
|
|
131501
131660
|
minImportance,
|
|
131502
|
-
types: types6
|
|
131661
|
+
types: types6,
|
|
131662
|
+
includePersistent
|
|
131503
131663
|
});
|
|
131504
131664
|
logger.info("FTS search completed", {
|
|
131505
131665
|
foundResults: ftsRows.length,
|
package/dist/index.js
CHANGED
|
@@ -25834,6 +25834,20 @@ function validateCapturePolicyConfig(raw2) {
|
|
|
25834
25834
|
...p.maxIgnorePatterns !== undefined && { maxIgnorePatterns: p.maxIgnorePatterns }
|
|
25835
25835
|
};
|
|
25836
25836
|
}
|
|
25837
|
+
function validateAllowedExtensionsConfig(raw2) {
|
|
25838
|
+
if (!Array.isArray(raw2)) {
|
|
25839
|
+
throw new TypeError("security.allowedExtensions must be an array of strings");
|
|
25840
|
+
}
|
|
25841
|
+
if (raw2.length === 0) {
|
|
25842
|
+
throw new TypeError("security.allowedExtensions must not be empty \u2014 an empty allow-list indexes nothing; omit the key to use the defaults");
|
|
25843
|
+
}
|
|
25844
|
+
for (const ext of raw2) {
|
|
25845
|
+
if (typeof ext !== "string" || !ext.startsWith(".") || ext.length < 2) {
|
|
25846
|
+
throw new TypeError(`security.allowedExtensions[] must be dot-prefixed extensions (got ${JSON.stringify(ext)})`);
|
|
25847
|
+
}
|
|
25848
|
+
}
|
|
25849
|
+
return [...raw2];
|
|
25850
|
+
}
|
|
25837
25851
|
function getGlobalDataDir() {
|
|
25838
25852
|
const envOverride = process.env.MASSA_AI_DATA_DIR;
|
|
25839
25853
|
if (envOverride && envOverride.trim())
|
|
@@ -26129,7 +26143,7 @@ var init_config = __esm(() => {
|
|
|
26129
26143
|
sanitizeInputs: process.env.SANITIZE_INPUTS !== "false",
|
|
26130
26144
|
maxIndexSize: 1e5,
|
|
26131
26145
|
maxFileSize: 1024 * 1024,
|
|
26132
|
-
allowedExtensions: [...DEFAULT_ALLOWED_EXTENSIONS],
|
|
26146
|
+
allowedExtensions: fileConfig.security?.allowedExtensions ? validateAllowedExtensionsConfig(fileConfig.security.allowedExtensions) : [...DEFAULT_ALLOWED_EXTENSIONS],
|
|
26133
26147
|
excludePatterns: [
|
|
26134
26148
|
"node_modules/**",
|
|
26135
26149
|
".git/**",
|
|
@@ -114143,14 +114157,140 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
114143
114157
|
});
|
|
114144
114158
|
|
|
114145
114159
|
// ../../packages/core/dist/services/search/capture-policy.js
|
|
114146
|
-
|
|
114160
|
+
function globToRegex(pattern) {
|
|
114161
|
+
let re = "^";
|
|
114162
|
+
let i = 0;
|
|
114163
|
+
while (i < pattern.length) {
|
|
114164
|
+
const ch = pattern[i];
|
|
114165
|
+
if (ch === "*") {
|
|
114166
|
+
if (pattern[i + 1] === "*") {
|
|
114167
|
+
re += ".*";
|
|
114168
|
+
i += 2;
|
|
114169
|
+
if (pattern[i] === "/")
|
|
114170
|
+
i += 1;
|
|
114171
|
+
} else {
|
|
114172
|
+
re += "[^/]*";
|
|
114173
|
+
i += 1;
|
|
114174
|
+
}
|
|
114175
|
+
} else if (ch === "?") {
|
|
114176
|
+
re += "[^/]";
|
|
114177
|
+
i += 1;
|
|
114178
|
+
} else if (ch === ".") {
|
|
114179
|
+
re += "\\.";
|
|
114180
|
+
i += 1;
|
|
114181
|
+
} else if ("+()^${}|[]\\".includes(ch)) {
|
|
114182
|
+
re += "\\" + ch;
|
|
114183
|
+
i += 1;
|
|
114184
|
+
} else {
|
|
114185
|
+
re += ch;
|
|
114186
|
+
i += 1;
|
|
114187
|
+
}
|
|
114188
|
+
}
|
|
114189
|
+
re += "$";
|
|
114190
|
+
return new RegExp(re);
|
|
114191
|
+
}
|
|
114192
|
+
function validatePolicy(policy, opts = {}) {
|
|
114193
|
+
if (!policy || typeof policy !== "object")
|
|
114194
|
+
throw new TypeError("policy must be an object");
|
|
114195
|
+
const p = policy;
|
|
114196
|
+
const allowedKeys = new Set(["rules", "maxMatchWork", "maxIgnorePatterns"]);
|
|
114197
|
+
if (opts.denyUnknownFields) {
|
|
114198
|
+
for (const key of Object.keys(p)) {
|
|
114199
|
+
if (!allowedKeys.has(key)) {
|
|
114200
|
+
throw new TypeError(`policy: unknown field "${key}" (denyUnknownFields=true)`);
|
|
114201
|
+
}
|
|
114202
|
+
}
|
|
114203
|
+
}
|
|
114204
|
+
if (!Array.isArray(p.rules))
|
|
114205
|
+
throw new TypeError("policy.rules must be an array");
|
|
114206
|
+
const dropCount = p.rules.filter((r) => r?.disposition === "Drop").length;
|
|
114207
|
+
const maxIgnore = typeof p.maxIgnorePatterns === "number" ? p.maxIgnorePatterns : MAX_IGNORE_PATTERNS2;
|
|
114208
|
+
if (dropCount > maxIgnore) {
|
|
114209
|
+
throw new TypeError(`policy: ${dropCount} Drop rules exceed maxIgnorePatterns=${maxIgnore}`);
|
|
114210
|
+
}
|
|
114211
|
+
if (p.maxMatchWork !== undefined) {
|
|
114212
|
+
if (typeof p.maxMatchWork !== "number" || p.maxMatchWork < 0) {
|
|
114213
|
+
throw new TypeError("policy.maxMatchWork must be a non-negative number");
|
|
114214
|
+
}
|
|
114215
|
+
}
|
|
114216
|
+
}
|
|
114217
|
+
function matchesGlob(path7, pattern) {
|
|
114218
|
+
let re = regexCache.get(pattern);
|
|
114219
|
+
if (!re) {
|
|
114220
|
+
re = globToRegex(pattern);
|
|
114221
|
+
regexCache.set(pattern, re);
|
|
114222
|
+
}
|
|
114223
|
+
return re.test(path7);
|
|
114224
|
+
}
|
|
114225
|
+
var MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS2 = 1024, DEFAULT_POLICY, applyPolicy = (filePath, policy) => {
|
|
114226
|
+
const normalized = filePath.trim();
|
|
114227
|
+
for (const rule of policy.rules) {
|
|
114228
|
+
if (matchesGlob(normalized, rule.pattern))
|
|
114229
|
+
return rule.disposition;
|
|
114230
|
+
}
|
|
114231
|
+
return "Keep";
|
|
114232
|
+
}, regexCache;
|
|
114147
114233
|
var init_capture_policy = __esm(() => {
|
|
114234
|
+
DEFAULT_POLICY = {
|
|
114235
|
+
rules: [
|
|
114236
|
+
{ pattern: "**/node_modules/**", disposition: "Drop" },
|
|
114237
|
+
{ pattern: "**/.git/**", disposition: "Drop" },
|
|
114238
|
+
{ pattern: "**/dist/**", disposition: "Drop" },
|
|
114239
|
+
{ pattern: "**/build/**", disposition: "Drop" },
|
|
114240
|
+
{ pattern: "**/coverage/**", disposition: "Drop" },
|
|
114241
|
+
{ pattern: ".env", disposition: "Drop" },
|
|
114242
|
+
{ pattern: ".env.*", disposition: "Drop" },
|
|
114243
|
+
{ pattern: "**/generated/**", disposition: "Drop" },
|
|
114244
|
+
{ pattern: "**/*.generated.*", disposition: "Drop" },
|
|
114245
|
+
{ pattern: "**/*.d.ts", disposition: "Drop" },
|
|
114246
|
+
{ pattern: "**/__tests__/**", disposition: "Drop" },
|
|
114247
|
+
{ pattern: "**/tests/**", disposition: "Drop" },
|
|
114248
|
+
{ pattern: "**/*.test.ts", disposition: "Drop" },
|
|
114249
|
+
{ pattern: "**/*.test.tsx", disposition: "Drop" },
|
|
114250
|
+
{ pattern: "**/*.test.js", disposition: "Drop" },
|
|
114251
|
+
{ pattern: "**/*.test.jsx", disposition: "Drop" },
|
|
114252
|
+
{ pattern: "**/*.spec.ts", disposition: "Drop" },
|
|
114253
|
+
{ pattern: "**/*.spec.tsx", disposition: "Drop" },
|
|
114254
|
+
{ pattern: "**/*.spec.js", disposition: "Drop" },
|
|
114255
|
+
{ pattern: "**/*.spec.jsx", disposition: "Drop" },
|
|
114256
|
+
{ pattern: "**/benchmarks/**", disposition: "Drop" },
|
|
114257
|
+
{ pattern: "**/fixtures/**", disposition: "Drop" },
|
|
114258
|
+
{ pattern: "**/*.wasm*", disposition: "Drop" },
|
|
114259
|
+
{ pattern: "**/*.min.*", disposition: "Drop" },
|
|
114260
|
+
{ pattern: "**/*.map", disposition: "Drop" },
|
|
114261
|
+
{ pattern: "**/lock.yaml", disposition: "Drop" },
|
|
114262
|
+
{ pattern: "**/pnpm-lock.yaml", disposition: "Drop" },
|
|
114263
|
+
{ pattern: "**/package-lock.json", disposition: "Drop" },
|
|
114264
|
+
{ pattern: "**/bun.lockb", disposition: "Drop" },
|
|
114265
|
+
{ pattern: "**/yarn.lock", disposition: "Drop" }
|
|
114266
|
+
],
|
|
114267
|
+
maxMatchWork: MAX_MATCH_WORK,
|
|
114268
|
+
maxIgnorePatterns: MAX_IGNORE_PATTERNS2
|
|
114269
|
+
};
|
|
114148
114270
|
regexCache = new Map;
|
|
114149
114271
|
});
|
|
114150
114272
|
|
|
114151
114273
|
// ../../packages/core/dist/services/search/ignore-patterns.js
|
|
114152
114274
|
import fs2 from "fs/promises";
|
|
114153
114275
|
import path7 from "path";
|
|
114276
|
+
function buildExtensionGlob(extensions) {
|
|
114277
|
+
return extensions.map((ext2) => `**/*${ext2}`);
|
|
114278
|
+
}
|
|
114279
|
+
function getActivePolicy() {
|
|
114280
|
+
if (cachedPolicy)
|
|
114281
|
+
return cachedPolicy;
|
|
114282
|
+
const fromConfig = config2.get("capturePolicy");
|
|
114283
|
+
if (!fromConfig) {
|
|
114284
|
+
cachedPolicy = DEFAULT_POLICY;
|
|
114285
|
+
return cachedPolicy;
|
|
114286
|
+
}
|
|
114287
|
+
validatePolicy(fromConfig, { denyUnknownFields: true });
|
|
114288
|
+
cachedPolicy = fromConfig;
|
|
114289
|
+
return cachedPolicy;
|
|
114290
|
+
}
|
|
114291
|
+
function getActiveCapturePolicy() {
|
|
114292
|
+
return getActivePolicy();
|
|
114293
|
+
}
|
|
114154
114294
|
async function loadProjectIgnore(projectPath) {
|
|
114155
114295
|
const ig = ignore();
|
|
114156
114296
|
ig.add(DEFAULT_IGNORES);
|
|
@@ -114169,7 +114309,7 @@ async function loadProjectIgnore(projectPath) {
|
|
|
114169
114309
|
}
|
|
114170
114310
|
return ig;
|
|
114171
114311
|
}
|
|
114172
|
-
var import_ignore3, ignore, DEFAULT_EXTENSIONS, DEFAULT_IGNORES;
|
|
114312
|
+
var import_ignore3, ignore, DEFAULT_EXTENSIONS, DEFAULT_IGNORES, cachedPolicy;
|
|
114173
114313
|
var init_ignore_patterns = __esm(() => {
|
|
114174
114314
|
init_dist();
|
|
114175
114315
|
init_capture_policy();
|
|
@@ -114494,9 +114634,9 @@ class IndexManager {
|
|
|
114494
114634
|
try {
|
|
114495
114635
|
const securityConfig = config2.get("security");
|
|
114496
114636
|
const allowedExtensions = securityConfig.allowedExtensions || DEFAULT_ALLOWED_EXTENSIONS;
|
|
114497
|
-
const
|
|
114637
|
+
const patterns = buildExtensionGlob(allowedExtensions);
|
|
114498
114638
|
const ig = await this.loadGitignore(projectPath);
|
|
114499
|
-
const matches = await globAsync(
|
|
114639
|
+
const matches = await globAsync(patterns, {
|
|
114500
114640
|
cwd: projectPath,
|
|
114501
114641
|
nodir: true,
|
|
114502
114642
|
dot: false
|
|
@@ -118801,7 +118941,7 @@ async function _indexProjectInternalImpl(rlm, projectPath, projectId, options =
|
|
|
118801
118941
|
];
|
|
118802
118942
|
try {
|
|
118803
118943
|
const ig = await loadGitignoreImpl(projectPath);
|
|
118804
|
-
const files = await globAsync2(
|
|
118944
|
+
const files = await globAsync2(buildExtensionGlob(allowedExtensions), {
|
|
118805
118945
|
cwd: projectPath,
|
|
118806
118946
|
absolute: true,
|
|
118807
118947
|
nodir: true,
|
|
@@ -119253,6 +119393,9 @@ class MemoryRepositoryPg {
|
|
|
119253
119393
|
if (filters.types && filters.types.length > 0) {
|
|
119254
119394
|
conditions.push(import_prisma2.Prisma.sql`type = ANY(${filters.types}::text[])`);
|
|
119255
119395
|
}
|
|
119396
|
+
if (filters.includePersistent === false) {
|
|
119397
|
+
conditions.push(import_prisma2.Prisma.sql`level <> ${MemoryLevel.PERSISTENT}`);
|
|
119398
|
+
}
|
|
119256
119399
|
const whereClause = import_prisma2.Prisma.sql`WHERE ${import_prisma2.Prisma.join(conditions, " AND ")}`;
|
|
119257
119400
|
const rows = await this.prisma.$queryRaw`
|
|
119258
119401
|
SELECT id, content, type, level,
|
|
@@ -119287,6 +119430,8 @@ class MemoryRepositoryPg {
|
|
|
119287
119430
|
conditions.push(import_prisma2.Prisma.sql`importance >= ${filters.minImportance}`);
|
|
119288
119431
|
if (filters?.types && filters.types.length > 0)
|
|
119289
119432
|
conditions.push(import_prisma2.Prisma.sql`type = ANY(${filters.types}::text[])`);
|
|
119433
|
+
if (filters?.includePersistent === false)
|
|
119434
|
+
conditions.push(import_prisma2.Prisma.sql`level <> ${MemoryLevel.PERSISTENT}`);
|
|
119290
119435
|
const whereClause = import_prisma2.Prisma.sql`WHERE ${import_prisma2.Prisma.join(conditions, " AND ")}
|
|
119291
119436
|
AND NOT EXISTS (
|
|
119292
119437
|
SELECT 1 FROM memory_edges me
|
|
@@ -123534,20 +123679,21 @@ class DiscoverStage {
|
|
|
123534
123679
|
payload: { projectId: ctx.projectId, projectPath: ctx.projectPath },
|
|
123535
123680
|
timestamp: Date.now()
|
|
123536
123681
|
});
|
|
123537
|
-
const
|
|
123682
|
+
const includeTests = opts.includeTests ?? false;
|
|
123683
|
+
const ig = await this.loadIgnore(ctx.projectPath, includeTests);
|
|
123684
|
+
const policy = this.loadPolicy(includeTests);
|
|
123538
123685
|
const allowedExts = config2.get("security").allowedExtensions ?? DEFAULT_EXTENSIONS;
|
|
123539
123686
|
let relPaths;
|
|
123540
123687
|
if (opts.filesToProcess && opts.filesToProcess.length > 0) {
|
|
123541
123688
|
relPaths = opts.filesToProcess;
|
|
123542
123689
|
} else {
|
|
123543
|
-
const
|
|
123544
|
-
const found = await glob(pattern, {
|
|
123690
|
+
const found = await glob(buildExtensionGlob(allowedExts), {
|
|
123545
123691
|
cwd: ctx.projectPath,
|
|
123546
123692
|
nodir: true,
|
|
123547
123693
|
dot: false,
|
|
123548
123694
|
absolute: false
|
|
123549
123695
|
});
|
|
123550
|
-
relPaths = found.map((p) => path10.isAbsolute(p) ? path10.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p));
|
|
123696
|
+
relPaths = found.map((p) => path10.isAbsolute(p) ? path10.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
|
|
123551
123697
|
}
|
|
123552
123698
|
if (ctx.resumeCursor?.path) {
|
|
123553
123699
|
const cursorPath = ctx.resumeCursor.path;
|
|
@@ -123633,6 +123779,15 @@ class DiscoverStage {
|
|
|
123633
123779
|
throw new Error(`required_file_unreadable:${relativePath}:${err.message}`);
|
|
123634
123780
|
}
|
|
123635
123781
|
}
|
|
123782
|
+
loadPolicy(includeTests) {
|
|
123783
|
+
const policy = getActiveCapturePolicy();
|
|
123784
|
+
if (!includeTests)
|
|
123785
|
+
return policy;
|
|
123786
|
+
return {
|
|
123787
|
+
...policy,
|
|
123788
|
+
rules: policy.rules.filter((rule) => !(rule.disposition === "Drop" && TEST_IGNORE_PATTERNS.has(rule.pattern)))
|
|
123789
|
+
};
|
|
123790
|
+
}
|
|
123636
123791
|
async loadIgnore(projectPath, includeTests) {
|
|
123637
123792
|
if (!includeTests)
|
|
123638
123793
|
return loadProjectIgnore(projectPath);
|
|
@@ -123658,6 +123813,7 @@ var init_discover = __esm(() => {
|
|
|
123658
123813
|
init_dist();
|
|
123659
123814
|
init_symbol_repository_factory();
|
|
123660
123815
|
init_ignore_patterns();
|
|
123816
|
+
init_capture_policy();
|
|
123661
123817
|
import_ignore4 = __toESM(require_ignore(), 1);
|
|
123662
123818
|
ignore2 = import_ignore4.default.default ?? import_ignore4.default;
|
|
123663
123819
|
TEST_IGNORE_PATTERNS = new Set([
|
|
@@ -126487,19 +126643,22 @@ class StructuralResolverRegistry {
|
|
|
126487
126643
|
return resolver;
|
|
126488
126644
|
}
|
|
126489
126645
|
}
|
|
126646
|
+
function declarationGroupKey(file2, qualifiedName) {
|
|
126647
|
+
return `${file2}\x00${qualifiedName}`;
|
|
126648
|
+
}
|
|
126490
126649
|
function buildStructuralResolverDefinitions(documents) {
|
|
126491
126650
|
const groups = new Map;
|
|
126492
126651
|
const exportedRoots = new Set;
|
|
126493
126652
|
for (const document2 of documents)
|
|
126494
126653
|
for (const symbol27 of document2.structure.symbols) {
|
|
126495
|
-
const key =
|
|
126654
|
+
const key = declarationGroupKey(document2.file, symbol27.qualifiedName);
|
|
126496
126655
|
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
126497
126656
|
if (symbol27.exported && symbol27.qualifiedName === symbol27.name) {
|
|
126498
126657
|
exportedRoots.add(`${document2.file}\x00${symbol27.qualifiedName.split(".")[0]}`);
|
|
126499
126658
|
}
|
|
126500
126659
|
}
|
|
126501
126660
|
return Object.freeze(documents.flatMap((document2) => document2.structure.symbols.map((symbol27) => {
|
|
126502
|
-
const key =
|
|
126661
|
+
const key = declarationGroupKey(document2.file, symbol27.qualifiedName);
|
|
126503
126662
|
const visibleNested = document2.dialect === "java" ? symbol27.signatureMaterial.modifiers.includes("public") && (["class", "interface", "enum"].includes(symbol27.kind) || symbol27.signatureMaterial.modifiers.includes("static")) : !symbol27.signatureMaterial.modifiers.includes("private");
|
|
126504
126663
|
const isExportMarker = symbol27.kind === "export";
|
|
126505
126664
|
return Object.freeze({
|
|
@@ -132790,7 +132949,7 @@ class MemoryController {
|
|
|
132790
132949
|
types: types6,
|
|
132791
132950
|
minImportance = 0.3,
|
|
132792
132951
|
limit = 10,
|
|
132793
|
-
includePersistent
|
|
132952
|
+
includePersistent = true,
|
|
132794
132953
|
includeRelated = false
|
|
132795
132954
|
} = input;
|
|
132796
132955
|
logger.info("Searching memories", {
|
|
@@ -132808,7 +132967,8 @@ class MemoryController {
|
|
|
132808
132967
|
projectId,
|
|
132809
132968
|
agentId,
|
|
132810
132969
|
minImportance,
|
|
132811
|
-
types: types6
|
|
132970
|
+
types: types6,
|
|
132971
|
+
includePersistent
|
|
132812
132972
|
});
|
|
132813
132973
|
logger.info("FTS search completed", {
|
|
132814
132974
|
foundResults: ftsRows.length,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massa-ai/mcp-client",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "massa-ai MCP server - Semantic code search, memory, and context compression via Model Context Protocol",
|
|
5
5
|
"author": "luizgmassa",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"type-check": "tsc --noEmit"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@massa-ai/core": "^1.9.
|
|
24
|
-
"@massa-ai/shared": "^1.9.
|
|
23
|
+
"@massa-ai/core": "^1.9.1",
|
|
24
|
+
"@massa-ai/shared": "^1.9.1",
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|