memorix 0.9.32 → 0.9.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +260 -212
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +165 -152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -8790,12 +8790,12 @@ var init_stdio2 = __esm({
|
|
|
8790
8790
|
this.onclose?.();
|
|
8791
8791
|
}
|
|
8792
8792
|
send(message) {
|
|
8793
|
-
return new Promise((
|
|
8793
|
+
return new Promise((resolve) => {
|
|
8794
8794
|
const json = serializeMessage(message);
|
|
8795
8795
|
if (this._stdout.write(json)) {
|
|
8796
|
-
|
|
8796
|
+
resolve();
|
|
8797
8797
|
} else {
|
|
8798
|
-
this._stdout.once("drain",
|
|
8798
|
+
this._stdout.once("drain", resolve);
|
|
8799
8799
|
}
|
|
8800
8800
|
});
|
|
8801
8801
|
}
|
|
@@ -15438,7 +15438,7 @@ var init_protocol = __esm({
|
|
|
15438
15438
|
return;
|
|
15439
15439
|
}
|
|
15440
15440
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
15441
|
-
await new Promise((
|
|
15441
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
15442
15442
|
options2?.signal?.throwIfAborted();
|
|
15443
15443
|
}
|
|
15444
15444
|
} catch (error2) {
|
|
@@ -15455,7 +15455,7 @@ var init_protocol = __esm({
|
|
|
15455
15455
|
*/
|
|
15456
15456
|
request(request, resultSchema, options2) {
|
|
15457
15457
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options2 ?? {};
|
|
15458
|
-
return new Promise((
|
|
15458
|
+
return new Promise((resolve, reject) => {
|
|
15459
15459
|
const earlyReject = (error2) => {
|
|
15460
15460
|
reject(error2);
|
|
15461
15461
|
};
|
|
@@ -15533,7 +15533,7 @@ var init_protocol = __esm({
|
|
|
15533
15533
|
if (!parseResult.success) {
|
|
15534
15534
|
reject(parseResult.error);
|
|
15535
15535
|
} else {
|
|
15536
|
-
|
|
15536
|
+
resolve(parseResult.data);
|
|
15537
15537
|
}
|
|
15538
15538
|
} catch (error2) {
|
|
15539
15539
|
reject(error2);
|
|
@@ -15794,12 +15794,12 @@ var init_protocol = __esm({
|
|
|
15794
15794
|
}
|
|
15795
15795
|
} catch {
|
|
15796
15796
|
}
|
|
15797
|
-
return new Promise((
|
|
15797
|
+
return new Promise((resolve, reject) => {
|
|
15798
15798
|
if (signal.aborted) {
|
|
15799
15799
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
15800
15800
|
return;
|
|
15801
15801
|
}
|
|
15802
|
-
const timeoutId = setTimeout(
|
|
15802
|
+
const timeoutId = setTimeout(resolve, interval);
|
|
15803
15803
|
signal.addEventListener("abort", () => {
|
|
15804
15804
|
clearTimeout(timeoutId);
|
|
15805
15805
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -18847,7 +18847,7 @@ var require_compile = __commonJS({
|
|
|
18847
18847
|
const schOrFunc = root.refs[ref];
|
|
18848
18848
|
if (schOrFunc)
|
|
18849
18849
|
return schOrFunc;
|
|
18850
|
-
let _sch =
|
|
18850
|
+
let _sch = resolve.call(this, root, ref);
|
|
18851
18851
|
if (_sch === void 0) {
|
|
18852
18852
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
18853
18853
|
const { schemaId } = this.opts;
|
|
@@ -18874,7 +18874,7 @@ var require_compile = __commonJS({
|
|
|
18874
18874
|
function sameSchemaEnv(s1, s2) {
|
|
18875
18875
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
18876
18876
|
}
|
|
18877
|
-
function
|
|
18877
|
+
function resolve(root, ref) {
|
|
18878
18878
|
let sch;
|
|
18879
18879
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
18880
18880
|
ref = sch;
|
|
@@ -19452,7 +19452,7 @@ var require_fast_uri = __commonJS({
|
|
|
19452
19452
|
}
|
|
19453
19453
|
return uri;
|
|
19454
19454
|
}
|
|
19455
|
-
function
|
|
19455
|
+
function resolve(baseURI, relativeURI, options2) {
|
|
19456
19456
|
const schemelessOptions = options2 ? Object.assign({ scheme: "null" }, options2) : { scheme: "null" };
|
|
19457
19457
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
19458
19458
|
schemelessOptions.skipEscape = true;
|
|
@@ -19679,7 +19679,7 @@ var require_fast_uri = __commonJS({
|
|
|
19679
19679
|
var fastUri = {
|
|
19680
19680
|
SCHEMES,
|
|
19681
19681
|
normalize,
|
|
19682
|
-
resolve
|
|
19682
|
+
resolve,
|
|
19683
19683
|
resolveComponent,
|
|
19684
19684
|
equal,
|
|
19685
19685
|
serialize,
|
|
@@ -23943,7 +23943,7 @@ var init_mcp = __esm({
|
|
|
23943
23943
|
let task = createTaskResult.task;
|
|
23944
23944
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
23945
23945
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
23946
|
-
await new Promise((
|
|
23946
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
23947
23947
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
23948
23948
|
if (!updatedTask) {
|
|
23949
23949
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -24563,9 +24563,6 @@ import { promises as fs2 } from "fs";
|
|
|
24563
24563
|
import path3 from "path";
|
|
24564
24564
|
import os from "os";
|
|
24565
24565
|
async function getProjectDataDir(_projectId, baseDir) {
|
|
24566
|
-
if (_projectId === "__invalid__") {
|
|
24567
|
-
throw new Error("Cannot create data directory for invalid project");
|
|
24568
|
-
}
|
|
24569
24566
|
const base = baseDir ?? DEFAULT_DATA_DIR;
|
|
24570
24567
|
await fs2.mkdir(base, { recursive: true });
|
|
24571
24568
|
return base;
|
|
@@ -29397,12 +29394,12 @@ async function removeMultipleAsync(orama, ids, batchSize, language, skipHooks) {
|
|
|
29397
29394
|
if (!skipHooks) {
|
|
29398
29395
|
await runMultipleHook(orama.beforeRemoveMultiple, orama, docIdsForHooks);
|
|
29399
29396
|
}
|
|
29400
|
-
await new Promise((
|
|
29397
|
+
await new Promise((resolve, reject) => {
|
|
29401
29398
|
let i2 = 0;
|
|
29402
29399
|
async function _removeMultiple() {
|
|
29403
29400
|
const batch = ids.slice(i2 * batchSize, ++i2 * batchSize);
|
|
29404
29401
|
if (!batch.length) {
|
|
29405
|
-
return
|
|
29402
|
+
return resolve();
|
|
29406
29403
|
}
|
|
29407
29404
|
for (const doc of batch) {
|
|
29408
29405
|
try {
|
|
@@ -30801,13 +30798,42 @@ var fastembed_provider_exports = {};
|
|
|
30801
30798
|
__export(fastembed_provider_exports, {
|
|
30802
30799
|
FastEmbedProvider: () => FastEmbedProvider
|
|
30803
30800
|
});
|
|
30804
|
-
|
|
30801
|
+
import { createHash } from "crypto";
|
|
30802
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
30803
|
+
import { join } from "path";
|
|
30804
|
+
import { homedir } from "os";
|
|
30805
|
+
function textHash(text) {
|
|
30806
|
+
return createHash("sha256").update(text).digest("hex").slice(0, 16);
|
|
30807
|
+
}
|
|
30808
|
+
async function loadDiskCache() {
|
|
30809
|
+
try {
|
|
30810
|
+
const raw = await readFile(CACHE_FILE, "utf-8");
|
|
30811
|
+
const entries = JSON.parse(raw);
|
|
30812
|
+
for (const [k5, v5] of entries) cache.set(k5, v5);
|
|
30813
|
+
console.error(`[memorix] Loaded ${entries.length} cached embeddings from disk`);
|
|
30814
|
+
} catch {
|
|
30815
|
+
}
|
|
30816
|
+
}
|
|
30817
|
+
async function saveDiskCache() {
|
|
30818
|
+
if (!diskCacheDirty) return;
|
|
30819
|
+
try {
|
|
30820
|
+
await mkdir(CACHE_DIR, { recursive: true });
|
|
30821
|
+
const entries = Array.from(cache.entries());
|
|
30822
|
+
await writeFile(CACHE_FILE, JSON.stringify(entries));
|
|
30823
|
+
diskCacheDirty = false;
|
|
30824
|
+
} catch {
|
|
30825
|
+
}
|
|
30826
|
+
}
|
|
30827
|
+
var CACHE_DIR, CACHE_FILE, cache, MAX_CACHE_SIZE, diskCacheDirty, FastEmbedProvider;
|
|
30805
30828
|
var init_fastembed_provider = __esm({
|
|
30806
30829
|
"src/embedding/fastembed-provider.ts"() {
|
|
30807
30830
|
"use strict";
|
|
30808
30831
|
init_esm_shims();
|
|
30832
|
+
CACHE_DIR = join(homedir(), ".memorix", "data");
|
|
30833
|
+
CACHE_FILE = join(CACHE_DIR, ".embedding-cache.json");
|
|
30809
30834
|
cache = /* @__PURE__ */ new Map();
|
|
30810
30835
|
MAX_CACHE_SIZE = 5e3;
|
|
30836
|
+
diskCacheDirty = false;
|
|
30811
30837
|
FastEmbedProvider = class _FastEmbedProvider {
|
|
30812
30838
|
name = "fastembed-bge-small";
|
|
30813
30839
|
dimensions = 384;
|
|
@@ -30818,23 +30844,26 @@ var init_fastembed_provider = __esm({
|
|
|
30818
30844
|
/**
|
|
30819
30845
|
* Initialize the FastEmbed provider.
|
|
30820
30846
|
* Downloads model on first use (~30MB), cached locally after.
|
|
30847
|
+
* Loads persistent embedding cache from disk.
|
|
30821
30848
|
*/
|
|
30822
30849
|
static async create() {
|
|
30823
30850
|
const { EmbeddingModel, FlagEmbedding } = await import("fastembed");
|
|
30824
30851
|
const model = await FlagEmbedding.init({
|
|
30825
30852
|
model: EmbeddingModel.BGESmallENV15
|
|
30826
30853
|
});
|
|
30854
|
+
await loadDiskCache();
|
|
30827
30855
|
return new _FastEmbedProvider(model);
|
|
30828
30856
|
}
|
|
30829
30857
|
async embed(text) {
|
|
30830
|
-
const
|
|
30858
|
+
const hash = textHash(text);
|
|
30859
|
+
const cached2 = cache.get(hash);
|
|
30831
30860
|
if (cached2) return cached2;
|
|
30832
30861
|
const raw = await this.model.queryEmbed(text);
|
|
30833
30862
|
const result = Array.from(raw);
|
|
30834
30863
|
if (result.length !== this.dimensions) {
|
|
30835
30864
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
30836
30865
|
}
|
|
30837
|
-
this.cacheSet(
|
|
30866
|
+
this.cacheSet(hash, result);
|
|
30838
30867
|
return result;
|
|
30839
30868
|
}
|
|
30840
30869
|
async embedBatch(texts) {
|
|
@@ -30842,7 +30871,8 @@ var init_fastembed_provider = __esm({
|
|
|
30842
30871
|
const uncachedIndices = [];
|
|
30843
30872
|
const uncachedTexts = [];
|
|
30844
30873
|
for (let i2 = 0; i2 < texts.length; i2++) {
|
|
30845
|
-
const
|
|
30874
|
+
const hash = textHash(texts[i2]);
|
|
30875
|
+
const cached2 = cache.get(hash);
|
|
30846
30876
|
if (cached2) {
|
|
30847
30877
|
results[i2] = cached2;
|
|
30848
30878
|
} else {
|
|
@@ -30851,25 +30881,28 @@ var init_fastembed_provider = __esm({
|
|
|
30851
30881
|
}
|
|
30852
30882
|
}
|
|
30853
30883
|
if (uncachedTexts.length > 0) {
|
|
30884
|
+
console.error(`[memorix] Embedding ${uncachedTexts.length}/${texts.length} uncached texts (${texts.length - uncachedTexts.length} from cache)`);
|
|
30854
30885
|
let batchIdx = 0;
|
|
30855
30886
|
for await (const batch of this.model.embed(uncachedTexts, 64)) {
|
|
30856
30887
|
for (const vec of batch) {
|
|
30857
30888
|
const originalIdx = uncachedIndices[batchIdx];
|
|
30858
30889
|
const plain = Array.from(vec);
|
|
30859
30890
|
results[originalIdx] = plain;
|
|
30860
|
-
this.cacheSet(uncachedTexts[batchIdx], plain);
|
|
30891
|
+
this.cacheSet(textHash(uncachedTexts[batchIdx]), plain);
|
|
30861
30892
|
batchIdx++;
|
|
30862
30893
|
}
|
|
30863
30894
|
}
|
|
30895
|
+
await saveDiskCache();
|
|
30864
30896
|
}
|
|
30865
30897
|
return results;
|
|
30866
30898
|
}
|
|
30867
|
-
cacheSet(
|
|
30899
|
+
cacheSet(hash, value) {
|
|
30868
30900
|
if (cache.size >= MAX_CACHE_SIZE) {
|
|
30869
30901
|
const firstKey = cache.keys().next().value;
|
|
30870
30902
|
if (firstKey !== void 0) cache.delete(firstKey);
|
|
30871
30903
|
}
|
|
30872
|
-
cache.set(
|
|
30904
|
+
cache.set(hash, value);
|
|
30905
|
+
diskCacheDirty = true;
|
|
30873
30906
|
}
|
|
30874
30907
|
};
|
|
30875
30908
|
}
|
|
@@ -31012,6 +31045,7 @@ var init_provider = __esm({
|
|
|
31012
31045
|
// src/store/orama-store.ts
|
|
31013
31046
|
var orama_store_exports = {};
|
|
31014
31047
|
__export(orama_store_exports, {
|
|
31048
|
+
batchGenerateEmbeddings: () => batchGenerateEmbeddings,
|
|
31015
31049
|
generateEmbedding: () => generateEmbedding,
|
|
31016
31050
|
getDb: () => getDb,
|
|
31017
31051
|
getObservationCount: () => getObservationCount,
|
|
@@ -31059,6 +31093,16 @@ async function generateEmbedding(text) {
|
|
|
31059
31093
|
if (!provider2) return null;
|
|
31060
31094
|
return provider2.embed(text);
|
|
31061
31095
|
}
|
|
31096
|
+
async function batchGenerateEmbeddings(texts) {
|
|
31097
|
+
const provider2 = await getEmbeddingProvider();
|
|
31098
|
+
if (!provider2 || texts.length === 0) return texts.map(() => null);
|
|
31099
|
+
try {
|
|
31100
|
+
const results = await provider2.embedBatch(texts);
|
|
31101
|
+
return results;
|
|
31102
|
+
} catch {
|
|
31103
|
+
return texts.map(() => null);
|
|
31104
|
+
}
|
|
31105
|
+
}
|
|
31062
31106
|
async function insertObservation(doc) {
|
|
31063
31107
|
const database = await getDb();
|
|
31064
31108
|
await insert3(database, doc);
|
|
@@ -33491,17 +33535,22 @@ function suggestTopicKey(type, title) {
|
|
|
33491
33535
|
return `${family}/${slug}`;
|
|
33492
33536
|
}
|
|
33493
33537
|
async function reindexObservations() {
|
|
33538
|
+
if (observations.length === 0) return 0;
|
|
33539
|
+
let embeddings = [];
|
|
33540
|
+
if (isEmbeddingEnabled()) {
|
|
33541
|
+
try {
|
|
33542
|
+
const texts = observations.map(
|
|
33543
|
+
(obs) => [obs.title, obs.narrative, ...obs.facts].join(" ")
|
|
33544
|
+
);
|
|
33545
|
+
embeddings = await batchGenerateEmbeddings(texts);
|
|
33546
|
+
} catch {
|
|
33547
|
+
}
|
|
33548
|
+
}
|
|
33494
33549
|
let count3 = 0;
|
|
33495
|
-
for (
|
|
33550
|
+
for (let i2 = 0; i2 < observations.length; i2++) {
|
|
33551
|
+
const obs = observations[i2];
|
|
33496
33552
|
try {
|
|
33497
|
-
|
|
33498
|
-
if (isEmbeddingEnabled()) {
|
|
33499
|
-
try {
|
|
33500
|
-
const searchableText = [obs.title, obs.narrative, ...obs.facts].join(" ");
|
|
33501
|
-
embedding = await generateEmbedding(searchableText);
|
|
33502
|
-
} catch {
|
|
33503
|
-
}
|
|
33504
|
-
}
|
|
33553
|
+
const embedding = embeddings[i2] ?? null;
|
|
33505
33554
|
const doc = {
|
|
33506
33555
|
id: `obs-${obs.id}`,
|
|
33507
33556
|
observationId: obs.id,
|
|
@@ -33817,8 +33866,11 @@ function detectProject(cwd) {
|
|
|
33817
33866
|
return { id: id2, name: name2, gitRemote, rootPath };
|
|
33818
33867
|
}
|
|
33819
33868
|
if (isDangerousRoot(rootPath)) {
|
|
33820
|
-
|
|
33821
|
-
|
|
33869
|
+
const name2 = path4.basename(rootPath) || "unknown";
|
|
33870
|
+
const id2 = `placeholder/${name2}`;
|
|
33871
|
+
console.error(`[memorix] WARNING: cwd "${rootPath}" is not a project directory \u2014 using degraded mode (${id2})`);
|
|
33872
|
+
console.error(`[memorix] For best results, set MEMORIX_PROJECT_ROOT or --cwd to your project path.`);
|
|
33873
|
+
return { id: id2, name: name2, rootPath };
|
|
33822
33874
|
}
|
|
33823
33875
|
const name = path4.basename(rootPath);
|
|
33824
33876
|
const id = `local/${name}`;
|
|
@@ -37480,9 +37532,9 @@ var require_gray_matter = __commonJS({
|
|
|
37480
37532
|
});
|
|
37481
37533
|
|
|
37482
37534
|
// src/rules/utils.ts
|
|
37483
|
-
import { createHash } from "crypto";
|
|
37535
|
+
import { createHash as createHash2 } from "crypto";
|
|
37484
37536
|
function hashContent(content) {
|
|
37485
|
-
return
|
|
37537
|
+
return createHash2("sha256").update(content.trim()).digest("hex").substring(0, 16);
|
|
37486
37538
|
}
|
|
37487
37539
|
function generateRuleId(source, filePath) {
|
|
37488
37540
|
const sanitized = filePath.replace(/[\/\\]/g, "-").replace(/^\./, "");
|
|
@@ -38240,8 +38292,8 @@ var init_syncer = __esm({
|
|
|
38240
38292
|
});
|
|
38241
38293
|
|
|
38242
38294
|
// src/workspace/mcp-adapters/windsurf.ts
|
|
38243
|
-
import { homedir } from "os";
|
|
38244
|
-
import { join } from "path";
|
|
38295
|
+
import { homedir as homedir2 } from "os";
|
|
38296
|
+
import { join as join2 } from "path";
|
|
38245
38297
|
var WindsurfMCPAdapter;
|
|
38246
38298
|
var init_windsurf2 = __esm({
|
|
38247
38299
|
"src/workspace/mcp-adapters/windsurf.ts"() {
|
|
@@ -38303,15 +38355,15 @@ var init_windsurf2 = __esm({
|
|
|
38303
38355
|
return JSON.stringify({ mcpServers }, null, 2);
|
|
38304
38356
|
}
|
|
38305
38357
|
getConfigPath(_projectRoot) {
|
|
38306
|
-
return
|
|
38358
|
+
return join2(homedir2(), ".codeium", "windsurf", "mcp_config.json");
|
|
38307
38359
|
}
|
|
38308
38360
|
};
|
|
38309
38361
|
}
|
|
38310
38362
|
});
|
|
38311
38363
|
|
|
38312
38364
|
// src/workspace/mcp-adapters/cursor.ts
|
|
38313
|
-
import { homedir as
|
|
38314
|
-
import { join as
|
|
38365
|
+
import { homedir as homedir3 } from "os";
|
|
38366
|
+
import { join as join3 } from "path";
|
|
38315
38367
|
var CursorMCPAdapter;
|
|
38316
38368
|
var init_cursor2 = __esm({
|
|
38317
38369
|
"src/workspace/mcp-adapters/cursor.ts"() {
|
|
@@ -38353,17 +38405,17 @@ var init_cursor2 = __esm({
|
|
|
38353
38405
|
}
|
|
38354
38406
|
getConfigPath(projectRoot) {
|
|
38355
38407
|
if (projectRoot) {
|
|
38356
|
-
return
|
|
38408
|
+
return join3(projectRoot, ".cursor", "mcp.json");
|
|
38357
38409
|
}
|
|
38358
|
-
return
|
|
38410
|
+
return join3(homedir3(), ".cursor", "mcp.json");
|
|
38359
38411
|
}
|
|
38360
38412
|
};
|
|
38361
38413
|
}
|
|
38362
38414
|
});
|
|
38363
38415
|
|
|
38364
38416
|
// src/workspace/mcp-adapters/codex.ts
|
|
38365
|
-
import { homedir as
|
|
38366
|
-
import { join as
|
|
38417
|
+
import { homedir as homedir4 } from "os";
|
|
38418
|
+
import { join as join4 } from "path";
|
|
38367
38419
|
var CodexMCPAdapter;
|
|
38368
38420
|
var init_codex2 = __esm({
|
|
38369
38421
|
"src/workspace/mcp-adapters/codex.ts"() {
|
|
@@ -38458,9 +38510,9 @@ var init_codex2 = __esm({
|
|
|
38458
38510
|
}
|
|
38459
38511
|
getConfigPath(projectRoot) {
|
|
38460
38512
|
if (projectRoot) {
|
|
38461
|
-
return
|
|
38513
|
+
return join4(projectRoot, ".codex", "config.toml");
|
|
38462
38514
|
}
|
|
38463
|
-
return
|
|
38515
|
+
return join4(homedir4(), ".codex", "config.toml");
|
|
38464
38516
|
}
|
|
38465
38517
|
// ---- TOML helpers ----
|
|
38466
38518
|
parseTomlString(raw) {
|
|
@@ -38508,8 +38560,8 @@ var init_codex2 = __esm({
|
|
|
38508
38560
|
});
|
|
38509
38561
|
|
|
38510
38562
|
// src/workspace/mcp-adapters/claude-code.ts
|
|
38511
|
-
import { homedir as
|
|
38512
|
-
import { join as
|
|
38563
|
+
import { homedir as homedir5 } from "os";
|
|
38564
|
+
import { join as join5 } from "path";
|
|
38513
38565
|
var ClaudeCodeMCPAdapter;
|
|
38514
38566
|
var init_claude_code2 = __esm({
|
|
38515
38567
|
"src/workspace/mcp-adapters/claude-code.ts"() {
|
|
@@ -38551,17 +38603,17 @@ var init_claude_code2 = __esm({
|
|
|
38551
38603
|
}
|
|
38552
38604
|
getConfigPath(projectRoot) {
|
|
38553
38605
|
if (projectRoot) {
|
|
38554
|
-
return
|
|
38606
|
+
return join5(projectRoot, ".claude", "settings.json");
|
|
38555
38607
|
}
|
|
38556
|
-
return
|
|
38608
|
+
return join5(homedir5(), ".claude.json");
|
|
38557
38609
|
}
|
|
38558
38610
|
};
|
|
38559
38611
|
}
|
|
38560
38612
|
});
|
|
38561
38613
|
|
|
38562
38614
|
// src/workspace/mcp-adapters/copilot.ts
|
|
38563
|
-
import { homedir as
|
|
38564
|
-
import { join as
|
|
38615
|
+
import { homedir as homedir6 } from "os";
|
|
38616
|
+
import { join as join6 } from "path";
|
|
38565
38617
|
var CopilotMCPAdapter;
|
|
38566
38618
|
var init_copilot2 = __esm({
|
|
38567
38619
|
"src/workspace/mcp-adapters/copilot.ts"() {
|
|
@@ -38621,15 +38673,15 @@ var init_copilot2 = __esm({
|
|
|
38621
38673
|
}
|
|
38622
38674
|
getConfigPath(projectRoot) {
|
|
38623
38675
|
if (projectRoot) {
|
|
38624
|
-
return
|
|
38676
|
+
return join6(projectRoot, ".vscode", "mcp.json");
|
|
38625
38677
|
}
|
|
38626
|
-
const home =
|
|
38678
|
+
const home = homedir6();
|
|
38627
38679
|
if (process.platform === "win32") {
|
|
38628
|
-
return
|
|
38680
|
+
return join6(home, "AppData", "Roaming", "Code", "User", "settings.json");
|
|
38629
38681
|
} else if (process.platform === "darwin") {
|
|
38630
|
-
return
|
|
38682
|
+
return join6(home, "Library", "Application Support", "Code", "User", "settings.json");
|
|
38631
38683
|
} else {
|
|
38632
|
-
return
|
|
38684
|
+
return join6(home, ".config", "Code", "User", "settings.json");
|
|
38633
38685
|
}
|
|
38634
38686
|
}
|
|
38635
38687
|
};
|
|
@@ -38637,8 +38689,8 @@ var init_copilot2 = __esm({
|
|
|
38637
38689
|
});
|
|
38638
38690
|
|
|
38639
38691
|
// src/workspace/mcp-adapters/antigravity.ts
|
|
38640
|
-
import { homedir as
|
|
38641
|
-
import { join as
|
|
38692
|
+
import { homedir as homedir7 } from "os";
|
|
38693
|
+
import { join as join7 } from "path";
|
|
38642
38694
|
var AntigravityMCPAdapter;
|
|
38643
38695
|
var init_antigravity2 = __esm({
|
|
38644
38696
|
"src/workspace/mcp-adapters/antigravity.ts"() {
|
|
@@ -38701,17 +38753,17 @@ var init_antigravity2 = __esm({
|
|
|
38701
38753
|
}
|
|
38702
38754
|
getConfigPath(projectRoot) {
|
|
38703
38755
|
if (projectRoot) {
|
|
38704
|
-
return
|
|
38756
|
+
return join7(projectRoot, ".gemini", "settings.json");
|
|
38705
38757
|
}
|
|
38706
|
-
return
|
|
38758
|
+
return join7(homedir7(), ".gemini", "settings.json");
|
|
38707
38759
|
}
|
|
38708
38760
|
};
|
|
38709
38761
|
}
|
|
38710
38762
|
});
|
|
38711
38763
|
|
|
38712
38764
|
// src/workspace/mcp-adapters/kiro.ts
|
|
38713
|
-
import { homedir as
|
|
38714
|
-
import { join as
|
|
38765
|
+
import { homedir as homedir8 } from "os";
|
|
38766
|
+
import { join as join8 } from "path";
|
|
38715
38767
|
var KiroMCPAdapter;
|
|
38716
38768
|
var init_kiro2 = __esm({
|
|
38717
38769
|
"src/workspace/mcp-adapters/kiro.ts"() {
|
|
@@ -38753,9 +38805,9 @@ var init_kiro2 = __esm({
|
|
|
38753
38805
|
}
|
|
38754
38806
|
getConfigPath(projectRoot) {
|
|
38755
38807
|
if (projectRoot) {
|
|
38756
|
-
return
|
|
38808
|
+
return join8(projectRoot, ".kiro", "settings", "mcp.json");
|
|
38757
38809
|
}
|
|
38758
|
-
return
|
|
38810
|
+
return join8(homedir8(), ".kiro", "settings", "mcp.json");
|
|
38759
38811
|
}
|
|
38760
38812
|
};
|
|
38761
38813
|
}
|
|
@@ -39004,8 +39056,8 @@ var init_applier = __esm({
|
|
|
39004
39056
|
|
|
39005
39057
|
// src/workspace/engine.ts
|
|
39006
39058
|
import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync3, cpSync, mkdirSync as mkdirSync2 } from "fs";
|
|
39007
|
-
import { join as
|
|
39008
|
-
import { homedir as
|
|
39059
|
+
import { join as join10 } from "path";
|
|
39060
|
+
import { homedir as homedir9 } from "os";
|
|
39009
39061
|
var WorkspaceSyncEngine;
|
|
39010
39062
|
var init_engine2 = __esm({
|
|
39011
39063
|
"src/workspace/engine.ts"() {
|
|
@@ -39162,7 +39214,7 @@ var init_engine2 = __esm({
|
|
|
39162
39214
|
getTargetSkillsDir(target) {
|
|
39163
39215
|
const dirs = _WorkspaceSyncEngine.SKILLS_DIRS[target];
|
|
39164
39216
|
if (!dirs || dirs.length === 0) return null;
|
|
39165
|
-
return
|
|
39217
|
+
return join10(this.projectRoot, dirs[0]);
|
|
39166
39218
|
}
|
|
39167
39219
|
/**
|
|
39168
39220
|
* Scan all agent skills directories and collect unique skills.
|
|
@@ -39171,12 +39223,12 @@ var init_engine2 = __esm({
|
|
|
39171
39223
|
const skills = [];
|
|
39172
39224
|
const conflicts = [];
|
|
39173
39225
|
const seen = /* @__PURE__ */ new Map();
|
|
39174
|
-
const home =
|
|
39226
|
+
const home = homedir9();
|
|
39175
39227
|
for (const [agent, dirs] of Object.entries(_WorkspaceSyncEngine.SKILLS_DIRS)) {
|
|
39176
39228
|
for (const dir of dirs) {
|
|
39177
39229
|
const paths = [
|
|
39178
|
-
|
|
39179
|
-
|
|
39230
|
+
join10(this.projectRoot, dir),
|
|
39231
|
+
join10(home, dir)
|
|
39180
39232
|
];
|
|
39181
39233
|
for (const skillsRoot of paths) {
|
|
39182
39234
|
if (!existsSync3(skillsRoot)) continue;
|
|
@@ -39184,7 +39236,7 @@ var init_engine2 = __esm({
|
|
|
39184
39236
|
const entries = readdirSync(skillsRoot, { withFileTypes: true });
|
|
39185
39237
|
for (const entry of entries) {
|
|
39186
39238
|
if (!entry.isDirectory()) continue;
|
|
39187
|
-
const skillMd =
|
|
39239
|
+
const skillMd = join10(skillsRoot, entry.name, "SKILL.md");
|
|
39188
39240
|
if (!existsSync3(skillMd)) continue;
|
|
39189
39241
|
let description = "";
|
|
39190
39242
|
try {
|
|
@@ -39196,7 +39248,7 @@ var init_engine2 = __esm({
|
|
|
39196
39248
|
const newEntry = {
|
|
39197
39249
|
name: entry.name,
|
|
39198
39250
|
description,
|
|
39199
|
-
sourcePath:
|
|
39251
|
+
sourcePath: join10(skillsRoot, entry.name),
|
|
39200
39252
|
sourceAgent: agent
|
|
39201
39253
|
};
|
|
39202
39254
|
const existing = seen.get(entry.name);
|
|
@@ -39233,7 +39285,7 @@ var init_engine2 = __esm({
|
|
|
39233
39285
|
}
|
|
39234
39286
|
for (const skill of skills) {
|
|
39235
39287
|
if (skill.sourceAgent === target) continue;
|
|
39236
|
-
const dest =
|
|
39288
|
+
const dest = join10(targetDir, skill.name);
|
|
39237
39289
|
if (existsSync3(dest)) {
|
|
39238
39290
|
skipped.push(`${skill.name} (already exists in ${target})`);
|
|
39239
39291
|
continue;
|
|
@@ -39249,13 +39301,13 @@ var init_engine2 = __esm({
|
|
|
39249
39301
|
}
|
|
39250
39302
|
scanWorkflows() {
|
|
39251
39303
|
const workflows = [];
|
|
39252
|
-
const wfDir =
|
|
39304
|
+
const wfDir = join10(this.projectRoot, ".windsurf", "workflows");
|
|
39253
39305
|
if (!existsSync3(wfDir)) return workflows;
|
|
39254
39306
|
try {
|
|
39255
39307
|
const files = readdirSync(wfDir).filter((f4) => f4.endsWith(".md"));
|
|
39256
39308
|
for (const file of files) {
|
|
39257
39309
|
try {
|
|
39258
|
-
const content = readFileSync2(
|
|
39310
|
+
const content = readFileSync2(join10(wfDir, file), "utf-8");
|
|
39259
39311
|
workflows.push(this.workflowSyncer.parseWindsurfWorkflow(file, content));
|
|
39260
39312
|
} catch {
|
|
39261
39313
|
}
|
|
@@ -39646,8 +39698,8 @@ __export(engine_exports, {
|
|
|
39646
39698
|
SkillsEngine: () => SkillsEngine
|
|
39647
39699
|
});
|
|
39648
39700
|
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync2 } from "fs";
|
|
39649
|
-
import { join as
|
|
39650
|
-
import { homedir as
|
|
39701
|
+
import { join as join11 } from "path";
|
|
39702
|
+
import { homedir as homedir10 } from "os";
|
|
39651
39703
|
var SKILLS_DIRS, SKILL_WORTHY_TYPES, MIN_OBS_FOR_SKILL, MIN_SCORE_FOR_SKILL, SkillsEngine;
|
|
39652
39704
|
var init_engine3 = __esm({
|
|
39653
39705
|
"src/skills/engine.ts"() {
|
|
@@ -39686,12 +39738,12 @@ var init_engine3 = __esm({
|
|
|
39686
39738
|
listSkills() {
|
|
39687
39739
|
const skills = [];
|
|
39688
39740
|
const seen = /* @__PURE__ */ new Set();
|
|
39689
|
-
const home =
|
|
39741
|
+
const home = homedir10();
|
|
39690
39742
|
for (const [agent, dirs] of Object.entries(SKILLS_DIRS)) {
|
|
39691
39743
|
for (const dir of dirs) {
|
|
39692
|
-
const paths = [
|
|
39744
|
+
const paths = [join11(this.projectRoot, dir)];
|
|
39693
39745
|
if (!this.skipGlobal) {
|
|
39694
|
-
paths.push(
|
|
39746
|
+
paths.push(join11(home, dir));
|
|
39695
39747
|
}
|
|
39696
39748
|
for (const skillsRoot of paths) {
|
|
39697
39749
|
if (!existsSync4(skillsRoot)) continue;
|
|
@@ -39701,7 +39753,7 @@ var init_engine3 = __esm({
|
|
|
39701
39753
|
if (!entry.isDirectory()) continue;
|
|
39702
39754
|
const name = entry.name;
|
|
39703
39755
|
if (seen.has(name)) continue;
|
|
39704
|
-
const skillMd =
|
|
39756
|
+
const skillMd = join11(skillsRoot, name, "SKILL.md");
|
|
39705
39757
|
if (!existsSync4(skillMd)) continue;
|
|
39706
39758
|
try {
|
|
39707
39759
|
const content = readFileSync3(skillMd, "utf-8");
|
|
@@ -39709,7 +39761,7 @@ var init_engine3 = __esm({
|
|
|
39709
39761
|
skills.push({
|
|
39710
39762
|
name,
|
|
39711
39763
|
description,
|
|
39712
|
-
sourcePath:
|
|
39764
|
+
sourcePath: join11(skillsRoot, name),
|
|
39713
39765
|
sourceAgent: agent,
|
|
39714
39766
|
content,
|
|
39715
39767
|
generated: false
|
|
@@ -39751,11 +39803,11 @@ var init_engine3 = __esm({
|
|
|
39751
39803
|
writeSkill(skill, target) {
|
|
39752
39804
|
const dirs = SKILLS_DIRS[target];
|
|
39753
39805
|
if (!dirs || dirs.length === 0) return null;
|
|
39754
|
-
const targetDir =
|
|
39806
|
+
const targetDir = join11(this.projectRoot, dirs[0], skill.name);
|
|
39755
39807
|
try {
|
|
39756
39808
|
mkdirSync3(targetDir, { recursive: true });
|
|
39757
|
-
writeFileSync2(
|
|
39758
|
-
return
|
|
39809
|
+
writeFileSync2(join11(targetDir, "SKILL.md"), skill.content, "utf-8");
|
|
39810
|
+
return join11(dirs[0], skill.name, "SKILL.md");
|
|
39759
39811
|
} catch {
|
|
39760
39812
|
return null;
|
|
39761
39813
|
}
|
|
@@ -40286,31 +40338,27 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir) {
|
|
|
40286
40338
|
let effectiveProjectId = projectId;
|
|
40287
40339
|
let effectiveProjectName = projectName;
|
|
40288
40340
|
if (requestedProject && requestedProject !== projectId) {
|
|
40289
|
-
|
|
40290
|
-
|
|
40291
|
-
|
|
40292
|
-
await fs4.access(candidateDir);
|
|
40293
|
-
effectiveDataDir = candidateDir;
|
|
40294
|
-
effectiveProjectId = requestedProject;
|
|
40295
|
-
effectiveProjectName = requestedProject.split("/").pop() || requestedProject;
|
|
40296
|
-
} catch {
|
|
40297
|
-
}
|
|
40341
|
+
effectiveDataDir = baseDir;
|
|
40342
|
+
effectiveProjectId = requestedProject;
|
|
40343
|
+
effectiveProjectName = requestedProject.split("/").pop() || requestedProject;
|
|
40298
40344
|
}
|
|
40299
40345
|
try {
|
|
40300
40346
|
switch (apiPath) {
|
|
40301
40347
|
case "/projects": {
|
|
40302
40348
|
try {
|
|
40303
|
-
const
|
|
40304
|
-
const
|
|
40305
|
-
|
|
40306
|
-
|
|
40307
|
-
|
|
40308
|
-
|
|
40309
|
-
|
|
40310
|
-
|
|
40311
|
-
|
|
40312
|
-
|
|
40313
|
-
|
|
40349
|
+
const allObs = await loadObservationsJson(baseDir);
|
|
40350
|
+
const projectSet = /* @__PURE__ */ new Map();
|
|
40351
|
+
for (const obs of allObs) {
|
|
40352
|
+
if (obs.projectId) {
|
|
40353
|
+
projectSet.set(obs.projectId, (projectSet.get(obs.projectId) || 0) + 1);
|
|
40354
|
+
}
|
|
40355
|
+
}
|
|
40356
|
+
const projects = Array.from(projectSet.entries()).sort((a3, b3) => b3[1] - a3[1]).map(([id, count3]) => ({
|
|
40357
|
+
id,
|
|
40358
|
+
name: id.split("/").pop() || id,
|
|
40359
|
+
count: count3,
|
|
40360
|
+
isCurrent: id === projectId
|
|
40361
|
+
}));
|
|
40314
40362
|
sendJson(res, projects);
|
|
40315
40363
|
} catch {
|
|
40316
40364
|
sendJson(res, []);
|
|
@@ -40499,10 +40547,10 @@ function openBrowser(url) {
|
|
|
40499
40547
|
});
|
|
40500
40548
|
}
|
|
40501
40549
|
function readBody(req) {
|
|
40502
|
-
return new Promise((
|
|
40550
|
+
return new Promise((resolve, reject) => {
|
|
40503
40551
|
const chunks = [];
|
|
40504
40552
|
req.on("data", (c5) => chunks.push(c5));
|
|
40505
|
-
req.on("end", () =>
|
|
40553
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
|
|
40506
40554
|
req.on("error", reject);
|
|
40507
40555
|
});
|
|
40508
40556
|
}
|
|
@@ -40516,17 +40564,9 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
40516
40564
|
try {
|
|
40517
40565
|
const body = JSON.parse(await readBody(req));
|
|
40518
40566
|
if (body.projectId) {
|
|
40519
|
-
const sanitized = body.projectId.replace(/\//g, "--").replace(/[<>:"|?*\\]/g, "_");
|
|
40520
|
-
const candidateDir = path6.join(baseDir, sanitized);
|
|
40521
|
-
try {
|
|
40522
|
-
await fs4.access(candidateDir);
|
|
40523
|
-
} catch {
|
|
40524
|
-
sendError(res, `Project data directory not found: ${candidateDir}`, 404);
|
|
40525
|
-
return;
|
|
40526
|
-
}
|
|
40527
40567
|
state.projectId = body.projectId;
|
|
40528
40568
|
state.projectName = body.projectName || body.projectId.split("/").pop() || body.projectId;
|
|
40529
|
-
state.dataDir =
|
|
40569
|
+
state.dataDir = baseDir;
|
|
40530
40570
|
console.error(`[dashboard] Switched current project to: ${state.projectId}`);
|
|
40531
40571
|
sendJson(res, { ok: true, projectId: state.projectId, projectName: state.projectName });
|
|
40532
40572
|
} else {
|
|
@@ -40543,7 +40583,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
40543
40583
|
await serveStatic(req, res, resolvedStaticDir);
|
|
40544
40584
|
}
|
|
40545
40585
|
});
|
|
40546
|
-
return new Promise((
|
|
40586
|
+
return new Promise((resolve, reject) => {
|
|
40547
40587
|
server.on("error", (err) => {
|
|
40548
40588
|
if (err.code === "EADDRINUSE") {
|
|
40549
40589
|
console.error(`Port ${port} is already in use. Try: memorix dashboard --port ${port + 1}`);
|
|
@@ -40564,7 +40604,7 @@ async function startDashboard(dataDir, port, staticDir, projectId, projectName,
|
|
|
40564
40604
|
Press Ctrl+C to stop
|
|
40565
40605
|
`);
|
|
40566
40606
|
if (autoOpen) openBrowser(url);
|
|
40567
|
-
|
|
40607
|
+
resolve();
|
|
40568
40608
|
});
|
|
40569
40609
|
});
|
|
40570
40610
|
}
|
|
@@ -40598,25 +40638,9 @@ __export(installers_exports, {
|
|
|
40598
40638
|
import * as fs5 from "fs/promises";
|
|
40599
40639
|
import * as path7 from "path";
|
|
40600
40640
|
import * as os3 from "os";
|
|
40601
|
-
import { createRequire } from "module";
|
|
40602
40641
|
function resolveHookCommand() {
|
|
40603
40642
|
if (process.platform === "win32") {
|
|
40604
|
-
|
|
40605
|
-
const devPath = path7.resolve(import.meta.dirname ?? __dirname, "../../cli/index.js");
|
|
40606
|
-
try {
|
|
40607
|
-
const fsStat = __require("fs");
|
|
40608
|
-
if (fsStat.existsSync(devPath)) {
|
|
40609
|
-
return `node ${devPath.replace(/\\/g, "/")}`;
|
|
40610
|
-
}
|
|
40611
|
-
} catch {
|
|
40612
|
-
}
|
|
40613
|
-
const require_ = createRequire(import.meta.url);
|
|
40614
|
-
const pkgPath = require_.resolve("memorix/package.json");
|
|
40615
|
-
const cliPath = path7.join(path7.dirname(pkgPath), "dist", "cli", "index.js");
|
|
40616
|
-
return `node ${cliPath.replace(/\\/g, "/")}`;
|
|
40617
|
-
} catch {
|
|
40618
|
-
return "memorix";
|
|
40619
|
-
}
|
|
40643
|
+
return "cmd /c memorix";
|
|
40620
40644
|
}
|
|
40621
40645
|
return "memorix";
|
|
40622
40646
|
}
|
|
@@ -40651,7 +40675,9 @@ function generateCopilotConfig() {
|
|
|
40651
40675
|
sessionStart: [hookEntry],
|
|
40652
40676
|
sessionEnd: [hookEntry],
|
|
40653
40677
|
userPromptSubmitted: [hookEntry],
|
|
40654
|
-
|
|
40678
|
+
// NOTE: preToolUse intentionally omitted — VS Code Copilot requires
|
|
40679
|
+
// hookSpecificOutput.permissionDecision in the response; memorix is
|
|
40680
|
+
// an observer, not a gatekeeper, so we only use postToolUse.
|
|
40655
40681
|
postToolUse: [hookEntry],
|
|
40656
40682
|
errorOccurred: [hookEntry]
|
|
40657
40683
|
}
|
|
@@ -40906,6 +40932,10 @@ async function installHooks(agent, projectRoot, global = false) {
|
|
|
40906
40932
|
if (Object.keys(t2).length === 0) delete merged.tools;
|
|
40907
40933
|
}
|
|
40908
40934
|
}
|
|
40935
|
+
if (agent === "copilot") {
|
|
40936
|
+
const h3 = merged.hooks;
|
|
40937
|
+
if (h3) delete h3.preToolUse;
|
|
40938
|
+
}
|
|
40909
40939
|
await fs5.writeFile(configPath, JSON.stringify(merged, null, 2), "utf-8");
|
|
40910
40940
|
}
|
|
40911
40941
|
const events = [];
|
|
@@ -41171,17 +41201,6 @@ function coerceObjectArray(val) {
|
|
|
41171
41201
|
}
|
|
41172
41202
|
async function createMemorixServer(cwd, existingServer) {
|
|
41173
41203
|
const project = detectProject(cwd);
|
|
41174
|
-
if (project.id === "__invalid__") {
|
|
41175
|
-
const resolvedCwd = cwd ?? process.cwd();
|
|
41176
|
-
console.error(`[memorix] ERROR: Could not detect a valid project at: ${resolvedCwd}`);
|
|
41177
|
-
console.error(`[memorix] The directory is not a git repository and has no project indicator files.`);
|
|
41178
|
-
console.error(`[memorix] Fix: set --cwd to your project directory, or set MEMORIX_PROJECT_ROOT env var.`);
|
|
41179
|
-
console.error(`[memorix] Example: memorix serve --cwd /path/to/your/project`);
|
|
41180
|
-
console.error(`[memorix] Example: "env": { "MEMORIX_PROJECT_ROOT": "/path/to/your/project" }`);
|
|
41181
|
-
throw new Error(
|
|
41182
|
-
`Cannot start Memorix: no valid project detected at "${resolvedCwd}". Set --cwd or MEMORIX_PROJECT_ROOT to your project directory.`
|
|
41183
|
-
);
|
|
41184
|
-
}
|
|
41185
41204
|
try {
|
|
41186
41205
|
const { migrateSubdirsToFlat: migrateSubdirsToFlat2 } = await Promise.resolve().then(() => (init_persistence(), persistence_exports));
|
|
41187
41206
|
const migrated = await migrateSubdirsToFlat2();
|
|
@@ -42143,33 +42162,33 @@ ${json}
|
|
|
42143
42162
|
const url = `http://localhost:${portNum}`;
|
|
42144
42163
|
if (dashboardRunning) {
|
|
42145
42164
|
const { createConnection } = await import("net");
|
|
42146
|
-
const isAlive = await new Promise((
|
|
42165
|
+
const isAlive = await new Promise((resolve) => {
|
|
42147
42166
|
const sock = createConnection(portNum, "127.0.0.1");
|
|
42148
42167
|
sock.once("connect", () => {
|
|
42149
42168
|
sock.destroy();
|
|
42150
|
-
|
|
42169
|
+
resolve(true);
|
|
42151
42170
|
});
|
|
42152
42171
|
sock.once("error", () => {
|
|
42153
42172
|
sock.destroy();
|
|
42154
|
-
|
|
42173
|
+
resolve(false);
|
|
42155
42174
|
});
|
|
42156
42175
|
setTimeout(() => {
|
|
42157
42176
|
sock.destroy();
|
|
42158
|
-
|
|
42177
|
+
resolve(false);
|
|
42159
42178
|
}, 1e3);
|
|
42160
42179
|
});
|
|
42161
42180
|
if (isAlive) {
|
|
42162
42181
|
const http = await import("http");
|
|
42163
42182
|
const postData = JSON.stringify({ projectId: project.id, projectName: project.name });
|
|
42164
|
-
await new Promise((
|
|
42183
|
+
await new Promise((resolve) => {
|
|
42165
42184
|
const req = http.request({
|
|
42166
42185
|
hostname: "127.0.0.1",
|
|
42167
42186
|
port: portNum,
|
|
42168
42187
|
path: "/api/set-current-project",
|
|
42169
42188
|
method: "POST",
|
|
42170
42189
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) }
|
|
42171
|
-
}, () =>
|
|
42172
|
-
req.on("error", () =>
|
|
42190
|
+
}, () => resolve());
|
|
42191
|
+
req.on("error", () => resolve());
|
|
42173
42192
|
req.write(postData);
|
|
42174
42193
|
req.end();
|
|
42175
42194
|
});
|
|
@@ -42215,18 +42234,18 @@ ${json}
|
|
|
42215
42234
|
dashboardRunning = false;
|
|
42216
42235
|
});
|
|
42217
42236
|
const { createConnection } = await import("net");
|
|
42218
|
-
await new Promise((
|
|
42237
|
+
await new Promise((resolve) => {
|
|
42219
42238
|
const deadline = Date.now() + 5e3;
|
|
42220
42239
|
const tryConnect = () => {
|
|
42221
42240
|
const sock = createConnection(portNum, "127.0.0.1");
|
|
42222
42241
|
sock.once("connect", () => {
|
|
42223
42242
|
sock.destroy();
|
|
42224
|
-
|
|
42243
|
+
resolve();
|
|
42225
42244
|
});
|
|
42226
42245
|
sock.once("error", () => {
|
|
42227
42246
|
sock.destroy();
|
|
42228
42247
|
if (Date.now() < deadline) setTimeout(tryConnect, 100);
|
|
42229
|
-
else
|
|
42248
|
+
else resolve();
|
|
42230
42249
|
});
|
|
42231
42250
|
};
|
|
42232
42251
|
tryConnect();
|
|
@@ -42402,7 +42421,7 @@ var init_serve = __esm({
|
|
|
42402
42421
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
42403
42422
|
const { detectProject: detectProject2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
42404
42423
|
const { existsSync: existsSync5 } = await import("fs");
|
|
42405
|
-
const { join:
|
|
42424
|
+
const { join: join13 } = await import("path");
|
|
42406
42425
|
let safeCwd;
|
|
42407
42426
|
try {
|
|
42408
42427
|
safeCwd = process.cwd();
|
|
@@ -42411,43 +42430,51 @@ var init_serve = __esm({
|
|
|
42411
42430
|
}
|
|
42412
42431
|
let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || process.env.INIT_CWD || safeCwd;
|
|
42413
42432
|
console.error(`[memorix] Starting with cwd: ${projectRoot}`);
|
|
42414
|
-
const looksValid = existsSync5(
|
|
42433
|
+
const looksValid = existsSync5(join13(projectRoot, ".git")) || existsSync5(join13(projectRoot, "package.json")) || existsSync5(join13(projectRoot, "Cargo.toml")) || existsSync5(join13(projectRoot, "go.mod")) || existsSync5(join13(projectRoot, "pyproject.toml"));
|
|
42415
42434
|
if (!looksValid) {
|
|
42416
|
-
|
|
42417
|
-
const
|
|
42418
|
-
|
|
42419
|
-
|
|
42420
|
-
|
|
42421
|
-
|
|
42422
|
-
|
|
42423
|
-
|
|
42424
|
-
|
|
42425
|
-
]);
|
|
42426
|
-
|
|
42427
|
-
|
|
42428
|
-
|
|
42429
|
-
|
|
42430
|
-
|
|
42431
|
-
|
|
42432
|
-
|
|
42433
|
-
|
|
42435
|
+
const earlyDetect = detectProject2(projectRoot);
|
|
42436
|
+
const isDegraded = earlyDetect.id.startsWith("placeholder/");
|
|
42437
|
+
if (!isDegraded) {
|
|
42438
|
+
console.error(`[memorix] detectProject succeeded without standard indicators`);
|
|
42439
|
+
const { server, projectId, deferredInit } = await createMemorixServer2(projectRoot);
|
|
42440
|
+
const transport = new StdioServerTransport2();
|
|
42441
|
+
await server.connect(transport);
|
|
42442
|
+
console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
|
|
42443
|
+
console.error(`[memorix] Project root: ${projectRoot}`);
|
|
42444
|
+
deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
|
|
42445
|
+
} else {
|
|
42446
|
+
console.error(`[memorix] cwd may not be a valid project, trying MCP roots protocol...`);
|
|
42447
|
+
const mcpServer = new McpServer2({ name: "memorix", version: "0.1.0" });
|
|
42448
|
+
mcpServer.registerTool("_memorix_loading", {
|
|
42449
|
+
description: "Memorix is initializing, detecting project root...",
|
|
42450
|
+
inputSchema: {}
|
|
42451
|
+
}, async () => ({
|
|
42452
|
+
content: [{ type: "text", text: "Memorix is still loading. Please retry shortly." }]
|
|
42453
|
+
}));
|
|
42454
|
+
const transport = new StdioServerTransport2();
|
|
42455
|
+
await mcpServer.connect(transport);
|
|
42456
|
+
try {
|
|
42457
|
+
const rootsResult = await Promise.race([
|
|
42458
|
+
mcpServer.server.listRoots(),
|
|
42459
|
+
new Promise((_4, reject) => setTimeout(() => reject(new Error("timeout")), 5e3))
|
|
42460
|
+
]);
|
|
42461
|
+
if (rootsResult && "roots" in rootsResult && Array.isArray(rootsResult.roots) && rootsResult.roots.length > 0) {
|
|
42462
|
+
const rootUri = rootsResult.roots[0].uri;
|
|
42463
|
+
if (rootUri.startsWith("file://")) {
|
|
42464
|
+
const urlPath = decodeURIComponent(new URL(rootUri).pathname);
|
|
42465
|
+
const normalizedPath = process.platform === "win32" && urlPath.match(/^\/[A-Za-z]:/) ? urlPath.slice(1) : urlPath;
|
|
42466
|
+
console.error(`[memorix] MCP client root: ${normalizedPath}`);
|
|
42467
|
+
projectRoot = normalizedPath;
|
|
42468
|
+
}
|
|
42434
42469
|
}
|
|
42470
|
+
} catch {
|
|
42471
|
+
console.error(`[memorix] MCP roots not available (client may not support it)`);
|
|
42435
42472
|
}
|
|
42436
|
-
|
|
42437
|
-
console.error(`[memorix] MCP
|
|
42438
|
-
|
|
42439
|
-
|
|
42440
|
-
const earlyDetect = detectProject2(projectRoot);
|
|
42441
|
-
if (earlyDetect.id === "__invalid__") {
|
|
42442
|
-
console.error(`[memorix] ERROR: Could not detect a valid project.`);
|
|
42443
|
-
console.error(`[memorix] Fix: set --cwd or MEMORIX_PROJECT_ROOT, or use an IDE that supports MCP roots.`);
|
|
42444
|
-
process.exit(1);
|
|
42445
|
-
}
|
|
42473
|
+
const { projectId, deferredInit } = await createMemorixServer2(projectRoot, mcpServer);
|
|
42474
|
+
console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
|
|
42475
|
+
console.error(`[memorix] Project root: ${projectRoot}`);
|
|
42476
|
+
deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
|
|
42446
42477
|
}
|
|
42447
|
-
const { projectId, deferredInit } = await createMemorixServer2(projectRoot, mcpServer);
|
|
42448
|
-
console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
|
|
42449
|
-
console.error(`[memorix] Project root: ${projectRoot}`);
|
|
42450
|
-
deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
|
|
42451
42478
|
} else {
|
|
42452
42479
|
const { server, projectId, deferredInit } = await createMemorixServer2(projectRoot);
|
|
42453
42480
|
const transport = new StdioServerTransport2();
|
|
@@ -43200,13 +43227,13 @@ var init_status = __esm({
|
|
|
43200
43227
|
const { getProjectDataDir: getProjectDataDir2 } = await Promise.resolve().then(() => (init_persistence(), persistence_exports));
|
|
43201
43228
|
const { getEmbeddingProvider: getEmbeddingProvider2 } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
43202
43229
|
const { existsSync: existsSync5, readFileSync: readFileSync4 } = await import("fs");
|
|
43203
|
-
const { join:
|
|
43230
|
+
const { join: join13 } = await import("path");
|
|
43204
43231
|
we("memorix status");
|
|
43205
43232
|
const project = detectProject2();
|
|
43206
43233
|
const dataDir = await getProjectDataDir2(project.id);
|
|
43207
43234
|
let obsCount = 0;
|
|
43208
43235
|
try {
|
|
43209
|
-
const obsFile =
|
|
43236
|
+
const obsFile = join13(dataDir, "observations.json");
|
|
43210
43237
|
if (existsSync5(obsFile)) {
|
|
43211
43238
|
const data = JSON.parse(readFileSync4(obsFile, "utf-8"));
|
|
43212
43239
|
obsCount = Array.isArray(data) ? data.length : 0;
|
|
@@ -44052,20 +44079,35 @@ async function handleHookEvent(input) {
|
|
|
44052
44079
|
};
|
|
44053
44080
|
}
|
|
44054
44081
|
async function runHook() {
|
|
44055
|
-
const
|
|
44056
|
-
|
|
44057
|
-
chunks.
|
|
44058
|
-
|
|
44059
|
-
|
|
44082
|
+
const rawInput = await new Promise((resolve) => {
|
|
44083
|
+
const chunks = [];
|
|
44084
|
+
const finish = () => resolve(Buffer.concat(chunks).toString("utf-8").trim());
|
|
44085
|
+
const timer = setTimeout(() => {
|
|
44086
|
+
process.stdin.removeAllListeners("data");
|
|
44087
|
+
process.stdin.removeAllListeners("end");
|
|
44088
|
+
finish();
|
|
44089
|
+
}, 3e3);
|
|
44090
|
+
process.stdin.on("data", (chunk) => {
|
|
44091
|
+
chunks.push(chunk);
|
|
44092
|
+
});
|
|
44093
|
+
process.stdin.on("end", () => {
|
|
44094
|
+
clearTimeout(timer);
|
|
44095
|
+
finish();
|
|
44096
|
+
});
|
|
44097
|
+
process.stdin.on("error", () => {
|
|
44098
|
+
clearTimeout(timer);
|
|
44099
|
+
finish();
|
|
44100
|
+
});
|
|
44101
|
+
});
|
|
44060
44102
|
if (!rawInput) {
|
|
44061
|
-
process.stdout.write(JSON.stringify({ continue: true }));
|
|
44103
|
+
process.stdout.write(JSON.stringify({ continue: true, hookSpecificOutput: {} }));
|
|
44062
44104
|
return;
|
|
44063
44105
|
}
|
|
44064
44106
|
let payload;
|
|
44065
44107
|
try {
|
|
44066
44108
|
payload = JSON.parse(rawInput);
|
|
44067
44109
|
} catch {
|
|
44068
|
-
process.stdout.write(JSON.stringify({ continue: true }));
|
|
44110
|
+
process.stdout.write(JSON.stringify({ continue: true, hookSpecificOutput: {} }));
|
|
44069
44111
|
return;
|
|
44070
44112
|
}
|
|
44071
44113
|
const input = normalizeHookInput(payload);
|
|
@@ -44085,7 +44127,13 @@ ${emoji2} Memorix saved: ${observation.title} [${observation.type}]`;
|
|
|
44085
44127
|
} catch {
|
|
44086
44128
|
}
|
|
44087
44129
|
}
|
|
44088
|
-
|
|
44130
|
+
const hookEventName = payload.hookEventName ?? "";
|
|
44131
|
+
const finalOutput = { ...output };
|
|
44132
|
+
finalOutput.hookSpecificOutput = {
|
|
44133
|
+
...hookEventName ? { hookEventName } : {},
|
|
44134
|
+
...output.systemMessage ? { additionalContext: output.systemMessage } : {}
|
|
44135
|
+
};
|
|
44136
|
+
process.stdout.write(JSON.stringify(finalOutput));
|
|
44089
44137
|
}
|
|
44090
44138
|
var TYPE_EMOJI, cooldowns, COOLDOWN_MS, MIN_PROMPT_LENGTH, MAX_CONTENT_LENGTH, NOISE_COMMANDS, STORAGE_POLICY;
|
|
44091
44139
|
var init_handler = __esm({
|
|
@@ -44429,9 +44477,9 @@ var init_cleanup = __esm({
|
|
|
44429
44477
|
},
|
|
44430
44478
|
async run({ args }) {
|
|
44431
44479
|
const project = detectProject();
|
|
44432
|
-
if (project.id
|
|
44433
|
-
console.error("\
|
|
44434
|
-
|
|
44480
|
+
if (project.id.startsWith("placeholder/")) {
|
|
44481
|
+
console.error("\u26A0\uFE0F Not in a valid project directory \u2014 using degraded mode.");
|
|
44482
|
+
console.error("Set MEMORIX_PROJECT_ROOT or --cwd for best results.");
|
|
44435
44483
|
}
|
|
44436
44484
|
console.log(`
|
|
44437
44485
|
\u{1F4E6} Project: ${project.name} (${project.id})
|
|
@@ -44484,8 +44532,8 @@ var init_cleanup = __esm({
|
|
|
44484
44532
|
if (!args.force) {
|
|
44485
44533
|
const readline = await import("readline");
|
|
44486
44534
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
44487
|
-
const answer = await new Promise((
|
|
44488
|
-
rl.question(`\u26A0\uFE0F Delete ${toRemove.length} observations? (y/N) `,
|
|
44535
|
+
const answer = await new Promise((resolve) => {
|
|
44536
|
+
rl.question(`\u26A0\uFE0F Delete ${toRemove.length} observations? (y/N) `, resolve);
|
|
44489
44537
|
});
|
|
44490
44538
|
rl.close();
|
|
44491
44539
|
if (answer.trim().toLowerCase() !== "y") {
|
|
@@ -44505,8 +44553,8 @@ var init_cleanup = __esm({
|
|
|
44505
44553
|
// src/cli/index.ts
|
|
44506
44554
|
init_esm_shims();
|
|
44507
44555
|
init_dist2();
|
|
44508
|
-
import { createRequire
|
|
44509
|
-
var require2 =
|
|
44556
|
+
import { createRequire } from "module";
|
|
44557
|
+
var require2 = createRequire(import.meta.url);
|
|
44510
44558
|
var pkg = require2("../../package.json");
|
|
44511
44559
|
var main = defineCommand({
|
|
44512
44560
|
meta: {
|