memorix 1.8.0 → 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 (45) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/cli/index.js +407 -130
  3. package/dist/dashboard/static/app.js +37 -23
  4. package/dist/dashboard/static/index.html +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +633 -391
  7. package/dist/maintenance-runner.js +31 -25
  8. package/dist/media-audio-runner.js +31 -25
  9. package/dist/media-video-runner.js +31 -25
  10. package/dist/memcode-runtime/CHANGELOG.md +29 -0
  11. package/dist/sdk.js +625 -390
  12. package/dist/vector-backfill-runner.js +31 -25
  13. package/docs/1.2.0-PROVIDER-QUALITY.md +15 -6
  14. package/docs/1.3.3-MULTIMODAL-MEDIA-AND-MCP-COMPAT.md +7 -6
  15. package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +10 -8
  16. package/docs/API_REFERENCE.md +12 -8
  17. package/docs/ARCHITECTURE.md +3 -1
  18. package/docs/CONFIGURATION.md +2 -2
  19. package/docs/DASHBOARD.md +6 -0
  20. package/docs/DEVELOPMENT.md +2 -2
  21. package/docs/README.md +14 -8
  22. package/package.json +1 -1
  23. package/plugins/antigravity/memorix/plugin.json +2 -1
  24. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  25. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  26. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  27. package/plugins/copilot/memorix/plugin.json +1 -1
  28. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  29. package/plugins/hermes/memorix/plugin.yaml +1 -1
  30. package/plugins/omp/memorix/package.json +1 -1
  31. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  32. package/plugins/pi/memorix/package.json +1 -1
  33. package/server.json +3 -3
  34. package/src/cli/commands/dashboard.ts +1 -1
  35. package/src/cli/commands/serve-http.ts +38 -3
  36. package/src/codegraph/external-provider.ts +299 -19
  37. package/src/config/dotenv-loader.ts +9 -4
  38. package/src/config.ts +16 -16
  39. package/src/dashboard/maintenance.ts +4 -1
  40. package/src/dashboard/server.ts +85 -86
  41. package/src/dashboard/static/index.html +1 -1
  42. package/src/llm/provider.ts +17 -4
  43. package/src/server/mcp-compat.ts +82 -0
  44. package/src/server/mcp-diagnostics.ts +13 -4
  45. package/src/server.ts +9 -6
@@ -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
 
@@ -864,6 +866,8 @@ Important inputs:
864
866
 
865
867
  When using HTTP mode, the main dashboard is usually served from the same port as `serve-http`.
866
868
 
869
+ The Dashboard's Coordination Status page is read-only. It reads the selected project's agents, tasks, locks, handoffs, messages, and poll state from the persistent SQLite `TeamStore`; it does not expose team/task write endpoints or replace task execution and orchestration tools. A coordination read failure is returned as an explicit degraded/error response rather than an empty healthy snapshot.
870
+
867
871
  ---
868
872
 
869
873
  ## 12. Optional Graph Compatibility Tools
@@ -498,7 +498,9 @@ It provides an operational view for:
498
498
  - sessions
499
499
  - retention state
500
500
  - preview-first cleanup, consolidation, intelligent deduplication, and retention archival
501
- - read-only orchestration coordination state in the standalone dashboard and live state in HTTP service mode
501
+ - read-only Coordination Status derived from the project-scoped SQLite `TeamStore`; the page is a projection, not a task execution surface
502
+
503
+ `TeamStore` is the real persistent coordination layer for agents, tasks, messages, locks, handoffs, and poll state. Dashboard coordination reads use that same SQLite state and return an explicit degraded/error status when it cannot be read; they must not substitute a normal-looking empty snapshot.
502
504
 
503
505
  Dashboard maintenance is not a separate business-logic implementation. CLI, MCP, background jobs, and Dashboard routes share the same cleanup, consolidation, deduplication, and retention functions. Mutation routes issue a project-bound signed preview token and reject execution when the candidate set changed after preview.
504
506
 
@@ -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
package/docs/DASHBOARD.md CHANGED
@@ -19,6 +19,12 @@ memorix dashboard
19
19
 
20
20
  Both modes read the same project-scoped stores. The project switcher changes the active project filter; it does not merge projects or grant access to personal memories.
21
21
 
22
+ ## Coordination Status
23
+
24
+ The Coordination Status page is a read-only projection of the selected project's persistent coordination state. `TeamStore` is the canonical SQLite layer for agents, tasks, messages, locks, handoffs, and poll state; the Dashboard does not keep a second in-memory coordination registry.
25
+
26
+ The page reports agents, task status, file locks, and handoffs for the selected project. It exposes no team or task write endpoints and is not a task execution or full orchestration platform. If the SQLite read fails, the API returns an explicit degraded/error status and the page shows that the status is unavailable instead of presenting an empty result as healthy.
27
+
22
28
  ## Maintenance Workbench
23
29
 
24
30
  The Observations page exposes three explicit maintenance actions:
@@ -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.0 release line** and package metadata
17
- is kept at `1.8.0` 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
@@ -33,7 +33,7 @@ The public docs are organized by user intent:
33
33
  | CLI commands and MCP tools | [API_REFERENCE.md](API_REFERENCE.md) |
