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 CHANGED
@@ -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
package/dist/cli/index.js CHANGED
@@ -3212,7 +3212,7 @@ ${import_picocolors.default.gray(m3)} ${s2}
3212
3212
 
3213
3213
  // src/cli/version.ts
3214
3214
  function getCliVersion() {
3215
- return true ? "1.1.8" : pkg.version;
3215
+ return true ? "1.1.9" : pkg.version;
3216
3216
  }
3217
3217
  var init_version = __esm({
3218
3218
  "src/cli/version.ts"() {
@@ -12429,6 +12429,7 @@ function loadYamlConfig(projectRoot) {
12429
12429
  agent: { ...userConfig.agent, ...projectConfig.agent },
12430
12430
  embedding: { ...userConfig.embedding, ...projectConfig.embedding },
12431
12431
  git: { ...userConfig.git, ...projectConfig.git },
12432
+ codegraph: { ...userConfig.codegraph, ...projectConfig.codegraph },
12432
12433
  behavior: { ...userConfig.behavior, ...projectConfig.behavior },
12433
12434
  server: { ...userConfig.server, ...projectConfig.server },
12434
12435
  team: { ...userConfig.team, ...projectConfig.team }
@@ -12531,6 +12532,7 @@ function mergeTomlConfig(base, override) {
12531
12532
  embedding: { ...base.embedding, ...override.embedding },
12532
12533
  hooks: { ...base.hooks, ...override.hooks },
12533
12534
  git: { ...base.git, ...override.git },
12535
+ codegraph: { ...base.codegraph, ...override.codegraph },
12534
12536
  server: { ...base.server, ...override.server }
12535
12537
  };
12536
12538
  }
@@ -13154,6 +13156,9 @@ function getResolvedConfig(options2 = {}) {
13154
13156
  excludePatterns: firstArray(toml.git?.exclude_patterns, yaml4.git?.excludePatterns),
13155
13157
  noiseKeywords: firstArray(toml.git?.noise_keywords, yaml4.git?.noiseKeywords)
13156
13158
  },
13159
+ codegraph: {
13160
+ excludePatterns: firstArray(toml.codegraph?.exclude_patterns, yaml4.codegraph?.excludePatterns)
13161
+ },
13157
13162
  server: {
13158
13163
  transport: first(toml.server?.transport, yaml4.server?.transport),
13159
13164
  dashboard: firstBool(toml.server?.dashboard, yaml4.server?.dashboard),
@@ -15701,8 +15706,12 @@ function makeEntryKey(projectId, observationId) {
15701
15706
  return `${projectId ?? ""}::${observationId}`;
15702
15707
  }
15703
15708
  function rememberObservationDoc(doc) {
15704
- if (!doc.projectId || typeof doc.observationId !== "number") return;
15705
- docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), doc);
15709
+ const publicDoc = { ...doc };
15710
+ delete publicDoc.embedding;
15711
+ if (doc.projectId && typeof doc.observationId === "number") {
15712
+ docByObservationKey.set(makeEntryKey(doc.projectId, doc.observationId), publicDoc);
15713
+ }
15714
+ return publicDoc;
15706
15715
  }
15707
15716
  function isCommandLikeQuery(query) {
15708
15717
  return COMMAND_LIKE_QUERY2.test(query);
@@ -15804,14 +15813,14 @@ async function batchGenerateEmbeddings(texts) {
15804
15813
  }
15805
15814
  async function hydrateIndex(observations2) {
15806
15815
  const database = await getDb();
15807
- const currentCount = await count2(database);
15808
- if (currentCount > 0) return 0;
15809
15816
  let inserted = 0;
15810
15817
  for (const obs of observations2) {
15811
15818
  if (!obs || !obs.id || !obs.projectId) continue;
15812
15819
  try {
15820
+ const id = makeOramaObservationId(obs.projectId, obs.id);
15821
+ if (getByID(database, id)) continue;
15813
15822
  const doc = {
15814
- id: makeOramaObservationId(obs.projectId, obs.id),
15823
+ id,
15815
15824
  observationId: obs.id,
15816
15825
  entityName: obs.entityName || "",
15817
15826
  type: obs.type || "discovery",
@@ -15905,6 +15914,7 @@ async function searchObservations(options2) {
15905
15914
  let searchParams = {
15906
15915
  term: originalQuery,
15907
15916
  limit: requestLimit,
15917
+ includeVectors: true,
15908
15918
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
15909
15919
  // Search specific fields (not tokens, accessCount, etc.)
15910
15920
  properties: ["title", "entityName", "narrative", "facts", "concepts", "filesModified"],
@@ -15976,6 +15986,7 @@ async function searchObservations(options2) {
15976
15986
  const vectorOnlyParams = {
15977
15987
  term: "",
15978
15988
  limit: requestLimit,
15989
+ includeVectors: true,
15979
15990
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
15980
15991
  mode: "vector",
15981
15992
  vector: {
@@ -16274,6 +16285,7 @@ async function getObservationsByIds(ids, projectId) {
16274
16285
  }
16275
16286
  const searchResult = await search2(database, {
16276
16287
  term: "",
16288
+ includeVectors: true,
16277
16289
  where: {
16278
16290
  observationId: { eq: id },
16279
16291
  ...projectId ? { projectId } : {}
@@ -16281,7 +16293,7 @@ async function getObservationsByIds(ids, projectId) {
16281
16293
  limit: 1
16282
16294
  });
16283
16295
  if (searchResult.hits.length > 0) {
16284
- results.push(searchResult.hits[0].document);
16296
+ results.push(rememberObservationDoc(searchResult.hits[0].document));
16285
16297
  }
16286
16298
  }
16287
16299
  return results;
@@ -23258,11 +23270,17 @@ __export(config_get_exports, {
23258
23270
  function readDotted(source, key) {
23259
23271
  let cursor = source;
23260
23272
  for (const part of key.split(".")) {
23261
- if (!cursor || typeof cursor !== "object" || !(part in cursor)) return void 0;
23262
- cursor = cursor[part];
23273
+ if (!cursor || typeof cursor !== "object") return void 0;
23274
+ const record2 = cursor;
23275
+ const normalizedPart = part in record2 ? part : snakeToCamel(part);
23276
+ if (!(normalizedPart in record2)) return void 0;
23277
+ cursor = record2[normalizedPart];
23263
23278
  }
23264
23279
  return cursor;
23265
23280
  }
23281
+ function snakeToCamel(value) {
23282
+ return value.replace(/_([a-z])/g, (_4, char) => char.toUpperCase());
23283
+ }
23266
23284
  function formatValue(value, key) {
23267
23285
  if (typeof value === "string") return shouldRedactKey(key) ? "<redacted>" : value;
23268
23286
  if (typeof value === "number" || typeof value === "boolean") return String(value);
@@ -26289,6 +26307,58 @@ var init_current_facts = __esm({
26289
26307
  }
26290
26308
  });
26291
26309
 
26310
+ // src/codegraph/exclude.ts
26311
+ function normalizeCodeGraphExcludePatterns(exclude) {
26312
+ return [.../* @__PURE__ */ new Set([
26313
+ ...DEFAULT_CODEGRAPH_EXCLUDES,
26314
+ ...(exclude ?? []).map((pattern) => pattern.trim()).filter(Boolean)
26315
+ ])];
26316
+ }
26317
+ function isCodeGraphExcludedPath(path29, exclude) {
26318
+ const normalized = normalizeCodePath2(path29);
26319
+ return normalizeCodeGraphExcludePatterns(exclude).some((pattern) => matchesPattern(normalized, normalizeCodePath2(pattern)));
26320
+ }
26321
+ function normalizeCodePath2(path29) {
26322
+ return path29.replace(/\\/g, "/").replace(/^\.\/+/, "");
26323
+ }
26324
+ function matchesPattern(path29, pattern) {
26325
+ if (pattern.endsWith("/**")) {
26326
+ const base = pattern.slice(0, -3);
26327
+ if (base.startsWith("**/")) {
26328
+ const suffix = base.slice(3);
26329
+ return path29 === suffix || path29.endsWith(`/${suffix}`) || path29.includes(`/${suffix}/`);
26330
+ }
26331
+ if (!base.includes("/")) {
26332
+ return path29 === base || path29.startsWith(`${base}/`) || path29.includes(`/${base}/`);
26333
+ }
26334
+ return path29 === base || path29.startsWith(`${base}/`);
26335
+ }
26336
+ if (pattern.startsWith("**/")) {
26337
+ const suffix = pattern.slice(3);
26338
+ return path29 === suffix || path29.endsWith(`/${suffix}`);
26339
+ }
26340
+ return path29 === pattern || path29.startsWith(`${pattern}/`);
26341
+ }
26342
+ var DEFAULT_CODEGRAPH_EXCLUDES;
26343
+ var init_exclude = __esm({
26344
+ "src/codegraph/exclude.ts"() {
26345
+ "use strict";
26346
+ init_esm_shims();
26347
+ DEFAULT_CODEGRAPH_EXCLUDES = [
26348
+ "node_modules/**",
26349
+ "dist/**",
26350
+ "build/**",
26351
+ "coverage/**",
26352
+ ".next/**",
26353
+ ".turbo/**",
26354
+ ".git/**",
26355
+ ".tmp/**",
26356
+ ".worktrees/**",
26357
+ ".claude/worktrees/**"
26358
+ ];
26359
+ }
26360
+ });
26361
+
26292
26362
  // src/codegraph/lite-provider.ts
26293
26363
  import { createHash as createHash4 } from "crypto";
26294
26364
  import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
@@ -26304,18 +26374,6 @@ function languageForPath(path29) {
26304
26374
  const ext = extension(path29);
26305
26375
  return LANGUAGE_BY_EXTENSION.get(ext) ?? "unknown";
26306
26376
  }
26307
- function isExcluded(path29, exclude) {
26308
- const normalized = normalizeCodePath(path29);
26309
- return exclude.some((pattern) => {
26310
- const p2 = normalizeCodePath(pattern);
26311
- if (p2.endsWith("/**")) {
26312
- const base = p2.slice(0, -3);
26313
- return normalized === base || normalized.startsWith(`${base}/`);
26314
- }
26315
- if (p2.startsWith("**/")) return normalized.endsWith(p2.slice(3));
26316
- return normalized === p2 || normalized.startsWith(`${p2}/`);
26317
- });
26318
- }
26319
26377
  function walk(root, exclude, maxFiles) {
26320
26378
  const out = [];
26321
26379
  const visit = (dir) => {
@@ -26329,7 +26387,7 @@ function walk(root, exclude, maxFiles) {
26329
26387
  for (const entry of entries) {
26330
26388
  const abs = join20(dir, entry.name);
26331
26389
  const rel = normalizeCodePath(relative(root, abs));
26332
- if (isExcluded(rel, exclude)) continue;
26390
+ if (isCodeGraphExcludedPath(rel, exclude)) continue;
26333
26391
  if (entry.isDirectory()) {
26334
26392
  if (entry.name === ".git" || entry.name === ".worktrees" || entry.name === ".tmp" || entry.name === "node_modules") continue;
26335
26393
  if (rel === ".claude/worktrees" || rel.startsWith(".claude/worktrees/")) continue;
@@ -26417,18 +26475,7 @@ function extractImportEdges(projectId, file, text, indexedAt) {
26417
26475
  return edges;
26418
26476
  }
26419
26477
  async function indexProjectLite(options2) {
26420
- const exclude = options2.exclude ?? [
26421
- "node_modules/**",
26422
- "dist/**",
26423
- "build/**",
26424
- "coverage/**",
26425
- ".next/**",
26426
- ".turbo/**",
26427
- ".git/**",
26428
- ".tmp/**",
26429
- ".worktrees/**",
26430
- ".claude/worktrees/**"
26431
- ];
26478
+ const exclude = normalizeCodeGraphExcludePatterns(options2.exclude);
26432
26479
  const maxFiles = options2.maxFiles ?? 5e3;
26433
26480
  const indexedAt = (/* @__PURE__ */ new Date()).toISOString();
26434
26481
  const paths = walk(options2.projectRoot, exclude, maxFiles);
@@ -26467,6 +26514,7 @@ var init_lite_provider = __esm({
26467
26514
  "use strict";
26468
26515
  init_esm_shims();
26469
26516
  init_ids();
26517
+ init_exclude();
26470
26518
  LANGUAGE_BY_EXTENSION = /* @__PURE__ */ new Map([
26471
26519
  [".ts", "typescript"],
26472
26520
  [".tsx", "typescript"],
@@ -26643,24 +26691,17 @@ function countLanguages(files) {
26643
26691
  }
26644
26692
  return [...counts.entries()].map(([language, files2]) => ({ language, files: files2 })).sort((a3, b3) => a3.language.localeCompare(b3.language));
26645
26693
  }
26646
- function normalizePath2(path29) {
26647
- return path29.replace(/\\/g, "/");
26648
- }
26649
- function isGeneratedPath(path29) {
26650
- const normalized = normalizePath2(path29);
26651
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
26652
- }
26653
26694
  function suggestedReadRank(path29) {
26654
- const normalized = normalizePath2(path29);
26695
+ const normalized = path29.replace(/\\/g, "/");
26655
26696
  if (normalized.startsWith("src/")) return 0;
26656
26697
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 0;
26657
26698
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
26658
26699
  return 3;
26659
26700
  }
26660
- function compactSuggestedReads(paths, limit = 8) {
26661
- return uniq(paths).filter((path29) => !isGeneratedPath(path29)).sort((a3, b3) => suggestedReadRank(a3) - suggestedReadRank(b3)).slice(0, limit);
26701
+ function compactSuggestedReads(paths, limit = 8, exclude) {
26702
+ return uniq(paths).filter((path29) => !isCodeGraphExcludedPath(path29, exclude)).sort((a3, b3) => suggestedReadRank(a3) - suggestedReadRank(b3)).slice(0, limit);
26662
26703
  }
26663
- function collectGraph(store2, projectId, observations2) {
26704
+ function collectGraph(store2, projectId, observations2, exclude) {
26664
26705
  const files = store2.listFiles(projectId);
26665
26706
  const symbols = files.flatMap((file) => store2.listSymbolsForFile(file.id));
26666
26707
  const filesById = new Map(files.map((file) => [file.id, file]));
@@ -26682,7 +26723,9 @@ function collectGraph(store2, projectId, observations2) {
26682
26723
  freshness[result.status] += 1;
26683
26724
  const observation = observationsById.get(ref.observationId);
26684
26725
  if (!observation) continue;
26685
- if (result.status === "current" && file) suggestedReads.push(file.path);
26726
+ const excluded = file ? isCodeGraphExcludedPath(file.path, exclude) : false;
26727
+ if (result.status === "current" && file && !excluded) suggestedReads.push(file.path);
26728
+ if (excluded) continue;
26686
26729
  sources.push({
26687
26730
  observationId: observation.id,
26688
26731
  title: observation.title,
@@ -26699,12 +26742,12 @@ function collectGraph(store2, projectId, observations2) {
26699
26742
  refs,
26700
26743
  freshness,
26701
26744
  sources,
26702
- suggestedReads: compactSuggestedReads(suggestedReads)
26745
+ suggestedReads: compactSuggestedReads(suggestedReads, 8, exclude)
26703
26746
  };
26704
26747
  }
26705
26748
  function buildProjectContextOverview(input) {
26706
26749
  const active = activeObservations(input.observations, input.project.id);
26707
- const graph = collectGraph(input.store, input.project.id, active);
26750
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
26708
26751
  const status = input.store.status(input.project.id);
26709
26752
  return {
26710
26753
  project: input.project,
@@ -26728,7 +26771,7 @@ function buildProjectContextOverview(input) {
26728
26771
  function buildProjectContextExplain(input) {
26729
26772
  const overview = buildProjectContextOverview(input);
26730
26773
  const active = activeObservations(input.observations, input.project.id);
26731
- const graph = collectGraph(input.store, input.project.id, active);
26774
+ const graph = collectGraph(input.store, input.project.id, active, input.exclude);
26732
26775
  return {
26733
26776
  project: input.project,
26734
26777
  sources: graph.sources.sort((a3, b3) => a3.observationId - b3.observationId || (a3.path ?? "").localeCompare(b3.path ?? "")),
@@ -26782,11 +26825,12 @@ var init_project_context = __esm({
26782
26825
  "use strict";
26783
26826
  init_esm_shims();
26784
26827
  init_freshness2();
26828
+ init_exclude();
26785
26829
  }
26786
26830
  });
26787
26831
 
26788
26832
  // src/codegraph/task-lens.ts
26789
- function normalizePath3(path29) {
26833
+ function normalizePath2(path29) {
26790
26834
  return path29.replace(/\\/g, "/");
26791
26835
  }
26792
26836
  function tokenize3(text) {
@@ -26816,7 +26860,7 @@ function resolveTaskLens(task) {
26816
26860
  return best.score > 0 ? LENSES[best.id] : LENSES.general;
26817
26861
  }
26818
26862
  function pathKindScore(path29, lens) {
26819
- const normalized = normalizePath3(path29).toLowerCase();
26863
+ const normalized = normalizePath2(path29).toLowerCase();
26820
26864
  const name = normalized.split("/").pop() ?? normalized;
26821
26865
  const inDocs = normalized.startsWith("docs/") || name === "readme.md" || name.includes("readme");
26822
26866
  const isTest = /(^|\/)(tests?|__tests__|spec|fixtures?)\//.test(normalized) || /\.(test|spec)\.[cm]?[jt]sx?$/.test(normalized) || /\.(test|spec)\.py$/.test(normalized);
@@ -26865,7 +26909,7 @@ function sourceTaskMatchScore(source, task) {
26865
26909
  return 0;
26866
26910
  }
26867
26911
  function fallbackPathRank(path29) {
26868
- const normalized = normalizePath3(path29);
26912
+ const normalized = normalizePath2(path29);
26869
26913
  if (normalized.startsWith("src/")) return 0;
26870
26914
  if (normalized.startsWith("tests/") || normalized.startsWith("test/")) return 1;
26871
26915
  if (normalized.startsWith("packages/") && normalized.includes("/src/")) return 2;
@@ -26874,7 +26918,7 @@ function fallbackPathRank(path29) {
26874
26918
  }
26875
26919
  function rankLensPaths(paths, lens, task) {
26876
26920
  const tokens = tokenize3(task ?? "");
26877
- return [...new Set(paths.map(normalizePath3))].map((path29, index) => ({
26921
+ return [...new Set(paths.map(normalizePath2))].map((path29, index) => ({
26878
26922
  path: path29,
26879
26923
  index,
26880
26924
  score: pathKindScore(path29, lens) + tokenScore(path29, tokens),
@@ -27128,6 +27172,7 @@ async function buildAutoProjectContext(input) {
27128
27172
  const now = input.now ?? /* @__PURE__ */ new Date();
27129
27173
  const task = input.task?.trim();
27130
27174
  const lens = resolveTaskLens(task);
27175
+ const exclude = input.exclude ?? getResolvedConfig({ projectRoot: input.project.rootPath }).codegraph.excludePatterns;
27131
27176
  const store2 = new CodeGraphStore();
27132
27177
  await store2.init(input.dataDir);
27133
27178
  const initialStatus = store2.status(input.project.id);
@@ -27145,7 +27190,8 @@ async function buildAutoProjectContext(input) {
27145
27190
  try {
27146
27191
  const indexed = await indexProjectLite({
27147
27192
  projectId: input.project.id,
27148
- projectRoot: input.project.rootPath
27193
+ projectRoot: input.project.rootPath,
27194
+ exclude
27149
27195
  });
27150
27196
  store2.replaceProjectIndex(input.project.id, indexed);
27151
27197
  const backfill = await backfillMissingObservationCodeRefs(
@@ -27165,12 +27211,14 @@ async function buildAutoProjectContext(input) {
27165
27211
  const overview = buildProjectContextOverview({
27166
27212
  project: input.project,
27167
27213
  store: store2,
27168
- observations: input.observations
27214
+ observations: input.observations,
27215
+ exclude
27169
27216
  });
27170
27217
  const explain = buildProjectContextExplain({
27171
27218
  project: input.project,
27172
27219
  store: store2,
27173
- observations: input.observations
27220
+ observations: input.observations,
27221
+ exclude
27174
27222
  });
27175
27223
  return {
27176
27224
  project: input.project,
@@ -27380,6 +27428,7 @@ var init_auto_context = __esm({
27380
27428
  "src/codegraph/auto-context.ts"() {
27381
27429
  "use strict";
27382
27430
  init_esm_shims();
27431
+ init_resolved_config();
27383
27432
  init_binder();
27384
27433
  init_current_facts();
27385
27434
  init_lite_provider();
@@ -27516,10 +27565,6 @@ function tokenize4(text) {
27516
27565
  function timestampOf(observation) {
27517
27566
  return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
27518
27567
  }
27519
- function isGeneratedPath2(path29) {
27520
- const normalized = path29.replace(/\\/g, "/");
27521
- return /(^|\/)(dist|build|coverage|\.next|\.turbo|node_modules|\.git|\.tmp|\.worktrees)(\/|$)/i.test(normalized) || /(^|\/)\.claude\/worktrees(\/|$)/i.test(normalized);
27522
- }
27523
27568
  function relevanceScore(observation, taskTokens) {
27524
27569
  if (taskTokens.length === 0) return 0;
27525
27570
  const title = observation.title.toLowerCase();
@@ -27570,7 +27615,8 @@ function assembleContextPackForTask(input) {
27570
27615
  refs,
27571
27616
  files,
27572
27617
  symbols,
27573
- suggestedVerification: input.suggestedVerification
27618
+ suggestedVerification: input.suggestedVerification,
27619
+ exclude: input.exclude
27574
27620
  });
27575
27621
  }
27576
27622
  function assembleContextPack(input) {
@@ -27589,6 +27635,7 @@ function assembleContextPack(input) {
27589
27635
  observationIdsWithRefs.add(ref.observationId);
27590
27636
  const file = ref.fileId ? files.get(ref.fileId) : void 0;
27591
27637
  const symbol = ref.symbolId ? symbols.get(ref.symbolId) : void 0;
27638
+ if (file && isCodeGraphExcludedPath(file.path, input.exclude)) continue;
27592
27639
  const freshness = evaluateCodeRefFreshness(ref, file, symbol);
27593
27640
  if (freshness.status === "current") {
27594
27641
  const memoryKey = `${observation.id}:${freshness.status}`;
@@ -27654,8 +27701,8 @@ function buildContextPackPrompt(pack) {
27654
27701
  const reliableMemories = pack.memories.filter((memory) => memory.status === "current");
27655
27702
  const unboundMemories = pack.memories.filter((memory) => memory.status === "unbound");
27656
27703
  const lines = ["## Task", pack.task, "", "## Reliable Memories"];
27657
- const visibleCodeFacts = pack.codeFacts.filter((fact) => !isGeneratedPath2(fact.path)).slice(0, 5);
27658
- const visibleSuggestedReads = pack.suggestedReads.filter((path29) => !isGeneratedPath2(path29)).slice(0, 5);
27704
+ const visibleCodeFacts = pack.codeFacts.filter((fact) => !isCodeGraphExcludedPath(fact.path)).slice(0, 5);
27705
+ const visibleSuggestedReads = pack.suggestedReads.filter((path29) => !isCodeGraphExcludedPath(path29)).slice(0, 5);
27659
27706
  if (reliableMemories.length === 0) lines.push("- none");
27660
27707
  for (const memory of reliableMemories) {
27661
27708
  lines.push(`- #${memory.id} ${memory.status}: [${memory.type}] ${memory.title} (${memory.reason})`);
@@ -27690,6 +27737,7 @@ var init_context_pack = __esm({
27690
27737
  "use strict";
27691
27738
  init_esm_shims();
27692
27739
  init_freshness2();
27740
+ init_exclude();
27693
27741
  }
27694
27742
  });
27695
27743
 
@@ -27728,6 +27776,7 @@ var init_codegraph = __esm({
27728
27776
  init_lite_provider();
27729
27777
  init_context_pack();
27730
27778
  init_binder();
27779
+ init_resolved_config();
27731
27780
  init_observations();
27732
27781
  init_operator_shared();
27733
27782
  codegraph_default = defineCommand({
@@ -27750,6 +27799,7 @@ var init_codegraph = __esm({
27750
27799
  const store2 = new CodeGraphStore();
27751
27800
  await store2.init(dataDir);
27752
27801
  const explicitAction = Boolean(positional[0] || args.action);
27802
+ const exclude = getResolvedConfig({ projectRoot: project.rootPath }).codegraph.excludePatterns;
27753
27803
  switch (action) {
27754
27804
  case "status": {
27755
27805
  const status = store2.status(project.id);
@@ -27762,7 +27812,8 @@ ${formatUsageHint()}`;
27762
27812
  case "refresh": {
27763
27813
  const indexed = await indexProjectLite({
27764
27814
  projectId: project.id,
27765
- projectRoot: project.rootPath
27815
+ projectRoot: project.rootPath,
27816
+ exclude
27766
27817
  });
27767
27818
  store2.replaceProjectIndex(project.id, indexed);
27768
27819
  const activeObservations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active");
@@ -27793,7 +27844,8 @@ ${formatUsageHint()}`;
27793
27844
  projectId: project.id,
27794
27845
  task,
27795
27846
  observations: observations2,
27796
- limit
27847
+ limit,
27848
+ exclude
27797
27849
  });
27798
27850
  emitResult({ project, pack }, buildContextPackPrompt(pack), asJson);
27799
27851
  return;
@@ -61964,7 +62016,7 @@ The path should point to a directory containing a .git folder.`
61964
62016
  };
61965
62017
  const server = existingServer ?? new McpServer({
61966
62018
  name: "memorix",
61967
- version: true ? "1.1.8" : "1.0.1"
62019
+ version: true ? "1.1.9" : "1.0.1"
61968
62020
  });
61969
62021
  const originalRegisterTool = server.registerTool.bind(server);
61970
62022
  server.registerTool = ((name, ...args) => {
@@ -62666,15 +62718,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
62666
62718
  return withFreshIndex(async () => {
62667
62719
  const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
62668
62720
  const { assembleContextPackForTask: assembleContextPackForTask2, buildContextPackPrompt: buildContextPackPrompt2 } = await Promise.resolve().then(() => (init_context_pack(), context_pack_exports));
62721
+ const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
62669
62722
  const store2 = new CodeGraphStore2();
62670
62723
  await store2.init(projectDir2);
62724
+ const exclude = getResolvedConfig2({ projectRoot: project.rootPath }).codegraph.excludePatterns;
62671
62725
  const observations2 = getAllObservations().filter((obs) => obs.projectId === project.id && (obs.status ?? "active") === "active").reverse();
62672
62726
  const pack = assembleContextPackForTask2({
62673
62727
  store: store2,
62674
62728
  projectId: project.id,
62675
62729
  task,
62676
62730
  observations: observations2,
62677
- limit: typeof limit === "number" ? limit : 20
62731
+ limit: typeof limit === "number" ? limit : 20,
62732
+ exclude
62678
62733
  });
62679
62734
  const text = buildContextPackPrompt2(pack);
62680
62735
  return {
@@ -71470,7 +71525,7 @@ function getMemorixDir() {
71470
71525
  const home = process.env.HOME || process.env.USERPROFILE || "";
71471
71526
  return home.replace(/\\/g, "/") + "/.memorix";
71472
71527
  }
71473
- function normalizePath4(p2) {
71528
+ function normalizePath3(p2) {
71474
71529
  return process.platform === "win32" ? p2.replace(/\//g, "\\") : p2;
71475
71530
  }
71476
71531
  function getStateFilePath() {
@@ -71636,7 +71691,7 @@ async function doStart(port) {
71636
71691
  ` Port: ${port}`,
71637
71692
  ` Dashboard: http://127.0.0.1:${port}/`,
71638
71693
  ` MCP: http://127.0.0.1:${port}/mcp`,
71639
- ` Logs: ${normalizePath4(logFile)}`,
71694
+ ` Logs: ${normalizePath3(logFile)}`,
71640
71695
  ""
71641
71696
  ].join("\n");
71642
71697
  process.stderr.write(startMsg + "\n");
@@ -71650,7 +71705,7 @@ async function doStart(port) {
71650
71705
  }
71651
71706
  if (!isProcessRunning(pid)) {
71652
71707
  console.error("[ERROR] Background process exited unexpectedly.");
71653
- console.error(` Check logs: ${normalizePath4(logFile)}`);
71708
+ console.error(` Check logs: ${normalizePath3(logFile)}`);
71654
71709
  clearState();
71655
71710
  process.exitCode = 1;
71656
71711
  return;
@@ -71788,7 +71843,7 @@ async function doStatus() {
71788
71843
  if (state.instanceToken) console.log(` Instance: ${state.instanceToken.slice(0, 8)}\u2026`);
71789
71844
  console.log(` Dashboard: http://127.0.0.1:${state.port}/`);
71790
71845
  console.log(` MCP: http://127.0.0.1:${state.port}/mcp`);
71791
- console.log(` Logs: ${normalizePath4(state.logFile)}`);
71846
+ console.log(` Logs: ${normalizePath3(state.logFile)}`);
71792
71847
  if (health.ok && health.data) {
71793
71848
  const d3 = health.data;
71794
71849
  console.log("");
@@ -72759,8 +72814,10 @@ var init_doctor = __esm({
72759
72814
  try {
72760
72815
  const { CodeGraphStore: CodeGraphStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
72761
72816
  const { buildProjectContextOverview: buildProjectContextOverview2 } = await Promise.resolve().then(() => (init_project_context(), project_context_exports));
72817
+ const { getResolvedConfig: getResolvedConfig2 } = await Promise.resolve().then(() => (init_resolved_config(), resolved_config_exports));
72762
72818
  const codeStore = new CodeGraphStore2();
72763
72819
  await codeStore.init(dataDir);
72820
+ const exclude = getResolvedConfig2({ projectRoot: projectRoot || process.cwd() }).codegraph.excludePatterns;
72764
72821
  const overview = buildProjectContextOverview2({
72765
72822
  project: {
72766
72823
  id: projectId,
@@ -72768,7 +72825,8 @@ var init_doctor = __esm({
72768
72825
  rootPath: projectRoot || process.cwd()
72769
72826
  },
72770
72827
  store: codeStore,
72771
- observations: projectObservations
72828
+ observations: projectObservations,
72829
+ exclude
72772
72830
  });
72773
72831
  const languageText = overview.code.languages.length > 0 ? overview.code.languages.map((item) => `${item.language} ${item.files}`).join(", ") : "none indexed yet";
72774
72832
  if (overview.code.files > 0) {
@@ -74826,8 +74884,8 @@ function buildIdleReasons(available, dispatchedNames, config2, excludeAgents) {
74826
74884
  const excluded = excludeAgents ?? /* @__PURE__ */ new Set();
74827
74885
  for (const adapter of available) {
74828
74886
  if (dispatchedNames.has(adapter.name)) continue;
74829
- const isExcluded2 = excluded.has(adapter.name);
74830
- if (isExcluded2) {
74887
+ const isExcluded = excluded.has(adapter.name);
74888
+ if (isExcluded) {
74831
74889
  result.push({ name: adapter.name, reason: "excluded due to prior failure" });
74832
74890
  } else {
74833
74891
  const inAnyPref = Object.values(DEFAULT_ROLE_PREFERENCES).some((prefs) => prefs.includes(adapter.name));