codex-dev-mcp-suite 1.8.2 → 1.9.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/CHANGELOG.md CHANGED
@@ -32,6 +32,14 @@
32
32
 
33
33
  # Changelog
34
34
 
35
+ ## 1.9.0 - 2026-07-22
36
+
37
+ ### Added
38
+ - **Non-Blocking Upstream Update Checker (`lib/update-check.js`)**:
39
+ - Automatically queries npm registry in the background once every 24 hours (cached locally).
40
+ - Notifies users via `stderr` when a new version of `codex-dev-mcp-suite` is published to upstream npm.
41
+ - Safe for stdio MCP JSON-RPC protocol transport; sub-millisecond execution, zero startup latency.
42
+
35
43
  ## 1.4.0 - 2026-06-17
36
44
 
37
45
  ### Added
package/bin/_meta.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
+ import { checkForUpdates } from "../lib/update-check.js";
4
5
 
5
6
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
7
 
@@ -41,6 +42,9 @@ function doctorLines(meta) {
41
42
  }
42
43
 
43
44
  export function handleCliMeta(meta) {
45
+ // Non-blocking update check on startup (cached 24h, logged to stderr)
46
+ checkForUpdates().catch(() => {});
47
+
44
48
  const argv = process.argv.slice(2);
45
49
  if (argv.includes("-v") || argv.includes("--version")) {
46
50
  process.stdout.write(`${pkgVersion()}\n`);
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Non-blocking, cached upstream update checker for Dev MCP Suite.
3
+ * Checks npm registry (https://registry.npmjs.org/codex-dev-mcp-suite/latest)
4
+ * once every 24 hours. Safe for stdio MCP transport (logs only to stderr).
5
+ */
6
+
7
+ import http from "http";
8
+ import https from "https";
9
+ import fs from "fs";
10
+ import path from "path";
11
+ import os from "os";
12
+ import { fileURLToPath } from "url";
13
+
14
+ const CACHE_FILE = path.join(os.homedir(), ".ai-shared-memory", ".update-check-cache.json");
15
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
16
+ const PKG_NAME = "codex-dev-mcp-suite";
17
+
18
+ /** Reads current package version from package.json */
19
+ function getCurrentVersion() {
20
+ try {
21
+ const dir = path.dirname(fileURLToPath(import.meta.url));
22
+ const pkgPath = path.join(dir, "..", "package.json");
23
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
24
+ return pkg.version || "1.8.2";
25
+ } catch {
26
+ return "1.8.2";
27
+ }
28
+ }
29
+
30
+ /** Simple version comparator (e.g. "1.9.0" > "1.8.2") */
31
+ export function isNewerVersion(current, latest) {
32
+ if (!current || !latest) return false;
33
+ const c = current.split(".").map(Number);
34
+ const l = latest.split(".").map(Number);
35
+ for (let i = 0; i < 3; i++) {
36
+ if ((l[i] || 0) > (c[i] || 0)) return true;
37
+ if ((l[i] || 0) < (c[i] || 0)) return false;
38
+ }
39
+ return false;
40
+ }
41
+
42
+ /** Check npm registry for latest version asynchronously with timeout */
43
+ function fetchLatestNpmVersion() {
44
+ return new Promise((resolve) => {
45
+ const req = https.get(
46
+ `https://registry.npmjs.org/${PKG_NAME}/latest`,
47
+ { headers: { "User-Agent": `${PKG_NAME}-update-check` }, timeout: 1500 },
48
+ (res) => {
49
+ if (res.statusCode !== 200) return resolve(null);
50
+ let body = "";
51
+ res.on("data", (chunk) => (body += chunk));
52
+ res.on("end", () => {
53
+ try {
54
+ const data = JSON.parse(body);
55
+ resolve(data.version || null);
56
+ } catch {
57
+ resolve(null);
58
+ }
59
+ });
60
+ }
61
+ );
62
+ req.on("error", () => resolve(null));
63
+ req.on("timeout", () => {
64
+ req.destroy();
65
+ resolve(null);
66
+ });
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Triggers a background check for updates.
72
+ * Never blocks process execution or breaks stdio protocol.
73
+ */
74
+ export async function checkForUpdates() {
75
+ try {
76
+ const now = Date.now();
77
+ let cache = { lastCheck: 0, latestVersion: null };
78
+
79
+ // Read existing cache if available
80
+ try {
81
+ if (fs.existsSync(CACHE_FILE)) {
82
+ cache = JSON.parse(fs.readFileSync(CACHE_FILE, "utf8"));
83
+ }
84
+ } catch { /* ignore cache read error */ }
85
+
86
+ const currentVersion = getCurrentVersion();
87
+
88
+ // If cache is fresh, check cached latest version
89
+ if (now - (cache.lastCheck || 0) < CHECK_INTERVAL_MS && cache.latestVersion) {
90
+ if (isNewerVersion(currentVersion, cache.latestVersion)) {
91
+ console.error(
92
+ `\nšŸ’” [Dev MCP Suite] Update available: ${currentVersion} → ${cache.latestVersion}\n` +
93
+ ` Run "npm i -g ${PKG_NAME}@latest" or use "npx -y -p ${PKG_NAME}@latest"\n`
94
+ );
95
+ }
96
+ return;
97
+ }
98
+
99
+ // Perform background check
100
+ fetchLatestNpmVersion().then((latest) => {
101
+ if (!latest) return;
102
+
103
+ // Update cache
104
+ try {
105
+ const cacheDir = path.dirname(CACHE_FILE);
106
+ if (!fs.existsSync(cacheDir)) {
107
+ fs.mkdirSync(cacheDir, { recursive: true });
108
+ }
109
+ fs.writeFileSync(CACHE_FILE, JSON.stringify({ lastCheck: now, latestVersion: latest }));
110
+ } catch { /* ignore cache write error */ }
111
+
112
+ if (isNewerVersion(currentVersion, latest)) {
113
+ console.error(
114
+ `\nšŸ’” [Dev MCP Suite] Update available: ${currentVersion} → ${latest}\n` +
115
+ ` Run "npm i -g ${PKG_NAME}@latest" or use "npx -y -p ${PKG_NAME}@latest"\n`
116
+ );
117
+ }
118
+ }).catch(() => {});
119
+ } catch {
120
+ /* Silent catch: update checks must never throw or disrupt the application */
121
+ }
122
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-dev-mcp-suite",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "description": "Four local, file-based MCP servers for solo devs/vibecoders: persistent project memory, session handoff/resume, git-independent file checkpoints, and token-efficient project briefings. Works with any MCP client.",
5
5
  "type": "module",
6
6
  "license": "MIT",