memorix 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/TEAM.md +86 -86
  3. package/dist/cli/index.js +211 -69
  4. package/dist/cli/memcode.js +0 -0
  5. package/dist/index.js +211 -69
  6. package/dist/maintenance-runner.js +169 -37
  7. package/dist/media-audio-runner.js +169 -37
  8. package/dist/media-video-runner.js +169 -37
  9. package/dist/memcode-runtime/CHANGELOG.md +14 -0
  10. package/dist/sdk.js +210 -68
  11. package/dist/types.d.ts +2 -0
  12. package/dist/vector-backfill-runner.js +169 -37
  13. package/docs/DESIGN_DECISIONS.md +357 -357
  14. package/package.json +1 -1
  15. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  16. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  17. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  18. package/plugins/copilot/memorix/plugin.json +1 -1
  19. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  20. package/plugins/omp/memorix/package.json +1 -1
  21. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  22. package/plugins/pi/memorix/package.json +1 -1
  23. package/server.json +2 -2
  24. package/src/audit/index.ts +156 -156
  25. package/src/cli/commands/formation.ts +48 -48
  26. package/src/cli/commands/git-hook-install.ts +111 -111
  27. package/src/cli/commands/handoff.ts +54 -54
  28. package/src/cli/commands/hooks-status.ts +63 -63
  29. package/src/cli/commands/ingest.ts +44 -44
  30. package/src/cli/commands/integrate-shared.ts +15 -15
  31. package/src/cli/commands/lock.ts +82 -82
  32. package/src/cli/commands/message.ts +104 -104
  33. package/src/cli/commands/poll.ts +58 -58
  34. package/src/cli/commands/reasoning.ts +118 -118
  35. package/src/cli/commands/skills.ts +114 -114
  36. package/src/cli/commands/task.ts +167 -167
  37. package/src/cli/commands/transfer.ts +47 -47
  38. package/src/cli/index.ts +406 -406
  39. package/src/cli/tui/ChatView.tsx +234 -234
  40. package/src/cli/tui/CommandBar.tsx +312 -312
  41. package/src/cli/tui/ContextRail.tsx +118 -118
  42. package/src/cli/tui/HeaderBar.tsx +72 -72
  43. package/src/cli/tui/LogoBanner.tsx +51 -51
  44. package/src/cli/tui/index.ts +41 -41
  45. package/src/cli/version.ts +7 -7
  46. package/src/cli/workbench.ts +1 -1
  47. package/src/dashboard/project-classification.ts +64 -64
  48. package/src/embedding/api-provider.ts +105 -22
  49. package/src/embedding/provider.ts +2 -0
  50. package/src/git/hooks-path.ts +85 -85
  51. package/src/hooks/pattern-detector.ts +173 -173
  52. package/src/hooks/significance-filter.ts +250 -250
  53. package/src/llm/memory-manager.ts +328 -328
  54. package/src/llm/provider.ts +17 -8
  55. package/src/llm/quality.ts +248 -248
  56. package/src/memory/attribution-guard.ts +249 -249
  57. package/src/memory/disclosure-policy.ts +135 -135
  58. package/src/memory/entity-extractor.ts +197 -197
  59. package/src/memory/formation/evaluate.ts +217 -217
  60. package/src/memory/formation/extract.ts +6 -3
  61. package/src/memory/formation/index.ts +2 -1
  62. package/src/memory/formation/resolve.ts +10 -6
  63. package/src/memory/formation/types.ts +3 -1
  64. package/src/memory/freshness.ts +122 -122
  65. package/src/memory/graph.ts +197 -197
  66. package/src/memory/long-term.ts +7 -1
  67. package/src/memory/refs.ts +94 -94
  68. package/src/memory/secret-filter.ts +79 -79
  69. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  70. package/src/orchestrate/adapters/claude.ts +111 -111
  71. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  72. package/src/orchestrate/adapters/codex.ts +41 -41
  73. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  74. package/src/orchestrate/adapters/gemini.ts +42 -42
  75. package/src/orchestrate/adapters/index.ts +73 -73
  76. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  77. package/src/orchestrate/adapters/opencode.ts +47 -47
  78. package/src/orchestrate/adapters/types.ts +77 -77
  79. package/src/orchestrate/capability-router.ts +284 -284
  80. package/src/orchestrate/cost-tracker.ts +219 -219
  81. package/src/orchestrate/error-recovery.ts +191 -191
  82. package/src/orchestrate/evidence.ts +140 -140
  83. package/src/orchestrate/ledger.ts +110 -110
  84. package/src/orchestrate/memorix-bridge.ts +343 -343
  85. package/src/orchestrate/output-budget.ts +80 -80
  86. package/src/orchestrate/permission.ts +152 -152
  87. package/src/orchestrate/pipeline-trace.ts +131 -131
  88. package/src/orchestrate/prompt-builder.ts +155 -155
  89. package/src/orchestrate/ring-buffer.ts +37 -37
  90. package/src/orchestrate/task-graph.ts +389 -389
  91. package/src/project/aliases.ts +374 -374
  92. package/src/rules/adapters/trae.ts +56 -56
  93. package/src/rules/syncer.ts +235 -235
  94. package/src/search/query-expansion.ts +52 -52
  95. package/src/server/formation-timeout.ts +27 -27
  96. package/src/server.ts +14 -10
  97. package/src/skills/mini-skills.ts +386 -386
  98. package/src/store/chat-store.ts +119 -119
  99. package/src/store/graph-store.ts +249 -249
  100. package/src/store/mini-skill-store.ts +349 -349
  101. package/src/store/orama-store.ts +6 -4
  102. package/src/store/persistence-json.ts +212 -212
  103. package/src/store/persistence.ts +291 -291
  104. package/src/store/project-affinity.ts +195 -195
  105. package/src/team/event-bus.ts +76 -76
  106. package/src/team/handoff.ts +161 -161
  107. package/src/team/poll.ts +132 -132
  108. package/src/timeout.ts +67 -0
  109. package/src/types.ts +2 -0
  110. package/src/workspace/mcp-adapters/codex.ts +191 -191
  111. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  112. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  113. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  114. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  115. package/src/workspace/mcp-adapters/trae.ts +134 -134
  116. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  117. package/src/workspace/sanitizer.ts +60 -60
