memorix 1.8.1 → 1.8.2

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cli/index.js +326 -52
  3. package/dist/index.js +581 -315
  4. package/dist/maintenance-runner.js +31 -25
  5. package/dist/media-audio-runner.js +31 -25
  6. package/dist/media-video-runner.js +31 -25
  7. package/dist/memcode-runtime/CHANGELOG.md +20 -0
  8. package/dist/sdk.js +573 -314
  9. package/dist/vector-backfill-runner.js +31 -25
  10. package/docs/1.2.0-PROVIDER-QUALITY.md +15 -6
  11. package/docs/1.3.3-MULTIMODAL-MEDIA-AND-MCP-COMPAT.md +7 -6
  12. package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +10 -8
  13. package/docs/API_REFERENCE.md +10 -8
  14. package/docs/CONFIGURATION.md +2 -2
  15. package/docs/DEVELOPMENT.md +2 -2
  16. package/docs/README.md +10 -7
  17. package/package.json +1 -1
  18. package/plugins/antigravity/memorix/plugin.json +2 -1
  19. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  20. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  21. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  22. package/plugins/copilot/memorix/plugin.json +1 -1
  23. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  24. package/plugins/hermes/memorix/plugin.yaml +1 -1
  25. package/plugins/omp/memorix/package.json +1 -1
  26. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  27. package/plugins/pi/memorix/package.json +1 -1
  28. package/server.json +3 -3
  29. package/src/cli/commands/serve-http.ts +10 -2
  30. package/src/codegraph/external-provider.ts +299 -19
  31. package/src/config/dotenv-loader.ts +9 -4
  32. package/src/config.ts +16 -16
  33. package/src/dashboard/maintenance.ts +4 -1
  34. package/src/llm/provider.ts +17 -4
  35. package/src/server/mcp-compat.ts +82 -0
  36. package/src/server/mcp-diagnostics.ts +13 -4
  37. package/src/server.ts +5 -2
@@ -104,8 +104,10 @@ function loadEnvFile(filePath) {
104
104
  loadedEnvFiles.push(filePath);
105
105
  }