34
34
  | Memory Autopilot, Code State, and context packs | [API_REFERENCE.md § Memory Autopilot, Code State, and Context Packs](API_REFERENCE.md#memory-autopilot-code-state-and-context-packs), [1.2 Code State](1.2.0-CODE-STATE.md), and [1.2 Workset Retrieval](1.2.0-WORKSET-RETRIEVAL.md) |
35
35
  | Reviewed episodic, semantic, and procedural long-term memory | [1.3 Memory Architecture](1.3-MEMORY-ARCHITECTURE.md) |
36
- | Browse memory and run preview-first local maintenance | [Dashboard](DASHBOARD.md) |
36
+ | Browse memory, maintenance, and read-only Coordination Status | [Dashboard](DASHBOARD.md) |
37
37
  | Reviewable knowledge pages and workflow inheritance | [API_REFERENCE.md § Knowledge Workspace and Workflows](API_REFERENCE.md#knowledge-workspace-and-workflows), [1.2 Knowledge Workspace](1.2.0-KNOWLEDGE-WORKSPACE.md), and [1.2 Workflow Inheritance](1.2.0-WORKFLOW-INHERITANCE.md) |
38
38
  | Git-derived engineering memory | [GIT_MEMORY.md](GIT_MEMORY.md) |
39
39
  | Memory formation and quality pipeline | [MEMORY_FORMATION_PIPELINE.md](MEMORY_FORMATION_PIPELINE.md) |
@@ -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.0**. 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
 
@@ -130,6 +131,9 @@ The current baseline has:
130
131
  - `memorix background start` runs the shared HTTP MCP service and dashboard
131
132
  - Dashboard maintenance is preview-first, project-scoped, and uses the same
132
133
  cleanup and deduplication planners as CLI and MCP
134
+ - Dashboard Coordination Status is read-only and projects the persistent SQLite
135
+ `TeamStore` truth; its task section is `Task Status` and failed reads are
136
+ explicit `error`/`degraded` states
133
137
  - context and CodeGraph commands return bounded task receipts before detailed diagnostics
134
138
  - HTTP MCP sessions have a bounded, explicit lifecycle and fail with a reinitialize hint after expiry
135
139
  - `memorix integrate --agent <agent>` and `memorix hooks install --agent <agent>` remain manual/fallback generation commands
@@ -137,8 +141,10 @@ The current baseline has:
137
141
  - `~/.memorix/config.toml` and project `memorix.toml` are the user-facing configuration model
138
142
  - legacy `memorix.yml`, `.env`, and `config.json` files are still read for compatibility, but new setups should use TOML
139
143
 
140
- For MCP compatibility, 1.8 preserves legacy stateful Streamable HTTP and
141
- supports 2026-07-28 stateless requests with durable project handles. Tasks and
142
- polling are reported as unsupported when the pinned SDK cannot provide a real
143
- durable implementation. Antigravity is the primary setup target; Gemini CLI is
144
- 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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
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.0",
25
+ "version": "1.8.2",
26
26
  "runtimeHint": "npx",
27
27
  "packageArguments": [
28
28
  {
@@ -59,7 +59,7 @@ export default defineCommand({
59
59
  const cliDir = path.dirname(fileURLToPath(import.meta.url));
60
60
  const staticDir = path.join(cliDir, '..', 'dashboard', 'static');
61
61
 
62
- await startDashboard(dataDir, port, staticDir, project.id, project.name, true, undefined, project.rootPath, true);
62
+ await startDashboard(dataDir, port, staticDir, project.id, project.name, true, project.rootPath, true);
63
63
 
64
64
  // Keep alive
65
65
  await new Promise(() => { });
@@ -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;
@@ -889,6 +897,15 @@ export default defineCommand({
889
897
  }
890
898
 
891
899
  if (apiPath === '/team') {
900
+ if (req.method !== 'GET') {
901
+ sendJson({
902
+ status: 'error',
903
+ readOnly: true,
904
+ error: 'Coordination status is read-only',
905
+ errorCode: 'COORDINATION_STATUS_READ_ONLY',
906
+ }, 405);
907
+ return;
908
+ }
892
909
  // Phase 4a: All team state is in SQLite via TeamStore
893
910
  const { projectId: teamProjectId, dataDir: teamDataDir } = await resolveRequestProject(url);
894
911
  const ts = await getTeamStore(teamDataDir);
@@ -967,8 +984,9 @@ export default defineCommand({
967
984
  const openHandoffs = handoffs.filter((handoff: any) => handoff.status !== 'completed').length;
968
985
 
969
986
  sendJson({
987
+ status: 'ok',
970
988
  mode: 'control-plane',
971
- readOnly: false,
989
+ readOnly: true,
972
990
  scope,
973
991
  agents: withTier,
974
992
  // Primary headline number
@@ -1650,6 +1668,23 @@ export default defineCommand({
1650
1668
 
1651
1669
  sendJson({ error: 'Not found' }, 404);
1652
1670
  } catch (err) {
1671
+ if (apiPath === '/team') {
1672
+ const scope = url.searchParams.get('scope') === 'global' ? 'global' : 'project';
1673
+ console.error('[memorix] coordination snapshot unavailable', { status: 'error', scope });
1674
+ sendJson({
1675
+ status: 'error',
1676
+ mode: 'control-plane',
1677
+ readOnly: true,
1678
+ scope,
1679
+ agents: [],
1680
+ locks: [],
1681
+ tasks: [],
1682
+ handoffs: [],
1683
+ error: 'Coordination state unavailable',
1684
+ errorCode: 'COORDINATION_STATE_UNAVAILABLE',
1685
+ }, 503);
1686
+ return;
1687
+ }
1653
1688
  sendJson({ error: err instanceof Error ? err.message : 'Unknown error' }, 500);
1654
1689
  }
1655
1690
  }