@codemem/opencode-plugin 0.36.1 → 0.37.0
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/.opencode/plugins/codemem.js +40 -9
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
const TRUTHY_VALUES = ["1", "true", "yes"];
|
|
17
17
|
const DISABLED_VALUES = ["0", "false", "off"];
|
|
18
|
-
const PINNED_BACKEND_VERSION = "0.
|
|
18
|
+
const PINNED_BACKEND_VERSION = "0.37.0";
|
|
19
19
|
const COMPAT_CHECK_DELAY_MS = 1500;
|
|
20
20
|
const COMPAT_CHECK_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
21
21
|
|
|
@@ -623,7 +623,22 @@ const detectRunner = ({ cwd, envRunner }) => {
|
|
|
623
623
|
// Prefer the TS codemem if installed globally, fall back to npx
|
|
624
624
|
try {
|
|
625
625
|
const versionOutput = execSync("codemem --version", { encoding: "utf-8", timeout: 3000 }).trim();
|
|
626
|
-
|
|
626
|
+
// Accept any global codemem at or above the pinned backend version, so a
|
|
627
|
+
// newer global install is used instead of silently downgrading to
|
|
628
|
+
// `npx codemem@<pin>` (the old check only matched the exact pin or the
|
|
629
|
+
// long-obsolete 0.2x series).
|
|
630
|
+
// Accept a global codemem only when it is the EXACT pinned version, or a
|
|
631
|
+
// clean (non-prerelease) release at least as new as the pin. isVersionAtLeast
|
|
632
|
+
// ignores prerelease suffixes, so without this a prerelease like
|
|
633
|
+
// "0.36.1-alpha.0" would wrongly compare >= the "0.36.1" release even though
|
|
634
|
+
// SemVer orders it below. Requiring an exact match for prereleases also
|
|
635
|
+
// handles a prerelease PIN correctly (the release script can set one): only
|
|
636
|
+
// the identical prerelease is trusted, never an older/different one.
|
|
637
|
+
const isPrerelease = versionOutput.includes("-");
|
|
638
|
+
const matchesOrCleanNewer =
|
|
639
|
+
versionOutput === PINNED_BACKEND_VERSION ||
|
|
640
|
+
(!isPrerelease && isVersionAtLeast(versionOutput, PINNED_BACKEND_VERSION));
|
|
641
|
+
if (matchesOrCleanNewer) {
|
|
627
642
|
return "codemem";
|
|
628
643
|
}
|
|
629
644
|
} catch {
|
|
@@ -722,10 +737,14 @@ export const OpencodeMemPlugin = async ({
|
|
|
722
737
|
const viewerPort = process.env.CODEMEM_VIEWER_PORT || "38888";
|
|
723
738
|
const viewerDbPath = process.env.CODEMEM_DB || "";
|
|
724
739
|
const viewerConfigPath = process.env.CODEMEM_CONFIG || "";
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
)
|
|
740
|
+
// A malformed value (e.g. "abc", "", "-1") falls back to the 20s default
|
|
741
|
+
// instead of NaN, which would silently disable the timeout. An explicit "0"
|
|
742
|
+
// is preserved as the intentional opt-out (disable the timeout, e.g. for slow
|
|
743
|
+
// first-run npx installs/backend updates) — the `commandTimeout > 0` guard at
|
|
744
|
+
// the call site skips installing the timer when it is 0.
|
|
745
|
+
const rawCommandTimeout = String(process.env.CODEMEM_PLUGIN_CMD_TIMEOUT ?? "").trim();
|
|
746
|
+
const commandTimeout =
|
|
747
|
+
rawCommandTimeout === "0" ? 0 : parsePositiveInt(rawCommandTimeout, 20000);
|
|
729
748
|
const backendUpdatePolicy = parseBackendUpdatePolicy(
|
|
730
749
|
process.env.CODEMEM_BACKEND_UPDATE_POLICY || "notify"
|
|
731
750
|
);
|
|
@@ -1272,8 +1291,18 @@ export const OpencodeMemPlugin = async ({
|
|
|
1272
1291
|
});
|
|
1273
1292
|
let stdout = "";
|
|
1274
1293
|
let stderr = "";
|
|
1275
|
-
|
|
1276
|
-
|
|
1294
|
+
// Guard stdio access: a hard spawn failure (ENOENT) can hand back null
|
|
1295
|
+
// streams, and a synchronous null-deref here would reject the promise
|
|
1296
|
+
// that callers await for a resolved { exitCode, stdout, stderr }.
|
|
1297
|
+
if (proc.stdout) proc.stdout.on("data", (chunk) => { stdout += chunk; });
|
|
1298
|
+
if (proc.stderr) proc.stderr.on("data", (chunk) => { stderr += chunk; });
|
|
1299
|
+
// Absorb async stream errors (e.g. EPIPE when the child exits mid-write,
|
|
1300
|
+
// or a spawn failure surfacing on a pipe). Without these handlers an
|
|
1301
|
+
// unhandled stream "error" event would crash the host process. The
|
|
1302
|
+
// child-level proc.once("error") below still resolves the promise.
|
|
1303
|
+
for (const stream of [proc.stdin, proc.stdout, proc.stderr]) {
|
|
1304
|
+
if (stream && typeof stream.on === "function") stream.on("error", () => {});
|
|
1305
|
+
}
|
|
1277
1306
|
if (typeof stdinText === "string") {
|
|
1278
1307
|
try {
|
|
1279
1308
|
proc.stdin.write(stdinText);
|
|
@@ -2078,7 +2107,9 @@ export const OpencodeMemPlugin = async ({
|
|
|
2078
2107
|
limit: tool.schema.number().optional(),
|
|
2079
2108
|
},
|
|
2080
2109
|
async execute({ limit }) {
|
|
2081
|
-
|
|
2110
|
+
// Number.isFinite accepts floats and negatives; coerce to a positive
|
|
2111
|
+
// integer (default 5) before forwarding to the CLI.
|
|
2112
|
+
const safeLimit = String(parsePositiveInt(limit, 5));
|
|
2082
2113
|
const recent = await runCli(["recent", "--limit", safeLimit]);
|
|
2083
2114
|
if (recent.exitCode === 0) {
|
|
2084
2115
|
return recent.stdout.trim() || "No recent memories.";
|