memorix 1.8.4 → 1.8.6
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 +52 -0
- package/CLAUDE.md +3 -0
- package/README.md +8 -6
- package/README.zh-CN.md +5 -3
- package/assets/star-history-dark.svg +5 -5
- package/assets/star-history-light.svg +5 -5
- package/assets/star-history.json +35 -5
- package/dist/cli/index.js +1848 -754
- package/dist/dashboard/static/app.js +29 -885
- package/dist/dashboard/static/index.html +1 -5
- package/dist/dashboard/static/style.css +36 -503
- package/dist/index.d.ts +4 -4
- package/dist/index.js +286 -79
- package/dist/memcode/index.js +28035 -169
- package/dist/memcode-runtime/CHANGELOG.md +52 -0
- package/dist/sdk.js +103 -21
- package/dist/types.d.ts +1 -1
- package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +22 -16
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +2 -2
- package/docs/API_REFERENCE.md +10 -8
- package/docs/DASHBOARD.md +23 -0
- package/docs/DEVELOPMENT.md +2 -2
- package/docs/DOCKER.md +6 -3
- package/docs/INTEGRATIONS.md +2 -1
- package/docs/MODULES.md +46 -20
- package/docs/PERFORMANCE.md +1 -1
- package/docs/README.md +8 -7
- package/docs/SETUP.md +4 -3
- package/package.json +11 -11
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/antigravity/memorix/rules/memorix.md +5 -0
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/claude/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/claude/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/codebuddy/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/codebuddy/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/codex/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/codex/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/copilot/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/copilot/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/cursor/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/cursor/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/plugins/gemini/memorix/GEMINI.md +5 -0
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +7 -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/plugins/pi/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/pi/memorix/skills/memorix-mini-skills/SKILL.md +2 -0
- package/plugins/pi/memorix/skills/memorix-orchestrate/SKILL.md +2 -0
- package/server.json +2 -2
- package/src/cli/command-guide.ts +52 -1
- package/src/cli/commands/agent-integrations.ts +1 -0
- package/src/cli/commands/background.ts +166 -6
- package/src/cli/commands/hooks-install.ts +9 -2
- package/src/cli/commands/hooks-preview.ts +5 -0
- package/src/cli/commands/integrate.ts +2 -0
- package/src/cli/commands/serve-http.ts +73 -80
- package/src/cli/commands/serve.ts +95 -93
- package/src/cli/commands/setup.ts +11 -1
- package/src/cli/commands/uninstall.ts +24 -2
- package/src/cli/index.ts +1 -1
- package/src/codegraph/task-lens.ts +72 -7
- package/src/dashboard/static/index.html +1 -5
- package/src/dashboard/static/style.css +36 -503
- package/src/hooks/installers/index.ts +58 -0
- package/src/hooks/official-skills.ts +13 -6
- package/src/hooks/types.ts +2 -0
- package/src/integrations/registry.ts +9 -0
- package/src/memory/graph.ts +2 -2
- package/src/server/mcp-diagnostics.ts +9 -7
- package/src/server/modern-mcp-bridge.ts +108 -0
- package/src/server/stdio-startup-gate.ts +41 -2
- package/src/server/tool-profile.ts +7 -6
- package/src/server.ts +1 -1
- package/src/store/orama-store.ts +2 -2
- package/src/types.ts +1 -1
- package/src/wiki/types.ts +2 -2
- package/src/workspace/mcp-adapters/workbuddy.ts +71 -0
package/dist/index.js
CHANGED
|
@@ -149968,6 +149968,15 @@ __export(task_lens_exports, {
|
|
|
149968
149968
|
scoreLensSource: () => scoreLensSource,
|
|
149969
149969
|
shouldShowLensSource: () => shouldShowLensSource
|
|
149970
149970
|
});
|
|
149971
|
+
function hasSubstantiveTask(text2, keyword) {
|
|
149972
|
+
const withoutKeyword = text2.replace(
|
|
149973
|
+
new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"),
|
|
149974
|
+
" "
|
|
149975
|
+
);
|
|
149976
|
+
const residual = withoutKeyword.replace(TASK_FILLER_WORDS, " ").replace(TASK_FILLER_PHRASES, " ").replace(/[\s\p{P}]/gu, "");
|
|
149977
|
+
if (/^(?:任务|工作|一下|一起|接着)$/u.test(residual)) return false;
|
|
149978
|
+
return Array.from(residual).length >= MIN_TASK_SUBSTANCE;
|
|
149979
|
+
}
|
|
149971
149980
|
function normalizePath2(path37) {
|
|
149972
149981
|
return path37.replace(/\\/g, "/");
|
|
149973
149982
|
}
|
|
@@ -150027,8 +150036,12 @@ function resolveTaskLens(task) {
|
|
|
150027
150036
|
}
|
|
150028
150037
|
function isContinuationTask(task) {
|
|
150029
150038
|
const normalized = (task ?? "").trim().toLowerCase();
|
|
150030
|
-
|
|
150031
|
-
|
|
150039
|
+
if (normalized.length === 0) return false;
|
|
150040
|
+
if (EXPLICIT_HANDOFF_KEYWORDS.some((keyword) => containsTaskKeyword(normalized, keyword))) {
|
|
150041
|
+
return true;
|
|
150042
|
+
}
|
|
150043
|
+
return AMBIGUOUS_CONTINUATION_KEYWORDS.some(
|
|
150044
|
+
(keyword) => containsTaskKeyword(normalized, keyword) && hasSubstantiveTask(normalized, keyword)
|
|
150032
150045
|
);
|
|
150033
150046
|
}
|
|
150034
150047
|
function pathKindScore(path37, lens) {
|
|
@@ -150174,7 +150187,7 @@ function shouldShowLensSource(source, lens, task) {
|
|
|
150174
150187
|
if (lens.id === "onboarding" || lens.id === "release" || lens.id === "docs") return score >= 40;
|
|
150175
150188
|
return score > 0;
|
|
150176
150189
|
}
|
|
150177
|
-
var STOP_WORDS, LENSES, KEYWORDS,
|
|
150190
|
+
var STOP_WORDS, LENSES, KEYWORDS, EXPLICIT_HANDOFF_KEYWORDS, AMBIGUOUS_CONTINUATION_KEYWORDS, TASK_FILLER_WORDS, TASK_FILLER_PHRASES, MIN_TASK_SUBSTANCE, LENS_PRIORITY;
|
|
150178
150191
|
var init_task_lens = __esm({
|
|
150179
150192
|
"src/codegraph/task-lens.ts"() {
|
|
150180
150193
|
"use strict";
|
|
@@ -150295,18 +150308,31 @@ var init_task_lens = __esm({
|
|
|
150295
150308
|
docs: ["doc", "docs", "readme", "\u6587\u6863", "\u8BF4\u660E"],
|
|
150296
150309
|
test: ["coverage", "fixture", "smoke", "spec", "test", "tests", "testing", "vitest", "\u6D4B\u8BD5"]
|
|
150297
150310
|
};
|
|
150298
|
-
|
|
150311
|
+
EXPLICIT_HANDOFF_KEYWORDS = [
|
|
150312
|
+
"handoff",
|
|
150313
|
+
"hand off",
|
|
150314
|
+
"hand over",
|
|
150315
|
+
"previous session",
|
|
150316
|
+
"last session",
|
|
150317
|
+
"pick up where",
|
|
150318
|
+
"\u4EA4\u63A5",
|
|
150319
|
+
// 覆盖「任务交接」「工作交接」
|
|
150320
|
+
"\u63A5\u624B",
|
|
150321
|
+
"\u4E0A\u6B21\u4F1A\u8BDD",
|
|
150322
|
+
"\u4E0A\u6B21\u7684\u4F1A\u8BDD"
|
|
150323
|
+
];
|
|
150324
|
+
AMBIGUOUS_CONTINUATION_KEYWORDS = [
|
|
150299
150325
|
"continue",
|
|
150300
150326
|
"resume",
|
|
150301
|
-
"pick up",
|
|
150302
150327
|
"carry on",
|
|
150303
|
-
"
|
|
150328
|
+
"pick up",
|
|
150304
150329
|
"\u7EE7\u7EED",
|
|
150305
|
-
"\u63A5\u624B",
|
|
150306
150330
|
"\u6062\u590D",
|
|
150307
|
-
"\u5EF6\u7EED"
|
|
150308
|
-
"\u4E0A\u6B21\u4F1A\u8BDD"
|
|
150331
|
+
"\u5EF6\u7EED"
|
|
150309
150332
|
];
|
|
150333
|
+
TASK_FILLER_WORDS = /\b(?:please|task|work|the|a|an)\b/giu;
|
|
150334
|
+
TASK_FILLER_PHRASES = /(?:吧|了|呢|啊|吗|嘛|呀|哦|噢|一下|一起|接着|请|帮我)/gu;
|
|
150335
|
+
MIN_TASK_SUBSTANCE = 2;
|
|
150310
150336
|
LENS_PRIORITY = [
|
|
150311
150337
|
"bugfix",
|
|
150312
150338
|
"release",
|
|
@@ -156854,17 +156880,25 @@ function resolveToolProfile(opts) {
|
|
|
156854
156880
|
return normalize(opts.explicit) ?? normalize(opts.envValue) ?? opts.fallback;
|
|
156855
156881
|
}
|
|
156856
156882
|
function describeProfile(profile) {
|
|
156883
|
+
const count2 = countToolsInProfile(profile);
|
|
156857
156884
|
switch (profile) {
|
|
156858
156885
|
case "micro":
|
|
156859
|
-
return
|
|
156886
|
+
return `micro (agent-ready context + bounded recovery/media, ${count2} tools)`;
|
|
156860
156887
|
case "lite":
|
|
156861
|
-
return
|
|
156888
|
+
return `lite (core memory + sessions, ${count2} tools)`;
|
|
156862
156889
|
case "team":
|
|
156863
|
-
return
|
|
156890
|
+
return `team (lite + coordination tools + dashboard + knowledge workspace, ${count2} tools)`;
|
|
156864
156891
|
case "full":
|
|
156865
|
-
return
|
|
156892
|
+
return `full (all tools including advanced / KG-compat, ${count2} tools)`;
|
|
156866
156893
|
}
|
|
156867
156894
|
}
|
|
156895
|
+
function countToolsInProfile(profile) {
|
|
156896
|
+
let n = 0;
|
|
156897
|
+
for (const name of Object.keys(TOOL_PROFILES)) {
|
|
156898
|
+
if (isToolInProfile(name, profile)) n++;
|
|
156899
|
+
}
|
|
156900
|
+
return n;
|
|
156901
|
+
}
|
|
156868
156902
|
var TOOL_PROFILES;
|
|
156869
156903
|
var init_tool_profile = __esm({
|
|
156870
156904
|
"src/server/tool-profile.ts"() {
|
|
@@ -158121,7 +158155,7 @@ var init_request_context = __esm({
|
|
|
158121
158155
|
function getMcpServerInfo() {
|
|
158122
158156
|
return {
|
|
158123
158157
|
name: "memorix",
|
|
158124
|
-
version: true ? "1.8.
|
|
158158
|
+
version: true ? "1.8.6" : "1.0.1"
|
|
158125
158159
|
};
|
|
158126
158160
|
}
|
|
158127
158161
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -166530,6 +166564,9 @@ var init_official_skills = __esm({
|
|
|
166530
166564
|
'| Specific past decision, bug, file, or change | `memorix_search` | `memorix memory search --query "<topic>"` |',
|
|
166531
166565
|
"| Need the full source for a search hit | `memorix_detail` | `memorix memory detail --id <id>` |",
|
|
166532
166566
|
"| Need the sequence around one memory | `memorix_timeline` | `memorix memory timeline --id <id>` |",
|
|
166567
|
+
"| Check source and freshness for a memory | `memorix_evidence` | `memorix evidence list|get|events` |",
|
|
166568
|
+
"| Record whether a memory helped, conflicted, or was corrected | `memorix_feedback` | `memorix feedback record|show|audit` |",
|
|
166569
|
+
"| Inspect or import controlled media | `memorix_media` | `memorix media import|attach|list|show|status` |",
|
|
166533
166570
|
'| Learned reusable project knowledge | `memorix_store` | `memorix memory store --type <type> --entity <name> --title "<title>" "<text>"` |',
|
|
166534
166571
|
"| Task or bug is complete/outdated | `memorix_resolve` | `memorix memory resolve --ids <ids>` |",
|
|
166535
166572
|
"",
|
|
@@ -166660,6 +166697,8 @@ var init_official_skills = __esm({
|
|
|
166660
166697
|
"",
|
|
166661
166698
|
"Promote memories into mini-skills only when they are reusable instructions, not just historical notes.",
|
|
166662
166699
|
"",
|
|
166700
|
+
"The standard setup uses the `lite` MCP profile. `memorix_skills` and `memorix_promote` are full-profile tools, so use the CLI fallback unless the current server was explicitly started with `MEMORIX_MODE=full` or `--mode full`. Do not probe hidden MCP tools repeatedly.",
|
|
166701
|
+
"",
|
|
166663
166702
|
"## Tool Router",
|
|
166664
166703
|
"",
|
|
166665
166704
|
"| Situation | Prefer | CLI fallback |",
|
|
@@ -166695,15 +166734,17 @@ var init_official_skills = __esm({
|
|
|
166695
166734
|
"| Situation | Prefer | CLI fallback |",
|
|
166696
166735
|
"|---|---|---|",
|
|
166697
166736
|
'| Run managed subagent execution | CLI | `memorix orchestrate --goal "<goal>" --agents claude:1,codex:1` |',
|
|
166698
|
-
"| Register coordination identity | `team_manage` action `join` | `memorix team join --agentType <agent>` |",
|
|
166699
|
-
"| Create or inspect tasks | `team_task` | `memorix task create|list|claim|complete` |",
|
|
166700
|
-
"| Send or read coordination messages | `team_message` | `memorix message send|broadcast|inbox` |",
|
|
166701
|
-
"| Share structured handoff | `memorix_handoff` | `memorix handoff send` |",
|
|
166702
|
-
"| Avoid file conflicts | `team_file_lock` | `memorix lock lock|unlock|status` |",
|
|
166703
|
-
"| Poll joined coordination state | `memorix_poll` | `memorix poll` |",
|
|
166737
|
+
"| Register coordination identity when team MCP tools are available | `team_manage` action `join` | `memorix team join --agentType <agent>` |",
|
|
166738
|
+
"| Create or inspect tasks when team MCP tools are available | `team_task` | `memorix task create|list|claim|complete` |",
|
|
166739
|
+
"| Send or read coordination messages when team MCP tools are available | `team_message` | `memorix message send|broadcast|inbox` |",
|
|
166740
|
+
"| Share structured handoff when team MCP tools are available | `memorix_handoff` | `memorix handoff send` |",
|
|
166741
|
+
"| Avoid file conflicts when team MCP tools are available | `team_file_lock` | `memorix lock lock|unlock|status` |",
|
|
166742
|
+
"| Poll joined coordination state when team MCP tools are available | `memorix_poll` | `memorix poll` |",
|
|
166704
166743
|
"",
|
|
166705
166744
|
"## Boundaries",
|
|
166706
166745
|
"",
|
|
166746
|
+
"The standard setup uses the `lite` MCP profile. Coordination MCP tools are exposed only by `team` or `full`; use the CLI fallback for ordinary installations, or explicitly start the server with `--mode team`. Do not probe unavailable team tools in a loop.",
|
|
166747
|
+
"",
|
|
166707
166748
|
"- For ordinary memory, do not join coordination state.",
|
|
166708
166749
|
"- For production multi-agent execution, prefer `memorix orchestrate` so the main process owns planning, dispatch, retries, and verification gates.",
|
|
166709
166750
|
"- `memorix orchestrate` uses the current checkout for single-worker runs and task worktrees for parallel runs. Use `--isolated` to force worktree isolation, `--no-worktree` to disable it, `--allow-dirty` to run with uncommitted changes, and `--no-auto-merge` to preserve task worktrees for manual review.",
|
|
@@ -167318,6 +167359,8 @@ function getProjectConfigPath(agent, projectRoot) {
|
|
|
167318
167359
|
return path33.join(projectRoot, ".agents", "hooks.json");
|
|
167319
167360
|
case "gemini-cli":
|
|
167320
167361
|
return path33.join(projectRoot, ".gemini", "settings.json");
|
|
167362
|
+
case "workbuddy":
|
|
167363
|
+
return "";
|
|
167321
167364
|
default:
|
|
167322
167365
|
return path33.join(projectRoot, ".memorix", "hooks.json");
|
|
167323
167366
|
}
|
|
@@ -167351,6 +167394,8 @@ function getGlobalConfigPath(agent) {
|
|
|
167351
167394
|
return path33.join(home, ".trae", "rules", "project_rules.md");
|
|
167352
167395
|
case "dsh":
|
|
167353
167396
|
return path33.join(process.env.DSH_HOME?.trim() || path33.join(home, ".dsh"), "AGENTS.md");
|
|
167397
|
+
case "workbuddy":
|
|
167398
|
+
return "";
|
|
167354
167399
|
default:
|
|
167355
167400
|
return path33.join(home, ".memorix", "hooks.json");
|
|
167356
167401
|
}
|
|
@@ -167377,6 +167422,8 @@ function getAgentRulesPath(agent, root, global2 = false) {
|
|
|
167377
167422
|
return path33.join(root, ".trae", "rules", "project_rules.md");
|
|
167378
167423
|
case "dsh":
|
|
167379
167424
|
return path33.join(process.env.DSH_HOME?.trim() || path33.join(root, ".dsh"), "AGENTS.md");
|
|
167425
|
+
case "workbuddy":
|
|
167426
|
+
return "";
|
|
167380
167427
|
default:
|
|
167381
167428
|
return path33.join(root, ".agent", "rules", "memorix.md");
|
|
167382
167429
|
}
|
|
@@ -167403,6 +167450,8 @@ function getAgentRulesPath(agent, root, global2 = false) {
|
|
|
167403
167450
|
return path33.join(root, ".trae", "rules", "project_rules.md");
|
|
167404
167451
|
case "dsh":
|
|
167405
167452
|
return path33.join(root, "AGENTS.md");
|
|
167453
|
+
case "workbuddy":
|
|
167454
|
+
return path33.join(root, "AGENTS.md");
|
|
167406
167455
|
default:
|
|
167407
167456
|
return path33.join(root, ".agent", "rules", "memorix.md");
|
|
167408
167457
|
}
|
|
@@ -167491,6 +167540,11 @@ async function detectInstalledAgents() {
|
|
|
167491
167540
|
agents.push("dsh");
|
|
167492
167541
|
} catch {
|
|
167493
167542
|
}
|
|
167543
|
+
try {
|
|
167544
|
+
await fs21.access(path33.join(home, ".workbuddy"));
|
|
167545
|
+
agents.push("workbuddy");
|
|
167546
|
+
} catch {
|
|
167547
|
+
}
|
|
167494
167548
|
return agents;
|
|
167495
167549
|
}
|
|
167496
167550
|
async function installHooks(agent, projectRoot, global2 = false) {
|
|
@@ -167504,6 +167558,16 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
167504
167558
|
}
|
|
167505
167559
|
};
|
|
167506
167560
|
}
|
|
167561
|
+
if (agent === "workbuddy" && global2) {
|
|
167562
|
+
return {
|
|
167563
|
+
agent,
|
|
167564
|
+
configPath: "",
|
|
167565
|
+
events: [],
|
|
167566
|
+
generated: {
|
|
167567
|
+
note: "WorkBuddy has no hook system and no user-global guidance file \u2014 MCP only; no global guidance/hooks. Run `memorix setup --agent workbuddy` (without --global) to install project MCP config and AGENTS.md guidance."
|
|
167568
|
+
}
|
|
167569
|
+
};
|
|
167570
|
+
}
|
|
167507
167571
|
if (global2 && getGlobalConfigPath(agent) === "") {
|
|
167508
167572
|
return {
|
|
167509
167573
|
agent,
|
|
@@ -167586,6 +167650,17 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
167586
167650
|
}
|
|
167587
167651
|
};
|
|
167588
167652
|
}
|
|
167653
|
+
case "workbuddy": {
|
|
167654
|
+
const rulesPath = await installAgentRules(agent, projectRoot, global2);
|
|
167655
|
+
return {
|
|
167656
|
+
agent,
|
|
167657
|
+
configPath: rulesPath,
|
|
167658
|
+
events: [],
|
|
167659
|
+
generated: {
|
|
167660
|
+
note: "WorkBuddy has no hook system \u2014 installed AGENTS.md guidance only; the MCP row is installed by `memorix setup --agent workbuddy`."
|
|
167661
|
+
}
|
|
167662
|
+
};
|
|
167663
|
+
}
|
|
167589
167664
|
case "opencode": {
|
|
167590
167665
|
const pluginContent = generateOpenCodePlugin();
|
|
167591
167666
|
const pluginPath = global2 ? getGlobalConfigPath(agent) : getProjectConfigPath(agent, projectRoot);
|
|
@@ -167715,6 +167790,7 @@ async function installHooks(agent, projectRoot, global2 = false) {
|
|
|
167715
167790
|
};
|
|
167716
167791
|
}
|
|
167717
167792
|
async function installAgentRules(agent, projectRoot, global2 = false) {
|
|
167793
|
+
if (agent === "workbuddy" && global2) return "";
|
|
167718
167794
|
const rulesContent = getAgentRulesContent(agent, global2 ? "global" : "project");
|
|
167719
167795
|
const rulesRoot = global2 ? os5.homedir() : projectRoot;
|
|
167720
167796
|
const rulesPath = getAgentRulesPath(agent, rulesRoot, global2);
|
|
@@ -167867,7 +167943,10 @@ alwaysApply: true
|
|
|
167867
167943
|
"| `memorix_store` | Save something worth persisting |",
|
|
167868
167944
|
'| `memorix_store_reasoning` | Save the "why" behind a decision |',
|
|
167869
167945
|
"| `memorix_resolve` | Mark completed/outdated memories |",
|
|
167870
|
-
"| `memorix_session_start` | Load session context (handoff, orchestration coordination) |"
|
|
167946
|
+
"| `memorix_session_start` | Load session context (handoff, orchestration coordination) |",
|
|
167947
|
+
"| `memorix_evidence` | Check a memory source, freshness, and verification state |",
|
|
167948
|
+
"| `memorix_feedback` | Record whether a memory helped, conflicted, or was corrected |",
|
|
167949
|
+
"| `memorix_media` | Inspect or import controlled local media |"
|
|
167871
167950
|
].join("\n");
|
|
167872
167951
|
}
|
|
167873
167952
|
async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
@@ -167877,6 +167956,9 @@ async function uninstallHooks(agent, projectRoot, global2 = false) {
|
|
|
167877
167956
|
if (agent === "pi") {
|
|
167878
167957
|
return false;
|
|
167879
167958
|
}
|
|
167959
|
+
if (agent === "workbuddy") {
|
|
167960
|
+
return false;
|
|
167961
|
+
}
|
|
167880
167962
|
if (global2 && getGlobalConfigPath(agent) === "") {
|
|
167881
167963
|
return false;
|
|
167882
167964
|
}
|
|
@@ -172907,7 +172989,17 @@ var init_stdio_startup_gate = __esm({
|
|
|
172907
172989
|
this.fail(new Error(`stdio input chunk exceeded ${this.maxBufferSize} bytes`));
|
|
172908
172990
|
return;
|
|
172909
172991
|
}
|
|
172910
|
-
this.
|
|
172992
|
+
this.pendingInput += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
172993
|
+
let newline2 = this.pendingInput.indexOf("\n");
|
|
172994
|
+
while (newline2 >= 0 && !this.stopped) {
|
|
172995
|
+
const line = this.pendingInput.slice(0, newline2 + 1);
|
|
172996
|
+
this.pendingInput = this.pendingInput.slice(newline2 + 1);
|
|
172997
|
+
this.handleReadyLine(line);
|
|
172998
|
+
newline2 = this.pendingInput.indexOf("\n");
|
|
172999
|
+
}
|
|
173000
|
+
if (!this.stopped && Buffer.byteLength(this.pendingInput, "utf8") > this.maxBufferSize) {
|
|
173001
|
+
this.fail(new Error(`stdio input exceeded ${this.maxBufferSize} bytes`));
|
|
173002
|
+
}
|
|
172911
173003
|
return;
|
|
172912
173004
|
}
|
|
172913
173005
|
const text2 = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
@@ -173006,6 +173098,24 @@ var init_stdio_startup_gate = __esm({
|
|
|
173006
173098
|
this.queuedMessages.push(line);
|
|
173007
173099
|
this.queuedBytes += bytes;
|
|
173008
173100
|
}
|
|
173101
|
+
handleReadyLine(line) {
|
|
173102
|
+
const parsed = this.parseLine(line);
|
|
173103
|
+
if (parsed && !("error" in parsed) && this.isDiscoveryRequest(parsed.message)) {
|
|
173104
|
+
const response = {
|
|
173105
|
+
jsonrpc: "2.0",
|
|
173106
|
+
id: parsed.message.id,
|
|
173107
|
+
result: createMcpStartupDiscoverResult(this.serverInfo)
|
|
173108
|
+
};
|
|
173109
|
+
try {
|
|
173110
|
+
this.stdout.write(`${JSON.stringify(response)}
|
|
173111
|
+
`);
|
|
173112
|
+
} catch (error) {
|
|
173113
|
+
this.fail(error instanceof Error ? error : new Error(String(error)));
|
|
173114
|
+
}
|
|
173115
|
+
return;
|
|
173116
|
+
}
|
|
173117
|
+
this.input.write(line);
|
|
173118
|
+
}
|
|
173009
173119
|
parseLine(line) {
|
|
173010
173120
|
const trimmed = line.endsWith("\n") ? line.slice(0, -1).replace(/\r$/, "") : line;
|
|
173011
173121
|
if (!trimmed.trim()) return null;
|
|
@@ -173044,7 +173154,8 @@ var init_stdio_startup_gate = __esm({
|
|
|
173044
173154
|
if (message.method !== MCP_SERVER_DISCOVER_METHOD) return false;
|
|
173045
173155
|
if (!Object.prototype.hasOwnProperty.call(message, "id")) return false;
|
|
173046
173156
|
const params = message.params;
|
|
173047
|
-
|
|
173157
|
+
if (params === void 0) return true;
|
|
173158
|
+
return typeof params === "object" && params !== null && !Array.isArray(params) && !Object.prototype.hasOwnProperty.call(params, "_meta");
|
|
173048
173159
|
}
|
|
173049
173160
|
isValidRequestId(id) {
|
|
173050
173161
|
return id === null || typeof id === "string" || typeof id === "number" && Number.isFinite(id);
|
|
@@ -173123,6 +173234,81 @@ var init_mcp_root_path = __esm({
|
|
|
173123
173234
|
}
|
|
173124
173235
|
});
|
|
173125
173236
|
|
|
173237
|
+
// src/server/modern-mcp-bridge.ts
|
|
173238
|
+
var modern_mcp_bridge_exports = {};
|
|
173239
|
+
__export(modern_mcp_bridge_exports, {
|
|
173240
|
+
createModernMcpBridge: () => createModernMcpBridge
|
|
173241
|
+
});
|
|
173242
|
+
import {
|
|
173243
|
+
fromJsonSchema,
|
|
173244
|
+
McpServer as ModernMcpServer
|
|
173245
|
+
} from "@modelcontextprotocol/server";
|
|
173246
|
+
import { Client as LegacyClient } from "@modelcontextprotocol/sdk/client/index.js";
|
|
173247
|
+
import { InMemoryTransport as LegacyInMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
173248
|
+
async function createModernMcpBridge(options) {
|
|
173249
|
+
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server2(), server_exports2));
|
|
173250
|
+
const legacy = await createMemorixServer2(
|
|
173251
|
+
options.projectRoot,
|
|
173252
|
+
void 0,
|
|
173253
|
+
void 0,
|
|
173254
|
+
{
|
|
173255
|
+
...options,
|
|
173256
|
+
allowUntrackedFallback: options.allowUntrackedFallback ?? false,
|
|
173257
|
+
deferProjectInitUntilBound: options.deferProjectInitUntilBound ?? true,
|
|
173258
|
+
deferProjectRuntimeInit: options.deferProjectRuntimeInit ?? true
|
|
173259
|
+
}
|
|
173260
|
+
);
|
|
173261
|
+
const [clientTransport, serverTransport] = LegacyInMemoryTransport.createLinkedPair();
|
|
173262
|
+
const legacyClient = new LegacyClient({
|
|
173263
|
+
name: "memorix-modern-bridge",
|
|
173264
|
+
version: getMcpServerInfo().version
|
|
173265
|
+
});
|
|
173266
|
+
await legacy.server.connect(serverTransport);
|
|
173267
|
+
await legacyClient.connect(clientTransport);
|
|
173268
|
+
const listed = await legacyClient.listTools();
|
|
173269
|
+
const modern = new ModernMcpServer(getMcpServerInfo());
|
|
173270
|
+
for (const tool of listed.tools) {
|
|
173271
|
+
modern.registerTool(
|
|
173272
|
+
tool.name,
|
|
173273
|
+
{
|
|
173274
|
+
...tool.title ? { title: tool.title } : {},
|
|
173275
|
+
...tool.description ? { description: tool.description } : {},
|
|
173276
|
+
inputSchema: fromJsonSchema(tool.inputSchema)
|
|
173277
|
+
},
|
|
173278
|
+
async (args) => await legacyClient.callTool({
|
|
173279
|
+
name: tool.name,
|
|
173280
|
+
arguments: args
|
|
173281
|
+
})
|
|
173282
|
+
);
|
|
173283
|
+
}
|
|
173284
|
+
const bridge = modern;
|
|
173285
|
+
bridge.memorix = {
|
|
173286
|
+
projectId: legacy.projectId,
|
|
173287
|
+
deferredInit: legacy.deferredInit,
|
|
173288
|
+
switchProject: legacy.switchProject,
|
|
173289
|
+
isExplicitlyBound: legacy.isExplicitlyBound,
|
|
173290
|
+
handleTransportClose: legacy.handleTransportClose
|
|
173291
|
+
};
|
|
173292
|
+
let closed = false;
|
|
173293
|
+
const modernClose = modern.close.bind(modern);
|
|
173294
|
+
modern.close = async () => {
|
|
173295
|
+
if (closed) return;
|
|
173296
|
+
closed = true;
|
|
173297
|
+
await modernClose();
|
|
173298
|
+
await legacyClient.close().catch(() => void 0);
|
|
173299
|
+
await legacy.server.close().catch(() => void 0);
|
|
173300
|
+
legacy.handleTransportClose();
|
|
173301
|
+
};
|
|
173302
|
+
return bridge;
|
|
173303
|
+
}
|
|
173304
|
+
var init_modern_mcp_bridge = __esm({
|
|
173305
|
+
"src/server/modern-mcp-bridge.ts"() {
|
|
173306
|
+
"use strict";
|
|
173307
|
+
init_esm_shims();
|
|
173308
|
+
init_mcp_discovery();
|
|
173309
|
+
}
|
|
173310
|
+
});
|
|
173311
|
+
|
|
173126
173312
|
// src/cli/commands/serve-shared.ts
|
|
173127
173313
|
var serve_shared_exports = {};
|
|
173128
173314
|
__export(serve_shared_exports, {
|
|
@@ -173231,7 +173417,7 @@ var init_serve_shared = __esm({
|
|
|
173231
173417
|
|
|
173232
173418
|
// src/cli/version.ts
|
|
173233
173419
|
function getCliVersion() {
|
|
173234
|
-
return true ? "1.8.
|
|
173420
|
+
return true ? "1.8.6" : pkg.version;
|
|
173235
173421
|
}
|
|
173236
173422
|
var init_version3 = __esm({
|
|
173237
173423
|
"src/cli/version.ts"() {
|
|
@@ -173487,6 +173673,14 @@ var init_serve = __esm({
|
|
|
173487
173673
|
}
|
|
173488
173674
|
},
|
|
173489
173675
|
run: async ({ args }) => {
|
|
173676
|
+
const { serveStdio, StdioServerTransport } = await import("@modelcontextprotocol/server/stdio");
|
|
173677
|
+
const { createModernMcpBridge: createModernMcpBridge2 } = await Promise.resolve().then(() => (init_modern_mcp_bridge(), modern_mcp_bridge_exports));
|
|
173678
|
+
const { detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
173679
|
+
const { homedir: homedir27 } = await import("os");
|
|
173680
|
+
const { writeLastProjectRoot: writeLastProjectRoot2 } = await Promise.resolve().then(() => (init_launch_root(), launch_root_exports));
|
|
173681
|
+
const { resolveServeProject: resolveServeProject2 } = await Promise.resolve().then(() => (init_serve_shared(), serve_shared_exports));
|
|
173682
|
+
let stdioHandle;
|
|
173683
|
+
let stdinEndedBeforeHandle = false;
|
|
173490
173684
|
const startupGate = new StdioStartupGate({
|
|
173491
173685
|
stdin: process.stdin,
|
|
173492
173686
|
stdout: process.stdout,
|
|
@@ -173496,16 +173690,17 @@ var init_serve = __esm({
|
|
|
173496
173690
|
process.exit(1);
|
|
173497
173691
|
},
|
|
173498
173692
|
onEnd: () => {
|
|
173499
|
-
console.error("[memorix] stdin closed
|
|
173500
|
-
|
|
173693
|
+
console.error("[memorix] stdin closed - exiting");
|
|
173694
|
+
if (stdioHandle) {
|
|
173695
|
+
void stdioHandle.close().catch((error) => {
|
|
173696
|
+
console.error(`[memorix] stdio close error: ${error instanceof Error ? error.message : String(error)}`);
|
|
173697
|
+
});
|
|
173698
|
+
} else {
|
|
173699
|
+
stdinEndedBeforeHandle = true;
|
|
173700
|
+
}
|
|
173501
173701
|
}
|
|
173502
173702
|
});
|
|
173503
173703
|
startupGate.start();
|
|
173504
|
-
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
173505
|
-
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server2(), server_exports2));
|
|
173506
|
-
const { detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
173507
|
-
const { homedir: homedir27 } = await import("os");
|
|
173508
|
-
const { resolveServeProject: resolveServeProject2 } = await Promise.resolve().then(() => (init_serve_shared(), serve_shared_exports));
|
|
173509
173704
|
let safeCwd;
|
|
173510
173705
|
try {
|
|
173511
173706
|
safeCwd = process.cwd();
|
|
@@ -173522,70 +173717,82 @@ var init_serve = __esm({
|
|
|
173522
173717
|
},
|
|
173523
173718
|
{ detectProject: detectProject2, findGitInSubdirs: findGitInSubdirs2, isSystemDirectory: isSystemDirectory2 }
|
|
173524
173719
|
);
|
|
173525
|
-
for (const message of resolution.messages)
|
|
173526
|
-
console.error(message);
|
|
173527
|
-
}
|
|
173720
|
+
for (const message of resolution.messages) console.error(message);
|
|
173528
173721
|
if (!resolution.detectedProject) {
|
|
173529
173722
|
console.error(`[memorix] [WARN] ${resolution.error}`);
|
|
173530
|
-
console.error(
|
|
173531
|
-
console.error(
|
|
173723
|
+
console.error("[memorix] Starting in deferred-binding mode - bind with memorix_session_start(projectRoot=...) when needed.");
|
|
173724
|
+
console.error("[memorix] For non-git directories, use --allow-untracked to enable untracked/ fallback.");
|
|
173532
173725
|
}
|
|
173533
173726
|
const detected = resolution.detectedProject;
|
|
173534
173727
|
const projectRoot = resolution.projectRoot;
|
|
173535
|
-
if (detected)
|
|
173536
|
-
const { writeLastProjectRoot: writeLastProjectRoot2 } = await Promise.resolve().then(() => (init_launch_root(), launch_root_exports));
|
|
173537
|
-
writeLastProjectRoot2(detected.rootPath);
|
|
173538
|
-
}
|
|
173728
|
+
if (detected) writeLastProjectRoot2(detected.rootPath);
|
|
173539
173729
|
const allowUntracked = args["allow-untracked"] ?? false;
|
|
173540
|
-
const toolProfile = resolveToolProfile({
|
|
173541
|
-
|
|
173542
|
-
|
|
173730
|
+
const toolProfile = resolveToolProfile({
|
|
173731
|
+
explicit: args.mode,
|
|
173732
|
+
envValue: process.env.MEMORIX_MODE,
|
|
173733
|
+
fallback: "micro"
|
|
173734
|
+
});
|
|
173543
173735
|
const transport = new StdioServerTransport(startupGate.input, process.stdout);
|
|
173544
|
-
|
|
173545
|
-
|
|
173546
|
-
|
|
173547
|
-
|
|
173548
|
-
|
|
173549
|
-
|
|
173550
|
-
|
|
173551
|
-
|
|
173552
|
-
|
|
173553
|
-
|
|
173554
|
-
|
|
173555
|
-
|
|
173556
|
-
const
|
|
173557
|
-
|
|
173558
|
-
const
|
|
173736
|
+
const createBridge = async () => {
|
|
173737
|
+
const bridge = await createModernMcpBridge2({
|
|
173738
|
+
projectRoot,
|
|
173739
|
+
allowUntrackedFallback: allowUntracked,
|
|
173740
|
+
deferProjectInitUntilBound: !allowUntracked,
|
|
173741
|
+
deferProjectRuntimeInit: true,
|
|
173742
|
+
toolProfile
|
|
173743
|
+
});
|
|
173744
|
+
const tryRootsSwitch = async () => {
|
|
173745
|
+
try {
|
|
173746
|
+
if (bridge.memorix.isExplicitlyBound()) return;
|
|
173747
|
+
const { roots } = await bridge.server.listRoots();
|
|
173748
|
+
for (const root of roots ?? []) {
|
|
173749
|
+
if (!root.uri.startsWith("file://")) continue;
|
|
173750
|
+
const rootPath = mcpFileUriToPath(root.uri);
|
|
173751
|
+
if (!rootPath) continue;
|
|
173752
|
+
const switched = await bridge.memorix.switchProject(rootPath, "mcp-roots");
|
|
173559
173753
|
if (switched) {
|
|
173560
|
-
console.error(`[memorix] [UPDATED] Project updated via MCP roots: ${
|
|
173754
|
+
console.error(`[memorix] [UPDATED] Project updated via MCP roots: ${rootPath}`);
|
|
173755
|
+
return;
|
|
173561
173756
|
}
|
|
173562
|
-
|
|
173563
|
-
|
|
173564
|
-
const subGit = findGitInSubdirs2(rootPath);
|
|
173565
|
-
if (subGit) {
|
|
173566
|
-
const switched = await switchProject(subGit);
|
|
173567
|
-
if (switched) {
|
|
173757
|
+
const subGit = findGitInSubdirs2(rootPath);
|
|
173758
|
+
if (subGit && await bridge.memorix.switchProject(subGit, "mcp-roots")) {
|
|
173568
173759
|
console.error(`[memorix] [UPDATED] Project updated via MCP roots (subdir): ${subGit}`);
|
|
173760
|
+
return;
|
|
173569
173761
|
}
|
|
173570
|
-
return;
|
|
173571
173762
|
}
|
|
173763
|
+
} catch (error) {
|
|
173764
|
+
console.error(`[memorix] MCP roots not available (${error instanceof Error ? error.message : "unsupported"})`);
|
|
173572
173765
|
}
|
|
173573
|
-
}
|
|
173574
|
-
|
|
173575
|
-
}
|
|
173576
|
-
};
|
|
173577
|
-
try {
|
|
173578
|
-
const { RootsListChangedNotificationSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
173579
|
-
server.server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
|
|
173580
|
-
console.error(`[memorix] Roots changed \u2014 re-detecting project...`);
|
|
173766
|
+
};
|
|
173767
|
+
bridge.server.setNotificationHandler("notifications/roots/list_changed", async () => {
|
|
173581
173768
|
await tryRootsSwitch();
|
|
173582
173769
|
});
|
|
173583
|
-
|
|
173770
|
+
const deferredInitTimer = setTimeout(() => {
|
|
173771
|
+
bridge.memorix.deferredInit().catch((error) => {
|
|
173772
|
+
console.error(`[memorix] Deferred init error: ${error instanceof Error ? error.message : String(error)}`);
|
|
173773
|
+
});
|
|
173774
|
+
}, 5e3);
|
|
173775
|
+
deferredInitTimer.unref?.();
|
|
173776
|
+
const originalClose = bridge.close.bind(bridge);
|
|
173777
|
+
bridge.close = async () => {
|
|
173778
|
+
clearTimeout(deferredInitTimer);
|
|
173779
|
+
await originalClose();
|
|
173780
|
+
};
|
|
173781
|
+
return bridge;
|
|
173782
|
+
};
|
|
173783
|
+
stdioHandle = serveStdio(createBridge, {
|
|
173784
|
+
transport,
|
|
173785
|
+
legacy: "serve",
|
|
173786
|
+
onerror: (error) => console.error(`[memorix] stdio MCP error: ${error.message}`)
|
|
173787
|
+
});
|
|
173788
|
+
startupGate.markReady();
|
|
173789
|
+
if (stdinEndedBeforeHandle) {
|
|
173790
|
+
void stdioHandle.close().catch((error) => {
|
|
173791
|
+
console.error(`[memorix] stdio close error: ${error instanceof Error ? error.message : String(error)}`);
|
|
173792
|
+
});
|
|
173584
173793
|
}
|
|
173585
|
-
|
|
173586
|
-
|
|
173587
|
-
}, 5e3);
|
|
173588
|
-
deferredInitTimer.unref?.();
|
|
173794
|
+
console.error(`[memorix] MCP Server running on stdio (profile: ${toolProfile}, project: ${detected?.id ?? "deferred"})`);
|
|
173795
|
+
console.error(`[memorix] Project root: ${detected?.rootPath ?? projectRoot}`);
|
|
173589
173796
|
Promise.resolve().then(() => (init_update_checker(), update_checker_exports)).then((m2) => m2.checkForUpdates()).catch(() => {
|
|
173590
173797
|
});
|
|
173591
173798
|
}
|