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.
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.1.9] - 2026-07-12
6
+
7
+ ### Added
8
+ - **Configurable CodeGraph excludes** -- Added `[codegraph].exclude_patterns` / YAML `codegraph.excludePatterns` support so CodeGraph, Project Context suggested reads, context packs, diagnostics, and related CLI flows can skip project-specific generated or vendor paths while keeping the built-in defaults.
9
+
10
+ ### Fixed
11
+ - **Config inspection aliases** -- `memorix config get` now accepts TOML-style snake_case dotted keys such as `codegraph.exclude_patterns` when reading resolved camelCase config values.
12
+ - **Orama search index consistency** -- Search access tracking now preserves internally stored vector-backed documents, public/detail cache results continue to strip embeddings, and hydration reconciles persisted observations by exact composite ID instead of skipping observation hydration when a shared index already contains mini-skills.
13
+
5
14
  ## [1.1.8] - 2026-07-08
6
15
 
7
16
  ### Added
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memorix/memcode",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "Memorix-native coding agent CLI with terminal chat, project memory, hooks, and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -34,9 +34,9 @@
34
34
  "prepublishOnly": "npm run clean && npm run build"
35
35
  },
36
36
  "dependencies": {
37
- "@memorix/agent-core": "1.1.8",
38
- "@memorix/ai": "1.1.8",
39
- "@memorix/tui": "1.1.8",
37
+ "@memorix/agent-core": "1.1.9",
38
+ "@memorix/ai": "1.1.9",
39
+ "@memorix/tui": "1.1.9",
40
40
  "@opentui/core": "^0.3.4",
41
41
  "@opentui/react": "^0.3.4",
42
42
  "@silvia-odwyer/photon-node": "0.3.4",
package/dist/sdk.js CHANGED
@@ -1791,6 +1791,7 @@ function loadYamlConfig(projectRoot) {
1791
1791
  agent: { ...userConfig.agent, ...projectConfig.agent },
1792
1792
  embedding: { ...userConfig.embedding, ...projectConfig.embedding },
1793
1793
  git: { ...userConfig.git, ...projectConfig.git },
1794
+ codegraph: { ...userConfig.codegraph, ...projectConfig.codegraph },
1794
1795
  behavior: { ...userConfig.behavior, ...projectConfig.behavior },
1795
1796
  server: { ...userConfig.server, ...projectConfig.server },
1796
1797
  team: { ...userConfig.team, ...projectConfig.team }
@@ -2073,6 +2074,7 @@ function mergeTomlConfig(base, override) {
2073
2074
  embedding: { ...base.embedding, ...override.embedding },
2074
2075
  hooks: { ...base.hooks, ...override.hooks },
2075
2076
  git: { ...base.git, ...override.git },
2077
+ codegraph: { ...base.codegraph, ...override.codegraph },
2076
2078
  server: { ...base.server, ...override.server }
2077
2079
  };
2078
2080
  }
@@ -2214,6 +2216,15 @@ var init_dotenv_loader = __esm({
2214
2216
  });
2215
2217
 
2216
2218
  // src/config/resolved-config.ts
2219
+ var resolved_config_exports = {};
2220
+ __export(resolved_config_exports, {
2221
+ getResolvedAgentLane: () => getResolvedAgentLane,
2222
+ getResolvedConfig: () => getResolvedConfig,
2223
+ getResolvedConfigForCwd: () => getResolvedConfigForCwd,
2224
+ getResolvedEmbeddingLane: () => getResolvedEmbeddingLane,
2225
+ getResolvedMemoryLane: () => getResolvedMemoryLane,
2226
+ resetResolvedConfigCache: () => resetResolvedConfigCache
2227
+ });
2217
2228
  import { homedir as homedir5 } from "os";
2218
2229
  import { existsSync as existsSync6 } from "fs";
2219
2230
  function getResolvedConfig(options = {}) {
@@ -2291,6 +2302,9 @@ function getResolvedConfig(options = {}) {
2291
2302
  excludePatterns: firstArray(toml.git?.exclude_patterns, yaml2.git?.excludePatterns),
2292
2303
  noiseKeywords: firstArray(toml.git?.noise_keywords, yaml2.git?.noiseKeywords)
2293
2304
  },
2305
+ codegraph: {
2306
+ excludePatterns: firstArray(toml.codegraph?.exclude_patterns, yaml2.codegraph?.excludePatterns)
2307
+ },
2294
2308
  server: {
2295
2309
  transport: first(toml.server?.transport, yaml2.server?.transport),
2296
2310
  dashboard: firstBool(toml.server?.dashboard, yaml2.server?.dashboard),
@@ -2312,6 +2326,10 @@ function getResolvedConfig(options = {}) {
2312
2326
  };
2313
2327
  return resolved;
2314
2328
  }
2329
+ function getResolvedConfigForCwd(cwd = process.cwd()) {
2330
+ const project = detectProject(cwd);
2331
+ return getResolvedConfig({ projectRoot: project?.rootPath ?? null });
2332
+ }
2315
2333
  function getResolvedAgentLane(options = {}) {
2316
2334
  const resolved = getResolvedConfig(options);
2317
2335
  return {
@@ -2328,6 +2346,8 @@ function getResolvedMemoryLane(options = {}) {
2328
2346
  function getResolvedEmbeddingLane(options = {}) {
2329
2347
  return getResolvedConfig(options).embedding;
2330
2348
  }
2349
+ function resetResolvedConfigCache() {
2350
+ }
2331
2351
  function first(...values) {
2332
2352
  return values.find((value) => value !== void 0 && value !== null && value !== "");
2333
2353
  }
@@ -4822,7 +4842,7 @@ __export(orama_store_exports, {
4822
4842
  resetDb: () => resetDb,
4823
4843
  searchObservations: () => searchObservations
4824
4844
  });
4825
- import { create, insert as insert2, search, remove as remove2, update, count } from "@orama/orama";
4845
+ import { create, insert as insert2, search, remove as remove2, update, count, getByID } from "@orama/orama";
4826
4846
  function getLastSearchMode(projectId) {
4827
4847
  return lastSearchModeByProject.get(projectId ?? SEARCH_MODE_DEFAULT_KEY) ?? "fulltext";
4828
4848
  }
@@ -4833,8 +4853,12 @@ function makeEntryKey(projectId, observationId) {
4833
4853
  return `${projectId ?? ""}::${observationId}`;
4834
4854
  }
4835
4855
  function rememberObservationDoc(doc) {
4836
- if (!doc.projectId || typeof doc.observationId !== "number") return;
4837
- docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), doc);
4856
+ const publicDoc = { ...doc };
4857
+ delete publicDoc.embedding;
4858
+ if (doc.projectId && typeof doc.observationId === "number") {
4859
+ docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), publicDoc);
4860
+ }
4861
+ return publicDoc;
4838
4862
  }
4839
4863
  function isCommandLikeQuery(query) {
4840
4864
  return COMMAND_LIKE_QUERY2.test(query);
@@ -4936,14 +4960,14 @@ async function batchGenerateEmbeddings(texts) {
4936
4960
  }
4937
4961
  async function hydrateIndex(observations2) {
4938
4962
  const database = await getDb();
4939
- const currentCount = await count(database);
4940
- if (currentCount > 0) return 0;
4941
4963
  let inserted = 0;
4942
4964
  for (const obs of observations2) {
4943
4965
  if (!obs || !obs.id || !obs.projectId) continue;
4944
4966
  try {
4967
+ const id = makeOramaObservationId(obs.projectId, obs.id);
4968
+ if (getByID(database, id)) continue;
4945
4969
  const doc = {
4946
- id: makeOramaObservationId(obs.projectId, obs.id),
4970
+ id,
4947
4971
  observationId: obs.id,
4948
4972
  entityName: obs.entityName || "",
4949
4973
  type: obs.type || "discovery",
@@ -5037,6 +5061,7 @@ async function searchObservations(options) {
5037
5061
  let searchParams = {
5038
5062
  term: originalQuery,
5039
5063
  limit: requestLimit,
5064
+ includeVectors: true,
5040
5065
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
5041
5066
  // Search specific fields (not tokens, accessCount, etc.)
5042
5067
  properties: ["title", "entityName", "narrative", "facts", "concepts", "filesModified"],
@@ -5108,6 +5133,7 @@ async function searchObservations(options) {
5108
5133
  const vectorOnlyParams = {
5109
5134
  term: "",
5110
5135
  limit: requestLimit,
5136
+ includeVectors: true,
5111
5137
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
5112
5138
  mode: "vector",
5113
5139
  vector: {
@@ -5406,6 +5432,7 @@ async function getObservationsByIds(ids, projectId) {
5406
5432
  }
5407
5433
  const searchResult = await search(database, {
5408
5434
  term: "",
5435
+ includeVectors: true,
5409
5436
  where: {
5410
5437
  observationId: { eq: id },
5411
5438
  ...projectId ? { projectId } : {}
@@ -5413,7 +5440,7 @@ async function getObservationsByIds(ids, projectId) {
5413
5440
  limit: 1
5414
5441
  });
5415
5442
  if (searchResult.hits.length > 0) {
5416
- results.push(searchResult.hits[0].document);
5443
+ results.push(rememberObservationDoc(searchResult.hits[0].document));
5417
5444
  }
5418
5445
  }
5419
5446
  return results;
@@ -9300,6 +9327,58 @@ var init_current_facts = __esm({
9300
9327
  }
9301
9328
  });
9302
9329
 
9330
+ // src/codegraph/exclude.ts
9331
+ function normalizeCodeGraphExcludePatterns(exclude) {
9332
+ return [.../* @__PURE__ */ new Set([
9333
+ ...DEFAULT_CODEGRAPH_EXCLUDES,
9334
+ ...(exclude ?? []).map((pattern) => pattern.trim()).filter(Boolean)
9335
+ ])];
9336
+ }
9337
+ function isCodeGraphExcludedPath(path20, exclude) {
9338
+ const normalized = normalizeCodePath2(path20);
9339
+ return normalizeCodeGraphExcludePatterns(exclude).some((pattern) => matchesPattern(normalized, normalizeCodePath2(pattern)));
9340
+ }
9341
+ function normalizeCodePath2(path20) {
9342
+ return path20.replace(/\\/g, "/").replace(/^\.\/+/, "");
9343
+ }
9344
+ function matchesPattern(path20, pattern) {
9345
+ if (pattern.endsWith("/**")) {
9346
+ const base = pattern.slice(0, -3);
9347
+ if (base.startsWith("**/")) {
9348
+ const suffix = base.slice(3);
9349
+ return path20 === suffix || path20.endsWith(`/${suffix}`) || path20.includes(`/${suffix}/`);
9350
+ }
9351
+ if (!base.includes("/")) {
9352
+ return path20 === base || path20.startsWith(`${base}/`) || path20.includes(`/${base}/`);
9353
+ }
9354
+ return path20 === base || path20.startsWith(`${base}/`);
9355
+ }
9356
+ if (pattern.startsWith("**/")) {
9357
+ const suffix = pattern.slice(3);
9358
+ return path20 === suffix || path20.endsWith(`/${suffix}`);
9359
+ }
9360
+ return path20 === pattern || path20.startsWith(`${pattern}/`);
9361
+ }
9362
+ var DEFAULT_CODEGRAPH_EXCLUDES;
9363
+ var init_exclude = __esm({
9364
+ "src/codegraph/exclude.ts"() {
9365
+ "use strict";
9366
+ init_esm_shims();
9367
+ DEFAULT_CODEGRAPH_EXCLUDES = [
9368
+ "node_modules/**",
9369
+ "dist/**",
9370
+ "build/**",
9371
+ "coverage/**",
9372
+ ".next/**",
9373
+ ".turbo/**",
9374
+ ".git/**",
9375
+ ".tmp/**",
9376
+ ".worktrees/**",
9377
+ ".claude/worktrees/**"
9378
+ ];
9379
+ }
9380
+ });
9381
+
9303
9382
  // src/codegraph/lite-provider.ts
9304
9383
  import { createHash as createHash5 } from "crypto";
9305
9384
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
@@ -9315,18 +9394,6 @@ function languageForPath(path20) {
9315
9394
  const ext = extension(path20);
9316
9395
  return LANGUAGE_BY_EXTENSION.get(ext) ?? "unknown";
9317
9396
  }
9318
- function isExcluded(path20, exclude) {
9319
- const normalized = normalizeCodePath(path20);
9320
- return exclude.some((pattern) => {
9321
- const p = normalizeCodePath(pattern);
9322
- if (p.endsWith("/**")) {
9323
- const base = p.slice(0, -3);
9324
- return normalized === base || normalized.startsWith(`${base}/`);
9325
- }
9326
- if (p.startsWith("**/")) return normalized.endsWith(p.slice(3));
9327
- return normalized === p || normalized.startsWith(`${p}/`);
9328
- });
9329
- }
9330
9397
  function walk(root, exclude, maxFiles) {
9331
9398
  const out = [];
9332
9399
  const visit = (dir) => {
@@ -9340,7 +9407,7 @@ function walk(root, exclude, maxFiles) {
9340
9407
  for (const entry of entries) {
9341
9408
  const abs = join20(dir, entry.name);
9342
9409
  const rel = normalizeCodePath(relative(root, abs));
9343
- if (isExcluded(rel, exclude)) continue;
9410
+ if (isCodeGraphExcludedPath(rel, exclude)) continue;
9344
9411
  if (entry.isDirectory()) {
9345
9412
  if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
9346
9413
  if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
@@ -9428,18 +9495,7 @@ function extractImportEdges(projectId, file, text, indexedAt) {
9428
9495
  return edges;
9429
9496
  }
9430
9497
  async function indexProjectLite(options) {
9431
- const exclude = options.exclude ?? [
9432
- "node_modules/**",
9433
- "dist/**",
9434
- "build/**",
9435
- "coverage/**",
9436
- ".next/**",
9437
- ".turbo/**",
9438
- ".git/**",
9439
- ".tmp/**",
9440
- ".worktrees/**",
9441
- ".claude/worktrees/**"
9442
- ];
9498
+ const exclude = normalizeCodeGraphExcludePatterns(options.exclude);
9443
9499
  const maxFiles = options.maxFiles ?? 5e3;
9444
9500
  const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
9445
9501
  const paths = walk(options.projectRoot, exclude, maxFiles);
@@ -9478,6 +9534,7 @@ var init_lite_provider = __esm({
9478
9534
  "use strict";
9479
9535
  init_esm_shims();
9480
9536
  init_ids();
9537
+ init_exclude();
9481
9538
  LANGUAGE_BY_EXTENSION = /* @__PURE__ */ new Map([
9482
9539
  [".ts", "typescript"],
9483
9540
  [".tsx", "typescript"],
@@ -9647,24 +9704,17 @@ function countLanguages(files) {
9647
9704
  }
9648
9705
  return [...counts.entries()].map(([language, files2]) => ({ language, files: files2 })).sort((a, b) => a.language.localeCompare(b.language));
9649
9706
  }
9650
- function normalizePath2(path20) {
9651
- return path20.replace(/\\/g, "/");
9652
- }
9653
- function isGeneratedPath(path20) {
9654
- const normalized = normalizePath2(path20);
9655
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
9656
- }
9657
9707
  function suggestedReadRank(path20) {
9658
- const normalized = normalizePath2(path20);
9708
+ const normalized = path20.replace(/\\/g, "/");
9659
9709
  if (normalized.startsWith("src/")) return 0;
9660
9710
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 0;
9661
9711
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
9662
9712
  return 3;
9663
9713
  }
9664
- function compactSuggestedReads(paths, limit = 8) {
9665
- return uniq(paths).filter((path20) => !isGeneratedPath(path20)).sort((a, b) => suggestedReadRank(a) - suggestedReadRank(b)).slice(0, limit);
9714
+ function compactSuggestedReads(paths, limit = 8, exclude) {
9715
+ return uniq(paths).filter((path20) => !isCodeGraphExcludedPath(path20, exclude)).sort((a, b) => suggestedReadRank(a) - suggestedReadRank(b)).slice(0, limit);
9666
9716
  }
9667
- function collectGraph(store, projectId, observations2) {
9717
+ function collectGraph(store, projectId, observations2, exclude) {
9668
9718
  const files = store.listFiles(projectId);
9669
9719
  const symbols = files.flatMap((file) => store.listSymbolsForFile(file.id));
9670
9720
  const filesById = new Map(files.map((file) => [file.id, file]));
@@ -9686,7 +9736,9 @@ function collectGraph(store, projectId, observations2) {
9686
9736
  freshness[result.status] += 1;
9687
9737
  const observation = observationsById.get(ref.observationId);
9688
9738
  if (!observation) continue;
9689
- if (result.status === "current" && file) suggestedReads.push(file.path);
9739
+ const excluded = file ? isCodeGraphExcludedPath(file.path, exclude) : false;
9740
+ if (result.status === "current" && file && !excluded) suggestedReads.push(file.path);
9741
+ if (excluded) continue;
9690
9742
  sources.push({
9691
9743
  observationId: observation.id,
9692
9744
  title: observation.title,
@@ -9703,12 +9755,12 @@ function collectGraph(store, projectId, observations2) {
9703
9755
  refs,
9704
9756
  freshness,
9705
9757
  sources,
9706
- suggestedReads: compactSuggestedReads(suggestedReads)
9758
+ suggestedReads: compactSuggestedReads(suggestedReads, 8, exclude)
9707
9759
  };
9708
9760
  }
9709
9761
  function buildProjectContextOverview(input) {
9710
9762
  const active = activeObservations(input.observations, input.project.id);
9711
- const graph = collectGraph(input.store, input.project.id, active);
9763
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
9712
9764
  const status = input.store.status(input.project.id);
9713
9765
  return {
9714
9766
  project: input.project,
@@ -9732,7 +9784,7 @@ function buildProjectContextOverview(input) {
9732
9784
  function buildProjectContextExplain(input) {
9733
9785
  const overview = buildProjectContextOverview(input);
9734
9786
  const active = activeObservations(input.observations, input.project.id);
9735
- const graph = collectGraph(input.store, input.project.id, active);
9787
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
9736
9788
  return {
9737
9789
  project: input.project,
9738
9790
  sources: graph.sources.sort((a, b) => a.observationId - b.observationId || (a.path ?? "").localeCompare(b.path ?? "")),
@@ -9744,11 +9796,12 @@ var init_project_context = __esm({
9744
9796
  "use strict";
9745
9797
  init_esm_shims();
9746
9798
  init_freshness2();
9799
+ init_exclude();
9747
9800
  }
9748
9801
  });
9749
9802
 
9750
9803
  // src/codegraph/task-lens.ts
9751
- function normalizePath3(path20) {
9804
+ function normalizePath2(path20) {
9752
9805
  return path20.replace(/\\/g, "/");
9753
9806
  }
9754
9807
  function tokenize(text) {
@@ -9778,7 +9831,7 @@ function resolveTaskLens(task) {
9778
9831
  return best.score > 0 ? LENSES[best.id] : LENSES.general;
9779
9832
  }
9780
9833
  function pathKindScore(path20, lens) {
9781
- const normalized = normalizePath3(path20).toLowerCase();
9834
+ const normalized = normalizePath2(path20).toLowerCase();
9782
9835
  const name = normalized.split("/").pop() ?? normalized;
9783
9836
  const inDocs = normalized.startsWith("docs/") || name === "readme.md" || name.includes("readme");
9784
9837
  const isTest = /(^|\/)(tests?|__tests__|spec|fixtures?)\//.test(normalized) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized) || /\.(test|spec)\.py$/.test(normalized);
@@ -9827,7 +9880,7 @@ function sourceTaskMatchScore(source, task) {
9827
9880
  return 0;
9828
9881
  }
9829
9882
  function fallbackPathRank(path20) {
9830
- const normalized = normalizePath3(path20);
9883
+ const normalized = normalizePath2(path20);
9831
9884
  if (normalized.startsWith("src/")) return 0;
9832
9885
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 1;
9833
9886
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
@@ -9836,7 +9889,7 @@ function fallbackPathRank(path20) {
9836
9889
  }
9837
9890
  function rankLensPaths(paths, lens, task) {
9838
9891
  const tokens = tokenize(task ?? "");
9839
- return [...new Set(paths.map(normalizePath3))].map((path20, index) => ({
9892
+ return [...new Set(paths.map(normalizePath2))].map((path20, index) => ({
9840
9893
  path: path20,
9841
9894
  index,
9842
9895
  score: pathKindScore(path20, lens) + tokenScore(path20, tokens),
@@ -10090,6 +10143,7 @@ async function buildAutoProjectContext(input) {
10090
10143
  const now = input.now ?? /* @__PURE__ */ new Date();
10091
10144
  const task = input.task?.trim();
10092
10145
  const lens = resolveTaskLens(task);
10146
+ const exclude = input.exclude ?? getResolvedConfig({ projectRoot: input.project.rootPath }).codegraph.excludePatterns;
10093
10147
  const store = new CodeGraphStore();
10094
10148
  await store.init(input.dataDir);
10095
10149
  const initialStatus = store.status(input.project.id);
@@ -10107,7 +10161,8 @@ async function buildAutoProjectContext(input) {
10107
10161
  try {
10108
10162
  const indexed = await indexProjectLite({
10109
10163
  projectId: input.project.id,
10110
- projectRoot: input.project.rootPath
10164
+ projectRoot: input.project.rootPath,
10165
+ exclude
10111
10166
  });
10112
10167
  store.replaceProjectIndex(input.project.id, indexed);
10113
10168
  const backfill = await backfillMissingObservationCodeRefs(
@@ -10127,12 +10182,14 @@ async function buildAutoProjectContext(input) {
10127
10182
  const overview = buildProjectContextOverview({
10128
10183
  project: input.project,
10129
10184
  store,
10130
- observations: input.observations
10185
+ observations: input.observations,
10186
+ exclude
10131
10187
  });
10132
10188
  const explain = buildProjectContextExplain({
10133
10189
  project: input.project,
10134
10190
  store,
10135
- observations: input.observations
10191
+ observations: input.observations,
10192
+ exclude
10136
10193
  });
10137
10194
  return {
10138
10195
  project: input.project,
@@ -10342,6 +10399,7 @@ var init_auto_context = __esm({
10342
10399
  "src/codegraph/auto-context.ts"() {
10343
10400
  "use strict";
10344
10401
  init_esm_shims();
10402
+ init_resolved_config();
10345
10403
  init_binder();
10346
10404
  init_current_facts();
10347
10405
  init_lite_provider();
@@ -10369,10 +10427,6 @@ function tokenize2(text) {
10369
10427
  function timestampOf(observation) {
10370
10428
  return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
10371
10429
  }
10372
- function isGeneratedPath2(path20) {
10373
- const normalized = path20.replace(/\\/g, "/");
10374
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
10375
- }
10376
10430
  function relevanceScore(observation, taskTokens) {
10377
10431
  if (taskTokens.length === 0) return 0;
10378
10432
  const title = observation.title.toLowerCase();
@@ -10423,7 +10477,8 @@ function assembleContextPackForTask(input) {
10423
10477
  refs,
10424
10478
  files,
10425
10479
  symbols,
10426
- suggestedVerification: input.suggestedVerification
10480
+ suggestedVerification: input.suggestedVerification,
10481
+ exclude: input.exclude
10427
10482
  });
10428
10483
  }
10429
10484
  function assembleContextPack(input) {
@@ -10442,6 +10497,7 @@ function assembleContextPack(input) {
10442
10497
  observationIdsWithRefs.add(ref.observationId);
10443
10498
  const file = ref.fileId ? files.get(ref.fileId) : void 0;
10444
10499
  const symbol = ref.symbolId ? symbols.get(ref.symbolId) : void 0;
10500
+ if (file && isCodeGraphExcludedPath(file.path, input.exclude)) continue;
10445
10501
  const freshness = evaluateCodeRefFreshness(ref, file, symbol);
10446
10502
  if (freshness.status === "current") {
10447
10503
  const memoryKey = `${observation.id}:${freshness.status}`;
@@ -10507,8 +10563,8 @@ function buildContextPackPrompt(pack) {
10507
10563
  const reliableMemories = pack.memories.filter((memory) => memory.status === "current");
10508
10564
  const unboundMemories = pack.memories.filter((memory) => memory.status === "unbound");
10509
10565
  const lines = ["## Task", pack.task, "", "## Reliable Memories"];
10510
- const visibleCodeFacts = pack.codeFacts.filter((fact) => !isGeneratedPath2(fact.path)).slice(0, 5);
10511
- const visibleSuggestedReads = pack.suggestedReads.filter((path20) => !isGeneratedPath2(path20)).slice(0, 5);
10566
+ const visibleCodeFacts = pack.codeFacts.filter((fact) => !isCodeGraphExcludedPath(fact.path)).slice(0, 5);
10567
+ const visibleSuggestedReads = pack.suggestedReads.filter((path20) => !isCodeGraphExcludedPath(path20)).slice(0, 5);
10512
10568
  if (reliableMemories.length === 0) lines.push("- none");
10513
10569
  for (const memory of reliableMemories) {
10514
10570
  lines.push(`- #${memory.id} ${memory.status}: [${memory.type}] ${memory.title} (${memory.reason})`);
@@ -10543,6 +10599,7 @@ var init_context_pack = __esm({
10543
10599
  "use strict";
10544
10600
  init_esm_shims();
10545
10601
  init_freshness2();
10602
+ init_exclude();
10546
10603
  }
10547
10604
  });
10548
10605
 
@@ -19924,7 +19981,7 @@ The path should point to a directory containing a .git folder.`
19924
19981
  };
19925
19982
  const server = existingServer ?? new McpServer({
19926
19983
  name: "memorix",
19927
- version: true ? "1.1.8" : "1.0.1"
19984
+ version: true ? "1.1.9" : "1.0.1"
19928
19985
  });
19929
19986
  const originalRegisterTool = server.registerTool.bind(server);
19930
19987
  server.registerTool = ((name, ...args) => {
@@ -20626,15 +20683,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
20626
20683
  return withFreshIndex(async () => {
20627
20684
  const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
20628
20685
  const { assembleContextPackForTask: assembleContextPackForTask2, buildContextPackPrompt: buildContextPackPrompt2 } = await Promise.resolve().then(() => (init_context_pack(), context_pack_exports));
20686
+ const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
20629
20687
  const store = new CodeGraphStore2();
20630
20688
  await store.init(projectDir2);
20689
+ const exclude = getResolvedConfig2({ projectRoot: project.rootPath }).codegraph.excludePatterns;
20631
20690
  const observations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active").reverse();
20632
20691
  const pack = assembleContextPackForTask2({
20633
20692
  store,
20634
20693
  projectId: project.id,
20635
20694
  task,
20636
20695
  observations: observations2,
20637
- limit: typeof limit === "number" ? limit : 20
20696
+ limit: typeof limit === "number" ? limit : 20,
20697
+ exclude
20638
20698
  });
20639
20699
  const text = buildContextPackPrompt2(pack);
20640
20700
  return {