memorix 0.9.2 → 0.9.4
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 +14 -0
- package/dist/cli/index.js +84 -44
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +54 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.9.4] — 2026-02-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Codex/all-IDE `tools/list -> Method not found`** — Critical bug where `local/<dirname>` projects (any directory without a git remote) wrongly entered the MCP roots resolution flow. This flow connects the server *before* registering tools, so the MCP `initialize` handshake declared no `tools` capability, causing all subsequent `tools/list` calls to fail with "Method not found". Now only truly invalid projects (home dir, system dirs) enter the roots flow; `local/` projects go through the normal path (register tools first, then connect).
|
|
9
|
+
|
|
10
|
+
## [0.9.3] — 2026-02-25
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **`memorix_timeline` "not found" bug** — Timeline was using unreliable Orama empty-term search. Now uses in-memory observations (same fix pattern as `memorix_detail`).
|
|
14
|
+
- **`memorix_retention` "no observations found" bug** — Same root cause as timeline. Now uses in-memory observations for reliable document retrieval.
|
|
15
|
+
- **`memorix_search` cross-IDE projectId mismatch** — Removed redundant projectId filter from search. Data isolation is already handled at the directory level. Different IDEs resolving different projectIds for the same directory no longer causes empty search results.
|
|
16
|
+
- **Claude Code hooks format** — Updated `generateClaudeConfig` to use the new `{matcher: {}, hooks: [...]}` structure required by Claude Code 2025+. Fixes "Expected array, but received undefined" error on `memorix hooks install --agent claude --global`.
|
|
17
|
+
- **EPERM `process.cwd()` crash** — All CLI commands (`serve`, `hooks install/uninstall/status`) now safely handle `process.cwd()` failures (e.g., deleted CWD on macOS) with fallback to home directory.
|
|
18
|
+
|
|
5
19
|
## [0.9.2] — 2026-02-25
|
|
6
20
|
|
|
7
21
|
### Fixed
|
package/dist/cli/index.js
CHANGED
|
@@ -959,37 +959,30 @@ async function getObservationsByIds(ids, projectId) {
|
|
|
959
959
|
}
|
|
960
960
|
return results;
|
|
961
961
|
}
|
|
962
|
-
async function getTimeline(anchorId,
|
|
963
|
-
const
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
};
|
|
968
|
-
if (projectId) {
|
|
969
|
-
searchParams.where = { projectId };
|
|
970
|
-
}
|
|
971
|
-
const allResults = await search(database, searchParams);
|
|
972
|
-
const docs = allResults.hits.map((h) => h.document).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
973
|
-
const anchorIndex = docs.findIndex((d) => d.observationId === anchorId);
|
|
962
|
+
async function getTimeline(anchorId, _projectId, depthBefore = 3, depthAfter = 3) {
|
|
963
|
+
const { getAllObservations: getAllObservations2 } = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
964
|
+
const allObs = getAllObservations2();
|
|
965
|
+
const sorted = allObs.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
966
|
+
const anchorIndex = sorted.findIndex((o) => o.id === anchorId);
|
|
974
967
|
if (anchorIndex === -1) {
|
|
975
968
|
return { before: [], anchor: null, after: [] };
|
|
976
969
|
}
|
|
977
|
-
const toIndexEntry = (
|
|
978
|
-
const obsType =
|
|
970
|
+
const toIndexEntry = (obs) => {
|
|
971
|
+
const obsType = obs.type;
|
|
979
972
|
return {
|
|
980
|
-
id:
|
|
981
|
-
time: formatTime(
|
|
973
|
+
id: obs.id,
|
|
974
|
+
time: formatTime(obs.createdAt),
|
|
982
975
|
type: obsType,
|
|
983
976
|
icon: OBSERVATION_ICONS[obsType] ?? "\u2753",
|
|
984
|
-
title:
|
|
985
|
-
tokens:
|
|
977
|
+
title: obs.title,
|
|
978
|
+
tokens: obs.tokens
|
|
986
979
|
};
|
|
987
980
|
};
|
|
988
|
-
const before =
|
|
989
|
-
const after =
|
|
981
|
+
const before = sorted.slice(Math.max(0, anchorIndex - depthBefore), anchorIndex).map(toIndexEntry);
|
|
982
|
+
const after = sorted.slice(anchorIndex + 1, anchorIndex + 1 + depthAfter).map(toIndexEntry);
|
|
990
983
|
return {
|
|
991
984
|
before,
|
|
992
|
-
anchor: toIndexEntry(
|
|
985
|
+
anchor: toIndexEntry(sorted[anchorIndex]),
|
|
993
986
|
after
|
|
994
987
|
};
|
|
995
988
|
}
|
|
@@ -1169,6 +1162,7 @@ var init_entity_extractor = __esm({
|
|
|
1169
1162
|
// src/memory/observations.ts
|
|
1170
1163
|
var observations_exports = {};
|
|
1171
1164
|
__export(observations_exports, {
|
|
1165
|
+
getAllObservations: () => getAllObservations,
|
|
1172
1166
|
getObservation: () => getObservation,
|
|
1173
1167
|
getObservationCount: () => getObservationCount2,
|
|
1174
1168
|
getProjectObservations: () => getProjectObservations,
|
|
@@ -1336,6 +1330,9 @@ function getObservation(id) {
|
|
|
1336
1330
|
function getProjectObservations(projectId) {
|
|
1337
1331
|
return observations.filter((o) => o.projectId === projectId);
|
|
1338
1332
|
}
|
|
1333
|
+
function getAllObservations() {
|
|
1334
|
+
return [...observations];
|
|
1335
|
+
}
|
|
1339
1336
|
function getObservationCount2() {
|
|
1340
1337
|
return observations.length;
|
|
1341
1338
|
}
|
|
@@ -3703,18 +3700,23 @@ function resolveHookCommand() {
|
|
|
3703
3700
|
}
|
|
3704
3701
|
function generateClaudeConfig() {
|
|
3705
3702
|
const cmd = `${resolveHookCommand()} hook`;
|
|
3706
|
-
const
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3703
|
+
const hookGroup = {
|
|
3704
|
+
matcher: {},
|
|
3705
|
+
hooks: [
|
|
3706
|
+
{
|
|
3707
|
+
type: "command",
|
|
3708
|
+
command: cmd,
|
|
3709
|
+
timeout: 10
|
|
3710
|
+
}
|
|
3711
|
+
]
|
|
3710
3712
|
};
|
|
3711
3713
|
return {
|
|
3712
3714
|
hooks: {
|
|
3713
|
-
SessionStart: [
|
|
3714
|
-
PostToolUse: [
|
|
3715
|
-
UserPromptSubmit: [
|
|
3716
|
-
PreCompact: [
|
|
3717
|
-
Stop: [
|
|
3715
|
+
SessionStart: [hookGroup],
|
|
3716
|
+
PostToolUse: [hookGroup],
|
|
3717
|
+
UserPromptSubmit: [hookGroup],
|
|
3718
|
+
PreCompact: [hookGroup],
|
|
3719
|
+
Stop: [hookGroup]
|
|
3718
3720
|
}
|
|
3719
3721
|
};
|
|
3720
3722
|
}
|
|
@@ -5613,8 +5615,10 @@ Use this as the \`topicKey\` parameter in \`memorix_store\` to enable upsert beh
|
|
|
5613
5615
|
maxTokens: safeMaxTokens,
|
|
5614
5616
|
since,
|
|
5615
5617
|
until,
|
|
5616
|
-
//
|
|
5617
|
-
projectId
|
|
5618
|
+
// Data isolation is handled at the directory level (each project has its own data dir).
|
|
5619
|
+
// No projectId filter needed — avoids cross-IDE search failures when different IDEs
|
|
5620
|
+
// resolve different projectIds for the same directory.
|
|
5621
|
+
projectId: void 0
|
|
5618
5622
|
});
|
|
5619
5623
|
let text = result.formatted;
|
|
5620
5624
|
if (!syncAdvisoryShown && syncAdvisory) {
|
|
@@ -5711,13 +5715,24 @@ ${result.remaining} active observations remaining.
|
|
|
5711
5715
|
Archived memories can be restored manually if needed.` }]
|
|
5712
5716
|
};
|
|
5713
5717
|
}
|
|
5714
|
-
const
|
|
5715
|
-
const
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5718
|
+
const { getAllObservations: getAllObservations2 } = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
5719
|
+
const allObs = getAllObservations2();
|
|
5720
|
+
const docs = allObs.map((obs) => ({
|
|
5721
|
+
id: `obs-${obs.id}`,
|
|
5722
|
+
observationId: obs.id,
|
|
5723
|
+
entityName: obs.entityName,
|
|
5724
|
+
type: obs.type,
|
|
5725
|
+
title: obs.title,
|
|
5726
|
+
narrative: obs.narrative,
|
|
5727
|
+
facts: obs.facts.join("\n"),
|
|
5728
|
+
filesModified: obs.filesModified.join("\n"),
|
|
5729
|
+
concepts: obs.concepts.join(", "),
|
|
5730
|
+
tokens: obs.tokens,
|
|
5731
|
+
createdAt: obs.createdAt,
|
|
5732
|
+
projectId: obs.projectId,
|
|
5733
|
+
accessCount: 0,
|
|
5734
|
+
lastAccessedAt: ""
|
|
5735
|
+
}));
|
|
5721
5736
|
if (docs.length === 0) {
|
|
5722
5737
|
return {
|
|
5723
5738
|
content: [{ type: "text", text: "No observations found for this project." }]
|
|
@@ -6587,10 +6602,16 @@ var init_serve = __esm({
|
|
|
6587
6602
|
const { McpServer: McpServer2 } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
6588
6603
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server2(), server_exports2));
|
|
6589
6604
|
const { detectProject: detectProject2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
6590
|
-
let
|
|
6605
|
+
let safeCwd;
|
|
6606
|
+
try {
|
|
6607
|
+
safeCwd = process.cwd();
|
|
6608
|
+
} catch {
|
|
6609
|
+
safeCwd = (await import("os")).homedir();
|
|
6610
|
+
}
|
|
6611
|
+
let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || process.env.INIT_CWD || safeCwd;
|
|
6591
6612
|
console.error(`[memorix] Starting with cwd: ${projectRoot}`);
|
|
6592
6613
|
const earlyDetect = detectProject2(projectRoot);
|
|
6593
|
-
const needsRoots = earlyDetect.id === "__invalid__"
|
|
6614
|
+
const needsRoots = earlyDetect.id === "__invalid__";
|
|
6594
6615
|
if (needsRoots) {
|
|
6595
6616
|
console.error(`[memorix] cwd is not a valid project, trying MCP roots protocol...`);
|
|
6596
6617
|
const mcpServer = new McpServer2({ name: "memorix", version: "0.1.0" });
|
|
@@ -7486,7 +7507,14 @@ var init_hooks_install = __esm({
|
|
|
7486
7507
|
},
|
|
7487
7508
|
run: async ({ args }) => {
|
|
7488
7509
|
const { detectInstalledAgents: detectInstalledAgents2, installHooks: installHooks2 } = await Promise.resolve().then(() => (init_installers(), installers_exports));
|
|
7489
|
-
const
|
|
7510
|
+
const os4 = await import("os");
|
|
7511
|
+
let cwd;
|
|
7512
|
+
try {
|
|
7513
|
+
cwd = process.cwd();
|
|
7514
|
+
} catch {
|
|
7515
|
+
cwd = os4.homedir();
|
|
7516
|
+
console.log(`\u26A0\uFE0F Could not access current directory, using home: ${cwd}`);
|
|
7517
|
+
}
|
|
7490
7518
|
let agents;
|
|
7491
7519
|
if (args.agent) {
|
|
7492
7520
|
agents = [args.agent];
|
|
@@ -7547,7 +7575,13 @@ var init_hooks_uninstall = __esm({
|
|
|
7547
7575
|
},
|
|
7548
7576
|
run: async ({ args }) => {
|
|
7549
7577
|
const { detectInstalledAgents: detectInstalledAgents2, uninstallHooks: uninstallHooks2 } = await Promise.resolve().then(() => (init_installers(), installers_exports));
|
|
7550
|
-
const
|
|
7578
|
+
const os4 = await import("os");
|
|
7579
|
+
let cwd;
|
|
7580
|
+
try {
|
|
7581
|
+
cwd = process.cwd();
|
|
7582
|
+
} catch {
|
|
7583
|
+
cwd = os4.homedir();
|
|
7584
|
+
}
|
|
7551
7585
|
let agents;
|
|
7552
7586
|
if (args.agent) {
|
|
7553
7587
|
agents = [args.agent];
|
|
@@ -7589,7 +7623,13 @@ var init_hooks_status = __esm({
|
|
|
7589
7623
|
},
|
|
7590
7624
|
run: async () => {
|
|
7591
7625
|
const { getHookStatus: getHookStatus2 } = await Promise.resolve().then(() => (init_installers(), installers_exports));
|
|
7592
|
-
const
|
|
7626
|
+
const os4 = await import("os");
|
|
7627
|
+
let cwd;
|
|
7628
|
+
try {
|
|
7629
|
+
cwd = process.cwd();
|
|
7630
|
+
} catch {
|
|
7631
|
+
cwd = os4.homedir();
|
|
7632
|
+
}
|
|
7593
7633
|
const statuses = await getHookStatus2(cwd);
|
|
7594
7634
|
console.log("\nMemorix Hooks Status");
|
|
7595
7635
|
console.log("\u2550".repeat(50));
|