@codemem/opencode-plugin 0.21.2 → 0.22.0-alpha.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.
@@ -37,8 +37,8 @@ export const resolveUpgradeGuidance = ({ runner, runnerFrom }) => {
37
37
 
38
38
  if (normalizedRunner === "uv") {
39
39
  return {
40
- mode: "uv-dev",
41
- action: "In your codemem repo, pull latest changes and run `uv sync`, then restart OpenCode.",
40
+ mode: "repo-dev",
41
+ action: "In your codemem repo, pull latest changes and run `pnpm install` and `pnpm build`, then restart OpenCode.",
42
42
  note: "detected dev repo mode",
43
43
  };
44
44
  }
@@ -60,7 +60,7 @@ export const resolveUpgradeGuidance = ({ runner, runnerFrom }) => {
60
60
 
61
61
  return {
62
62
  mode: "generic",
63
- action: "Run `uv tool install --upgrade codemem`, then restart OpenCode.",
63
+ action: "Update codemem using your normal install method, then restart OpenCode.",
64
64
  note: "fallback guidance",
65
65
  };
66
66
  };
@@ -138,34 +138,18 @@ export const resolveAutoUpdatePlan = ({ runner, runnerFrom }) => {
138
138
  }
139
139
 
140
140
  if (normalizedRunner === "uvx") {
141
- if (!source) {
142
- return {
143
- allowed: false,
144
- reason: "missing-source",
145
- command: null,
146
- commandText: null,
147
- };
148
- }
149
- if (isPinnedGitSource(source)) {
150
- return {
151
- allowed: false,
152
- reason: "pinned-source",
153
- command: null,
154
- commandText: null,
155
- };
156
- }
157
141
  return {
158
- allowed: true,
159
- reason: null,
160
- command: ["uvx", "--refresh", "--from", source, "codemem", "version"],
161
- commandText: "uvx --refresh --from <source> codemem version",
142
+ allowed: false,
143
+ reason: !source ? "missing-source" : isPinnedGitSource(source) ? "pinned-source" : "custom-source",
144
+ command: null,
145
+ commandText: null,
162
146
  };
163
147
  }
164
148
 
165
149
  return {
166
150
  allowed: true,
167
151
  reason: null,
168
- command: ["uv", "tool", "install", "--upgrade", "codemem"],
169
- commandText: "uv tool install --upgrade codemem",
152
+ command: ["npm", "install", "-g", "codemem@latest"],
153
+ commandText: "npm install -g codemem@latest",
170
154
  };
171
155
  };
@@ -621,6 +621,14 @@ export const OpencodeMemPlugin = async ({
621
621
  let fallbackFailureNoted = false;
622
622
  let lastStatusCheckAt = 0;
623
623
  let lastStatusAvailable = true;
624
+
625
+ // Viewer health-check state
626
+ const HEALTH_CHECK_INTERVAL_MS = 60_000;
627
+ const HEALTH_CONSECUTIVE_FAILURES_BEFORE_RESTART = 3;
628
+ const HEALTH_RESTART_COOLDOWN_MS = 5 * 60_000;
629
+ let healthCheckTimer = null;
630
+ let healthConsecutiveFailures = 0;
631
+ let healthLastRestartAttempt = 0;
624
632
  const nextEventId = () => {
625
633
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
626
634
  return crypto.randomUUID();
@@ -1081,6 +1089,7 @@ export const OpencodeMemPlugin = async ({
1081
1089
  } catch (err) {
1082
1090
  logLine(`viewer spawn failed: ${err}`).catch(() => {});
1083
1091
  }
1092
+ startHealthCheck();
1084
1093
  };
1085
1094
 
1086
1095
  const runCommand = async (cmd, options = {}) => {
@@ -1399,10 +1408,68 @@ export const OpencodeMemPlugin = async ({
1399
1408
  return;
1400
1409
  }
1401
1410
  viewerStarted = false;
1411
+ stopHealthCheck();
1402
1412
  await logLine("viewer stop requested");
1403
1413
  await runCli(["serve", "stop"]);
1404
1414
  };
1405
1415
 
1416
+ const checkViewerHealth = async () => {
1417
+ if (!viewerStarted || !viewerEnabled) return;
1418
+ try {
1419
+ const resp = await fetch(rawEventsStatusUrl, {
1420
+ method: "GET",
1421
+ signal: AbortSignal.timeout(5000),
1422
+ });
1423
+ if (resp.ok) {
1424
+ if (healthConsecutiveFailures > 0) {
1425
+ await logLine(`viewer.health recovered after ${healthConsecutiveFailures} failure(s)`);
1426
+ }
1427
+ healthConsecutiveFailures = 0;
1428
+ return;
1429
+ }
1430
+ healthConsecutiveFailures++;
1431
+ await logLine(`viewer.health check failed (status=${resp.status}, consecutive=${healthConsecutiveFailures})`);
1432
+ } catch (err) {
1433
+ healthConsecutiveFailures++;
1434
+ await logLine(`viewer.health check error (consecutive=${healthConsecutiveFailures}): ${String(err).slice(0, 200)}`);
1435
+ }
1436
+
1437
+ if (
1438
+ healthConsecutiveFailures >= HEALTH_CONSECUTIVE_FAILURES_BEFORE_RESTART &&
1439
+ Date.now() - healthLastRestartAttempt >= HEALTH_RESTART_COOLDOWN_MS
1440
+ ) {
1441
+ healthLastRestartAttempt = Date.now();
1442
+ await logLine(`viewer.health restarting viewer after ${healthConsecutiveFailures} consecutive failures`);
1443
+ try {
1444
+ const result = await runCli(["serve", "restart"]);
1445
+ const ok = result?.exitCode === 0;
1446
+ await logLine(`viewer.health restart ${ok ? "succeeded" : "failed"} (exit=${result?.exitCode ?? "unknown"})`);
1447
+ if (ok) {
1448
+ healthConsecutiveFailures = 0;
1449
+ }
1450
+ } catch (restartErr) {
1451
+ await logLine(`viewer.health restart error: ${String(restartErr).slice(0, 200)}`);
1452
+ }
1453
+ }
1454
+ };
1455
+
1456
+ const startHealthCheck = () => {
1457
+ if (healthCheckTimer) return;
1458
+ healthConsecutiveFailures = 0;
1459
+ healthCheckTimer = setInterval(() => {
1460
+ checkViewerHealth().catch(() => {});
1461
+ }, HEALTH_CHECK_INTERVAL_MS);
1462
+ if (healthCheckTimer.unref) healthCheckTimer.unref();
1463
+ };
1464
+
1465
+ const stopHealthCheck = () => {
1466
+ if (healthCheckTimer) {
1467
+ clearInterval(healthCheckTimer);
1468
+ healthCheckTimer = null;
1469
+ }
1470
+ healthConsecutiveFailures = 0;
1471
+ };
1472
+
1406
1473
  // Get version info (commit hash) for debugging
1407
1474
  let version = "unknown";
1408
1475
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemem/opencode-plugin",
3
- "version": "0.21.2",
3
+ "version": "0.22.0-alpha.2",
4
4
  "description": "CodeMem plugin for OpenCode",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -18,7 +18,7 @@
18
18
  ".opencode/lib/"
19
19
  ],
20
20
  "dependencies": {
21
- "@opencode-ai/plugin": "1.3.2"
21
+ "@opencode-ai/plugin": "1.3.3"
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",