@momomemory/opencode-momo 0.1.2 → 0.1.5
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/README.md +34 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +279 -112
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +623 -91
- package/dist/services/jsonc.d.ts +5 -4
- package/dist/services/jsonc.d.ts.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -115,6 +115,14 @@ The `momo` tool supports 6 operational modes:
|
|
|
115
115
|
- **list**: List recent memories for a given scope.
|
|
116
116
|
- **forget**: Remove a specific memory by its ID.
|
|
117
117
|
|
|
118
|
+
### Ingestion Tools (RAG Pipeline)
|
|
119
|
+
For richer ingestion than plain `read`, the plugin also exposes dedicated tools that route through Momo's document pipeline:
|
|
120
|
+
- **momo_ingest**: Ingest text, URLs, or local files into documents + retrieval index, with optional memory extraction.
|
|
121
|
+
- **momo_ocr**: Ingest image files, run OCR, and optionally extract memories from recognized text.
|
|
122
|
+
- **momo_transcribe**: Ingest audio/video files, run transcription, and optionally extract memories.
|
|
123
|
+
|
|
124
|
+
These tools are especially useful with non-vision models: image/audio content is converted into searchable text in Momo.
|
|
125
|
+
|
|
118
126
|
### Codebase Indexing
|
|
119
127
|
The `/momo-init` command provides a structured workflow for agents to explore a new codebase and store its architecture, conventions, and key facts into project memory.
|
|
120
128
|
|
|
@@ -138,6 +146,14 @@ Momo supports the `<private>` tag. Any content wrapped in `<private>` tags is au
|
|
|
138
146
|
**Scopes**: `user` (cross-project), `project` (current project, default)
|
|
139
147
|
**Memory Types**: `fact`, `preference`, `episode`
|
|
140
148
|
|
|
149
|
+
### Ingestion Tool Arguments (high-level)
|
|
150
|
+
|
|
151
|
+
| Tool | Required Args | Optional Args |
|
|
152
|
+
|------|--------------|---------------|
|
|
153
|
+
| `momo_ingest` | `input` | `inputType`, `scope`, `extractMemories`, `metadataJson`, `contentType`, `wait`, `timeoutMs`, `pollIntervalMs` |
|
|
154
|
+
| `momo_ocr` | `filePath` | `scope`, `extractMemories`, `contentType`, `wait`, `timeoutMs`, `pollIntervalMs` |
|
|
155
|
+
| `momo_transcribe` | `filePath` | `scope`, `extractMemories`, `contentType`, `wait`, `timeoutMs`, `pollIntervalMs` |
|
|
156
|
+
|
|
141
157
|
## Memory Scoping
|
|
142
158
|
|
|
143
159
|
Memories are isolated using container tags derived from your environment:
|
|
@@ -156,10 +172,27 @@ Configuration is stored in `~/.config/opencode/momo.jsonc`:
|
|
|
156
172
|
// Momo server URL
|
|
157
173
|
"baseUrl": "http://localhost:3000",
|
|
158
174
|
// API key for authentication
|
|
159
|
-
"apiKey": "your-key-here"
|
|
175
|
+
"apiKey": "your-key-here",
|
|
176
|
+
// Optional override for user memory container tag
|
|
177
|
+
"containerTagUser": "",
|
|
178
|
+
// Optional override for project memory container tag
|
|
179
|
+
"containerTagProject": ""
|
|
160
180
|
}
|
|
161
181
|
```
|
|
162
182
|
|
|
183
|
+
### Project-local config (optional)
|
|
184
|
+
|
|
185
|
+
You can also place config in your project root as `.momo.jsonc` (preferred) or `momo.jsonc`.
|
|
186
|
+
This is useful when you want a stable `containerTagProject` for a specific repo.
|
|
187
|
+
|
|
188
|
+
### Config precedence
|
|
189
|
+
|
|
190
|
+
Highest to lowest precedence:
|
|
191
|
+
1. Environment variables (`MOMO_*`)
|
|
192
|
+
2. Project-local config (`.momo.jsonc` / `momo.jsonc`)
|
|
193
|
+
3. Global config (`~/.config/opencode/momo.jsonc`)
|
|
194
|
+
4. Built-in defaults
|
|
195
|
+
|
|
163
196
|
### Environment Variables
|
|
164
197
|
|
|
165
198
|
The following variables can be used to override configuration:
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA2IA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA+CjE;AA0ID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG;IACpD,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAWA;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,IAAI,CAwDN"}
|
package/dist/cli.js
CHANGED
|
@@ -11,89 +11,107 @@ import {
|
|
|
11
11
|
} from "node:fs";
|
|
12
12
|
import { join as join2 } from "node:path";
|
|
13
13
|
import { createInterface } from "node:readline";
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// node_modules/@momomemory/sdk/dist/plugin-config.js
|
|
15
|
+
import { homedir, hostname } from "node:os";
|
|
16
16
|
import { join } from "node:path";
|
|
17
|
-
|
|
17
|
+
var OPENCLAW_DEFAULTS = {
|
|
18
|
+
baseUrl: "http://localhost:3000",
|
|
19
|
+
containerTag: `oclw_${hostname()}`,
|
|
20
|
+
perAgentMemory: false,
|
|
21
|
+
autoRecall: true,
|
|
22
|
+
autoCapture: true,
|
|
23
|
+
maxRecallResults: 10,
|
|
24
|
+
profileFrequency: 50,
|
|
25
|
+
captureMode: "all",
|
|
26
|
+
debug: false
|
|
27
|
+
};
|
|
28
|
+
var OPENCODE_CONFIG_DIR = join(homedir(), ".config", "opencode");
|
|
29
|
+
var PI_DEFAULTS = {
|
|
30
|
+
baseUrl: "http://localhost:3000",
|
|
31
|
+
containerTag: `pi_${hostname()}`,
|
|
32
|
+
autoRecall: true,
|
|
33
|
+
autoCapture: true,
|
|
34
|
+
maxRecallResults: 10,
|
|
35
|
+
profileFrequency: 50,
|
|
36
|
+
debug: false
|
|
37
|
+
};
|
|
38
|
+
// src/config.ts
|
|
39
|
+
function getConfigDir() {
|
|
40
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
41
|
+
if (xdg) {
|
|
42
|
+
return `${xdg}/opencode`;
|
|
43
|
+
}
|
|
44
|
+
return `${process.env.HOME}/.config/opencode`;
|
|
45
|
+
}
|
|
18
46
|
|
|
19
47
|
// src/services/jsonc.ts
|
|
20
|
-
function stripJsoncComments(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
function stripJsoncComments(input) {
|
|
49
|
+
var Mode;
|
|
50
|
+
((Mode2) => {
|
|
51
|
+
Mode2[Mode2["Code"] = 0] = "Code";
|
|
52
|
+
Mode2[Mode2["String"] = 1] = "String";
|
|
53
|
+
Mode2[Mode2["LineComment"] = 2] = "LineComment";
|
|
54
|
+
Mode2[Mode2["BlockComment"] = 3] = "BlockComment";
|
|
55
|
+
})(Mode ||= {});
|
|
56
|
+
const out = [];
|
|
57
|
+
let mode = 0 /* Code */;
|
|
58
|
+
for (let i = 0;i < input.length; i++) {
|
|
59
|
+
const ch = input[i];
|
|
60
|
+
const next = input[i + 1];
|
|
61
|
+
if (mode === 1 /* String */) {
|
|
62
|
+
out.push(ch);
|
|
63
|
+
if (ch === "\\") {
|
|
64
|
+
if (next !== undefined) {
|
|
65
|
+
out.push(next);
|
|
66
|
+
i++;
|
|
39
67
|
}
|
|
40
|
-
result += char;
|
|
41
|
-
i++;
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (inString) {
|
|
46
|
-
result += char;
|
|
47
|
-
i++;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (!inSingleLineComment && !inMultiLineComment) {
|
|
51
|
-
if (char === "/" && nextChar === "/") {
|
|
52
|
-
inSingleLineComment = true;
|
|
53
|
-
i += 2;
|
|
54
68
|
continue;
|
|
55
69
|
}
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
i += 2;
|
|
59
|
-
continue;
|
|
70
|
+
if (ch === '"') {
|
|
71
|
+
mode = 0 /* Code */;
|
|
60
72
|
}
|
|
73
|
+
continue;
|
|
61
74
|
}
|
|
62
|
-
if (
|
|
63
|
-
if (
|
|
75
|
+
if (mode === 2 /* LineComment */) {
|
|
76
|
+
if (ch === `
|
|
64
77
|
`) {
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
mode = 0 /* Code */;
|
|
79
|
+
out.push(`
|
|
80
|
+
`);
|
|
67
81
|
}
|
|
68
|
-
i++;
|
|
69
82
|
continue;
|
|
70
83
|
}
|
|
71
|
-
if (
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
i
|
|
84
|
+
if (mode === 3 /* BlockComment */) {
|
|
85
|
+
if (ch === "*" && next === "/") {
|
|
86
|
+
mode = 0 /* Code */;
|
|
87
|
+
i++;
|
|
75
88
|
continue;
|
|
76
89
|
}
|
|
77
|
-
if (
|
|
90
|
+
if (ch === `
|
|
78
91
|
`) {
|
|
79
|
-
|
|
92
|
+
out.push(`
|
|
93
|
+
`);
|
|
80
94
|
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (ch === '"') {
|
|
98
|
+
mode = 1 /* String */;
|
|
99
|
+
out.push(ch);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (ch === "/" && next === "/") {
|
|
103
|
+
mode = 2 /* LineComment */;
|
|
81
104
|
i++;
|
|
82
105
|
continue;
|
|
83
106
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// src/config.ts
|
|
91
|
-
function getConfigDir() {
|
|
92
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
93
|
-
if (xdg) {
|
|
94
|
-
return join(xdg, "opencode");
|
|
107
|
+
if (ch === "/" && next === "*") {
|
|
108
|
+
mode = 3 /* BlockComment */;
|
|
109
|
+
i++;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
out.push(ch);
|
|
95
113
|
}
|
|
96
|
-
return join(
|
|
114
|
+
return out.join("").replace(/,\s*([}\]])/g, "$1");
|
|
97
115
|
}
|
|
98
116
|
|
|
99
117
|
// src/cli.ts
|
|
@@ -157,8 +175,10 @@ bunx @momomemory/opencode-momo configure
|
|
|
157
175
|
\`\`\`
|
|
158
176
|
|
|
159
177
|
Or set environment variables:
|
|
160
|
-
- \`
|
|
161
|
-
- \`
|
|
178
|
+
- \`MOMO_OPENCODE_BASE_URL\` - Momo server URL (default: http://localhost:3000)
|
|
179
|
+
- \`MOMO_OPENCODE_API_KEY\` - API key for authentication
|
|
180
|
+
- \`MOMO_OPENCODE_CONTAINER_TAG_USER\` - Optional user container tag override
|
|
181
|
+
- \`MOMO_OPENCODE_CONTAINER_TAG_PROJECT\` - Optional project container tag override
|
|
162
182
|
|
|
163
183
|
After configuration, restart OpenCode to activate.
|
|
164
184
|
`;
|
|
@@ -206,53 +226,186 @@ async function promptInput(question, defaultValue) {
|
|
|
206
226
|
}
|
|
207
227
|
function registerPluginInConfig(configDir) {
|
|
208
228
|
const configPath = join2(configDir, "opencode.jsonc");
|
|
209
|
-
if (existsSync(configPath)) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
if (content.includes('"plugin"')) {
|
|
215
|
-
const newContent = content.replace(/("plugin"\s*:\s*\[)([^\]]*?)(\])/, (_match, start, middle, end) => {
|
|
216
|
-
const trimmed = middle.trim();
|
|
217
|
-
if (trimmed === "") {
|
|
218
|
-
return `${start}
|
|
229
|
+
if (!existsSync(configPath)) {
|
|
230
|
+
mkdirSync(configDir, { recursive: true });
|
|
231
|
+
const newConfig = `{
|
|
232
|
+
"plugin": [
|
|
219
233
|
"${PLUGIN_NAME}"
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
writeFileSync(configPath, newConfig, "utf-8");
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
const content = readFileSync(configPath, "utf-8");
|
|
241
|
+
if (content.includes(PLUGIN_NAME)) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const pluginArrayStart = findPluginArrayStart(content);
|
|
245
|
+
if (pluginArrayStart !== -1) {
|
|
246
|
+
const pluginArrayEnd = findMatchingBracket(content, pluginArrayStart);
|
|
247
|
+
if (pluginArrayEnd !== -1) {
|
|
248
|
+
const before = content.slice(0, pluginArrayStart + 1);
|
|
249
|
+
const middle = content.slice(pluginArrayStart + 1, pluginArrayEnd);
|
|
250
|
+
const after = content.slice(pluginArrayEnd);
|
|
251
|
+
const middleTrimmed = middle.trim();
|
|
252
|
+
const appended = middleTrimmed.length === 0 ? `
|
|
253
|
+
"${PLUGIN_NAME}"
|
|
254
|
+
` : `${middle.replace(/\s*$/, "")},
|
|
223
255
|
"${PLUGIN_NAME}"
|
|
224
|
-
|
|
225
|
-
});
|
|
226
|
-
writeFileSync(configPath, newContent, "utf-8");
|
|
256
|
+
`;
|
|
257
|
+
writeFileSync(configPath, `${before}${appended}${after}`, "utf-8");
|
|
227
258
|
return true;
|
|
228
259
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
]
|
|
234
|
-
}`);
|
|
235
|
-
writeFileSync(configPath, insertContent, "utf-8");
|
|
236
|
-
} else {
|
|
237
|
-
const withComma = content.replace(/(\S)\s*\}\s*$/, `$1,
|
|
260
|
+
}
|
|
261
|
+
const rootClose = findRootObjectClose(content);
|
|
262
|
+
if (rootClose === -1) {
|
|
263
|
+
const rebuilt = `{
|
|
238
264
|
"plugin": [
|
|
239
265
|
"${PLUGIN_NAME}"
|
|
240
266
|
]
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
267
|
+
}
|
|
268
|
+
`;
|
|
269
|
+
writeFileSync(configPath, rebuilt, "utf-8");
|
|
244
270
|
return true;
|
|
245
271
|
}
|
|
246
|
-
|
|
247
|
-
const
|
|
272
|
+
const head = content.slice(0, rootClose).replace(/\s*$/, "");
|
|
273
|
+
const needsComma = !head.endsWith("{") && !head.endsWith(",");
|
|
274
|
+
const insertion = `${needsComma ? "," : ""}
|
|
248
275
|
"plugin": [
|
|
249
276
|
"${PLUGIN_NAME}"
|
|
250
277
|
]
|
|
251
|
-
}
|
|
252
278
|
`;
|
|
253
|
-
|
|
279
|
+
const tail = content.slice(rootClose);
|
|
280
|
+
writeFileSync(configPath, `${head}${insertion}${tail}`, "utf-8");
|
|
254
281
|
return true;
|
|
255
282
|
}
|
|
283
|
+
function findPluginArrayStart(content) {
|
|
284
|
+
const keyMatch = /"plugin"\s*:/.exec(content);
|
|
285
|
+
if (!keyMatch)
|
|
286
|
+
return -1;
|
|
287
|
+
const start = keyMatch.index + keyMatch[0].length;
|
|
288
|
+
for (let i = start;i < content.length; i++) {
|
|
289
|
+
const ch = content[i];
|
|
290
|
+
if (!ch || /\s/.test(ch))
|
|
291
|
+
continue;
|
|
292
|
+
return ch === "[" ? i : -1;
|
|
293
|
+
}
|
|
294
|
+
return -1;
|
|
295
|
+
}
|
|
296
|
+
function findMatchingBracket(content, openIndex) {
|
|
297
|
+
let depth = 0;
|
|
298
|
+
let inString = false;
|
|
299
|
+
let inLineComment = false;
|
|
300
|
+
let inBlockComment = false;
|
|
301
|
+
for (let i = openIndex;i < content.length; i++) {
|
|
302
|
+
const ch = content[i];
|
|
303
|
+
const next = content[i + 1];
|
|
304
|
+
if (inLineComment) {
|
|
305
|
+
if (ch === `
|
|
306
|
+
`)
|
|
307
|
+
inLineComment = false;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (inBlockComment) {
|
|
311
|
+
if (ch === "*" && next === "/") {
|
|
312
|
+
inBlockComment = false;
|
|
313
|
+
i++;
|
|
314
|
+
}
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (inString) {
|
|
318
|
+
if (ch === "\\") {
|
|
319
|
+
i++;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (ch === '"')
|
|
323
|
+
inString = false;
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
if (ch === '"') {
|
|
327
|
+
inString = true;
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (ch === "/" && next === "/") {
|
|
331
|
+
inLineComment = true;
|
|
332
|
+
i++;
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
if (ch === "/" && next === "*") {
|
|
336
|
+
inBlockComment = true;
|
|
337
|
+
i++;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (ch === "[") {
|
|
341
|
+
depth++;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (ch === "]") {
|
|
345
|
+
depth--;
|
|
346
|
+
if (depth === 0)
|
|
347
|
+
return i;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return -1;
|
|
351
|
+
}
|
|
352
|
+
function findRootObjectClose(content) {
|
|
353
|
+
let depth = 0;
|
|
354
|
+
let inString = false;
|
|
355
|
+
let inLineComment = false;
|
|
356
|
+
let inBlockComment = false;
|
|
357
|
+
let rootClose = -1;
|
|
358
|
+
for (let i = 0;i < content.length; i++) {
|
|
359
|
+
const ch = content[i];
|
|
360
|
+
const next = content[i + 1];
|
|
361
|
+
if (inLineComment) {
|
|
362
|
+
if (ch === `
|
|
363
|
+
`)
|
|
364
|
+
inLineComment = false;
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
if (inBlockComment) {
|
|
368
|
+
if (ch === "*" && next === "/") {
|
|
369
|
+
inBlockComment = false;
|
|
370
|
+
i++;
|
|
371
|
+
}
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (inString) {
|
|
375
|
+
if (ch === "\\") {
|
|
376
|
+
i++;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (ch === '"')
|
|
380
|
+
inString = false;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (ch === '"') {
|
|
384
|
+
inString = true;
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
if (ch === "/" && next === "/") {
|
|
388
|
+
inLineComment = true;
|
|
389
|
+
i++;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
if (ch === "/" && next === "*") {
|
|
393
|
+
inBlockComment = true;
|
|
394
|
+
i++;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (ch === "{") {
|
|
398
|
+
depth++;
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (ch === "}") {
|
|
402
|
+
depth--;
|
|
403
|
+
if (depth === 0)
|
|
404
|
+
rootClose = i;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return rootClose;
|
|
408
|
+
}
|
|
256
409
|
function writeCommandFiles(configDir) {
|
|
257
410
|
const commandDir = join2(configDir, "command");
|
|
258
411
|
mkdirSync(commandDir, { recursive: true });
|
|
@@ -275,10 +428,11 @@ function writeMomoConfig(configDir, options) {
|
|
|
275
428
|
existing = {};
|
|
276
429
|
}
|
|
277
430
|
}
|
|
278
|
-
const
|
|
279
|
-
const
|
|
280
|
-
const
|
|
281
|
-
const
|
|
431
|
+
const existingOpenCode = existing.opencode && typeof existing.opencode === "object" && !Array.isArray(existing.opencode) ? existing.opencode : {};
|
|
432
|
+
const priorBaseUrl = typeof existingOpenCode.baseUrl === "string" ? existingOpenCode.baseUrl : undefined;
|
|
433
|
+
const priorApiKey = typeof existingOpenCode.apiKey === "string" ? existingOpenCode.apiKey : undefined;
|
|
434
|
+
const priorContainerTagUser = typeof existingOpenCode.containerTagUser === "string" ? existingOpenCode.containerTagUser : undefined;
|
|
435
|
+
const priorContainerTagProject = typeof existingOpenCode.containerTagProject === "string" ? existingOpenCode.containerTagProject : undefined;
|
|
282
436
|
const config = {
|
|
283
437
|
baseUrl: options.baseUrl ?? priorBaseUrl ?? "http://localhost:3000",
|
|
284
438
|
apiKey: options.apiKey ?? priorApiKey ?? "",
|
|
@@ -286,14 +440,19 @@ function writeMomoConfig(configDir, options) {
|
|
|
286
440
|
containerTagProject: priorContainerTagProject ?? ""
|
|
287
441
|
};
|
|
288
442
|
const lines = ["{"];
|
|
289
|
-
lines.push(" //
|
|
290
|
-
lines.push(
|
|
291
|
-
lines.push("
|
|
292
|
-
lines.push(`
|
|
293
|
-
lines.push("
|
|
294
|
-
lines.push(`
|
|
295
|
-
lines.push("
|
|
296
|
-
lines.push(`
|
|
443
|
+
lines.push(" // OpenCode plugin config for Momo");
|
|
444
|
+
lines.push(' "opencode": {');
|
|
445
|
+
lines.push(" // Momo server URL (default: http://localhost:3000)");
|
|
446
|
+
lines.push(` "baseUrl": ${JSON.stringify(config.baseUrl)},`);
|
|
447
|
+
lines.push(" // API key for authentication (leave empty if your server has auth disabled)");
|
|
448
|
+
lines.push(` "apiKey": ${JSON.stringify(config.apiKey)},`);
|
|
449
|
+
lines.push(" // Optional override for user memory container tag (default: auto-derived from username)");
|
|
450
|
+
lines.push(` "containerTagUser": ${JSON.stringify(config.containerTagUser)},`);
|
|
451
|
+
lines.push(" // Optional override for project memory container tag (default: auto-derived from project directory)");
|
|
452
|
+
lines.push(` "containerTagProject": ${JSON.stringify(config.containerTagProject)}`);
|
|
453
|
+
lines.push(" }");
|
|
454
|
+
lines.push(" // Note: project-local config file (.momo.jsonc) overrides this global file,");
|
|
455
|
+
lines.push(" // and MOMO_OPENCODE_* environment variables override both.");
|
|
297
456
|
lines.push("}");
|
|
298
457
|
lines.push("");
|
|
299
458
|
writeFileSync(configPath, lines.join(`
|
|
@@ -331,6 +490,14 @@ async function runInstall(flags) {
|
|
|
331
490
|
writeCommandFiles(configDir);
|
|
332
491
|
console.log(` ✓ Created ${join2(configDir, "command", "momo-init.md")}`);
|
|
333
492
|
console.log(` ✓ Created ${join2(configDir, "command", "momo-configure.md")}`);
|
|
493
|
+
const momoConfigPath = join2(configDir, "momo.jsonc");
|
|
494
|
+
const hadMomoConfig = existsSync(momoConfigPath);
|
|
495
|
+
writeMomoConfig(configDir, {});
|
|
496
|
+
if (hadMomoConfig) {
|
|
497
|
+
console.log(` ✓ Updated ${momoConfigPath}`);
|
|
498
|
+
} else {
|
|
499
|
+
console.log(` ✓ Created ${momoConfigPath}`);
|
|
500
|
+
}
|
|
334
501
|
console.log(`
|
|
335
502
|
✅ Installation complete!
|
|
336
503
|
|
|
@@ -339,8 +506,8 @@ Next steps:
|
|
|
339
506
|
$ opencode-momo configure --base-url http://localhost:3000 --api-key YOUR_KEY
|
|
340
507
|
|
|
341
508
|
Or set environment variables:
|
|
342
|
-
$ export
|
|
343
|
-
$ export
|
|
509
|
+
$ export MOMO_OPENCODE_API_KEY=your-key
|
|
510
|
+
$ export MOMO_OPENCODE_BASE_URL=http://localhost:3000
|
|
344
511
|
|
|
345
512
|
2. Restart OpenCode to activate the plugin.
|
|
346
513
|
|
|
@@ -375,7 +542,7 @@ async function runConfigure(flags) {
|
|
|
375
542
|
Restart OpenCode to apply changes.`);
|
|
376
543
|
}
|
|
377
544
|
function printHelp() {
|
|
378
|
-
console.log(`opencode-momo v0.1.
|
|
545
|
+
console.log(`opencode-momo v0.1.3
|
|
379
546
|
|
|
380
547
|
OpenCode plugin that gives coding agents persistent memory using Momo.
|
|
381
548
|
|
package/dist/config.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { type ResolvedOpenCodePluginConfig } from "@momomemory/sdk";
|
|
2
|
+
export type { ResolvedOpenCodePluginConfig };
|
|
3
|
+
export type MomoConfig = ResolvedOpenCodePluginConfig & {
|
|
3
4
|
baseUrl: string;
|
|
4
|
-
|
|
5
|
-
containerTagProject?: string;
|
|
6
|
-
}
|
|
5
|
+
};
|
|
7
6
|
export declare function getConfigDir(): string;
|
|
8
|
-
export declare function loadConfig(): MomoConfig;
|
|
9
|
-
export declare function isConfigured(): boolean;
|
|
7
|
+
export declare function loadConfig(directory?: string): MomoConfig;
|
|
8
|
+
export declare function isConfigured(directory?: string): boolean;
|
|
10
9
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE9F,YAAY,EAAE,4BAA4B,EAAE,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG,4BAA4B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAMzD;AAED,wBAAgB,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAGxD"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAuG/D,eAAO,MAAM,UAAU,EAAE,MAqpBxB,CAAC"}
|