memorix 1.1.8 → 1.1.9
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/CHANGELOG.md +9 -0
- package/dist/cli/index.js +132 -74
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +123 -63
- package/dist/index.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +9 -0
- package/dist/memcode-runtime/package.json +4 -4
- package/dist/sdk.js +123 -63
- package/dist/sdk.js.map +1 -1
- package/docs/API_REFERENCE.md +2 -0
- package/docs/CONFIGURATION.md +18 -0
- package/docs/dev-log/progress.txt +15 -31
- package/package.json +1 -1
- package/src/cli/commands/codegraph.ts +4 -0
- package/src/cli/commands/config-get.ts +9 -2
- package/src/cli/commands/doctor.ts +3 -0
- package/src/codegraph/auto-context.ts +6 -0
- package/src/codegraph/context-pack.ts +7 -10
- package/src/codegraph/exclude.ts +47 -0
- package/src/codegraph/lite-provider.ts +3 -26
- package/src/codegraph/project-context.ts +13 -19
- package/src/config/resolved-config.ts +6 -0
- package/src/config/toml-loader.ts +4 -0
- package/src/config/yaml-loader.ts +7 -0
- package/src/server.ts +3 -0
- package/src/store/orama-store.ts +15 -8
package/dist/index.js
CHANGED
|
@@ -1787,6 +1787,7 @@ function loadYamlConfig(projectRoot) {
|
|
|
1787
1787
|
agent: { ...userConfig.agent, ...projectConfig.agent },
|
|
1788
1788
|
embedding: { ...userConfig.embedding, ...projectConfig.embedding },
|
|
1789
1789
|
git: { ...userConfig.git, ...projectConfig.git },
|
|
1790
|
+
codegraph: { ...userConfig.codegraph, ...projectConfig.codegraph },
|
|
1790
1791
|
behavior: { ...userConfig.behavior, ...projectConfig.behavior },
|
|
1791
1792
|
server: { ...userConfig.server, ...projectConfig.server },
|
|
1792
1793
|
team: { ...userConfig.team, ...projectConfig.team }
|
|
@@ -2069,6 +2070,7 @@ function mergeTomlConfig(base, override) {
|
|
|
2069
2070
|
embedding: { ...base.embedding, ...override.embedding },
|
|
2070
2071
|
hooks: { ...base.hooks, ...override.hooks },
|
|
2071
2072
|
git: { ...base.git, ...override.git },
|
|
2073
|
+
codegraph: { ...base.codegraph, ...override.codegraph },
|
|
2072
2074
|
server: { ...base.server, ...override.server }
|
|
2073
2075
|
};
|
|
2074
2076
|
}
|
|
@@ -2210,6 +2212,15 @@ var init_dotenv_loader = __esm({
|
|
|
2210
2212
|
});
|
|
2211
2213
|
|
|
2212
2214
|
// src/config/resolved-config.ts
|
|
2215
|
+
var resolved_config_exports = {};
|
|
2216
|
+
__export(resolved_config_exports, {
|
|
2217
|
+
getResolvedAgentLane: () => getResolvedAgentLane,
|
|
2218
|
+
getResolvedConfig: () => getResolvedConfig,
|
|
2219
|
+
getResolvedConfigForCwd: () => getResolvedConfigForCwd,
|
|
2220
|
+
getResolvedEmbeddingLane: () => getResolvedEmbeddingLane,
|
|
2221
|
+
getResolvedMemoryLane: () => getResolvedMemoryLane,
|
|
2222
|
+
resetResolvedConfigCache: () => resetResolvedConfigCache
|
|
2223
|
+
});
|
|
2213
2224
|
import { homedir as homedir5 } from "os";
|
|
2214
2225
|
import { existsSync as existsSync6 } from "fs";
|
|
2215
2226
|
function getResolvedConfig(options = {}) {
|
|
@@ -2287,6 +2298,9 @@ function getResolvedConfig(options = {}) {
|
|
|
2287
2298
|
excludePatterns: firstArray(toml.git?.exclude_patterns, yaml2.git?.excludePatterns),
|
|
2288
2299
|
noiseKeywords: firstArray(toml.git?.noise_keywords, yaml2.git?.noiseKeywords)
|
|
2289
2300
|
},
|
|
2301
|
+
codegraph: {
|
|
2302
|
+
excludePatterns: firstArray(toml.codegraph?.exclude_patterns, yaml2.codegraph?.excludePatterns)
|
|
2303
|
+
},
|
|
2290
2304
|
server: {
|
|
2291
2305
|
transport: first(toml.server?.transport, yaml2.server?.transport),
|
|
2292
2306
|
dashboard: firstBool(toml.server?.dashboard, yaml2.server?.dashboard),
|
|
@@ -2308,6 +2322,10 @@ function getResolvedConfig(options = {}) {
|
|
|
2308
2322
|
};
|
|
2309
2323
|
return resolved;
|
|
2310
2324
|
}
|
|
2325
|
+
function getResolvedConfigForCwd(cwd = process.cwd()) {
|
|
2326
|
+
const project = detectProject(cwd);
|
|
2327
|
+
return getResolvedConfig({ projectRoot: project?.rootPath ?? null });
|
|
2328
|
+
}
|
|
2311
2329
|
function getResolvedAgentLane(options = {}) {
|
|
2312
2330
|
const resolved = getResolvedConfig(options);
|
|
2313
2331
|
return {
|
|
@@ -2324,6 +2342,8 @@ function getResolvedMemoryLane(options = {}) {
|
|
|
2324
2342
|
function getResolvedEmbeddingLane(options = {}) {
|
|
2325
2343
|
return getResolvedConfig(options).embedding;
|
|
2326
2344
|
}
|
|
2345
|
+
function resetResolvedConfigCache() {
|
|
2346
|
+
}
|
|
2327
2347
|
function first(...values) {
|
|
2328
2348
|
return values.find((value) => value !== void 0 && value !== null && value !== "");
|
|
2329
2349
|
}
|
|
@@ -4818,7 +4838,7 @@ __export(orama_store_exports, {
|
|
|
4818
4838
|
resetDb: () => resetDb,
|
|
4819
4839
|
searchObservations: () => searchObservations
|
|
4820
4840
|
});
|
|
4821
|
-
import { create, insert as insert2, search, remove as remove2, update, count } from "@orama/orama";
|
|
4841
|
+
import { create, insert as insert2, search, remove as remove2, update, count, getByID } from "@orama/orama";
|
|
4822
4842
|
function getLastSearchMode(projectId) {
|
|
4823
4843
|
return lastSearchModeByProject.get(projectId ?? SEARCH_MODE_DEFAULT_KEY) ?? "fulltext";
|
|
4824
4844
|
}
|
|
@@ -4829,8 +4849,12 @@ function makeEntryKey(projectId, observationId) {
|
|
|
4829
4849
|
return `${projectId ?? ""}::${observationId}`;
|
|
4830
4850
|
}
|
|
4831
4851
|
function rememberObservationDoc(doc) {
|
|
4832
|
-
|
|
4833
|
-
|
|
4852
|
+
const publicDoc = { ...doc };
|
|
4853
|
+
delete publicDoc.embedding;
|
|
4854
|
+
if (doc.projectId && typeof doc.observationId === "number") {
|
|
4855
|
+
docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), publicDoc);
|
|
4856
|
+
}
|
|
4857
|
+
return publicDoc;
|
|
4834
4858
|
}
|
|
4835
4859
|
function isCommandLikeQuery(query) {
|
|
4836
4860
|
return COMMAND_LIKE_QUERY2.test(query);
|
|
@@ -4932,14 +4956,14 @@ async function batchGenerateEmbeddings(texts) {
|
|
|
4932
4956
|
}
|
|
4933
4957
|
async function hydrateIndex(observations2) {
|
|
4934
4958
|
const database = await getDb();
|
|
4935
|
-
const currentCount = await count(database);
|
|
4936
|
-
if (currentCount > 0) return 0;
|
|
4937
4959
|
let inserted = 0;
|
|
4938
4960
|
for (const obs of observations2) {
|
|
4939
4961
|
if (!obs || !obs.id || !obs.projectId) continue;
|
|
4940
4962
|
try {
|
|
4963
|
+
const id = makeOramaObservationId(obs.projectId, obs.id);
|
|
4964
|
+
if (getByID(database, id)) continue;
|
|
4941
4965
|
const doc = {
|
|
4942
|
-
id
|
|
4966
|
+
id,
|
|
4943
4967
|
observationId: obs.id,
|
|
4944
4968
|
entityName: obs.entityName || "",
|
|
4945
4969
|
type: obs.type || "discovery",
|
|
@@ -5033,6 +5057,7 @@ async function searchObservations(options) {
|
|
|
5033
5057
|
let searchParams = {
|
|
5034
5058
|
term: originalQuery,
|
|
5035
5059
|
limit: requestLimit,
|
|
5060
|
+
includeVectors: true,
|
|
5036
5061
|
...Object.keys(filters).length > 0 ? { where: filters } : {},
|
|
5037
5062
|
// Search specific fields (not tokens, accessCount, etc.)
|
|
5038
5063
|
properties: ["title", "entityName", "narrative", "facts", "concepts", "filesModified"],
|
|
@@ -5104,6 +5129,7 @@ async function searchObservations(options) {
|
|
|
5104
5129
|
const vectorOnlyParams = {
|
|
5105
5130
|
term: "",
|
|
5106
5131
|
limit: requestLimit,
|
|
5132
|
+
includeVectors: true,
|
|
5107
5133
|
...Object.keys(filters).length > 0 ? { where: filters } : {},
|
|
5108
5134
|
mode: "vector",
|
|
5109
5135
|
vector: {
|
|
@@ -5402,6 +5428,7 @@ async function getObservationsByIds(ids, projectId) {
|
|
|
5402
5428
|
}
|
|
5403
5429
|
const searchResult = await search(database, {
|
|
5404
5430
|
term: "",
|
|
5431
|
+
includeVectors: true,
|
|
5405
5432
|
where: {
|
|
5406
5433
|
observationId: { eq: id },
|
|
5407
5434
|
...projectId ? { projectId } : {}
|
|
@@ -5409,7 +5436,7 @@ async function getObservationsByIds(ids, projectId) {
|
|
|
5409
5436
|
limit: 1
|
|
5410
5437
|
});
|
|
5411
5438
|
if (searchResult.hits.length > 0) {
|
|
5412
|
-
results.push(searchResult.hits[0].document);
|
|
5439
|
+
results.push(rememberObservationDoc(searchResult.hits[0].document));
|
|
5413
5440
|
}
|
|
5414
5441
|
}
|
|
5415
5442
|
return results;
|
|
@@ -9296,6 +9323,58 @@ var init_current_facts = __esm({
|
|
|
9296
9323
|
}
|
|
9297
9324
|
});
|
|
9298
9325
|
|
|
9326
|
+
// src/codegraph/exclude.ts
|
|
9327
|
+
function normalizeCodeGraphExcludePatterns(exclude) {
|
|
9328
|
+
return [.../* @__PURE__ */ new Set([
|
|
9329
|
+
...DEFAULT_CODEGRAPH_EXCLUDES,
|
|
9330
|
+
...(exclude ?? []).map((pattern) => pattern.trim()).filter(Boolean)
|
|
9331
|
+
])];
|
|
9332
|
+
}
|
|
9333
|
+
function isCodeGraphExcludedPath(path20, exclude) {
|
|
9334
|
+
const normalized = normalizeCodePath2(path20);
|
|
9335
|
+
return normalizeCodeGraphExcludePatterns(exclude).some((pattern) => matchesPattern(normalized, normalizeCodePath2(pattern)));
|
|
9336
|
+
}
|
|
9337
|
+
function normalizeCodePath2(path20) {
|
|
9338
|
+
return path20.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
9339
|
+
}
|
|
9340
|
+
function matchesPattern(path20, pattern) {
|
|
9341
|
+
if (pattern.endsWith("/**")) {
|
|
9342
|
+
const base = pattern.slice(0, -3);
|
|
9343
|
+
if (base.startsWith("**/")) {
|
|
9344
|
+
const suffix = base.slice(3);
|
|
9345
|
+
return path20 === suffix || path20.endsWith(`/${suffix}`) || path20.includes(`/${suffix}/`);
|
|
9346
|
+
}
|
|
9347
|
+
if (!base.includes("/")) {
|
|
9348
|
+
return path20 === base || path20.startsWith(`${base}/`) || path20.includes(`/${base}/`);
|
|
9349
|
+
}
|
|
9350
|
+
return path20 === base || path20.startsWith(`${base}/`);
|
|
9351
|
+
}
|
|
9352
|
+
if (pattern.startsWith("**/")) {
|
|
9353
|
+
const suffix = pattern.slice(3);
|
|
9354
|
+
return path20 === suffix || path20.endsWith(`/${suffix}`);
|
|
9355
|
+
}
|
|
9356
|
+
return path20 === pattern || path20.startsWith(`${pattern}/`);
|
|
9357
|
+
}
|
|
9358
|
+
var DEFAULT_CODEGRAPH_EXCLUDES;
|
|
9359
|
+
var init_exclude = __esm({
|
|
9360
|
+
"src/codegraph/exclude.ts"() {
|
|
9361
|
+
"use strict";
|
|
9362
|
+
init_esm_shims();
|
|
9363
|
+
DEFAULT_CODEGRAPH_EXCLUDES = [
|
|
9364
|
+
"node_modules/**",
|
|
9365
|
+
"dist/**",
|
|
9366
|
+
"build/**",
|
|
9367
|
+
"coverage/**",
|
|
9368
|
+
".next/**",
|
|
9369
|
+
".turbo/**",
|
|
9370
|
+
".git/**",
|
|
9371
|
+
".tmp/**",
|
|
9372
|
+
".worktrees/**",
|
|
9373
|
+
".claude/worktrees/**"
|
|
9374
|
+
];
|
|
9375
|
+
}
|
|
9376
|
+
});
|
|
9377
|
+
|
|
9299
9378
|
// src/codegraph/lite-provider.ts
|
|
9300
9379
|
import { createHash as createHash5 } from "crypto";
|
|
9301
9380
|
import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
@@ -9311,18 +9390,6 @@ function languageForPath(path20) {
|
|
|
9311
9390
|
const ext = extension(path20);
|
|
9312
9391
|
return LANGUAGE_BY_EXTENSION.get(ext) ?? "unknown";
|
|
9313
9392
|
}
|
|
9314
|
-
function isExcluded(path20, exclude) {
|
|
9315
|
-
const normalized = normalizeCodePath(path20);
|
|
9316
|
-
return exclude.some((pattern) => {
|
|
9317
|
-
const p = normalizeCodePath(pattern);
|
|
9318
|
-
if (p.endsWith("/**")) {
|
|
9319
|
-
const base = p.slice(0, -3);
|
|
9320
|
-
return normalized === base || normalized.startsWith(`${base}/`);
|
|
9321
|
-
}
|
|
9322
|
-
if (p.startsWith("**/")) return normalized.endsWith(p.slice(3));
|
|
9323
|
-
return normalized === p || normalized.startsWith(`${p}/`);
|
|
9324
|
-
});
|
|
9325
|
-
}
|
|
9326
9393
|
function walk(root, exclude, maxFiles) {
|
|
9327
9394
|
const out = [];
|
|
9328
9395
|
const visit = (dir) => {
|
|
@@ -9336,7 +9403,7 @@ function walk(root, exclude, maxFiles) {
|
|
|
9336
9403
|
for (const entry of entries) {
|
|
9337
9404
|
const abs = join20(dir, entry.name);
|
|
9338
9405
|
const rel = normalizeCodePath(relative(root, abs));
|
|
9339
|
-
if (
|
|
9406
|
+
if (isCodeGraphExcludedPath(rel, exclude)) continue;
|
|
9340
9407
|
if (entry.isDirectory()) {
|
|
9341
9408
|
if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
|
|
9342
9409
|
if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
|
|
@@ -9424,18 +9491,7 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
9424
9491
|
return edges;
|
|
9425
9492
|
}
|
|
9426
9493
|
async function indexProjectLite(options) {
|
|
9427
|
-
const exclude = options.exclude
|
|
9428
|
-
"node_modules/**",
|
|
9429
|
-
"dist/**",
|
|
9430
|
-
"build/**",
|
|
9431
|
-
"coverage/**",
|
|
9432
|
-
".next/**",
|
|
9433
|
-
".turbo/**",
|
|
9434
|
-
".git/**",
|
|
9435
|
-
".tmp/**",
|
|
9436
|
-
".worktrees/**",
|
|
9437
|
-
".claude/worktrees/**"
|
|
9438
|
-
];
|
|
9494
|
+
const exclude = normalizeCodeGraphExcludePatterns(options.exclude);
|
|
9439
9495
|
const maxFiles = options.maxFiles ?? 5e3;
|
|
9440
9496
|
const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9441
9497
|
const paths = walk(options.projectRoot, exclude, maxFiles);
|
|
@@ -9474,6 +9530,7 @@ var init_lite_provider = __esm({
|
|
|
9474
9530
|
"use strict";
|
|
9475
9531
|
init_esm_shims();
|
|
9476
9532
|
init_ids();
|
|
9533
|
+
init_exclude();
|
|
9477
9534
|
LANGUAGE_BY_EXTENSION = /* @__PURE__ */ new Map([
|
|
9478
9535
|
[".ts", "typescript"],
|
|
9479
9536
|
[".tsx", "typescript"],
|
|
@@ -9643,24 +9700,17 @@ function countLanguages(files) {
|
|
|
9643
9700
|
}
|
|
9644
9701
|
return [...counts.entries()].map(([language, files2]) => ({ language, files: files2 })).sort((a, b) => a.language.localeCompare(b.language));
|
|
9645
9702
|
}
|
|
9646
|
-
function normalizePath2(path20) {
|
|
9647
|
-
return path20.replace(/\\/g, "/");
|
|
9648
|
-
}
|
|
9649
|
-
function isGeneratedPath(path20) {
|
|
9650
|
-
const normalized = normalizePath2(path20);
|
|
9651
|
-
return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
|
|
9652
|
-
}
|
|
9653
9703
|
function suggestedReadRank(path20) {
|
|
9654
|
-
const normalized =
|
|
9704
|
+
const normalized = path20.replace(/\\/g, "/");
|
|
9655
9705
|
if (normalized.startsWith("src/")) return 0;
|
|
9656
9706
|
if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 0;
|
|
9657
9707
|
if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
|
|
9658
9708
|
return 3;
|
|
9659
9709
|
}
|
|
9660
|
-
function compactSuggestedReads(paths, limit = 8) {
|
|
9661
|
-
return uniq(paths).filter((path20) => !
|
|
9710
|
+
function compactSuggestedReads(paths, limit = 8, exclude) {
|
|
9711
|
+
return uniq(paths).filter((path20) => !isCodeGraphExcludedPath(path20, exclude)).sort((a, b) => suggestedReadRank(a) - suggestedReadRank(b)).slice(0, limit);
|
|
9662
9712
|
}
|
|
9663
|
-
function collectGraph(store, projectId, observations2) {
|
|
9713
|
+
function collectGraph(store, projectId, observations2, exclude) {
|
|
9664
9714
|
const files = store.listFiles(projectId);
|
|
9665
9715
|
const symbols = files.flatMap((file) => store.listSymbolsForFile(file.id));
|
|
9666
9716
|
const filesById = new Map(files.map((file) => [file.id, file]));
|
|
@@ -9682,7 +9732,9 @@ function collectGraph(store, projectId, observations2) {
|
|
|
9682
9732
|
freshness[result.status] += 1;
|
|
9683
9733
|
const observation = observationsById.get(ref.observationId);
|
|
9684
9734
|
if (!observation) continue;
|
|
9685
|
-
|
|
9735
|
+
const excluded = file ? isCodeGraphExcludedPath(file.path, exclude) : false;
|
|
9736
|
+
if (result.status === "current" && file && !excluded) suggestedReads.push(file.path);
|
|
9737
|
+
if (excluded) continue;
|
|
9686
9738
|
sources.push({
|
|
9687
9739
|
observationId: observation.id,
|
|
9688
9740
|
title: observation.title,
|
|
@@ -9699,12 +9751,12 @@ function collectGraph(store, projectId, observations2) {
|
|
|
9699
9751
|
refs,
|
|
9700
9752
|
freshness,
|
|
9701
9753
|
sources,
|
|
9702
|
-
suggestedReads: compactSuggestedReads(suggestedReads)
|
|
9754
|
+
suggestedReads: compactSuggestedReads(suggestedReads, 8, exclude)
|
|
9703
9755
|
};
|
|
9704
9756
|
}
|
|
9705
9757
|
function buildProjectContextOverview(input) {
|
|
9706
9758
|
const active = activeObservations(input.observations, input.project.id);
|
|
9707
|
-
const graph = collectGraph(input.store, input.project.id, active);
|
|
9759
|
+
const graph = collectGraph(input.store, input.project.id, active, input.exclude);
|
|
9708
9760
|
const status = input.store.status(input.project.id);
|
|
9709
9761
|
return {
|
|
9710
9762
|
project: input.project,
|
|
@@ -9728,7 +9780,7 @@ function buildProjectContextOverview(input) {
|
|
|
9728
9780
|
function buildProjectContextExplain(input) {
|
|
9729
9781
|
const overview = buildProjectContextOverview(input);
|
|
9730
9782
|
const active = activeObservations(input.observations, input.project.id);
|
|
9731
|
-
const graph = collectGraph(input.store, input.project.id, active);
|
|
9783
|
+
const graph = collectGraph(input.store, input.project.id, active, input.exclude);
|
|
9732
9784
|
return {
|
|
9733
9785
|
project: input.project,
|
|
9734
9786
|
sources: graph.sources.sort((a, b) => a.observationId - b.observationId || (a.path ?? "").localeCompare(b.path ?? "")),
|
|
@@ -9740,11 +9792,12 @@ var init_project_context = __esm({
|
|
|
9740
9792
|
"use strict";
|
|
9741
9793
|
init_esm_shims();
|
|
9742
9794
|
init_freshness2();
|
|
9795
|
+
init_exclude();
|
|
9743
9796
|
}
|
|
9744
9797
|
});
|
|
9745
9798
|
|
|
9746
9799
|
// src/codegraph/task-lens.ts
|
|
9747
|
-
function
|
|
9800
|
+
function normalizePath2(path20) {
|
|
9748
9801
|
return path20.replace(/\\/g, "/");
|
|
9749
9802
|
}
|
|
9750
9803
|
function tokenize(text) {
|
|
@@ -9774,7 +9827,7 @@ function resolveTaskLens(task) {
|
|
|
9774
9827
|
return best.score > 0 ? LENSES[best.id] : LENSES.general;
|
|
9775
9828
|
}
|
|
9776
9829
|
function pathKindScore(path20, lens) {
|
|
9777
|
-
const normalized =
|
|
9830
|
+
const normalized = normalizePath2(path20).toLowerCase();
|
|
9778
9831
|
const name = normalized.split("/").pop() ?? normalized;
|
|
9779
9832
|
const inDocs = normalized.startsWith("docs/") || name === "readme.md" || name.includes("readme");
|
|
9780
9833
|
const isTest = /(^|\/)(tests?|__tests__|spec|fixtures?)\//.test(normalized) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized) || /\.(test|spec)\.py$/.test(normalized);
|
|
@@ -9823,7 +9876,7 @@ function sourceTaskMatchScore(source, task) {
|
|
|
9823
9876
|
return 0;
|
|
9824
9877
|
}
|
|
9825
9878
|
function fallbackPathRank(path20) {
|
|
9826
|
-
const normalized =
|
|
9879
|
+
const normalized = normalizePath2(path20);
|
|
9827
9880
|
if (normalized.startsWith("src/")) return 0;
|
|
9828
9881
|
if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 1;
|
|
9829
9882
|
if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
|
|
@@ -9832,7 +9885,7 @@ function fallbackPathRank(path20) {
|
|
|
9832
9885
|
}
|
|
9833
9886
|
function rankLensPaths(paths, lens, task) {
|
|
9834
9887
|
const tokens = tokenize(task ?? "");
|
|
9835
|
-
return [...new Set(paths.map(
|
|
9888
|
+
return [...new Set(paths.map(normalizePath2))].map((path20, index) => ({
|
|
9836
9889
|
path: path20,
|
|
9837
9890
|
index,
|
|
9838
9891
|
score: pathKindScore(path20, lens) + tokenScore(path20, tokens),
|
|
@@ -10086,6 +10139,7 @@ async function buildAutoProjectContext(input) {
|
|
|
10086
10139
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
10087
10140
|
const task = input.task?.trim();
|
|
10088
10141
|
const lens = resolveTaskLens(task);
|
|
10142
|
+
const exclude = input.exclude ?? getResolvedConfig({ projectRoot: input.project.rootPath }).codegraph.excludePatterns;
|
|
10089
10143
|
const store = new CodeGraphStore();
|
|
10090
10144
|
await store.init(input.dataDir);
|
|
10091
10145
|
const initialStatus = store.status(input.project.id);
|
|
@@ -10103,7 +10157,8 @@ async function buildAutoProjectContext(input) {
|
|
|
10103
10157
|
try {
|
|
10104
10158
|
const indexed = await indexProjectLite({
|
|
10105
10159
|
projectId: input.project.id,
|
|
10106
|
-
projectRoot: input.project.rootPath
|
|
10160
|
+
projectRoot: input.project.rootPath,
|
|
10161
|
+
exclude
|
|
10107
10162
|
});
|
|
10108
10163
|
store.replaceProjectIndex(input.project.id, indexed);
|
|
10109
10164
|
const backfill = await backfillMissingObservationCodeRefs(
|
|
@@ -10123,12 +10178,14 @@ async function buildAutoProjectContext(input) {
|
|
|
10123
10178
|
const overview = buildProjectContextOverview({
|
|
10124
10179
|
project: input.project,
|
|
10125
10180
|
store,
|
|
10126
|
-
observations: input.observations
|
|
10181
|
+
observations: input.observations,
|
|
10182
|
+
exclude
|
|
10127
10183
|
});
|
|
10128
10184
|
const explain = buildProjectContextExplain({
|
|
10129
10185
|
project: input.project,
|
|
10130
10186
|
store,
|
|
10131
|
-
observations: input.observations
|
|
10187
|
+
observations: input.observations,
|
|
10188
|
+
exclude
|
|
10132
10189
|
});
|
|
10133
10190
|
return {
|
|
10134
10191
|
project: input.project,
|
|
@@ -10338,6 +10395,7 @@ var init_auto_context = __esm({
|
|
|
10338
10395
|
"src/codegraph/auto-context.ts"() {
|
|
10339
10396
|
"use strict";
|
|
10340
10397
|
init_esm_shims();
|
|
10398
|
+
init_resolved_config();
|
|
10341
10399
|
init_binder();
|
|
10342
10400
|
init_current_facts();
|
|
10343
10401
|
init_lite_provider();
|
|
@@ -10365,10 +10423,6 @@ function tokenize2(text) {
|
|
|
10365
10423
|
function timestampOf(observation) {
|
|
10366
10424
|
return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
|
|
10367
10425
|
}
|
|
10368
|
-
function isGeneratedPath2(path20) {
|
|
10369
|
-
const normalized = path20.replace(/\\/g, "/");
|
|
10370
|
-
return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
|
|
10371
|
-
}
|
|
10372
10426
|
function relevanceScore(observation, taskTokens) {
|
|
10373
10427
|
if (taskTokens.length === 0) return 0;
|
|
10374
10428
|
const title = observation.title.toLowerCase();
|
|
@@ -10419,7 +10473,8 @@ function assembleContextPackForTask(input) {
|
|
|
10419
10473
|
refs,
|
|
10420
10474
|
files,
|
|
10421
10475
|
symbols,
|
|
10422
|
-
suggestedVerification: input.suggestedVerification
|
|
10476
|
+
suggestedVerification: input.suggestedVerification,
|
|
10477
|
+
exclude: input.exclude
|
|
10423
10478
|
});
|
|
10424
10479
|
}
|
|
10425
10480
|
function assembleContextPack(input) {
|
|
@@ -10438,6 +10493,7 @@ function assembleContextPack(input) {
|
|
|
10438
10493
|
observationIdsWithRefs.add(ref.observationId);
|
|
10439
10494
|
const file = ref.fileId ? files.get(ref.fileId) : void 0;
|
|
10440
10495
|
const symbol = ref.symbolId ? symbols.get(ref.symbolId) : void 0;
|
|
10496
|
+
if (file && isCodeGraphExcludedPath(file.path, input.exclude)) continue;
|
|
10441
10497
|
const freshness = evaluateCodeRefFreshness(ref, file, symbol);
|
|
10442
10498
|
if (freshness.status === "current") {
|
|
10443
10499
|
const memoryKey = `${observation.id}:${freshness.status}`;
|
|
@@ -10503,8 +10559,8 @@ function buildContextPackPrompt(pack) {
|
|
|
10503
10559
|
const reliableMemories = pack.memories.filter((memory) => memory.status === "current");
|
|
10504
10560
|
const unboundMemories = pack.memories.filter((memory) => memory.status === "unbound");
|
|
10505
10561
|
const lines = ["## Task", pack.task, "", "## Reliable Memories"];
|
|
10506
|
-
const visibleCodeFacts = pack.codeFacts.filter((fact) => !
|
|
10507
|
-
const visibleSuggestedReads = pack.suggestedReads.filter((path20) => !
|
|
10562
|
+
const visibleCodeFacts = pack.codeFacts.filter((fact) => !isCodeGraphExcludedPath(fact.path)).slice(0, 5);
|
|
10563
|
+
const visibleSuggestedReads = pack.suggestedReads.filter((path20) => !isCodeGraphExcludedPath(path20)).slice(0, 5);
|
|
10508
10564
|
if (reliableMemories.length === 0) lines.push("- none");
|
|
10509
10565
|
for (const memory of reliableMemories) {
|
|
10510
10566
|
lines.push(`- #${memory.id} ${memory.status}: [${memory.type}] ${memory.title} (${memory.reason})`);
|
|
@@ -10539,6 +10595,7 @@ var init_context_pack = __esm({
|
|
|
10539
10595
|
"use strict";
|
|
10540
10596
|
init_esm_shims();
|
|
10541
10597
|
init_freshness2();
|
|
10598
|
+
init_exclude();
|
|
10542
10599
|
}
|
|
10543
10600
|
});
|
|
10544
10601
|
|
|
@@ -20009,7 +20066,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
20009
20066
|
};
|
|
20010
20067
|
const server = existingServer ?? new McpServer({
|
|
20011
20068
|
name: "memorix",
|
|
20012
|
-
version: true ? "1.1.
|
|
20069
|
+
version: true ? "1.1.9" : "1.0.1"
|
|
20013
20070
|
});
|
|
20014
20071
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
20015
20072
|
server.registerTool = ((name, ...args) => {
|
|
@@ -20711,15 +20768,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
20711
20768
|
return withFreshIndex(async () => {
|
|
20712
20769
|
const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
20713
20770
|
const { assembleContextPackForTask: assembleContextPackForTask2, buildContextPackPrompt: buildContextPackPrompt2 } = await Promise.resolve().then(() => (init_context_pack(), context_pack_exports));
|
|
20771
|
+
const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
|
|
20714
20772
|
const store = new CodeGraphStore2();
|
|
20715
20773
|
await store.init(projectDir2);
|
|
20774
|
+
const exclude = getResolvedConfig2({ projectRoot: project.rootPath }).codegraph.excludePatterns;
|
|
20716
20775
|
const observations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active").reverse();
|
|
20717
20776
|
const pack = assembleContextPackForTask2({
|
|
20718
20777
|
store,
|
|
20719
20778
|
projectId: project.id,
|
|
20720
20779
|
task,
|
|
20721
20780
|
observations: observations2,
|
|
20722
|
-
limit: typeof limit === "number" ? limit : 20
|
|
20781
|
+
limit: typeof limit === "number" ? limit : 20,
|
|
20782
|
+
exclude
|
|
20723
20783
|
});
|
|
20724
20784
|
const text = buildContextPackPrompt2(pack);
|
|
20725
20785
|
return {
|