memorix 1.3.4 → 1.4.1
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 +21 -0
- package/CLAUDE.md +9 -9
- package/README.md +7 -2
- package/README.zh-CN.md +6 -2
- package/dist/cli/index.js +53 -23
- package/dist/index.js +53 -23
- package/dist/maintenance-runner.js +50 -21
- package/dist/media-video-runner.js +50 -21
- package/dist/memcode/index.js +53 -21
- package/dist/memcode-runtime/CHANGELOG.md +21 -0
- package/dist/sdk.js +52 -22
- package/dist/vector-backfill-runner.js +50 -21
- package/docs/1.3.3-MULTIMODAL-MEDIA-AND-MCP-COMPAT.md +13 -13
- package/docs/API_REFERENCE.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +52 -128
- package/package.json +5 -2
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/codegraph/current-facts.ts +1 -0
- package/docs/dev-log/progress.txt +0 -388
package/dist/sdk.js
CHANGED
|
@@ -32934,7 +32934,7 @@ var init_models_generated = __esm({
|
|
|
32934
32934
|
provider: "minimax",
|
|
32935
32935
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
32936
32936
|
reasoning: true,
|
|
32937
|
-
input: ["text", "image"],
|
|
32937
|
+
input: ["text", "image", "video"],
|
|
32938
32938
|
cost: {
|
|
32939
32939
|
input: 0.3,
|
|
32940
32940
|
output: 1.2,
|
|
@@ -32987,7 +32987,7 @@ var init_models_generated = __esm({
|
|
|
32987
32987
|
provider: "minimax-cn",
|
|
32988
32988
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
32989
32989
|
reasoning: true,
|
|
32990
|
-
input: ["text", "image"],
|
|
32990
|
+
input: ["text", "image", "video"],
|
|
32991
32991
|
cost: {
|
|
32992
32992
|
input: 0.3,
|
|
32993
32993
|
output: 1.2,
|
|
@@ -52262,11 +52262,11 @@ var init_simple_options = __esm({
|
|
|
52262
52262
|
});
|
|
52263
52263
|
|
|
52264
52264
|
// packages/ai/dist/providers/transform-messages.js
|
|
52265
|
-
function
|
|
52265
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52266
52266
|
const result = [];
|
|
52267
52267
|
let previousWasPlaceholder = false;
|
|
52268
52268
|
for (const block of content) {
|
|
52269
|
-
if (block.type ===
|
|
52269
|
+
if (block.type === dropType) {
|
|
52270
52270
|
if (!previousWasPlaceholder) {
|
|
52271
52271
|
result.push({ type: "text", text: placeholder });
|
|
52272
52272
|
}
|
|
@@ -52274,33 +52274,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52274
52274
|
continue;
|
|
52275
52275
|
}
|
|
52276
52276
|
result.push(block);
|
|
52277
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52277
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52278
52278
|
}
|
|
52279
52279
|
return result;
|
|
52280
52280
|
}
|
|
52281
|
-
function
|
|
52282
|
-
|
|
52281
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52282
|
+
const supportsImage = model.input.includes("image");
|
|
52283
|
+
const supportsVideo = model.input.includes("video");
|
|
52284
|
+
if (supportsImage && supportsVideo) {
|
|
52283
52285
|
return messages;
|
|
52284
52286
|
}
|
|
52285
52287
|
return messages.map((msg) => {
|
|
52286
52288
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52287
|
-
|
|
52288
|
-
|
|
52289
|
-
content
|
|
52290
|
-
|
|
52289
|
+
let content = msg.content;
|
|
52290
|
+
if (!supportsImage)
|
|
52291
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52292
|
+
if (!supportsVideo)
|
|
52293
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52294
|
+
return { ...msg, content };
|
|
52291
52295
|
}
|
|
52292
52296
|
if (msg.role === "toolResult") {
|
|
52293
|
-
|
|
52294
|
-
|
|
52295
|
-
content
|
|
52296
|
-
|
|
52297
|
+
let content = msg.content;
|
|
52298
|
+
if (!supportsImage)
|
|
52299
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52300
|
+
if (!supportsVideo)
|
|
52301
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52302
|
+
return { ...msg, content };
|
|
52297
52303
|
}
|
|
52298
52304
|
return msg;
|
|
52299
52305
|
});
|
|
52300
52306
|
}
|
|
52301
52307
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52302
52308
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52303
|
-
const imageAwareMessages =
|
|
52309
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52304
52310
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52305
52311
|
if (msg.role === "user") {
|
|
52306
52312
|
return msg;
|
|
@@ -52412,13 +52418,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52412
52418
|
insertSyntheticToolResults();
|
|
52413
52419
|
return result;
|
|
52414
52420
|
}
|
|
52415
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52421
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52416
52422
|
var init_transform_messages = __esm({
|
|
52417
52423
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52418
52424
|
"use strict";
|
|
52419
52425
|
init_esm_shims();
|
|
52420
52426
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52421
52427
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52428
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52429
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52422
52430
|
}
|
|
52423
52431
|
});
|
|
52424
52432
|
|
|
@@ -52449,8 +52457,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52449
52457
|
};
|
|
52450
52458
|
}
|
|
52451
52459
|
function convertContentBlocks(content) {
|
|
52452
|
-
const
|
|
52453
|
-
if (!
|
|
52460
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52461
|
+
if (!hasMedia) {
|
|
52454
52462
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52455
52463
|
}
|
|
52456
52464
|
const blocks = content.map((block) => {
|
|
@@ -52460,6 +52468,16 @@ function convertContentBlocks(content) {
|
|
|
52460
52468
|
text: sanitizeSurrogates(block.text)
|
|
52461
52469
|
};
|
|
52462
52470
|
}
|
|
52471
|
+
if (block.type === "video") {
|
|
52472
|
+
return {
|
|
52473
|
+
type: "video",
|
|
52474
|
+
source: {
|
|
52475
|
+
type: "base64",
|
|
52476
|
+
media_type: block.mimeType,
|
|
52477
|
+
data: block.data
|
|
52478
|
+
}
|
|
52479
|
+
};
|
|
52480
|
+
}
|
|
52463
52481
|
return {
|
|
52464
52482
|
type: "image",
|
|
52465
52483
|
source: {
|
|
@@ -52473,7 +52491,7 @@ function convertContentBlocks(content) {
|
|
|
52473
52491
|
if (!hasText) {
|
|
52474
52492
|
blocks.unshift({
|
|
52475
52493
|
type: "text",
|
|
52476
|
-
text: "(see attached
|
|
52494
|
+
text: "(see attached media)"
|
|
52477
52495
|
});
|
|
52478
52496
|
}
|
|
52479
52497
|
return blocks;
|
|
@@ -52823,6 +52841,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52823
52841
|
type: "text",
|
|
52824
52842
|
text: sanitizeSurrogates(item.text)
|
|
52825
52843
|
};
|
|
52844
|
+
} else if (item.type === "video") {
|
|
52845
|
+
return {
|
|
52846
|
+
type: "video",
|
|
52847
|
+
source: {
|
|
52848
|
+
type: "base64",
|
|
52849
|
+
media_type: item.mimeType,
|
|
52850
|
+
data: item.data
|
|
52851
|
+
}
|
|
52852
|
+
};
|
|
52826
52853
|
} else {
|
|
52827
52854
|
return {
|
|
52828
52855
|
type: "image",
|
|
@@ -52903,6 +52930,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52903
52930
|
toolResults.push({
|
|
52904
52931
|
type: "tool_result",
|
|
52905
52932
|
tool_use_id: msg.toolCallId,
|
|
52933
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
52934
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
52906
52935
|
content: convertContentBlocks(msg.content),
|
|
52907
52936
|
is_error: msg.isError
|
|
52908
52937
|
});
|
|
@@ -52929,7 +52958,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52929
52958
|
if (lastMessage.role === "user") {
|
|
52930
52959
|
if (Array.isArray(lastMessage.content)) {
|
|
52931
52960
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
52932
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
52961
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
52933
52962
|
lastBlock.cache_control = cacheControl;
|
|
52934
52963
|
}
|
|
52935
52964
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -152679,6 +152708,7 @@ function compareDateStrings(a, b) {
|
|
|
152679
152708
|
}
|
|
152680
152709
|
function detectStaleProgressNotes(input) {
|
|
152681
152710
|
const candidates = [
|
|
152711
|
+
"ACTIVE_WORK.md",
|
|
152682
152712
|
"progress.txt",
|
|
152683
152713
|
"docs/dev-log/progress.txt",
|
|
152684
152714
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -164129,7 +164159,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
164129
164159
|
};
|
|
164130
164160
|
const server = existingServer ?? new McpServer({
|
|
164131
164161
|
name: "memorix",
|
|
164132
|
-
version: true ? "1.
|
|
164162
|
+
version: true ? "1.4.1" : "1.0.1"
|
|
164133
164163
|
});
|
|
164134
164164
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
164135
164165
|
server.registerTool = ((name, ...args) => {
|
|
@@ -33079,7 +33079,7 @@ var init_models_generated = __esm({
|
|
|
33079
33079
|
provider: "minimax",
|
|
33080
33080
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
33081
33081
|
reasoning: true,
|
|
33082
|
-
input: ["text", "image"],
|
|
33082
|
+
input: ["text", "image", "video"],
|
|
33083
33083
|
cost: {
|
|
33084
33084
|
input: 0.3,
|
|
33085
33085
|
output: 1.2,
|
|
@@ -33132,7 +33132,7 @@ var init_models_generated = __esm({
|
|
|
33132
33132
|
provider: "minimax-cn",
|
|
33133
33133
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
33134
33134
|
reasoning: true,
|
|
33135
|
-
input: ["text", "image"],
|
|
33135
|
+
input: ["text", "image", "video"],
|
|
33136
33136
|
cost: {
|
|
33137
33137
|
input: 0.3,
|
|
33138
33138
|
output: 1.2,
|
|
@@ -52407,11 +52407,11 @@ var init_simple_options = __esm({
|
|
|
52407
52407
|
});
|
|
52408
52408
|
|
|
52409
52409
|
// packages/ai/dist/providers/transform-messages.js
|
|
52410
|
-
function
|
|
52410
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52411
52411
|
const result = [];
|
|
52412
52412
|
let previousWasPlaceholder = false;
|
|
52413
52413
|
for (const block of content) {
|
|
52414
|
-
if (block.type ===
|
|
52414
|
+
if (block.type === dropType) {
|
|
52415
52415
|
if (!previousWasPlaceholder) {
|
|
52416
52416
|
result.push({ type: "text", text: placeholder });
|
|
52417
52417
|
}
|
|
@@ -52419,33 +52419,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52419
52419
|
continue;
|
|
52420
52420
|
}
|
|
52421
52421
|
result.push(block);
|
|
52422
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52422
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52423
52423
|
}
|
|
52424
52424
|
return result;
|
|
52425
52425
|
}
|
|
52426
|
-
function
|
|
52427
|
-
|
|
52426
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52427
|
+
const supportsImage = model.input.includes("image");
|
|
52428
|
+
const supportsVideo = model.input.includes("video");
|
|
52429
|
+
if (supportsImage && supportsVideo) {
|
|
52428
52430
|
return messages;
|
|
52429
52431
|
}
|
|
52430
52432
|
return messages.map((msg) => {
|
|
52431
52433
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52432
|
-
|
|
52433
|
-
|
|
52434
|
-
content
|
|
52435
|
-
|
|
52434
|
+
let content = msg.content;
|
|
52435
|
+
if (!supportsImage)
|
|
52436
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52437
|
+
if (!supportsVideo)
|
|
52438
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52439
|
+
return { ...msg, content };
|
|
52436
52440
|
}
|
|
52437
52441
|
if (msg.role === "toolResult") {
|
|
52438
|
-
|
|
52439
|
-
|
|
52440
|
-
content
|
|
52441
|
-
|
|
52442
|
+
let content = msg.content;
|
|
52443
|
+
if (!supportsImage)
|
|
52444
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52445
|
+
if (!supportsVideo)
|
|
52446
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52447
|
+
return { ...msg, content };
|
|
52442
52448
|
}
|
|
52443
52449
|
return msg;
|
|
52444
52450
|
});
|
|
52445
52451
|
}
|
|
52446
52452
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52447
52453
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52448
|
-
const imageAwareMessages =
|
|
52454
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52449
52455
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52450
52456
|
if (msg.role === "user") {
|
|
52451
52457
|
return msg;
|
|
@@ -52557,13 +52563,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52557
52563
|
insertSyntheticToolResults();
|
|
52558
52564
|
return result;
|
|
52559
52565
|
}
|
|
52560
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52566
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52561
52567
|
var init_transform_messages = __esm({
|
|
52562
52568
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52563
52569
|
"use strict";
|
|
52564
52570
|
init_esm_shims();
|
|
52565
52571
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52566
52572
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52573
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52574
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52567
52575
|
}
|
|
52568
52576
|
});
|
|
52569
52577
|
|
|
@@ -52594,8 +52602,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52594
52602
|
};
|
|
52595
52603
|
}
|
|
52596
52604
|
function convertContentBlocks(content) {
|
|
52597
|
-
const
|
|
52598
|
-
if (!
|
|
52605
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52606
|
+
if (!hasMedia) {
|
|
52599
52607
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52600
52608
|
}
|
|
52601
52609
|
const blocks = content.map((block) => {
|
|
@@ -52605,6 +52613,16 @@ function convertContentBlocks(content) {
|
|
|
52605
52613
|
text: sanitizeSurrogates(block.text)
|
|
52606
52614
|
};
|
|
52607
52615
|
}
|
|
52616
|
+
if (block.type === "video") {
|
|
52617
|
+
return {
|
|
52618
|
+
type: "video",
|
|
52619
|
+
source: {
|
|
52620
|
+
type: "base64",
|
|
52621
|
+
media_type: block.mimeType,
|
|
52622
|
+
data: block.data
|
|
52623
|
+
}
|
|
52624
|
+
};
|
|
52625
|
+
}
|
|
52608
52626
|
return {
|
|
52609
52627
|
type: "image",
|
|
52610
52628
|
source: {
|
|
@@ -52618,7 +52636,7 @@ function convertContentBlocks(content) {
|
|
|
52618
52636
|
if (!hasText) {
|
|
52619
52637
|
blocks.unshift({
|
|
52620
52638
|
type: "text",
|
|
52621
|
-
text: "(see attached
|
|
52639
|
+
text: "(see attached media)"
|
|
52622
52640
|
});
|
|
52623
52641
|
}
|
|
52624
52642
|
return blocks;
|
|
@@ -52968,6 +52986,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52968
52986
|
type: "text",
|
|
52969
52987
|
text: sanitizeSurrogates(item.text)
|
|
52970
52988
|
};
|
|
52989
|
+
} else if (item.type === "video") {
|
|
52990
|
+
return {
|
|
52991
|
+
type: "video",
|
|
52992
|
+
source: {
|
|
52993
|
+
type: "base64",
|
|
52994
|
+
media_type: item.mimeType,
|
|
52995
|
+
data: item.data
|
|
52996
|
+
}
|
|
52997
|
+
};
|
|
52971
52998
|
} else {
|
|
52972
52999
|
return {
|
|
52973
53000
|
type: "image",
|
|
@@ -53048,6 +53075,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
53048
53075
|
toolResults.push({
|
|
53049
53076
|
type: "tool_result",
|
|
53050
53077
|
tool_use_id: msg.toolCallId,
|
|
53078
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
53079
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
53051
53080
|
content: convertContentBlocks(msg.content),
|
|
53052
53081
|
is_error: msg.isError
|
|
53053
53082
|
});
|
|
@@ -53074,7 +53103,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
53074
53103
|
if (lastMessage.role === "user") {
|
|
53075
53104
|
if (Array.isArray(lastMessage.content)) {
|
|
53076
53105
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
53077
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
53106
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
53078
53107
|
lastBlock.cache_control = cacheControl;
|
|
53079
53108
|
}
|
|
53080
53109
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -318,20 +318,20 @@ then document the 2026-07-28 migration boundary.
|
|
|
318
318
|
- no personal Codex/Claude/OpenCode configuration mutation;
|
|
319
319
|
- documentation and changelog reviewed.
|
|
320
320
|
|
|
321
|
-
### Phase G: 1.3.4 hardening
|
|
321
|
+
### Phase G: 1.3.4 hardening (completed 2026-08-02)
|
|
322
322
|
|
|
323
|
-
1.3.4
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
1.3.4 exercised fresh install, Windows CLI windows-hide behavior,
|
|
324
|
+
CLI/stdio/HTTP MCP routes, cancellation/restart of media jobs, quota cleanup,
|
|
325
|
+
failure messages, and agent-facing UX. The resulting fixes are published in
|
|
326
|
+
the 1.3.4 release notes and passed Windows and Ubuntu CI.
|
|
327
327
|
|
|
328
|
-
### Phase H: 1.4 stable release
|
|
328
|
+
### Phase H: 1.4 stable release (completed 2026-08-02)
|
|
329
329
|
|
|
330
|
-
1.4
|
|
331
|
-
packaged CLI evidence,
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
330
|
+
1.4.0 was cut after the 1.3.3 and 1.3.4 gates were green, supported paths had
|
|
331
|
+
packaged CLI evidence, and no high-severity data-loss, credential-retention,
|
|
332
|
+
Windows-popup, or MCP binding regression was known. “Stable” means no known
|
|
333
|
+
release blocker after these tests, not an impossible claim of mathematical
|
|
334
|
+
perfection.
|
|
335
335
|
|
|
336
336
|
## Acceptance criteria
|
|
337
337
|
|
|
@@ -351,8 +351,8 @@ not an impossible claim of mathematical perfection.
|
|
|
351
351
|
8. No generated asset enters project memory without an explicit attach action.
|
|
352
352
|
9. The same media action works through CLI and MCP using an explicit resolved
|
|
353
353
|
project binding, independent of a legacy HTTP session identifier.
|
|
354
|
-
10. 1.3.4 regression tests
|
|
355
|
-
HTTP MCP, quota cleanup, and error UX before 1.4
|
|
354
|
+
10. 1.3.4 regression tests covered Windows, fresh package install, CLI, stdio,
|
|
355
|
+
HTTP MCP, quota cleanup, and error UX before 1.4.0 was published.
|
|
356
356
|
|
|
357
357
|
## Research and implementation basis
|
|
358
358
|
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -114,7 +114,7 @@ MCP:
|
|
|
114
114
|
- `memorix_codegraph_status` returns provider/index counts for the current project.
|
|
115
115
|
- `memorix_context_pack` builds a task-specific packet with reliable current memories, lower-trust unbound memories, current code facts, freshness warnings, suggested reads, and suggested verification.
|
|
116
116
|
|
|
117
|
-
`memorix context` defaults to `--refresh auto`, so first use can seed Code State without a separate manual `memorix codegraph refresh`. Its brief puts live package/changelog/Git facts before memory hints and flags old `progress.txt
|
|
117
|
+
`memorix context` defaults to `--refresh auto`, so first use can seed Code State without a separate manual `memorix codegraph refresh`. Its brief puts live package/changelog/Git facts before memory hints and flags an old `ACTIVE_WORK.md`, legacy `progress.txt`, or legacy dev-log note as historical when it predates the latest changelog, so agents should treat current facts as the source of truth when files disagree. Task lenses keep the packet shaped to the work: bugfix briefs prefer failing tests and repros, release briefs prefer metadata/changelog/package checks, and onboarding briefs prefer docs and entry points while hiding unrelated suspect details. Continuation delivery is separate from the task lens: continuation language in `memorix_project_context` enables a bounded prior-work projection, and `memorix resume "..."` makes that choice explicit. It includes only the latest useful session summary, up to three readable durable memories, and at most one recent source-labelled compact checkpoint. Checkpoints are host lifecycle evidence, not durable memory or transcript backups; ordinary new tasks do not receive historical-session context. A completed MCP brief is the default retrieval boundary: search, detail, or Context Pack should expand it only for a named missing fact or an explicit request for deeper history. Use `--refresh never` for read-only inspection and `--refresh always` when you want to force a fresh scan.
|
|
118
118
|
|
|
119
119
|
Project-specific generated, vendored, or cache paths can be excluded from Code State with `[codegraph].exclude_patterns` in `memorix.toml` or `~/.memorix/config.toml` (`codegraph.excludePatterns` in legacy YAML). User patterns extend the built-in excludes and are applied to indexing, Project Context suggested reads, and Context Pack suggested reads.
|
|
120
120
|
|
|
@@ -1,149 +1,73 @@
|
|
|
1
|
-
# Memorix
|
|
1
|
+
# Memorix 已知边界与路线图
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 最后审阅:2026-08-03(对照 v1.4.0)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
这份文档说明仍然成立的产品边界、风险和方向;它不是发布流水账。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 已发布版本和每次修复的事实,以 [CHANGELOG](../CHANGELOG.md) 为准。
|
|
8
|
+
- 当前正在进行的维护工作,以 [ACTIVE_WORK](../ACTIVE_WORK.md) 为准。
|
|
9
|
+
- 可讨论、可订阅的后续事项,以 GitHub Open Issues 为准。
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
---
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|---|------|------|------|
|
|
13
|
-
| 1 | ~~**无文件锁**~~ — 多 Agent 同时写入 | 数据完整性 | ✅ v0.7.11 (`withFileLock` + `atomicWriteFile`) |
|
|
14
|
-
| 2 | **Orama where 过滤不可靠** — 空 term + number filter 时结果可能不正确 | `compactDetail` 已绕过 (使用内存查找) | 已变通 |
|
|
13
|
+
## 当前产品边界
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Memorix 是本地优先、可插拔的 Agent Memory 系统。它给不同 Agent 或同一 Agent 的新会话提供同一个项目记忆层,并把 CLI 作为最完整、最稳定的控制面;MCP 是面向 Agent 的受控入口,而不是唯一入口。
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|---|------|------|------|
|
|
20
|
-
| 3 | **非 Git 项目的 projectId 不稳定** — 基于目录名,不同机器或路径会不同 | 数据隔离 | 未修复 |
|
|
21
|
-
| 4 | ~~**retention 只有报告没有执行**~~ | 数据膨胀 | ✅ v0.7.11 (`archiveExpired` + `action="archive"`) |
|
|
22
|
-
| 5 | ~~**实体抽取不支持中文标识符**~~ | 中文项目覆盖不足 | ✅ v0.7.11 (中文括号/反引号 + 因果语言) |
|
|
23
|
-
| 6 | ~~**auto-relations 每次读取全图**~~ | 性能 | ✅ v0.7.11 (entityIndex O(1) 查找) |
|
|
24
|
-
| 7 | **高重要性 observations 永远免疫** — gotcha/decision/trade-off 永不过期 | 数据膨胀 | 设计如此,需评估 |
|
|
17
|
+
当前版本已经包括:
|
|
25
18
|
|
|
26
|
-
|
|
19
|
+
- 项目记忆、会话续接、任务透镜和按需展开的上下文;
|
|
20
|
+
- 代码状态、知识库 / Wiki、知识图谱投影和工作流记录;
|
|
21
|
+
- 受控的本地媒体资产库,可显式导入图片、音频、视频和 PDF,并保留来源、哈希、配额和删除审计;
|
|
22
|
+
- 多 Agent 集成、hook、doctor / repair,以及可选择的后台维护;
|
|
23
|
+
- SQLite 规范存储、可见性边界、保留策略和清理审计。
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|---|------|------|------|
|
|
30
|
-
| 8 | ~~**Kiro/Trae Agent hooks 未实现**~~ | 功能缺失 | ✅ v0.9.12+ (Kiro/Trae/OpenCode/Gemini CLI 全部支持) |
|
|
31
|
-
| 9 | **fastembed 首次使用需下载模型** — ~30MB,可能在网络不好时超时 | 用户体验 | 需用户显式安装 |
|
|
32
|
-
| 10 | **npx 缓存可能损坏** — 见 `MODULE_NOT_FOUND chownr` 问题 | 安装体验 | 需文档说明 |
|
|
25
|
+
这些能力并不等于“任何数据都会被自动收集”或“所有媒体都已经被模型理解”。Memorix 的默认边界是显式、可追溯、可清理,避免把无关聊天、任意本地文件或有成本的模型调用悄悄写入长期记忆。
|
|
33
26
|
|
|
34
27
|
---
|
|
35
28
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
### Phase 2: 推广 & 用户获取
|
|
48
|
-
- [ ] 社区推广 (Reddit, HN, X, Discord)
|
|
49
|
-
- [ ] 技术博客文章
|
|
50
|
-
- [ ] 演示视频
|
|
51
|
-
- [ ] 与其他 MCP Server 项目的对比文档
|
|
52
|
-
|
|
53
|
-
### Phase 3: Web Dashboard ✅
|
|
54
|
-
- [x] 知识图谱可视化 (D3.js force graph)
|
|
55
|
-
- [x] Observation 搜索/浏览 Web UI
|
|
56
|
-
- [x] 记忆保留状态仪表板
|
|
57
|
-
- [x] 跨项目记忆概览 (project switcher)
|
|
58
|
-
|
|
59
|
-
### Phase 4: 功能增强 ✅
|
|
60
|
-
- [x] 自动归档过期记忆 (`memorix_retention action="archive"`)
|
|
61
|
-
- [x] 文件锁机制 (多进程安全)
|
|
62
|
-
- [x] 搜索精确度优化 (fuzzy + field boosting)
|
|
63
|
-
- [x] 中文实体抽取
|
|
64
|
-
- [x] 图谱-记忆双向同步
|
|
65
|
-
- [x] `memorix_transfer` — 导出/导入记忆 (JSON + Markdown)
|
|
66
|
-
- [x] 记忆去重和冲突检测 (`memorix_deduplicate` + `memorix_consolidate`)
|
|
67
|
-
- [x] LLM 增强模式 (压缩/重排序/写入时去重)
|
|
68
|
-
|
|
69
|
-
### Phase 5: Agent 集成 ✅
|
|
70
|
-
- [x] Kiro 完整支持
|
|
71
|
-
- [x] Trae 支持
|
|
72
|
-
- [x] OpenCode 支持
|
|
73
|
-
- [x] Gemini CLI 支持
|
|
74
|
-
- [x] Copilot hooks 支持
|
|
75
|
-
- [x] 10 个 Agent 全覆盖
|
|
76
|
-
|
|
77
|
-
### Phase 6: v1.0.0 特性 ✅
|
|
78
|
-
- [x] 团队协作 (Agent注册/文件锁/任务板/消息)
|
|
79
|
-
- [x] 工具合并 (41 → 22 默认)
|
|
80
|
-
- [x] 启动自动清理 (归档 + LLM/Jaccard 去重)
|
|
81
|
-
- [x] Mini-Skills (永久技能, 自动注入)
|
|
82
|
-
- [x] 会话管理 (跨会话上下文注入)
|
|
83
|
-
|
|
84
|
-
### Phase 7: 未来路线图
|
|
85
|
-
- [ ] 多项目记忆关联搜索
|
|
86
|
-
- [ ] LLM-based 实体抽取 (替代正则)
|
|
87
|
-
- [ ] JetBrains AI 支持
|
|
88
|
-
- [ ] VS Code + Continue.dev 支持
|
|
89
|
-
- [ ] 自定义 embedding 模型支持
|
|
90
|
-
- [ ] 记忆联邦协议 (跨团队共享)
|
|
29
|
+
## 仍需注意的边界
|
|
30
|
+
|
|
31
|
+
| 主题 | 现状 | 使用建议 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 项目绑定 | 没有可靠工作区根目录时,MCP 会等待显式根目录、MCP Roots 或会话启动,而不会猜测上一个项目。 | 这是防止跨项目读写的安全边界;首次接入时按客户端的项目根目录配置即可。 |
|
|
34
|
+
| 向量与外部模型 | 可选嵌入提供商、网络和首次模型准备会影响写入或检索延迟。 | 不要把外部 API 的瞬时可用性当作本地数据是否已写入的唯一判断;先用 `memorix status` / `doctor` 看状态。 |
|
|
35
|
+
| 媒体记忆 | 已有受控附件和元数据/向量基础,但 PDF 文本提取、音频转写、视频语义提取仍不是默认的全自动链路。 | 只导入确实需要长期复用的资产;不要把截图或工具输出当作默认记忆来源。 |
|
|
36
|
+
| 图谱与 Wiki | 它们是从规范记忆和代码状态生成的可追溯投影,不是可任意编辑的 GraphRAG 数据库。 | 先写清楚有来源的知识和决策,让投影自然形成关联;不要把图谱当作另一份手工真相。 |
|
|
37
|
+
| Agent 集成 | 上游客户端会改变 hook、MCP、配置文件和权限模型。 | 使用 `memorix doctor agents` 诊断,优先让 `setup` / `repair` 做非破坏性修复。 |
|
|
38
|
+
| 大规模数据 | 保留、归档、去重和检索预算已存在,但上万至百万级数据仍需要按项目负载做容量验证。 | 为高增长项目配置明确的保留与清理策略,并关注 Dashboard / CLI 的审计信息。 |
|
|
91
39
|
|
|
92
40
|
---
|
|
93
41
|
|
|
94
|
-
##
|
|
95
|
-
|
|
96
|
-
### 运行时依赖
|
|
97
|
-
| 包 | 版本 | 用途 |
|
|
98
|
-
|---|------|------|
|
|
99
|
-
| `@modelcontextprotocol/sdk` | ^latest | MCP 协议 SDK |
|
|
100
|
-
| `@orama/orama` | ^latest | 全文/向量搜索 |
|
|
101
|
-
| `gpt-tokenizer` | ^latest | Token 计数 |
|
|
102
|
-
| `citty` | ^latest | CLI 框架 |
|
|
103
|
-
| `@clack/prompts` | ^latest | CLI 交互提示 |
|
|
104
|
-
| `zod` | ^3 | 参数验证 |
|
|
105
|
-
|
|
106
|
-
### 可选依赖
|
|
107
|
-
| 包 | 版本 | 用途 |
|
|
108
|
-
|---|------|------|
|
|
109
|
-
| `fastembed` | ^latest | 本地 ONNX embedding (384d),需用户显式安装 |
|
|
110
|
-
|
|
111
|
-
### 开发依赖
|
|
112
|
-
| 包 | 版本 | 用途 |
|
|
113
|
-
|---|------|------|
|
|
114
|
-
| `vitest` | ^latest | 测试框架 |
|
|
115
|
-
| `tsup` | ^latest | 打包构建 |
|
|
116
|
-
| `typescript` | ^5 | 类型系统 |
|
|
42
|
+
## 公开路线
|
|
117
43
|
|
|
118
|
-
|
|
44
|
+
### 1. 稳定性与可操作性
|
|
45
|
+
|
|
46
|
+
- 继续以 Windows、macOS/Linux、CLI、MCP、后台服务和全新安装作为发布门槛;
|
|
47
|
+
- 保持 MCP 工具面小而按需展开,CLI 保持完整的管理和恢复能力;
|
|
48
|
+
- 让配置迁移、诊断、修复和清理保持非破坏性、可解释、可回退。
|
|
49
|
+
|
|
50
|
+
### 2. 记忆质量与知识工作区
|
|
119
51
|
|
|
120
|
-
|
|
52
|
+
- 提高“新会话接手”时的相关性:先给简短进度卡,再按任务取详情;
|
|
53
|
+
- 统一保留状态、归档、检索预算和 Dashboard 的解释,避免同一条记忆在不同入口显示不同状态;
|
|
54
|
+
- 继续发展代码状态、知识库、Wiki、图谱和工作流之间的可追溯关联,而不是重复堆叠文本摘要。
|
|
121
55
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
56
|
+
### 3. 受控的多模态派生能力
|
|
57
|
+
|
|
58
|
+
- 在现有资产生命周期之上评估 PDF 文本提取、音频转写、视频语义派生;
|
|
59
|
+
- 每一类派生都必须有来源、成本边界、配额、删除联动和重建路径;
|
|
60
|
+
- 不把“接受任意 URL / 任意文件”误宣传为完整多模态 RAG。
|
|
61
|
+
|
|
62
|
+
### 4. Agent 生态与研究
|
|
63
|
+
|
|
64
|
+
- 跟进受用户需求推动的集成,例如 [Qwen 自动 hooks](https://github.com/AVIDS2/memorix/issues/3) 与 [持久化 Agent 身份](https://github.com/AVIDS2/memorix/issues/49);
|
|
65
|
+
- 独立推进记忆能力的实证研究,例如[模型能力如何改变项目记忆收益与伤害边界](https://github.com/AVIDS2/memorix/issues/152),不把研究假设当作产品已经证明的效果。
|
|
131
66
|
|
|
132
67
|
---
|
|
133
68
|
|
|
134
|
-
##
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| 2026-02-13 | Antigravity MCP 配置修复,Memorix MCP Server 首次成功运行 |
|
|
140
|
-
| 2026-02-13 | 发现并修复 npx 缓存损坏问题 (MODULE_NOT_FOUND chownr) |
|
|
141
|
-
| 2026-02-15 | 完成全部核心模块的深度代码审查 |
|
|
142
|
-
| 2026-02-15 | 开发文档完成 (ARCHITECTURE, MODULES, DEVELOPMENT, DESIGN_DECISIONS, API_REFERENCE) |
|
|
143
|
-
| 2026-02-24 | v0.7.8-0.7.10: Antigravity 兼容 + MCP roots + 中英双语文档 |
|
|
144
|
-
| 2026-02-24 | v0.7.11: P0-P2 全部完成 (文件锁 + 搜索优化 + 自动归档 + 中文实体 + 性能优化 + 图谱同步) |
|
|
145
|
-
| 2026-02-25 | v0.9.0-0.9.12: Hooks 系统全量修复 + 10 Agent 支持 |
|
|
146
|
-
| 2026-02-28 | v0.9.25: Windsurf 兼容性修复 |
|
|
147
|
-
| 2026-03-05 | v0.10.5: Antigravity/Claude Code hooks 修复 |
|
|
148
|
-
| 2026-03-07 | v0.11.0: Mini-Skills + LLM 增强模式 |
|
|
149
|
-
| 2026-03-09 | **v1.0.0**: 首个稳定版 — 22 工具 + 团队协作 + 自动清理 + 753 测试 |
|
|
69
|
+
## 贡献与验证原则
|
|
70
|
+
|
|
71
|
+
贡献会先检查三件事:是否符合当前存储/可见性/生命周期边界,是否能由 CLI 与 MCP 一致地使用,是否有可重复的测试或人工验证证据。功能方向有价值但架构已演进的 PR 会保留作者署名,并通过公开后续 Issue 延续,而不是悄悄重写或吞掉成果。
|
|
72
|
+
|
|
73
|
+
历史版本、已解决问题和详细发布日期请查看 [CHANGELOG](../CHANGELOG.md)。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memorix",
|
|
3
3
|
"mcpName": "io.github.AVIDS2/memorix",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"description": "Local-first shared memory layer for AI coding agents across MCP clients, Git history, reasoning context, and project sessions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"README.zh-CN.md",
|
|
45
45
|
"assets",
|
|
46
46
|
"docs",
|
|
47
|
+
"!docs/dev-log",
|
|
47
48
|
"!docs/memcode",
|
|
48
49
|
"!docs/superpowers",
|
|
49
50
|
"plugins",
|
|
@@ -69,9 +70,11 @@
|
|
|
69
70
|
"generate:star-history": "node scripts/generate-star-history.mjs",
|
|
70
71
|
"sync:mcp-registry": "node scripts/sync-mcp-registry-manifest.mjs",
|
|
71
72
|
"check:mcp-registry": "node scripts/check-mcp-registry-manifest.mjs",
|
|
73
|
+
"sync:plugin-release": "node scripts/sync-plugin-release-manifests.mjs",
|
|
74
|
+
"check:plugin-release": "node scripts/sync-plugin-release-manifests.mjs --check",
|
|
72
75
|
"audit:pi-upstream": "node scripts/pi-upstream-audit.mjs",
|
|
73
76
|
"lint": "tsc --noEmit",
|
|
74
|
-
"prepublishOnly": "npm run sync:mcp-registry && npm run check:mcp-registry && npm run build && npm test"
|
|
77
|
+
"prepublishOnly": "npm run sync:mcp-registry && npm run sync:plugin-release && npm run check:mcp-registry && npm run check:plugin-release && npm run build && npm test"
|
|
75
78
|
},
|
|
76
79
|
"keywords": [
|
|
77
80
|
"mcp",
|