@mojoaar/opencode-mimir 0.29.1 → 0.29.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.
package/dist/index.js CHANGED
@@ -62,8 +62,12 @@ export default Plugin.define({
62
62
  id: 'mimir',
63
63
  async setup(ctx) {
64
64
  const config = resolveConfig(ctx.options);
65
- if (!config)
65
+ if (!config) {
66
+ // This API has no logger, and an inert plugin is otherwise invisible:
67
+ // the digest, the tools and /mimir-learn simply never appear.
68
+ console.warn('mimir: no url, so no digest, tools or /mimir-learn. Set MIMIR_URL and MIMIR_TOKEN, or add options.url and options.tokenFile to the plugin entry.');
66
69
  return;
70
+ }
67
71
  // A folder without a git remote still needs a stable key, or every write
68
72
  // lands in a fresh project. The server maps absolute paths to `local:<hash>`.
69
73
  const repo = detectRepo(ctx.location.directory) ?? ctx.location.directory;
package/dist/tools.js CHANGED
@@ -10,11 +10,11 @@ export async function registerTools(ctx, config, repo) {
10
10
  if (config.tools === 'auto' && (await servedByMcp(ctx, config.url)))
11
11
  return IDLE;
12
12
  return ctx.tool.transform((editor) => {
13
- editor.add(digestTool(repo));
14
- editor.add(rememberTool(repo));
15
- editor.add(searchTool(repo));
16
- editor.add(readTool(repo));
17
- editor.add(learnTool(repo));
13
+ editor.add(digestTool(repo, config));
14
+ editor.add(rememberTool(repo, config));
15
+ editor.add(searchTool(repo, config));
16
+ editor.add(readTool(repo, config));
17
+ editor.add(learnTool(repo, config));
18
18
  });
19
19
  }
20
20
  const IDLE = { dispose: async () => { } };
@@ -40,7 +40,7 @@ function sameEndpoint(actual, expected) {
40
40
  function strip(value) {
41
41
  return (value ?? '').replace(/\/+$/, '');
42
42
  }
43
- function digestTool(repo) {
43
+ function digestTool(repo, config) {
44
44
  return {
45
45
  name: 'mimir_digest',
46
46
  description: 'Load what this project already knows from Mimir. Call once at the start of a session, before searching for anything.',
@@ -57,7 +57,7 @@ function digestTool(repo) {
57
57
  },
58
58
  async execute(input) {
59
59
  const args = input;
60
- const result = await callTool('memory_digest', { budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined }, { timeoutMs: 5000 });
60
+ const result = await callTool('memory_digest', { budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 5000 });
61
61
  if (!result.ok)
62
62
  return { content: `Mimir is unavailable (${result.error}). Carry on without it.` };
63
63
  const digest = result.result;
@@ -68,7 +68,7 @@ function digestTool(repo) {
68
68
  // A project created from a repo a teammate already knows about splits the
69
69
  // knowledge in two until someone asks the owner for a grant.
70
70
  const NEW_PROJECT = ' Started a new project. If a teammate already uses this repository, request access at /app/requests on your Mimir install.';
71
- function rememberTool(repo) {
71
+ function rememberTool(repo, config) {
72
72
  return {
73
73
  name: 'mimir_remember',
74
74
  description: 'Store one durable fact in Mimir. Use a path like "deploy/rollback" or "auth/token-rotation"; rewriting the same path replaces what was there.',
@@ -97,7 +97,7 @@ function rememberTool(repo) {
97
97
  repo: repo ?? undefined,
98
98
  client: 'opencode',
99
99
  session: context?.sessionID,
100
- }, { timeoutMs: 8000 });
100
+ }, { url: config.url, token: config.token, timeoutMs: 8000 });
101
101
  if (!result.ok)
102
102
  return { content: `Could not store that (${result.error}).` };
103
103
  const written = result.result;
@@ -108,7 +108,7 @@ function rememberTool(repo) {
108
108
  },
109
109
  };
110
110
  }
111
- function searchTool(repo) {
111
+ function searchTool(repo, config) {
112
112
  return {
113
113
  name: 'mimir_search',
114
114
  description: 'Search what this project has already settled in Mimir. Returns paths, titles and summaries; read a path with the MCP server if you need the body.',
@@ -123,7 +123,7 @@ function searchTool(repo) {
123
123
  },
124
124
  async execute(input) {
125
125
  const args = input;
126
- const result = await callTool('memory_search', { query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined }, { timeoutMs: 8000 });
126
+ const result = await callTool('memory_search', { query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 8000 });
127
127
  if (!result.ok)
128
128
  return { content: `Mimir is unavailable (${result.error}). Carry on without it.` };
129
129
  const hits = result.result;
@@ -143,7 +143,7 @@ function renderMemory(memory) {
143
143
  const head = day ? `${memory.path ?? ''} · updated ${day}` : (memory.path ?? '');
144
144
  return `${head}\n# ${memory.title ?? ''}\n\n${memory.body ?? ''}`;
145
145
  }
146
- function readTool(repo) {
146
+ function readTool(repo, config) {
147
147
  return {
148
148
  name: 'mimir_read',
149
149
  description: 'Read one memory in full by its path. Search returns paths and summaries; this is the body behind one.',
@@ -155,14 +155,14 @@ function readTool(repo) {
155
155
  },
156
156
  async execute(input) {
157
157
  const args = input;
158
- const result = await callTool('memory_read', { path: String(args.path ?? ''), repo: repo ?? undefined }, { timeoutMs: 8000 });
158
+ const result = await callTool('memory_read', { path: String(args.path ?? ''), repo: repo ?? undefined }, { url: config.url, token: config.token, timeoutMs: 8000 });
159
159
  if (!result.ok)
160
160
  return { content: 'Nothing is stored at that path.' };
161
161
  return { content: renderMemory(result.result) };
162
162
  },
163
163
  };
164
164
  }
165
- function learnTool(repo) {
165
+ function learnTool(repo, config) {
166
166
  return {
167
167
  name: 'mimir_learn',
168
168
  description: 'Hand the part of this conversation worth keeping to Mimir. The project model writes at most three memories, in the background, so this answers at once.',
@@ -183,7 +183,7 @@ function learnTool(repo) {
183
183
  repo: repo ?? undefined,
184
184
  client: 'opencode',
185
185
  session: context?.sessionID,
186
- }, { timeoutMs: 8000 });
186
+ }, { url: config.url, token: config.token, timeoutMs: 8000 });
187
187
  if (!result.ok)
188
188
  return { content: `Could not hand that over (${result.error}).` };
189
189
  const queued = result.result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojoaar/opencode-mimir",
3
- "version": "0.29.1",
3
+ "version": "0.29.2",
4
4
  "description": "Mimir long-term memory for OpenCode sessions",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/index.ts CHANGED
@@ -66,7 +66,14 @@ export default Plugin.define({
66
66
  id: 'mimir',
67
67
  async setup(ctx) {
68
68
  const config = resolveConfig(ctx.options)
69
- if (!config) return
69
+ if (!config) {
70
+ // This API has no logger, and an inert plugin is otherwise invisible:
71
+ // the digest, the tools and /mimir-learn simply never appear.
72
+ console.warn(
73
+ 'mimir: no url, so no digest, tools or /mimir-learn. Set MIMIR_URL and MIMIR_TOKEN, or add options.url and options.tokenFile to the plugin entry.',
74
+ )
75
+ return
76
+ }
70
77
 
71
78
  // A folder without a git remote still needs a stable key, or every write
72
79
  // lands in a fresh project. The server maps absolute paths to `local:<hash>`.
package/src/tools.ts CHANGED
@@ -36,11 +36,11 @@ export async function registerTools(
36
36
  if (config.tools === 'auto' && (await servedByMcp(ctx, config.url))) return IDLE
37
37
 
38
38
  return ctx.tool.transform((editor) => {
39
- editor.add(digestTool(repo))
40
- editor.add(rememberTool(repo))
41
- editor.add(searchTool(repo))
42
- editor.add(readTool(repo))
43
- editor.add(learnTool(repo))
39
+ editor.add(digestTool(repo, config))
40
+ editor.add(rememberTool(repo, config))
41
+ editor.add(searchTool(repo, config))
42
+ editor.add(readTool(repo, config))
43
+ editor.add(learnTool(repo, config))
44
44
  })
45
45
  }
46
46
 
@@ -70,7 +70,7 @@ function strip(value: string | undefined): string {
70
70
  return (value ?? '').replace(/\/+$/, '')
71
71
  }
72
72
 
73
- function digestTool(repo: string | null): ToolDefinition {
73
+ function digestTool(repo: string | null, config: MimirConfig): ToolDefinition {
74
74
  return {
75
75
  name: 'mimir_digest',
76
76
  description:
@@ -91,7 +91,7 @@ function digestTool(repo: string | null): ToolDefinition {
91
91
  const result = await callTool(
92
92
  'memory_digest',
93
93
  { budget_tokens: Number(args.budget_tokens ?? 800), repo: repo ?? undefined },
94
- { timeoutMs: 5000 },
94
+ { url: config.url, token: config.token, timeoutMs: 5000 },
95
95
  )
96
96
  if (!result.ok) return { content: `Mimir is unavailable (${result.error}). Carry on without it.` }
97
97
  const digest = result.result as { text?: string }
@@ -104,7 +104,7 @@ function digestTool(repo: string | null): ToolDefinition {
104
104
  // knowledge in two until someone asks the owner for a grant.
105
105
  const NEW_PROJECT = ' Started a new project. If a teammate already uses this repository, request access at /app/requests on your Mimir install.'
106
106
 
107
- function rememberTool(repo: string | null): ToolDefinition {
107
+ function rememberTool(repo: string | null, config: MimirConfig): ToolDefinition {
108
108
  return {
109
109
  name: 'mimir_remember',
110
110
  description:
@@ -137,7 +137,7 @@ function rememberTool(repo: string | null): ToolDefinition {
137
137
  client: 'opencode',
138
138
  session: context?.sessionID,
139
139
  },
140
- { timeoutMs: 8000 },
140
+ { url: config.url, token: config.token, timeoutMs: 8000 },
141
141
  )
142
142
  if (!result.ok) return { content: `Could not store that (${result.error}).` }
143
143
  const written = result.result as { path?: string; created?: boolean; projectCreated?: boolean }
@@ -149,7 +149,7 @@ function rememberTool(repo: string | null): ToolDefinition {
149
149
  }
150
150
  }
151
151
 
152
- function searchTool(repo: string | null): ToolDefinition {
152
+ function searchTool(repo: string | null, config: MimirConfig): ToolDefinition {
153
153
  return {
154
154
  name: 'mimir_search',
155
155
  description:
@@ -168,7 +168,7 @@ function searchTool(repo: string | null): ToolDefinition {
168
168
  const result = await callTool(
169
169
  'memory_search',
170
170
  { query: typeof args.query === 'string' ? args.query : '', path_prefix: typeof args.path_prefix === 'string' ? args.path_prefix : undefined, repo: repo ?? undefined },
171
- { timeoutMs: 8000 },
171
+ { url: config.url, token: config.token, timeoutMs: 8000 },
172
172
  )
173
173
  if (!result.ok) return { content: `Mimir is unavailable (${result.error}). Carry on without it.` }
174
174
  const hits = result.result as { path: string; title: string; summary: string | null }[]
@@ -189,7 +189,7 @@ function renderMemory(memory: { path?: string; title?: string; body?: string; up
189
189
  return `${head}\n# ${memory.title ?? ''}\n\n${memory.body ?? ''}`
190
190
  }
191
191
 
192
- function readTool(repo: string | null): ToolDefinition {
192
+ function readTool(repo: string | null, config: MimirConfig): ToolDefinition {
193
193
  return {
194
194
  name: 'mimir_read',
195
195
  description:
@@ -205,7 +205,7 @@ function readTool(repo: string | null): ToolDefinition {
205
205
  const result = await callTool(
206
206
  'memory_read',
207
207
  { path: String(args.path ?? ''), repo: repo ?? undefined },
208
- { timeoutMs: 8000 },
208
+ { url: config.url, token: config.token, timeoutMs: 8000 },
209
209
  )
210
210
  if (!result.ok) return { content: 'Nothing is stored at that path.' }
211
211
  return { content: renderMemory(result.result as { path?: string; title?: string; body?: string; updatedAt?: string }) }
@@ -213,7 +213,7 @@ function readTool(repo: string | null): ToolDefinition {
213
213
  }
214
214
  }
215
215
 
216
- function learnTool(repo: string | null): ToolDefinition {
216
+ function learnTool(repo: string | null, config: MimirConfig): ToolDefinition {
217
217
  return {
218
218
  name: 'mimir_learn',
219
219
  description:
@@ -238,7 +238,7 @@ function learnTool(repo: string | null): ToolDefinition {
238
238
  client: 'opencode',
239
239
  session: context?.sessionID,
240
240
  },
241
- { timeoutMs: 8000 },
241
+ { url: config.url, token: config.token, timeoutMs: 8000 },
242
242
  )
243
243
  if (!result.ok) return { content: `Could not hand that over (${result.error}).` }
244
244
  const queued = result.result as { queued?: boolean; reason?: string; projectCreated?: boolean }