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/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.
|
|
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
|
-
|
|
15705
|
-
|
|
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
|
|
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"
|
|
23262
|
-
|
|
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 (
|
|
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 =
|
|
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) => !
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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(
|
|
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) => !
|
|
27658
|
-
const visibleSuggestedReads = pack.suggestedReads.filter((path29) => !
|
|
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.
|
|
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
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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
|
|
74830
|
-
if (
|
|
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));
|