memorix 1.4.6 → 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 (119) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/TEAM.md +86 -86
  3. package/dist/cli/index.js +225 -70
  4. package/dist/cli/memcode.js +0 -0
  5. package/dist/index.js +225 -70
  6. package/dist/maintenance-runner.js +183 -38
  7. package/dist/media-audio-runner.js +183 -38
  8. package/dist/media-video-runner.js +183 -38
  9. package/dist/memcode-runtime/CHANGELOG.md +38 -0
  10. package/dist/sdk.js +224 -69
  11. package/dist/types.d.ts +2 -0
  12. package/dist/vector-backfill-runner.js +183 -38
  13. package/docs/CONFIGURATION.md +12 -0
  14. package/docs/DESIGN_DECISIONS.md +357 -357
  15. package/package.json +1 -1
  16. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  17. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  18. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  19. package/plugins/copilot/memorix/plugin.json +1 -1
  20. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  21. package/plugins/omp/memorix/package.json +1 -1
  22. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  23. package/plugins/pi/memorix/package.json +1 -1
  24. package/server.json +2 -2
  25. package/src/audit/index.ts +156 -156
  26. package/src/cli/commands/formation.ts +48 -48
  27. package/src/cli/commands/git-hook-install.ts +111 -111
  28. package/src/cli/commands/handoff.ts +54 -54
  29. package/src/cli/commands/hooks-status.ts +63 -63
  30. package/src/cli/commands/ingest.ts +44 -44
  31. package/src/cli/commands/integrate-shared.ts +15 -15
  32. package/src/cli/commands/lock.ts +82 -82
  33. package/src/cli/commands/message.ts +104 -104
  34. package/src/cli/commands/poll.ts +58 -58
  35. package/src/cli/commands/reasoning.ts +118 -118
  36. package/src/cli/commands/skills.ts +114 -114
  37. package/src/cli/commands/task.ts +167 -167
  38. package/src/cli/commands/transfer.ts +47 -47
  39. package/src/cli/index.ts +406 -406
  40. package/src/cli/tui/ChatView.tsx +234 -234
  41. package/src/cli/tui/CommandBar.tsx +312 -312
  42. package/src/cli/tui/ContextRail.tsx +118 -118
  43. package/src/cli/tui/HeaderBar.tsx +72 -72
  44. package/src/cli/tui/LogoBanner.tsx +51 -51
  45. package/src/cli/tui/index.ts +41 -41
  46. package/src/cli/version.ts +7 -7
  47. package/src/cli/workbench.ts +1 -1
  48. package/src/config.ts +23 -2
  49. package/src/dashboard/project-classification.ts +64 -64
  50. package/src/embedding/api-provider.ts +105 -22
  51. package/src/embedding/provider.ts +2 -0
  52. package/src/git/hooks-path.ts +85 -85
  53. package/src/hooks/pattern-detector.ts +173 -173
  54. package/src/hooks/significance-filter.ts +250 -250
  55. package/src/llm/memory-manager.ts +328 -328
  56. package/src/llm/provider.ts +17 -8
  57. package/src/llm/quality.ts +248 -248
  58. package/src/memory/attribution-guard.ts +249 -249
  59. package/src/memory/disclosure-policy.ts +135 -135
  60. package/src/memory/entity-extractor.ts +197 -197
  61. package/src/memory/formation/evaluate.ts +217 -217
  62. package/src/memory/formation/extract.ts +6 -3
  63. package/src/memory/formation/index.ts +2 -1
  64. package/src/memory/formation/resolve.ts +10 -6
  65. package/src/memory/formation/types.ts +3 -1
  66. package/src/memory/freshness.ts +122 -122
  67. package/src/memory/graph.ts +197 -197
  68. package/src/memory/long-term.ts +7 -1
  69. package/src/memory/refs.ts +94 -94
  70. package/src/memory/secret-filter.ts +79 -79
  71. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  72. package/src/orchestrate/adapters/claude.ts +111 -111
  73. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  74. package/src/orchestrate/adapters/codex.ts +41 -41
  75. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  76. package/src/orchestrate/adapters/gemini.ts +42 -42
  77. package/src/orchestrate/adapters/index.ts +73 -73
  78. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  79. package/src/orchestrate/adapters/opencode.ts +47 -47
  80. package/src/orchestrate/adapters/types.ts +77 -77
  81. package/src/orchestrate/capability-router.ts +284 -284
  82. package/src/orchestrate/cost-tracker.ts +219 -219
  83. package/src/orchestrate/error-recovery.ts +191 -191
  84. package/src/orchestrate/evidence.ts +140 -140
  85. package/src/orchestrate/ledger.ts +110 -110
  86. package/src/orchestrate/memorix-bridge.ts +343 -343
  87. package/src/orchestrate/output-budget.ts +80 -80
  88. package/src/orchestrate/permission.ts +152 -152
  89. package/src/orchestrate/pipeline-trace.ts +131 -131
  90. package/src/orchestrate/prompt-builder.ts +155 -155
  91. package/src/orchestrate/ring-buffer.ts +37 -37
  92. package/src/orchestrate/task-graph.ts +389 -389
  93. package/src/project/aliases.ts +374 -374
  94. package/src/rules/adapters/trae.ts +56 -56
  95. package/src/rules/syncer.ts +235 -235
  96. package/src/search/query-expansion.ts +52 -52
  97. package/src/server/formation-timeout.ts +27 -27
  98. package/src/server.ts +14 -10
  99. package/src/skills/mini-skills.ts +386 -386
  100. package/src/store/chat-store.ts +119 -119
  101. package/src/store/graph-store.ts +249 -249
  102. package/src/store/mini-skill-store.ts +349 -349
  103. package/src/store/orama-store.ts +6 -4
  104. package/src/store/persistence-json.ts +212 -212
  105. package/src/store/persistence.ts +291 -291
  106. package/src/store/project-affinity.ts +195 -195
  107. package/src/team/event-bus.ts +76 -76
  108. package/src/team/handoff.ts +161 -161
  109. package/src/team/poll.ts +132 -132
  110. package/src/timeout.ts +67 -0
  111. package/src/types.ts +2 -0
  112. package/src/workspace/mcp-adapters/codex.ts +191 -191
  113. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  114. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  115. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  116. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  117. package/src/workspace/mcp-adapters/trae.ts +134 -134
  118. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  119. 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
+ }