106
106
  function loadDotenv(projectRoot, options = {}) {
107
- if (dotenvLoaded && dotenvProjectRoot === (projectRoot ?? null)) return;
108
- if (dotenvLoaded && dotenvProjectRoot !== (projectRoot ?? null)) {
107
+ const userHomeDir = options.userHomeDir ?? homedir();
108
+ const normalizedProjectRoot = projectRoot ?? null;
109
+ if (dotenvLoaded && dotenvProjectRoot === normalizedProjectRoot && dotenvHomeDir === userHomeDir) return;
110
+ if (dotenvLoaded && (dotenvProjectRoot !== normalizedProjectRoot || dotenvHomeDir !== userHomeDir)) {
109
111
  resetDotenv();
110
112
  }
111
113
  loadedEnvFiles.length = 0;
@@ -114,9 +116,10 @@ function loadDotenv(projectRoot, options = {}) {
114
116
  if (projectRoot) {
115
117
  loadEnvFile(getProjectDotenvPath(projectRoot));
116
118
  }
117
- loadEnvFile(getGlobalDotenvPath(options.userHomeDir ?? homedir()));
119
+ loadEnvFile(getGlobalDotenvPath(userHomeDir));
118
120
  dotenvLoaded = true;
119
- dotenvProjectRoot = projectRoot ?? null;
121
+ dotenvProjectRoot = normalizedProjectRoot;
122
+ dotenvHomeDir = userHomeDir;
120
123
  }
121
124
  function resetDotenv() {
122
125
  for (const key of injectedKeys) {
@@ -125,13 +128,14 @@ function resetDotenv() {
125
128
  injectedKeys.clear();
126
129
  dotenvLoaded = false;
127
130
  dotenvProjectRoot = null;
131
+ dotenvHomeDir = null;
128
132
  loadedEnvFiles.length = 0;
129
133
  loadedEnvKeys.clear();
130
134
  }
131
135
  function getLoadedEnvFiles() {
132
136
  return loadedEnvFiles;
133
137
  }
134
- var dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
138
+ var dotenvLoaded, dotenvProjectRoot, dotenvHomeDir, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
135
139
  var init_dotenv_loader = __esm({
136
140
  "src/config/dotenv-loader.ts"() {
137
141
  "use strict";
@@ -139,6 +143,7 @@ var init_dotenv_loader = __esm({
139
143
  init_config_paths();
140
144
  dotenvLoaded = false;
141
145
  dotenvProjectRoot = null;
146
+ dotenvHomeDir = null;
142
147
  loadedEnvFiles = [];
143
148
  loadedEnvKeys = /* @__PURE__ */ new Set();
144
149
  loadedEnvValues = /* @__PURE__ */ new Map();
@@ -2372,33 +2377,33 @@ __export(config_exports, {
2372
2377
  resetConfigCache: () => resetConfigCache,
2373
2378
  resetDotenv: () => resetDotenv
2374
2379
  });
2375
- function getLLMApiKey() {
2376
- return getResolvedMemoryLane().llm.apiKey;
2380
+ function getLLMApiKey(options = {}) {
2381
+ return getResolvedMemoryLane(options).llm.apiKey;
2377
2382
  }
2378
- function getLLMProvider() {
2379
- const provider2 = getResolvedMemoryLane().llm.provider;
2383
+ function getLLMProvider(options = {}) {
2384
+ const provider2 = getResolvedMemoryLane(options).llm.provider;
2380
2385
  if (provider2) return provider2;
2381
2386
  if (process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) return "anthropic";
2382
2387
  if (process.env.OPENROUTER_API_KEY && !process.env.OPENAI_API_KEY) return "openrouter";
2383
2388
  return "openai";
2384
2389
  }
2385
- function getLLMModel(providerDefault) {
2386
- return getResolvedMemoryLane().llm.model || providerDefault;
2390
+ function getLLMModel(providerDefault, options = {}) {
2391
+ return getResolvedMemoryLane(options).llm.model || providerDefault;
2387
2392
  }
2388
- function getLLMBaseUrl(providerDefault) {
2389
- return getResolvedMemoryLane().llm.baseUrl || providerDefault;
2393
+ function getLLMBaseUrl(providerDefault, options = {}) {
2394
+ return getResolvedMemoryLane(options).llm.baseUrl || providerDefault;
2390
2395
  }
2391
- function getAgentLLMApiKey() {
2392
- return getResolvedAgentLane().apiKey;
2396
+ function getAgentLLMApiKey(options = {}) {
2397
+ return getResolvedAgentLane(options).apiKey;
2393
2398
  }
2394
- function getAgentLLMProvider() {
2395
- return getResolvedAgentLane().provider || getLLMProvider();
2399
+ function getAgentLLMProvider(options = {}) {
2400
+ return getResolvedAgentLane(options).provider || getLLMProvider(options);
2396
2401
  }
2397
- function getAgentLLMModel(providerDefault) {
2398
- return getResolvedAgentLane().model || getLLMModel(providerDefault);
2402
+ function getAgentLLMModel(providerDefault, options = {}) {
2403
+ return getResolvedAgentLane(options).model || getLLMModel(providerDefault, options);
2399
2404
  }
2400
- function getAgentLLMBaseUrl(providerDefault) {
2401
- return getResolvedAgentLane().baseUrl || getLLMBaseUrl(providerDefault);
2405
+ function getAgentLLMBaseUrl(providerDefault, options = {}) {
2406
+ return getResolvedAgentLane(options).baseUrl || getLLMBaseUrl(providerDefault, options);
2402
2407
  }
2403
2408
  function getEmbeddingMode() {
2404
2409
  const provider2 = getResolvedEmbeddingLane().provider?.toLowerCase()?.trim();
@@ -4657,18 +4662,19 @@ async function* callLLMWithToolsStream(messages, tools) {
4657
4662
  }
4658
4663
  function initLLM(options = {}) {
4659
4664
  const scope = options.scope ?? "memory";
4660
- const apiKey = scope === "agent" ? getAgentLLMApiKey() : getLLMApiKey();
4665
+ const configOptions = { projectRoot: options.projectRoot, homeDir: options.homeDir };
4666
+ const apiKey = scope === "agent" ? getAgentLLMApiKey(configOptions) : getLLMApiKey(configOptions);
4661
4667
  if (!apiKey) {
4662
4668
  currentConfig = null;
4663
4669
  return null;
4664
4670
  }
4665
- const provider2 = scope === "agent" ? getAgentLLMProvider() : getLLMProvider();
4671
+ const provider2 = scope === "agent" ? getAgentLLMProvider(configOptions) : getLLMProvider(configOptions);
4666
4672
  const defaults2 = PROVIDER_DEFAULTS[provider2] ?? PROVIDER_DEFAULTS.openai;
4667
4673
  currentConfig = {
4668
4674
  provider: provider2,
4669
4675
  apiKey,
4670
- model: scope === "agent" ? getAgentLLMModel(defaults2.model) : getLLMModel(defaults2.model),
4671
- baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl) : getLLMBaseUrl(defaults2.baseUrl)
4676
+ model: scope === "agent" ? getAgentLLMModel(defaults2.model, configOptions) : getLLMModel(defaults2.model, configOptions),
4677
+ baseUrl: scope === "agent" ? getAgentLLMBaseUrl(defaults2.baseUrl, configOptions) : getLLMBaseUrl(defaults2.baseUrl, configOptions)
4672
4678
  };
4673
4679
  return currentConfig;
4674
4680
  }
@@ -58,8 +58,9 @@ Memorix only considers the external provider when all of these are true:
58
58
  root;
59
59
  4. the index has no reported pending changes or worktree mismatch;
60
60
  5. the bounded command completes before its configured timeout; and
61
- 6. the returned JSON passes Memorix's schema, path, count, and output-size
62
- validation.
61
+ 6. the returned context JSON, or the official v1.5.0 `explore` output after a
62
+ context-command failure, passes Memorix's schema, path, relation, count,
63
+ and output-size validation.
63
64
 
64
65
  Memorix never runs `codegraph init`, `index`, or `sync` on the user's behalf.
65
66
  It does not transmit the repository to a remote service. Its default request is
@@ -90,7 +91,7 @@ external_context = "auto"
90
91
  # external_command = "C:\\tools\\codegraph.cmd"
91
92
 
92
93
  # A bounded local query. Values outside the safe range are clamped.
93
- external_timeout_ms = 1200
94
+ external_timeout_ms = 3000
94
95
  ~~~
95
96
 
96
97
  The equivalent YAML keys are `externalContext`, `externalCommand`, and
@@ -114,12 +115,19 @@ The status is visible through `memorix codegraph status --json`, `memorix
114
115
  doctor --json`, and Project Context JSON. Prompt output keeps it compact: it
115
116
  adds semantic start points only when a valid external outline is available, and
116
117
  adds one caution when a requested external outline was not safe to use.
118
+ An external status of `ready` means only that the index is initialized and
119
+ current; it does not prove that the installed CLI exposes `context`. The task
120
+ diagnostics therefore record `context` and `explore` independently.
117
121
 
118
122
  ## Validation and Fallback
119
123
 
120
124
  The external adapter executes without a shell, pins the working directory to
121
- the actual project root, uses a bounded timeout and stdout limit, and accepts
122
- JSON only. It rejects a result when:
125
+ the actual project root, uses a bounded timeout and stdout limit, and tries
126
+ `context` first. CodeGraph v1.5.0 does not register that command, so a failed
127
+ or invalid context result triggers the official `explore --path <root>
128
+ --max-files 4 <task>` command. JSON context output and the stable explore
129
+ outline/relationship markers are accepted only after the same strict path and
130
+ relation validation. It rejects a result when:
123
131
 
124
132
  - the status belongs to another project root;
125
133
  - the index is uninitialized, has pending changes, or reports a worktree
@@ -145,7 +153,8 @@ runner. It verifies:
145
153
  3. Stale, mismatched, malformed, timed-out, and oversized external output
146
154
  safely falls back to Lite.
147
155
  4. Raw code blocks and credentials do not enter the default Workset.
148
- 5. `codegraph status` and `doctor` identify the active/fallback provider.
156
+ 5. `codegraph status` and `doctor` identify the active/fallback provider, and
157
+ distinguish a healthy index from a usable task-query command.
149
158
 
150
159
  The optional real smoke can be run on a Windows project that already has an
151
160
  indexed CodeGraph installation:
@@ -158,15 +158,16 @@ layer, not Memorix product identity.
158
158
  - Product operations receive a resolved project/workspace binding and explicit
159
159
  actor metadata; they do not read an HTTP session map directly.
160
160
  - The old `Mcp-Session-Id` map remains isolated in `serve-http` as a legacy
161
- adapter until the current SDK has a stable released implementation of the
162
- 2026-07-28 protocol.
161
+ adapter. A low-level `server/discover` adapter now covers the required
162
+ 2026-07-28 discovery result without upgrading the pinned v1 SDK.
163
163
  - Asset IDs, media job IDs, project IDs, and attachment targets are explicit
164
164
  durable identifiers. They are never inferred from a live MCP connection.
165
165
  - New media tools work through stdio, legacy streamable HTTP, and direct CLI
166
166
  invocation with identical project binding behavior.
167
- - No release depends on an unreleased MCP SDK 2.x alpha. The current server
168
- remains compatible with existing Codex, Claude Code, OpenCode, and other
169
- configured clients.
167
+ - No release depends on the MCP TypeScript SDK v2. The current server remains
168
+ compatible with existing legacy clients and supports versionless list/call
169
+ through the v1 SDK's legacy envelopes. The adapter does not claim modern
170
+ result caching, Tasks, subscriptions, or complete 2026 conformance.
170
171
 
171
172
  ## Non-goals
172
173
 
@@ -177,7 +178,7 @@ layer, not Memorix product identity.
177
178
  - No automatic audio/video transcription, frame extraction, or arbitrary media
178
179
  understanding in 1.3.3. The asset model makes those future derivations safe.
179
180
  - No forced migration to a protocol version that the published MCP TypeScript
180
- SDK does not yet support.
181
+ SDK does not yet support; discovery is a narrow compatibility adapter.
181
182
  - No additional swarm of low-level MCP tools; CLI is the complete management
182
183
  surface and MCP exposes only small agent-facing operations.
183
184
 
@@ -17,14 +17,16 @@ Status: accepted implementation contract for Memorix 1.8.0.
17
17
 
18
18
  ## Compatibility Contract
19
19
 
20
- The MCP 2026-07-28 protocol is the external stateless request contract.
21
- Memorix also accepts the legacy stateful Streamable HTTP contract with
22
- `Mcp-Session-Id`. Stateless requests carry an explicit `Mcp-Project-Handle`
23
- that is persisted in SQLite and survives service restart; the handle, rather
24
- than a transport session id, owns project routing. The pinned SDK's accepted
25
- wire version is normalized internally at the HTTP boundary, while responses
26
- continue to advertise current protocol metadata. Unsupported Tasks/polling is
27
- reported by capability diagnostics rather than simulated.
20
+ Memorix preserves the legacy 2025-era initialize contract, including stdio and
21
+ stateful Streamable HTTP with `Mcp-Session-Id`. Memorix 1.8.2 also registers a
22
+ low-level `server/discover` compatibility adapter for the 2026-07-28 request.
23
+ Its `DiscoverResult` is complete for the required identity, versions,
24
+ capabilities, and private zero-TTL cache hint. Versionless `tools/list` and
25
+ `tools/call` are accepted by the pinned v1 SDK and retain its legacy result
26
+ envelopes. HTTP stateless project handles remain a compatibility adapter: they
27
+ own project routing, but do not turn the v1 SDK into a complete 2026 runtime.
28
+ Tasks, subscriptions, and list-response caching are unsupported and are not
29
+ advertised or simulated.
28
30
 
29
31
  Antigravity is the primary setup target. Gemini CLI remains a compatibility and
30
32
  migration path. GitHub issue #204 (WorkBuddy) is intentionally not merged or
@@ -150,14 +150,16 @@ feedback projection.
150
150
  ### HTTP MCP Compatibility
151
151
 
152
152
  Legacy clients use stateful Streamable HTTP with `Mcp-Session-Id`. Current
153
- stateless clients send `Mcp-Protocol-Version: 2026-07-28` and receive a durable
154
- `Mcp-Project-Handle`. Send that handle on subsequent requests; it is persisted
155
- in SQLite and remains valid across service restart until its TTL expires.
156
- `/protocol-diagnostics` reports the current/legacy contract and explicitly
157
- reports Tasks and polling as unsupported when the pinned SDK cannot provide a
158
- durable implementation. When MCP discovery is unavailable, use one bounded
159
- `memorix context --fallback` request for a task; repeated fallback probing is
160
- rejected by the local budget.
153
+ Legacy clients use the 2025-era `initialize` handshake and stateful
154
+ `Mcp-Session-Id`. The stdio server also accepts the 2026-07-28
155
+ `server/discover` request before `initialize` and returns the required
156
+ `DiscoverResult`. Versionless `tools/list` and `tools/call` use the pinned
157
+ SDK's legacy result envelopes. HTTP stateless clients may use a durable
158
+ `Mcp-Project-Handle`; `/protocol-diagnostics` labels this as compatibility-only.
159
+ Modern result metadata is discovery-only with a private zero-TTL hint. Tasks,
160
+ subscriptions, and list-response caching are unsupported. When MCP discovery
161
+ is unavailable, use one bounded `memorix context --fallback` request for a
162
+ task; repeated fallback probing is rejected by the local budget.
161
163
 
162
164
  The built-in Lite provider indexes common code files with lightweight file, symbol, and import facts. It is a structural fallback, not a language-server-quality graph. When a project already has a healthy local CodeGraph index, `[codegraph].external_context = "auto"` may add a validated, bounded semantic outline to the Workset. Memorix never initializes, syncs, or exports that external index, and never stores its raw source output. `memorix codegraph status --json`, `memorix doctor --json`, and Project Context JSON identify the actual provider quality.
163
165
 
@@ -74,7 +74,7 @@ max_file_bytes = 2097152
74
74
  # Optional: use an already-indexed local CodeGraph only when it is healthy.
75
75
  external_context = "auto"
76
76
  # external_command = "C:\\tools\\codegraph.cmd"
77
- external_timeout_ms = 1200
77
+ external_timeout_ms = 3000
78
78
 
79
79
  [server]
80
80
  transport = "stdio"
@@ -334,7 +334,7 @@ Common keys:
334
334
  - `max_file_bytes = 2097152` (2 MiB per source file by default)
335
335
  - `external_context = "auto"` (`"off"` keeps the built-in Lite provider only)
336
336
  - `external_command = "C:\\tools\\codegraph.cmd"` (optional path when CodeGraph is not on `PATH`)
337
- - `external_timeout_ms = 1200` (bounded local semantic-query timeout)
337
+ - `external_timeout_ms = 3000` (bounded local semantic-query timeout; values are clamped to 5 seconds)
338
338
 
339
339
  Legacy YAML uses `codegraph.excludePatterns`, `codegraph.maxFileBytes`,
340
340
  `codegraph.externalContext`, `codegraph.externalCommand`, and
@@ -13,8 +13,8 @@ Memorix is a TypeScript project built around:
13
13
 
14
14
  ## Current Development Baseline
15
15
 
16
- The current release work targets the **1.8.1 release line** and package metadata
17
- is kept at `1.8.1` for this release commit.
16
+ The current release work targets the **1.8.2 release line** and package metadata
17
+ is kept at `1.8.2` for this release commit.
18
18
 
19
19
  Contributors should assume the following areas are part of the current release line:
20
20
 
package/docs/README.md CHANGED
@@ -63,6 +63,7 @@ The public docs are organized by user intent:
63
63
  | Topic | Document |
64
64
  | --- | --- |
65
65
  | MCP / CLI commands | [API_REFERENCE.md](API_REFERENCE.md) |
66
+ | MCP protocol discovery and compatibility boundaries | [API_REFERENCE.md](API_REFERENCE.md), [1.3.3 MCP Compatibility](1.3.3-MULTIMODAL-MEDIA-AND-MCP-COMPAT.md), and [1.8.0 Release Specification](1.8.0-RELEASE-CANDIDATE-SPEC.md) |
66
67
  | Plugin, rules, hooks, skills, and MCP support matrix | [INTEGRATIONS.md](INTEGRATIONS.md) |
67
68
  | TypeScript SDK | [../README.md#sdk](../README.md#sdk) |
68
69
  | Workspace and rules sync | [API_REFERENCE.md § Workspace and Rules](API_REFERENCE.md#8-workspace-and-rules-tools) |
@@ -93,7 +94,7 @@ The public docs are organized by user intent:
93
94
  | 1.2 honest Lite and optional semantic CodeGraph provider contract | [1.2 Provider Quality](1.2.0-PROVIDER-QUALITY.md) |
94
95
  | 1.3 long-term memory model, source boundary, and lifecycle | [1.3 Memory Architecture](1.3-MEMORY-ARCHITECTURE.md) |
95
96
  | Active context-control work | [1.2.2 Memory Control Plane](1.2.2-MEMORY-CONTROL-PLANE.md) |
96
- | 1.8 context-control acceptance contract | [1.8.0 Release Specification](1.8.0-RELEASE-CANDIDATE-SPEC.md) |
97
+ | 1.8.2 context-control and compatibility acceptance contract | [1.8.0 Release Specification](1.8.0-RELEASE-CANDIDATE-SPEC.md) |
97
98
  | Historical cloud sync and multi-agent research | [CLOUD_SYNC_AND_MULTI_AGENT_RESEARCH.md](CLOUD_SYNC_AND_MULTI_AGENT_RESEARCH.md) |
98
99
  | Known issues and old roadmap notes | [KNOWN_ISSUES_AND_ROADMAP.md](KNOWN_ISSUES_AND_ROADMAP.md) |
99
100
 
@@ -121,7 +122,7 @@ Historical/deep-reference documents may describe older designs. If they conflict
121
122
 
122
123
  ## Current Product Line
123
124
 
124
- The current product line is **1.8.1**. The authoritative acceptance contract is
125
+ The current product line is **1.8.2**. The authoritative acceptance contract is
125
126
  [1.8.0 Release Specification](1.8.0-RELEASE-CANDIDATE-SPEC.md).
126
127
  The current baseline has:
127
128
 
@@ -140,8 +141,10 @@ The current baseline has:
140
141
  - `~/.memorix/config.toml` and project `memorix.toml` are the user-facing configuration model
141
142
  - legacy `memorix.yml`, `.env`, and `config.json` files are still read for compatibility, but new setups should use TOML
142
143
 
143
- For MCP compatibility, 1.8 preserves legacy stateful Streamable HTTP and
144
- supports 2026-07-28 stateless requests with durable project handles. Tasks and
145
- polling are reported as unsupported when the pinned SDK cannot provide a real
146
- durable implementation. Antigravity is the primary setup target; Gemini CLI is
147
- the compatibility path. See the release specification for the exact contract.
144
+ For MCP compatibility, 1.8.2 preserves legacy 2025-era initialize and
145
+ stateful Streamable HTTP behavior, and adds a tested 2026-07-28
146
+ `server/discover` adapter. Versionless `tools/list` and `tools/call` continue
147
+ through the SDK's legacy result envelopes. Modern result metadata is limited to
148
+ the discovery response (`ttlMs: 0`, private cache scope); Tasks, subscriptions,
149
+ and list-response caching are unsupported. Stateless HTTP project handles are
150
+ a compatibility adapter, not a claim of complete 2026 conformance.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "memorix",
3
3
  "mcpName": "io.github.AVIDS2/memorix",
4
- "version": "1.8.1",
4
+ "version": "1.8.2",
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,
@@ -1,3 +1,4 @@
1
1
  {
2
- "name": "memorix"
2
+ "name": "memorix",
3
+ "version": "1.8.2"
3
4
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "memorix",
4
- "version": "1.8.1",
4
+ "version": "1.8.2",
5
5
  "description": "Shared workspace memory for Claude Code and other AI coding agents.",
6
6
  "author": {
7
7
  "name": "AVIDS2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Local-first project memory for CodeBuddy Code and other coding agents.",
5
5
  "author": {
6
6
  "name": "AVIDS2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Shared workspace memory for Codex and other AI coding agents.",
5
5
  "author": {
6
6
  "name": "AVIDS2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Shared local workspace memory for GitHub Copilot CLI and other AI coding agents.",
5
5
  "author": {
6
6
  "name": "AVIDS2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "mcpServers": {
5
5
  "memorix": {
6
6
  "command": "memorix",
@@ -1,5 +1,5 @@
1
1
  name: memorix
2
- version: "1.1.1"
2
+ version: "1.8.2"
3
3
  description: Shared workspace memory bridge for Hermes Agent.
4
4
  author: AVIDS2
5
5
  license: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix-omp-package",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Memorix shared workspace memory package for Oh-my-Pi.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Shared workspace memory for OpenClaw and other AI coding agents.",
5
5
  "author": {
6
6
  "name": "AVIDS2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memorix-pi-package",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Memorix shared workspace memory package for Pi coding agent.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
package/server.json CHANGED
@@ -2,12 +2,12 @@
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.AVIDS2/memorix",
4
4
  "title": "Memorix",
5
- "description": "Local-first persistent project memory for AI coding agents across MCP clients and sessions.",
5
+ "description": "Local-first project memory with legacy MCP and 2026 discovery compatibility.",
6
6
  "repository": {
7
7
  "url": "https://github.com/AVIDS2/memorix",
8
8
  "source": "github"
9
9
  },
10
- "version": "1.8.1",
10
+ "version": "1.8.2",
11
11
  "websiteUrl": "https://github.com/AVIDS2/memorix#readme",
12
12
  "icons": [
13
13
  {
@@ -22,7 +22,7 @@
22
22
  {
23
23
  "registryType": "npm",
24
24
  "identifier": "memorix",
25
- "version": "1.8.1",
25
+ "version": "1.8.2",
26
26
  "runtimeHint": "npx",
27
27
  "packageArguments": [
28
28
  {
@@ -40,6 +40,12 @@ export const EXPIRED_SESSION_TTL_MS = 10 * 60 * 1000;
40
40
  /** Pinned SDK protocol accepted internally while the HTTP boundary speaks the current stateless contract. */
41
41
  export const MCP_SDK_COMPAT_PROTOCOL_VERSION = '2025-11-25';
42
42
 
43
+ /** Modern discovery is allowed before a durable project handle exists. */
44
+ export function isServerDiscoverRequest(body: unknown): boolean {
45
+ return Boolean(body && typeof body === 'object' && !Array.isArray(body)
46
+ && (body as { method?: unknown }).method === 'server/discover');
47
+ }
48
+
43
49
  export function parseSessionTimeoutMs(raw: string | undefined): number {
44
50
  const value = raw?.trim();
45
51
  if (!value) return DEFAULT_SESSION_TIMEOUT_MS;
@@ -427,7 +433,7 @@ export default defineCommand({
427
433
  ? req.headers['mcp-project-root']
428
434
  : undefined;
429
435
  const root = persisted?.projectRoot ?? requestedRoot ?? projectRoot;
430
- if (!persisted && !isInitializeRequest(body)) {
436
+ if (!persisted && !isInitializeRequest(body) && !isServerDiscoverRequest(body)) {
431
437
  res.writeHead(400, { 'Content-Type': 'application/json' });
432
438
  res.end(JSON.stringify({ jsonrpc: '2.0', error: { code: -32000, message: 'Stateless MCP requests require Mcp-Project-Handle; initialize first.' }, id: null }));
433
439
  return;
@@ -505,7 +511,9 @@ export default defineCommand({
505
511
 
506
512
  const requestedProtocol = req.headers['mcp-protocol-version'];
507
513
  const statelessRequested = req.headers['mcp-stateless'] === 'true'
508
- || requestedProtocol === CURRENT_MCP_PROTOCOL_VERSION;
514
+ || requestedProtocol === CURRENT_MCP_PROTOCOL_VERSION
515
+ || typeof req.headers['mcp-project-handle'] === 'string'
516
+ || isServerDiscoverRequest(body);
509
517
  if (!sessionId && statelessRequested) {
510
518
  await handleStatelessPost(req, res, body);
511
519
  return;