@eleboucher/opencode-memini 0.7.9 → 0.7.10
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/memini.js +45 -23
- package/package.json +1 -1
package/memini.js
CHANGED
|
@@ -120,14 +120,9 @@ export function resolveInstallContextFrom(startPath) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
|
-
* resolveInstallContext finds the opencode plugin cache wrapper directory
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* .../opencode-memini@latest/), containing a package.json listing the plugin as
|
|
127
|
-
* a dependency and a node_modules/ tree. The plugin's own file lives at
|
|
128
|
-
* <wrapper>/node_modules/@eleboucher/opencode-memini/memini.js, so the wrapper
|
|
129
|
-
* is the first ancestor whose child is a `node_modules` directory. Returns
|
|
130
|
-
* { installDir, packageJsonPath } or null. Exported for testing.
|
|
123
|
+
* resolveInstallContext finds the opencode plugin cache wrapper directory
|
|
124
|
+
* holding this running plugin instance, by walking up from import.meta.url.
|
|
125
|
+
* Exported for testing.
|
|
131
126
|
*/
|
|
132
127
|
export function resolveInstallContext() {
|
|
133
128
|
try {
|
|
@@ -175,7 +170,7 @@ export function prepareCacheUpdate(newVersion, log, ctx) {
|
|
|
175
170
|
ctx = resolveInstallContext();
|
|
176
171
|
}
|
|
177
172
|
if (!ctx) {
|
|
178
|
-
log.
|
|
173
|
+
log.error("auto-update: could not resolve install context");
|
|
179
174
|
return null;
|
|
180
175
|
}
|
|
181
176
|
// Rewrite package.json with the new version pin
|
|
@@ -187,7 +182,7 @@ export function prepareCacheUpdate(newVersion, log, ctx) {
|
|
|
187
182
|
pkg.dependencies = { ...pkg.dependencies, [PACKAGE_NAME]: newVersion };
|
|
188
183
|
writeFileSync(ctx.packageJsonPath, JSON.stringify(pkg, null, 2));
|
|
189
184
|
} catch (err) {
|
|
190
|
-
log.
|
|
185
|
+
log.error(`auto-update: failed to rewrite cache package.json: ${String(err)}`);
|
|
191
186
|
return null;
|
|
192
187
|
}
|
|
193
188
|
// Remove installed node_modules so the install re-fetches
|
|
@@ -195,7 +190,7 @@ export function prepareCacheUpdate(newVersion, log, ctx) {
|
|
|
195
190
|
const pkgDir = join(ctx.installDir, "node_modules", "@eleboucher", "opencode-memini");
|
|
196
191
|
if (existsSync(pkgDir)) rmSync(pkgDir, { recursive: true, force: true });
|
|
197
192
|
} catch (err) {
|
|
198
|
-
log.
|
|
193
|
+
log.error(`auto-update: failed to remove cached node_modules: ${String(err)}`);
|
|
199
194
|
return null;
|
|
200
195
|
}
|
|
201
196
|
// Clean lockfiles: opencode's installer may write either package-lock.json
|
|
@@ -1131,15 +1126,42 @@ export function lastAssistantFailed(messages) {
|
|
|
1131
1126
|
}
|
|
1132
1127
|
|
|
1133
1128
|
export const MeminiPlugin = async ({ client, worktree, directory }, options) => {
|
|
1129
|
+
// Structured logger is primary; console.error is the fallback when it
|
|
1130
|
+
// throws (absent client.app.log). Direct call so a missing app.log reaches
|
|
1131
|
+
// the catch. Symbols match oh-my-opencode-slim: [ok]/[x]/[!]/[i].
|
|
1132
|
+
const GREEN = "\x1b[32m";
|
|
1133
|
+
const RED = "\x1b[31m";
|
|
1134
|
+
const YELLOW = "\x1b[33m";
|
|
1135
|
+
const BLUE = "\x1b[34m";
|
|
1136
|
+
const RESET = "\x1b[0m";
|
|
1134
1137
|
const log = {
|
|
1138
|
+
error: (message) => {
|
|
1139
|
+
try {
|
|
1140
|
+
client.app.log({ body: { service: "memini", level: "error", message } });
|
|
1141
|
+
} catch {
|
|
1142
|
+
console.error(`${RED}[x]${RESET} [memini] ${message}`);
|
|
1143
|
+
}
|
|
1144
|
+
},
|
|
1135
1145
|
warn: (message) => {
|
|
1136
|
-
// client.app.log is opencode's structured logger; fall back to stderr.
|
|
1137
1146
|
try {
|
|
1138
|
-
client
|
|
1147
|
+
client.app.log({ body: { service: "memini", level: "warn", message } });
|
|
1148
|
+
} catch {
|
|
1149
|
+
console.error(`${YELLOW}[!]${RESET} [memini] ${message}`);
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
1152
|
+
info: (message) => {
|
|
1153
|
+
try {
|
|
1154
|
+
client.app.log({ body: { service: "memini", level: "info", message } });
|
|
1155
|
+
} catch {
|
|
1156
|
+
console.error(`${BLUE}[i]${RESET} [memini] ${message}`);
|
|
1157
|
+
}
|
|
1158
|
+
},
|
|
1159
|
+
success: (message) => {
|
|
1160
|
+
try {
|
|
1161
|
+
client.app.log({ body: { service: "memini", level: "info", message } });
|
|
1139
1162
|
} catch {
|
|
1140
|
-
|
|
1163
|
+
console.error(`${GREEN}[ok]${RESET} [memini] ${message}`);
|
|
1141
1164
|
}
|
|
1142
|
-
console.error(`[memini] ${message}`);
|
|
1143
1165
|
},
|
|
1144
1166
|
};
|
|
1145
1167
|
|
|
@@ -1245,7 +1267,7 @@ export const MeminiPlugin = async ({ client, worktree, directory }, options) =>
|
|
|
1245
1267
|
excludeIds: serverExcludeIds ? excludeIds : [],
|
|
1246
1268
|
onExcludeIdsUnsupported: () => {
|
|
1247
1269
|
serverExcludeIds = false;
|
|
1248
|
-
log.
|
|
1270
|
+
log.info("memini: server does not accept exclude_ids; using client-side dedupe only");
|
|
1249
1271
|
},
|
|
1250
1272
|
});
|
|
1251
1273
|
|
|
@@ -1256,7 +1278,7 @@ export const MeminiPlugin = async ({ client, worktree, directory }, options) =>
|
|
|
1256
1278
|
try {
|
|
1257
1279
|
return await fn(...args);
|
|
1258
1280
|
} catch (error) {
|
|
1259
|
-
log.
|
|
1281
|
+
log.error(`${name} hook failed: ${String(error)}`);
|
|
1260
1282
|
}
|
|
1261
1283
|
};
|
|
1262
1284
|
|
|
@@ -1375,7 +1397,7 @@ export const MeminiPlugin = async ({ client, worktree, directory }, options) =>
|
|
|
1375
1397
|
result = await Promise.race([settled, budget]);
|
|
1376
1398
|
clearTimeout(timer);
|
|
1377
1399
|
if (result === BUDGET_EXPIRED) {
|
|
1378
|
-
log.
|
|
1400
|
+
log.info(
|
|
1379
1401
|
`recall exceeded its ${live.recall_budget_ms}ms budget; late results will inject next turn`,
|
|
1380
1402
|
);
|
|
1381
1403
|
if (sessionID) {
|
|
@@ -1480,20 +1502,20 @@ export const MeminiPlugin = async ({ client, worktree, directory }, options) =>
|
|
|
1480
1502
|
const cur = parseVersion(CLIENT_VERSION);
|
|
1481
1503
|
const nxt = parseVersion(latest);
|
|
1482
1504
|
if (!cur || !nxt || cur.major !== nxt.major) {
|
|
1483
|
-
log.
|
|
1505
|
+
log.info(`auto-update: v${latest} available (major bump — update manually: pin @eleboucher/opencode-memini@${latest} in opencode.json)`);
|
|
1484
1506
|
return;
|
|
1485
1507
|
}
|
|
1486
|
-
log.
|
|
1508
|
+
log.info(`auto-update: updating ${CLIENT_VERSION} → ${latest}`);
|
|
1487
1509
|
const installDir = prepareCacheUpdate(latest, log);
|
|
1488
1510
|
if (!installDir) return;
|
|
1489
1511
|
const ok = runNpmInstall(installDir);
|
|
1490
1512
|
if (ok) {
|
|
1491
|
-
log.
|
|
1513
|
+
log.success(`auto-update: installed v${latest} — restart opencode to apply`);
|
|
1492
1514
|
} else {
|
|
1493
|
-
log.
|
|
1515
|
+
log.error(`auto-update: npm install failed; will retry next session`);
|
|
1494
1516
|
}
|
|
1495
1517
|
} catch (err) {
|
|
1496
|
-
log.
|
|
1518
|
+
log.error(`auto-update: check failed: ${String(err)}`);
|
|
1497
1519
|
}
|
|
1498
1520
|
})();
|
|
1499
1521
|
}
|