@@ -1,53 +1,53 @@
1
- import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
-
5
- /**
6
- * Cursor MCP config adapter.
7
- * Format: JSON file at ~/.cursor/mcp.json or .cursor/mcp.json (project-level)
8
- * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }
9
- */
10
- export class CursorMCPAdapter implements MCPConfigAdapter {
11
- readonly source = 'cursor' as const;
12
-
13
- parse(content: string): MCPServerEntry[] {
14
- try {
15
- const config = JSON.parse(content);
16
- const servers = config.mcpServers ?? {};
17
- return Object.entries(servers).map(([name, entry]: [string, any]) => ({
18
- name,
19
- command: entry.command ?? '',
20
- args: entry.args ?? [],
21
- ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),
22
- ...(entry.url ? { url: entry.url } : {}),
23
- }));
24
- } catch {
25
- return [];
26
- }
27
- }
28
-
29
- generate(servers: MCPServerEntry[]): string {
30
- const mcpServers: Record<string, any> = {};
31
- for (const s of servers) {
32
- const entry: Record<string, any> = {};
33
- if (s.url) {
34
- entry.url = s.url;
35
- } else {
36
- entry.command = s.command;
37
- entry.args = s.args;
38
- }
39
- if (s.env && Object.keys(s.env).length > 0) {
40
- entry.env = s.env;
41
- }
42
- mcpServers[s.name] = entry;
43
- }
44
- return JSON.stringify({ mcpServers }, null, 2);
45
- }
46
-
47
- getConfigPath(projectRoot?: string): string {
48
- if (projectRoot) {
49
- return join(projectRoot, '.cursor', 'mcp.json');
50
- }
51
- return join(homedir(), '.cursor', 'mcp.json');
52
- }
53
- }
1
+ import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+
5
+ /**
6
+ * Cursor MCP config adapter.
7
+ * Format: JSON file at ~/.cursor/mcp.json or .cursor/mcp.json (project-level)
8
+ * Structure: { mcpServers: { [name]: { command, args, env?, url? } } }
9
+ */
10
+ export class CursorMCPAdapter implements MCPConfigAdapter {
11
+ readonly source = 'cursor' as const;
12
+
13
+ parse(content: string): MCPServerEntry[] {
14
+ try {
15
+ const config = JSON.parse(content);
16
+ const servers = config.mcpServers ?? {};
17
+ return Object.entries(servers).map(([name, entry]: [string, any]) => ({
18
+ name,
19
+ command: entry.command ?? '',
20
+ args: entry.args ?? [],
21
+ ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),
22
+ ...(entry.url ? { url: entry.url } : {}),
23
+ }));
24
+ } catch {
25
+ return [];
26
+ }
27
+ }
28
+
29
+ generate(servers: MCPServerEntry[]): string {
30
+ const mcpServers: Record<string, any> = {};
31
+ for (const s of servers) {
32
+ const entry: Record<string, any> = {};
33
+ if (s.url) {
34
+ entry.url = s.url;
35
+ } else {
36
+ entry.command = s.command;
37
+ entry.args = s.args;
38
+ }
39
+ if (s.env && Object.keys(s.env).length > 0) {
40
+ entry.env = s.env;
41
+ }
42
+ mcpServers[s.name] = entry;
43
+ }
44
+ return JSON.stringify({ mcpServers }, null, 2);
45
+ }
46
+
47
+ getConfigPath(projectRoot?: string): string {
48
+ if (projectRoot) {
49
+ return join(projectRoot, '.cursor', 'mcp.json');
50
+ }
51
+ return join(homedir(), '.cursor', 'mcp.json');
52
+ }
53
+ }
@@ -1,64 +1,64 @@
1
- import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
-
5
- /**
6
- * Kiro MCP config adapter.
7
- * Format: JSON file at .kiro/settings/mcp.json (project-level)
8
- * or ~/.kiro/settings/mcp.json (user-level)
9
- * Structure: { mcpServers: { ... }, powers?: { mcpServers: { ... } } }
10
- *
11
- * Kiro stores user-added servers in `mcpServers` and power-installed
12
- * servers (context7, figma, postman, supabase etc.) in `powers.mcpServers`.
13
- * Both sections use the same entry format.
14
- *
15
- * Source: Kiro official MCP documentation.
16
- */
17
- export class KiroMCPAdapter implements MCPConfigAdapter {
18
- readonly source = 'kiro' as const;
19
-
20
- parse(content: string): MCPServerEntry[] {
21
- try {
22
- const config = JSON.parse(content);
23
- // Merge top-level mcpServers and powers.mcpServers (dedup by name)
24
- const topLevel = config.mcpServers ?? {};
25
- const powers = config.powers?.mcpServers ?? {};
26
- const merged = { ...powers, ...topLevel };
27
- return Object.entries(merged).map(([name, entry]: [string, any]) => ({
28
- name,
29
- command: entry.command ?? '',
30
- args: entry.args ?? [],
31
- ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),
32
- ...(entry.url ? { url: entry.url } : {}),
33
- ...(entry.disabled === true ? { disabled: true } : {}),
34
- }));
35
- } catch {
36
- return [];
37
- }
38
- }
39
-
40
- generate(servers: MCPServerEntry[]): string {
41
- const mcpServers: Record<string, any> = {};
42
- for (const s of servers) {
43
- const entry: Record<string, any> = {};
44
- if (s.url) {
45
- entry.url = s.url;
46
- } else {
47
- entry.command = s.command;
48
- entry.args = s.args;
49
- }
50
- if (s.env && Object.keys(s.env).length > 0) {
51
- entry.env = s.env;
52
- }
53
- mcpServers[s.name] = entry;
54
- }
55
- return JSON.stringify({ mcpServers }, null, 2);
56
- }
57
-
58
- getConfigPath(projectRoot?: string): string {
59
- if (projectRoot) {
60
- return join(projectRoot, '.kiro', 'settings', 'mcp.json');
61
- }
62
- return join(homedir(), '.kiro', 'settings', 'mcp.json');
63
- }
64
- }
1
+ import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+
5
+ /**
6
+ * Kiro MCP config adapter.
7
+ * Format: JSON file at .kiro/settings/mcp.json (project-level)
8
+ * or ~/.kiro/settings/mcp.json (user-level)
9
+ * Structure: { mcpServers: { ... }, powers?: { mcpServers: { ... } } }
10
+ *
11
+ * Kiro stores user-added servers in `mcpServers` and power-installed
12
+ * servers (context7, figma, postman, supabase etc.) in `powers.mcpServers`.
13
+ * Both sections use the same entry format.
14
+ *
15
+ * Source: Kiro official MCP documentation.
16
+ */
17
+ export class KiroMCPAdapter implements MCPConfigAdapter {
18
+ readonly source = 'kiro' as const;
19
+
20
+ parse(content: string): MCPServerEntry[] {
21
+ try {
22
+ const config = JSON.parse(content);
23
+ // Merge top-level mcpServers and powers.mcpServers (dedup by name)
24
+ const topLevel = config.mcpServers ?? {};
25
+ const powers = config.powers?.mcpServers ?? {};
26
+ const merged = { ...powers, ...topLevel };
27
+ return Object.entries(merged).map(([name, entry]: [string, any]) => ({
28
+ name,
29
+ command: entry.command ?? '',
30
+ args: entry.args ?? [],
31
+ ...(entry.env && Object.keys(entry.env).length > 0 ? { env: entry.env } : {}),
32
+ ...(entry.url ? { url: entry.url } : {}),
33
+ ...(entry.disabled === true ? { disabled: true } : {}),
34
+ }));
35
+ } catch {
36
+ return [];
37
+ }
38
+ }
39
+
40
+ generate(servers: MCPServerEntry[]): string {
41
+ const mcpServers: Record<string, any> = {};
42
+ for (const s of servers) {
43
+ const entry: Record<string, any> = {};
44
+ if (s.url) {
45
+ entry.url = s.url;
46
+ } else {
47
+ entry.command = s.command;
48
+ entry.args = s.args;
49
+ }
50
+ if (s.env && Object.keys(s.env).length > 0) {
51
+ entry.env = s.env;
52
+ }
53
+ mcpServers[s.name] = entry;
54
+ }
55
+ return JSON.stringify({ mcpServers }, null, 2);
56
+ }
57
+
58
+ getConfigPath(projectRoot?: string): string {
59
+ if (projectRoot) {
60
+ return join(projectRoot, '.kiro', 'settings', 'mcp.json');
61
+ }
62
+ return join(homedir(), '.kiro', 'settings', 'mcp.json');
63
+ }
64
+ }
@@ -1,123 +1,123 @@
1
- import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
- import { homedir } from 'node:os';
3
- import { join } from 'node:path';
4
-
5
- /**
6
- * OpenCode MCP Configuration Adapter.
7
- *
8
- * OpenCode uses JSON config files for MCP servers:
9
- * 1. Project-level: opencode.json in project root
10
- * 2. Global: ~/.config/opencode/opencode.json
11
- *
12
- * Format:
13
- * {
14
- * "$schema": "https://opencode.ai/config.json",
15
- * "mcp": {
16
- * "name": {
17
- * "type": "local",
18
- * "command": ["memorix", "serve"],
19
- * "environment": { "KEY": "value" },
20
- * "enabled": true
21
- * }
22
- * }
23
- * }
24
- *
25
- * Remote (HTTP) servers:
26
- * {
27
- * "mcp": {
28
- * "name": {
29
- * "type": "remote",
30
- * "url": "https://...",
31
- * "headers": { "Authorization": "Bearer ..." }
32
- * }
33
- * }
34
- * }
35
- *
36
- * Source: https://opencode.ai/docs/mcp-servers/
37
- */
38
- export class OpenCodeMCPAdapter implements MCPConfigAdapter {
39
- readonly source = 'opencode' as const;
40
-
41
- parse(content: string): MCPServerEntry[] {
42
- try {
43
- const config = JSON.parse(content);
44
- const servers = config.mcp ?? {};
45
- return Object.entries(servers).map(([name, entry]: [string, any]) => {
46
- const result: MCPServerEntry = {
47
- name,
48
- command: '',
49
- args: [],
50
- };
51
-
52
- if (entry.type === 'remote' && entry.url) {
53
- // HTTP transport
54
- result.url = entry.url;
55
- if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {
56
- result.headers = entry.headers;
57
- }
58
- } else {
59
- // Local (stdio) transport — command is an array in OpenCode
60
- if (Array.isArray(entry.command) && entry.command.length > 0) {
61
- result.command = entry.command[0];
62
- result.args = entry.command.slice(1);
63
- } else if (typeof entry.command === 'string') {
64
- result.command = entry.command;
65
- }
66
- }
67
-
68
- // Environment variables (OpenCode uses "environment" not "env")
69
- const env = entry.environment ?? entry.env;
70
- if (env && typeof env === 'object' && Object.keys(env).length > 0) {
71
- result.env = env;
72
- }
73
-
74
- // Disabled flag
75
- if (entry.enabled === false) {
76
- result.disabled = true;
77
- }
78
-
79
- return result;
80
- });
81
- } catch {
82
- return [];
83
- }
84
- }
85
-
86
- generate(servers: MCPServerEntry[]): string {
87
- const mcp: Record<string, any> = {};
88
- for (const s of servers) {
89
- const entry: Record<string, any> = {};
90
-
91
- if (s.url) {
92
- // HTTP transport
93
- entry.type = 'remote';
94
- entry.url = s.url;
95
- if (s.headers && Object.keys(s.headers).length > 0) {
96
- entry.headers = s.headers;
97
- }
98
- } else {
99
- // stdio transport — OpenCode uses command as array
100
- entry.type = 'local';
101
- entry.command = [s.command, ...s.args];
102
- }
103
-
104
- if (s.env && Object.keys(s.env).length > 0) {
105
- entry.environment = s.env;
106
- }
107
-
108
- if (s.disabled === true) {
109
- entry.enabled = false;
110
- }
111
-
112
- mcp[s.name] = entry;
113
- }
114
- return JSON.stringify({ $schema: 'https://opencode.ai/config.json', mcp }, null, 2);
115
- }
116
-
117
- getConfigPath(projectRoot?: string): string {
118
- if (projectRoot) {
119
- return join(projectRoot, 'opencode.json');
120
- }
121
- return join(homedir(), '.config', 'opencode', 'opencode.json');
122
- }
123
- }
1
+ import type { MCPConfigAdapter, MCPServerEntry } from '../../types.js';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+
5
+ /**
6
+ * OpenCode MCP Configuration Adapter.
7
+ *
8
+ * OpenCode uses JSON config files for MCP servers:
9
+ * 1. Project-level: opencode.json in project root
10
+ * 2. Global: ~/.config/opencode/opencode.json
11
+ *
12
+ * Format:
13
+ * {
14
+ * "$schema": "https://opencode.ai/config.json",
15
+ * "mcp": {
16
+ * "name": {
17
+ * "type": "local",
18
+ * "command": ["memorix", "serve"],
19
+ * "environment": { "KEY": "value" },
20
+ * "enabled": true
21
+ * }
22
+ * }
23
+ * }
24
+ *
25
+ * Remote (HTTP) servers:
26
+ * {
27
+ * "mcp": {
28
+ * "name": {
29
+ * "type": "remote",
30
+ * "url": "https://...",
31
+ * "headers": { "Authorization": "Bearer ..." }
32
+ * }
33
+ * }
34
+ * }
35
+ *
36
+ * Source: https://opencode.ai/docs/mcp-servers/
37
+ */
38
+ export class OpenCodeMCPAdapter implements MCPConfigAdapter {
39
+ readonly source = 'opencode' as const;
40
+
41
+ parse(content: string): MCPServerEntry[] {
42
+ try {
43
+ const config = JSON.parse(content);
44
+ const servers = config.mcp ?? {};
45
+ return Object.entries(servers).map(([name, entry]: [string, any]) => {
46
+ const result: MCPServerEntry = {
47
+ name,
48
+ command: '',
49
+ args: [],
50
+ };
51
+
52
+ if (entry.type === 'remote' && entry.url) {
53
+ // HTTP transport
54
+ result.url = entry.url;
55
+ if (entry.headers && typeof entry.headers === 'object' && Object.keys(entry.headers).length > 0) {
56
+ result.headers = entry.headers;
57
+ }
58
+ } else {
59
+ // Local (stdio) transport — command is an array in OpenCode
60
+ if (Array.isArray(entry.command) && entry.command.length > 0) {
61
+ result.command = entry.command[0];
62
+ result.args = entry.command.slice(1);
63
+ } else if (typeof entry.command === 'string') {
64
+ result.command = entry.command;
65
+ }
66
+ }
67
+
68
+ // Environment variables (OpenCode uses "environment" not "env")
69
+ const env = entry.environment ?? entry.env;
70
+ if (env && typeof env === 'object' && Object.keys(env).length > 0) {
71
+ result.env = env;
72
+ }
73
+
74
+ // Disabled flag
75
+ if (entry.enabled === false) {
76
+ result.disabled = true;
77
+ }
78
+
79
+ return result;
80
+ });
81
+ } catch {
82
+ return [];
83
+ }
84
+ }
85
+
86
+ generate(servers: MCPServerEntry[]): string {
87
+ const mcp: Record<string, any> = {};
88
+ for (const s of servers) {
89
+ const entry: Record<string, any> = {};
90
+
91
+ if (s.url) {
92
+ // HTTP transport
93
+ entry.type = 'remote';
94
+ entry.url = s.url;
95
+ if (s.headers && Object.keys(s.headers).length > 0) {
96
+ entry.headers = s.headers;
97
+ }
98
+ } else {
99
+ // stdio transport — OpenCode uses command as array
100
+ entry.type = 'local';
101
+ entry.command = [s.command, ...s.args];
102
+ }
103
+
104
+ if (s.env && Object.keys(s.env).length > 0) {
105
+ entry.environment = s.env;
106
+ }
107
+
108
+ if (s.disabled === true) {
109
+ entry.enabled = false;
110
+ }
111
+
112
+ mcp[s.name] = entry;
113
+ }
114
+ return JSON.stringify({ $schema: 'https://opencode.ai/config.json', mcp }, null, 2);
115
+ }
116
+
117
+ getConfigPath(projectRoot?: string): string {
118
+ if (projectRoot) {
119
+ return join(projectRoot, 'opencode.json');
120
+ }
121
+ return join(homedir(), '.config', 'opencode', 'opencode.json');
122
+ }
123
+ }