mthds 0.6.2 → 0.6.3
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/dist/agent/binaries.js +1 -1
- package/dist/agent/commands/bootstrap.js +8 -4
- package/dist/agent/commands/bootstrap.js.map +1 -1
- package/dist/agent/commands/update-check.js +7 -5
- package/dist/agent/commands/update-check.js.map +1 -1
- package/dist/agent/plugin-version.d.ts +63 -13
- package/dist/agent/plugin-version.js +197 -29
- package/dist/agent/plugin-version.js.map +1 -1
- package/dist/agent/update-cache.d.ts +15 -4
- package/dist/agent/update-cache.js +78 -28
- package/dist/agent/update-cache.js.map +1 -1
- package/package.json +1 -1
package/dist/agent/binaries.js
CHANGED
|
@@ -22,7 +22,7 @@ const VERSION_RE = /^[\w-]+\s+(\d+\.\d+\.\d+)/;
|
|
|
22
22
|
const PIPELEX_PKG = {
|
|
23
23
|
package: "pipelex",
|
|
24
24
|
uv_package: "pipelex",
|
|
25
|
-
version_constraint: ">=0.
|
|
25
|
+
version_constraint: ">=0.27.0",
|
|
26
26
|
version_extract: VERSION_RE,
|
|
27
27
|
install_url: "https://pypi.org/project/pipelex/",
|
|
28
28
|
auto_installable: true,
|
|
@@ -22,7 +22,7 @@ import { clearCache, ensureStateDir, STATE_DIR } from "../update-cache.js";
|
|
|
22
22
|
import { clearSnooze } from "../snooze.js";
|
|
23
23
|
import { loadConfig } from "../../config/config.js";
|
|
24
24
|
import { Runners } from "../../runners/types.js";
|
|
25
|
-
import { checkPluginVersion, MIN_PLUGIN_VERSION,
|
|
25
|
+
import { checkPluginVersion, detectHost, MIN_PLUGIN_VERSION, pluginUpdateCommand, } from "../plugin-version.js";
|
|
26
26
|
function errorMsg(err) {
|
|
27
27
|
return err instanceof Error ? err.message : String(err);
|
|
28
28
|
}
|
|
@@ -160,16 +160,20 @@ export async function agentBootstrap(options = {}) {
|
|
|
160
160
|
// 8. Check Claude Code plugin version (separate line, does not affect binary status)
|
|
161
161
|
emitPluginCheck();
|
|
162
162
|
}
|
|
163
|
-
/** Emit PLUGIN_UPDATE_AVAILABLE if the
|
|
163
|
+
/** Emit PLUGIN_UPDATE_AVAILABLE if the host's mthds plugin is outdated or missing. */
|
|
164
164
|
function emitPluginCheck() {
|
|
165
165
|
try {
|
|
166
|
-
const
|
|
166
|
+
const host = detectHost();
|
|
167
|
+
if (!host)
|
|
168
|
+
return;
|
|
169
|
+
const pluginCheck = checkPluginVersion(host);
|
|
167
170
|
if (pluginCheck && (pluginCheck.s === "outdated" || pluginCheck.s === "missing")) {
|
|
168
171
|
process.stdout.write("PLUGIN_UPDATE_AVAILABLE " +
|
|
169
172
|
JSON.stringify({
|
|
170
173
|
installed: pluginCheck.v,
|
|
171
174
|
required: MIN_PLUGIN_VERSION,
|
|
172
|
-
cmd:
|
|
175
|
+
cmd: pluginUpdateCommand(host),
|
|
176
|
+
host,
|
|
173
177
|
}) +
|
|
174
178
|
"\n");
|
|
175
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/agent/commands/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACnG,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/agent/commands/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACnG,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAU9B,SAAS,QAAQ,CAAC,GAAY;IAC5B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAYD,yEAAyE;AACzE,MAAM,eAAe,GAA2B;IAC9C,OAAO,EAAE,qBAAqB;CAC/B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAA4B,EAAE;IACjE,sDAAsD;IACtD,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,SAAS,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,UAAU,CACR,8BAA8B,QAAQ,CAAC,GAAG,CAAC,6EAA6E,EACxH,cAAc,EACd,EAAE,YAAY,EAAE,mBAAmB,CAAC,OAAO,EAAE,CAC9C,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,UAAU,CACR,wGAAwG,EACxG,cAAc,EACd,EAAE,YAAY,EAAE,mBAAmB,CAAC,OAAO,EAAE,CAC9C,CAAC;YACF,OAAO;QACT,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,UAAU,GAAa,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,sCAAsC;IACtC,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yCAAyC,GAAG,gCAAgC,CAC7E,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAuB,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,GAAG;gBACd,QAAQ;gBACR,UAAU,EAAE,KAAK,CAAC,iBAAiB;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC/C,eAAe,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IAED,gCAAgC;IAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhD,0BAA0B;IAC1B,MAAM,SAAS,GAAiC,IAAI,GAAG,EAAE,CAAC;IAC1D,MAAM,MAAM,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE9C,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxF,IAAI,SAAS,EAAE,CAAC;gBACd,kEAAkE;gBAClE,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;YACpF,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,gBAAgB,GAA2B,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QACxC,IAAI,UAAU,GAAkB,IAAI,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACtD,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,IAAI,SAAS,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;gBACpE,UAAU,GAAG,SAAS,CAAC,iBAAiB,CAAC;YAC3C,CAAC;iBAAM,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1C,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,YAAY,KAAK,8BAA8B,SAAS,CAAC,iBAAiB,wBAAwB,SAAS,CAAC,kBAAkB,KAAK,CACpI,CAAC;gBACF,UAAU,GAAG,SAAS,CAAC,iBAAiB,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,KAAK,KAAK,QAAQ,CAAC,GAAG,CAAC,KAAK,CAC/E,CAAC;YACF,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;QAC5C,MAAM,IAAI,GAAG,UAAU,IAAI,SAAS,CAAC;QACrC,gBAAgB,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAEjD,yDAAyD;IACzD,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtD,UAAU,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;IACzD,CAAC;IAED,iBAAiB;IACjB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC;IAEvC,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,cAAc,EAAE,CAAC;YACjB,aAAa,CACX,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,EACrC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAC1B,OAAO,CACR,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,4CAA4C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAC/D,CAAC;QACJ,CAAC;QACD,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAC/E,CAAC;IACJ,CAAC;SAAM,IAAI,SAAS,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,GAAG,IAAI,CACvE,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,UAAU,EAAE,CAAC;QACb,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oBAAoB;YAClB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YACtE,IAAI,CACP,CAAC;IACJ,CAAC;IAED,qFAAqF;IACrF,eAAe,EAAE,CAAC;AACpB,CAAC;AAED,sFAAsF;AACtF,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,UAAU,IAAI,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;YACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B;gBACxB,IAAI,CAAC,SAAS,CAAC;oBACb,SAAS,EAAE,WAAW,CAAC,CAAC;oBACxB,QAAQ,EAAE,kBAAkB;oBAC5B,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC;oBAC9B,IAAI;iBACL,CAAC;gBACF,IAAI,CACP,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yCAAyC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAC5G,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -19,7 +19,7 @@ import { loadConfig } from "../../config/config.js";
|
|
|
19
19
|
import { Runners } from "../../runners/types.js";
|
|
20
20
|
import { readCache, writeCache, clearCache, computeAggregate, STATE_DIR, } from "../update-cache.js";
|
|
21
21
|
import { isSnoozed, writeSnooze, clearSnooze, computeVersionKey, } from "../snooze.js";
|
|
22
|
-
import { checkPluginVersion } from "../plugin-version.js";
|
|
22
|
+
import { checkPluginVersion, detectHost } from "../plugin-version.js";
|
|
23
23
|
const require = createRequire(import.meta.url);
|
|
24
24
|
const pkg = require("../../../package.json");
|
|
25
25
|
const JUST_UPGRADED_PATH = join(STATE_DIR, "just-upgraded-from");
|
|
@@ -119,12 +119,14 @@ function runFreshChecks(runner) {
|
|
|
119
119
|
}
|
|
120
120
|
payload.pipelex_agent = toBinaryEntry(checkBinaryVersion(pipelexRecovery));
|
|
121
121
|
}
|
|
122
|
-
// Check
|
|
122
|
+
// Check the host's mthds plugin version (skip when no host is detected).
|
|
123
123
|
// Wrapped in try-catch so a plugin check failure never crashes update-check.
|
|
124
124
|
try {
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
127
|
-
|
|
125
|
+
const host = detectHost();
|
|
126
|
+
if (host) {
|
|
127
|
+
const pluginCheck = checkPluginVersion(host);
|
|
128
|
+
if (pluginCheck)
|
|
129
|
+
payload.plugin = pluginCheck;
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../../src/agent/commands/update-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../../src/agent/commands/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,79 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plugin version checking for the Claude Code
|
|
2
|
+
* Plugin version checking for the mthds plugin under Claude Code and Codex.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Detects the active host (Claude Code or Codex), reads the appropriate
|
|
5
|
+
* plugin registry, and checks the installed version against
|
|
6
|
+
* MIN_PLUGIN_VERSION. Returns null when no known host is detected (file
|
|
7
|
+
* absent on disk and no CODEX_HOME env).
|
|
7
8
|
*
|
|
8
9
|
* Bump MIN_PLUGIN_VERSION each release alongside min_mthds_version in the
|
|
9
10
|
* plugin's targets/defaults.toml.
|
|
10
11
|
*/
|
|
11
12
|
import type { BinaryCheckEntry } from "./update-cache.js";
|
|
12
13
|
/** Minimum plugin version this mthds-agent release requires. */
|
|
13
|
-
export declare const MIN_PLUGIN_VERSION = ">=0.10.
|
|
14
|
+
export declare const MIN_PLUGIN_VERSION = ">=0.10.2";
|
|
14
15
|
/** Keys in installed_plugins.json for the mthds plugin (prod and dev targets). */
|
|
15
16
|
export declare const PLUGIN_KEYS: readonly ["mthds@mthds-plugins", "mthds-dev@mthds-plugins"];
|
|
16
|
-
/** Command to update the plugin (prod). */
|
|
17
|
-
export declare const PLUGIN_UPDATE_CMD = "claude plugin install mthds@mthds-plugins";
|
|
18
17
|
/** Path to Claude Code's installed plugins registry. */
|
|
19
18
|
export declare const INSTALLED_PLUGINS_PATH: string;
|
|
19
|
+
/** A host that exposes an mthds plugin install. `detectHost()` returns this or null. */
|
|
20
|
+
export type PluginHost = "claude" | "codex";
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
+
* Detect the host that this mthds-agent process is running under.
|
|
23
|
+
*
|
|
24
|
+
* `$CODEX_HOME` alone is not enough to claim Codex — a user might export it
|
|
25
|
+
* in their shell profile for customization while running from Claude Code, in
|
|
26
|
+
* which case picking "codex" would surface a wrong `missing` warning and an
|
|
27
|
+
* irrelevant upgrade command. We require the cache directory to exist as
|
|
28
|
+
* corroborating evidence (Codex creates it on first plugin install).
|
|
29
|
+
*
|
|
30
|
+
* When a user has *both* hosts installed (Codex cache dir AND Claude
|
|
31
|
+
* registry both present), filesystem state alone can't tell us which one
|
|
32
|
+
* is currently running us. We use `CLAUDECODE=1` — set by Claude Code at
|
|
33
|
+
* runtime, not something users would set in a shell profile — as the
|
|
34
|
+
* tiebreaker. Codex doesn't have an equivalent runtime-only env var we
|
|
35
|
+
* can trust the same way, so absence of `CLAUDECODE` falls back to the
|
|
36
|
+
* filesystem-based preference (Codex cache wins).
|
|
37
|
+
*
|
|
38
|
+
* Order of checks:
|
|
39
|
+
* 1. CLAUDECODE=1 AND ~/.claude/plugins/installed_plugins.json exists → "claude"
|
|
40
|
+
* 2. ~/.codex/plugins/cache/ exists (honoring $CODEX_HOME) → "codex"
|
|
41
|
+
* 3. ~/.claude/plugins/installed_plugins.json exists → "claude"
|
|
42
|
+
* 4. neither → null
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectHost(): PluginHost | null;
|
|
45
|
+
/** Command to run inside the host to install / upgrade the plugin. */
|
|
46
|
+
export declare function pluginUpdateCommand(host: PluginHost): string;
|
|
47
|
+
/**
|
|
48
|
+
* Read the installed plugin version from Codex's plugin cache.
|
|
49
|
+
*
|
|
50
|
+
* Codex stores plugins at:
|
|
51
|
+
* $CODEX_HOME/plugins/cache/<marketplace>/<plugin>/<version>/.codex-plugin/plugin.json
|
|
52
|
+
*
|
|
53
|
+
* The directory name is the version. A directory named "local" is Codex's
|
|
54
|
+
* dev sentinel — treat it like an unparseable version (don't nag).
|
|
55
|
+
*
|
|
56
|
+
* Returns the same shape as readClaudePluginVersion().
|
|
57
|
+
*/
|
|
58
|
+
export declare function readCodexPluginVersion(): {
|
|
59
|
+
kind: "version";
|
|
60
|
+
version: string;
|
|
61
|
+
} | {
|
|
62
|
+
kind: "missing";
|
|
63
|
+
} | {
|
|
64
|
+
kind: "null";
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Check the installed plugin version against MIN_PLUGIN_VERSION for the
|
|
68
|
+
* given host.
|
|
22
69
|
*
|
|
23
70
|
* Returns:
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
71
|
+
* - `{ s: "ok", v: "0.10.1" }` — satisfies constraint
|
|
72
|
+
* - `{ s: "outdated", v: "0.6.2", r: ">=0.10.1" }` — too old
|
|
73
|
+
* - `{ s: "missing", v: null, r: ">=0.10.1" }` — registry present, plugin absent
|
|
74
|
+
* - `null` — registry unreadable, unparseable, or dev install
|
|
75
|
+
*
|
|
76
|
+
* Caller is expected to call `detectHost()` first and skip when it returns
|
|
77
|
+
* null — there is no "no host" return value here.
|
|
28
78
|
*/
|
|
29
|
-
export declare function checkPluginVersion(): BinaryCheckEntry | null;
|
|
79
|
+
export declare function checkPluginVersion(host: PluginHost): BinaryCheckEntry | null;
|
|
@@ -1,40 +1,94 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plugin version checking for the Claude Code
|
|
2
|
+
* Plugin version checking for the mthds plugin under Claude Code and Codex.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Detects the active host (Claude Code or Codex), reads the appropriate
|
|
5
|
+
* plugin registry, and checks the installed version against
|
|
6
|
+
* MIN_PLUGIN_VERSION. Returns null when no known host is detected (file
|
|
7
|
+
* absent on disk and no CODEX_HOME env).
|
|
7
8
|
*
|
|
8
9
|
* Bump MIN_PLUGIN_VERSION each release alongside min_mthds_version in the
|
|
9
10
|
* plugin's targets/defaults.toml.
|
|
10
11
|
*/
|
|
11
|
-
import { readFileSync } from "node:fs";
|
|
12
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "node:fs";
|
|
12
13
|
import { join } from "node:path";
|
|
13
14
|
import { homedir } from "node:os";
|
|
14
15
|
import semver from "semver";
|
|
15
16
|
// ── Constants ──────────────────────────────────────────────────────
|
|
16
17
|
/** Minimum plugin version this mthds-agent release requires. */
|
|
17
|
-
export const MIN_PLUGIN_VERSION = ">=0.10.
|
|
18
|
+
export const MIN_PLUGIN_VERSION = ">=0.10.2";
|
|
18
19
|
/** Keys in installed_plugins.json for the mthds plugin (prod and dev targets). */
|
|
19
20
|
export const PLUGIN_KEYS = [
|
|
20
21
|
"mthds@mthds-plugins",
|
|
21
22
|
"mthds-dev@mthds-plugins",
|
|
22
23
|
];
|
|
23
|
-
/**
|
|
24
|
-
|
|
24
|
+
/** Codex marketplace + plugin names searched under $CODEX_HOME/plugins/cache. */
|
|
25
|
+
const CODEX_MARKETPLACE = "mthds-plugins";
|
|
26
|
+
const CODEX_PLUGIN_NAMES = ["mthds", "mthds-dev"];
|
|
27
|
+
/** Sentinel directory name Codex uses for local dev installs. */
|
|
28
|
+
const CODEX_LOCAL_VERSION = "local";
|
|
25
29
|
/** Path to Claude Code's installed plugins registry. */
|
|
26
30
|
export const INSTALLED_PLUGINS_PATH = join(homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
27
|
-
// ──
|
|
31
|
+
// ── Host detection ─────────────────────────────────────────────────
|
|
32
|
+
/** Resolve $CODEX_HOME (defaulting to ~/.codex). */
|
|
33
|
+
function codexHomeDir() {
|
|
34
|
+
return process.env.CODEX_HOME ?? join(homedir(), ".codex");
|
|
35
|
+
}
|
|
36
|
+
function codexCacheDir() {
|
|
37
|
+
return join(codexHomeDir(), "plugins", "cache");
|
|
38
|
+
}
|
|
28
39
|
/**
|
|
29
|
-
*
|
|
40
|
+
* Detect the host that this mthds-agent process is running under.
|
|
41
|
+
*
|
|
42
|
+
* `$CODEX_HOME` alone is not enough to claim Codex — a user might export it
|
|
43
|
+
* in their shell profile for customization while running from Claude Code, in
|
|
44
|
+
* which case picking "codex" would surface a wrong `missing` warning and an
|
|
45
|
+
* irrelevant upgrade command. We require the cache directory to exist as
|
|
46
|
+
* corroborating evidence (Codex creates it on first plugin install).
|
|
47
|
+
*
|
|
48
|
+
* When a user has *both* hosts installed (Codex cache dir AND Claude
|
|
49
|
+
* registry both present), filesystem state alone can't tell us which one
|
|
50
|
+
* is currently running us. We use `CLAUDECODE=1` — set by Claude Code at
|
|
51
|
+
* runtime, not something users would set in a shell profile — as the
|
|
52
|
+
* tiebreaker. Codex doesn't have an equivalent runtime-only env var we
|
|
53
|
+
* can trust the same way, so absence of `CLAUDECODE` falls back to the
|
|
54
|
+
* filesystem-based preference (Codex cache wins).
|
|
55
|
+
*
|
|
56
|
+
* Order of checks:
|
|
57
|
+
* 1. CLAUDECODE=1 AND ~/.claude/plugins/installed_plugins.json exists → "claude"
|
|
58
|
+
* 2. ~/.codex/plugins/cache/ exists (honoring $CODEX_HOME) → "codex"
|
|
59
|
+
* 3. ~/.claude/plugins/installed_plugins.json exists → "claude"
|
|
60
|
+
* 4. neither → null
|
|
61
|
+
*/
|
|
62
|
+
export function detectHost() {
|
|
63
|
+
const claudeInstalled = existsSync(INSTALLED_PLUGINS_PATH);
|
|
64
|
+
if (process.env.CLAUDECODE === "1" && claudeInstalled)
|
|
65
|
+
return "claude";
|
|
66
|
+
if (existsSync(codexCacheDir()))
|
|
67
|
+
return "codex";
|
|
68
|
+
if (claudeInstalled)
|
|
69
|
+
return "claude";
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
// ── Update command per host ────────────────────────────────────────
|
|
73
|
+
/** Command to run inside the host to install / upgrade the plugin. */
|
|
74
|
+
export function pluginUpdateCommand(host) {
|
|
75
|
+
switch (host) {
|
|
76
|
+
case "codex":
|
|
77
|
+
return "/plugins install mthds";
|
|
78
|
+
case "claude":
|
|
79
|
+
return "claude plugin install mthds@mthds-plugins";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// ── Claude registry reader ─────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Read the installed plugin version from Claude Code's registry.
|
|
30
85
|
*
|
|
31
86
|
* Returns:
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* - `null` — not in Claude Code (file absent or corrupt)
|
|
87
|
+
* - { version: "0.10.1" } — plugin entry parsed successfully
|
|
88
|
+
* - { version: null } — registry missing / corrupt / unknown sentinel
|
|
89
|
+
* - { version: "missing" } — registry present, plugin not installed
|
|
36
90
|
*/
|
|
37
|
-
|
|
91
|
+
function readClaudePluginVersion() {
|
|
38
92
|
let content;
|
|
39
93
|
try {
|
|
40
94
|
content = readFileSync(INSTALLED_PLUGINS_PATH, "utf-8");
|
|
@@ -42,25 +96,24 @@ export function checkPluginVersion() {
|
|
|
42
96
|
catch (err) {
|
|
43
97
|
const code = err.code;
|
|
44
98
|
if (code === "ENOENT")
|
|
45
|
-
return
|
|
99
|
+
return { kind: "null" };
|
|
46
100
|
process.stderr.write(`Warning: could not read ${INSTALLED_PLUGINS_PATH} (${code ?? String(err)}). Plugin version check skipped.\n`);
|
|
47
|
-
return null;
|
|
101
|
+
return { kind: "null" };
|
|
48
102
|
}
|
|
49
103
|
let parsed;
|
|
50
104
|
try {
|
|
51
105
|
const raw = JSON.parse(content);
|
|
52
106
|
if (!raw || typeof raw !== "object" || !("plugins" in raw))
|
|
53
|
-
return null;
|
|
107
|
+
return { kind: "null" };
|
|
54
108
|
const plugins = raw.plugins;
|
|
55
109
|
if (!plugins || typeof plugins !== "object" || Array.isArray(plugins))
|
|
56
|
-
return null;
|
|
110
|
+
return { kind: "null" };
|
|
57
111
|
parsed = raw;
|
|
58
112
|
}
|
|
59
113
|
catch {
|
|
60
114
|
process.stderr.write(`Warning: ${INSTALLED_PLUGINS_PATH} contains invalid JSON. Plugin version check skipped.\n`);
|
|
61
|
-
return null;
|
|
115
|
+
return { kind: "null" };
|
|
62
116
|
}
|
|
63
|
-
// Try each known plugin key (prod first, then dev)
|
|
64
117
|
let entries;
|
|
65
118
|
for (const key of PLUGIN_KEYS) {
|
|
66
119
|
const candidate = parsed.plugins[key];
|
|
@@ -69,19 +122,134 @@ export function checkPluginVersion() {
|
|
|
69
122
|
break;
|
|
70
123
|
}
|
|
71
124
|
}
|
|
72
|
-
if (!entries)
|
|
73
|
-
|
|
74
|
-
return { s: "missing", v: null, r: MIN_PLUGIN_VERSION };
|
|
75
|
-
}
|
|
76
|
-
// Prefer scope=user; fall back to first entry
|
|
125
|
+
if (!entries)
|
|
126
|
+
return { kind: "missing" };
|
|
77
127
|
const userEntry = entries.find((e) => e.scope === "user") ?? entries[0];
|
|
78
128
|
const version = userEntry.version;
|
|
79
|
-
if (!version || typeof version !== "string")
|
|
129
|
+
if (!version || typeof version !== "string")
|
|
130
|
+
return { kind: "missing" };
|
|
131
|
+
return { kind: "version", version };
|
|
132
|
+
}
|
|
133
|
+
// ── Codex registry reader ──────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Read the installed plugin version from Codex's plugin cache.
|
|
136
|
+
*
|
|
137
|
+
* Codex stores plugins at:
|
|
138
|
+
* $CODEX_HOME/plugins/cache/<marketplace>/<plugin>/<version>/.codex-plugin/plugin.json
|
|
139
|
+
*
|
|
140
|
+
* The directory name is the version. A directory named "local" is Codex's
|
|
141
|
+
* dev sentinel — treat it like an unparseable version (don't nag).
|
|
142
|
+
*
|
|
143
|
+
* Returns the same shape as readClaudePluginVersion().
|
|
144
|
+
*/
|
|
145
|
+
export function readCodexPluginVersion() {
|
|
146
|
+
const cacheRoot = codexCacheDir();
|
|
147
|
+
// Track whether any plugin dir was unreadable for a non-"absent" reason
|
|
148
|
+
// (EACCES, EIO, ...). If so, don't claim "missing" at the end — that would
|
|
149
|
+
// tell the user to reinstall a plugin we couldn't actually inspect.
|
|
150
|
+
let sawReadError = false;
|
|
151
|
+
// Track whether any plugin dir had entries but none parsed as semver. If so,
|
|
152
|
+
// don't claim "missing" at the end — the install exists, we just don't
|
|
153
|
+
// recognize the version layout (e.g. a future Codex build).
|
|
154
|
+
let sawUnparseableDirs = false;
|
|
155
|
+
for (const pluginName of CODEX_PLUGIN_NAMES) {
|
|
156
|
+
const pluginDir = join(cacheRoot, CODEX_MARKETPLACE, pluginName);
|
|
157
|
+
let names;
|
|
158
|
+
try {
|
|
159
|
+
names = readdirSync(pluginDir);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
const code = err.code;
|
|
163
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") {
|
|
164
|
+
sawReadError = true;
|
|
165
|
+
process.stderr.write(`Warning: could not read Codex plugin dir ${pluginDir} (${code ?? String(err)}). Plugin version check skipped.\n`);
|
|
166
|
+
}
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const versionDirs = [];
|
|
170
|
+
for (const name of names) {
|
|
171
|
+
if (name.startsWith("."))
|
|
172
|
+
continue;
|
|
173
|
+
try {
|
|
174
|
+
if (!statSync(join(pluginDir, name)).isDirectory())
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
versionDirs.push(name);
|
|
181
|
+
}
|
|
182
|
+
if (versionDirs.length === 0)
|
|
183
|
+
continue;
|
|
184
|
+
// Codex's dev sentinel — caller should treat this like "unparseable".
|
|
185
|
+
if (versionDirs.includes(CODEX_LOCAL_VERSION))
|
|
186
|
+
return { kind: "null" };
|
|
187
|
+
// Pick the highest semver-coercible version directory.
|
|
188
|
+
let bestDirName = null;
|
|
189
|
+
let bestVersion = null;
|
|
190
|
+
for (const name of versionDirs) {
|
|
191
|
+
const coerced = semver.coerce(name);
|
|
192
|
+
if (!coerced)
|
|
193
|
+
continue;
|
|
194
|
+
if (!bestVersion || semver.gt(coerced.version, bestVersion)) {
|
|
195
|
+
bestDirName = name;
|
|
196
|
+
bestVersion = coerced.version;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!bestDirName) {
|
|
200
|
+
// Directories exist but none parse as semver — treat as unknown and
|
|
201
|
+
// fall through to the next candidate plugin name (e.g. mthds-dev).
|
|
202
|
+
sawUnparseableDirs = true;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
// Prefer the manifest's version field when present (covers renamed dirs).
|
|
206
|
+
const manifestPath = join(pluginDir, bestDirName, ".codex-plugin", "plugin.json");
|
|
207
|
+
let manifestVersion = null;
|
|
208
|
+
try {
|
|
209
|
+
const raw = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
210
|
+
if (raw && typeof raw === "object") {
|
|
211
|
+
const v = raw.version;
|
|
212
|
+
if (typeof v === "string" && v.length > 0) {
|
|
213
|
+
manifestVersion = v;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
/* fall back to directory name */
|
|
219
|
+
}
|
|
220
|
+
const finalVersion = manifestVersion ?? bestDirName;
|
|
221
|
+
return { kind: "version", version: finalVersion };
|
|
222
|
+
}
|
|
223
|
+
// No matching plugin directory under the Codex cache. If we couldn't even
|
|
224
|
+
// read one of the candidate dirs, or if we saw dirs with non-semver names,
|
|
225
|
+
// treat as "skip" — telling the user to reinstall when the real cause was
|
|
226
|
+
// unreadable perms or an unrecognized version layout would be misleading.
|
|
227
|
+
return sawReadError || sawUnparseableDirs ? { kind: "null" } : { kind: "missing" };
|
|
228
|
+
}
|
|
229
|
+
// ── Main ───────────────────────────────────────────────────────────
|
|
230
|
+
/**
|
|
231
|
+
* Check the installed plugin version against MIN_PLUGIN_VERSION for the
|
|
232
|
+
* given host.
|
|
233
|
+
*
|
|
234
|
+
* Returns:
|
|
235
|
+
* - `{ s: "ok", v: "0.10.1" }` — satisfies constraint
|
|
236
|
+
* - `{ s: "outdated", v: "0.6.2", r: ">=0.10.1" }` — too old
|
|
237
|
+
* - `{ s: "missing", v: null, r: ">=0.10.1" }` — registry present, plugin absent
|
|
238
|
+
* - `null` — registry unreadable, unparseable, or dev install
|
|
239
|
+
*
|
|
240
|
+
* Caller is expected to call `detectHost()` first and skip when it returns
|
|
241
|
+
* null — there is no "no host" return value here.
|
|
242
|
+
*/
|
|
243
|
+
export function checkPluginVersion(host) {
|
|
244
|
+
const result = host === "codex" ? readCodexPluginVersion() : readClaudePluginVersion();
|
|
245
|
+
if (result.kind === "null")
|
|
246
|
+
return null;
|
|
247
|
+
if (result.kind === "missing") {
|
|
80
248
|
return { s: "missing", v: null, r: MIN_PLUGIN_VERSION };
|
|
81
249
|
}
|
|
82
|
-
const coerced = semver.coerce(version);
|
|
250
|
+
const coerced = semver.coerce(result.version);
|
|
83
251
|
if (!coerced) {
|
|
84
|
-
// Unparseable version
|
|
252
|
+
// Unparseable version string — don't nag (matches "unknown" handling).
|
|
85
253
|
return null;
|
|
86
254
|
}
|
|
87
255
|
if (semver.satisfies(coerced, MIN_PLUGIN_VERSION)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-version.js","sourceRoot":"","sources":["../../src/agent/plugin-version.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-version.js","sourceRoot":"","sources":["../../src/agent/plugin-version.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cache for update-check results.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Primary location: ~/.mthds/state/last-update-check.
|
|
5
|
+
* Fallback location: $TMPDIR/mthds-agent/last-update-check — used when the
|
|
6
|
+
* primary location is not writable (e.g. Codex's workspaceWrite sandbox
|
|
7
|
+
* permits writes only under cwd / configured roots / $TMPDIR, not under the
|
|
8
|
+
* user's home dir).
|
|
9
|
+
*
|
|
10
|
+
* Two-line format:
|
|
5
11
|
* Line 1: aggregate status (UP_TO_DATE or UPGRADE_AVAILABLE)
|
|
6
12
|
* Line 2: JSON payload with per-binary check results
|
|
7
13
|
*
|
|
@@ -35,10 +41,15 @@ export declare function ensureStateDir(): void;
|
|
|
35
41
|
export declare function computeAggregate(payload: CachePayload): AggregateStatus;
|
|
36
42
|
/**
|
|
37
43
|
* Read the update-check cache.
|
|
38
|
-
*
|
|
44
|
+
*
|
|
45
|
+
* Tries the primary path first; on miss / corrupt / expired falls back to
|
|
46
|
+
* the $TMPDIR location. Returns null only when both lookups fail.
|
|
39
47
|
*/
|
|
40
48
|
export declare function readCache(): CacheResult | null;
|
|
41
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Write cache. Tries the primary path first; on sandbox / permission failures
|
|
51
|
+
* falls back to $TMPDIR. Both failing emits at most one warning per process.
|
|
52
|
+
*/
|
|
42
53
|
export declare function writeCache(result: CacheResult): void;
|
|
43
|
-
/** Delete cache
|
|
54
|
+
/** Delete cache files (used by --force and after upgrade). */
|
|
44
55
|
export declare function clearCache(): void;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cache for update-check results.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Primary location: ~/.mthds/state/last-update-check.
|
|
5
|
+
* Fallback location: $TMPDIR/mthds-agent/last-update-check — used when the
|
|
6
|
+
* primary location is not writable (e.g. Codex's workspaceWrite sandbox
|
|
7
|
+
* permits writes only under cwd / configured roots / $TMPDIR, not under the
|
|
8
|
+
* user's home dir).
|
|
9
|
+
*
|
|
10
|
+
* Two-line format:
|
|
5
11
|
* Line 1: aggregate status (UP_TO_DATE or UPGRADE_AVAILABLE)
|
|
6
12
|
* Line 2: JSON payload with per-binary check results
|
|
7
13
|
*
|
|
@@ -9,17 +15,24 @@
|
|
|
9
15
|
* Split TTL: 60 min for UP_TO_DATE, 720 min for UPGRADE_AVAILABLE.
|
|
10
16
|
*/
|
|
11
17
|
import { join } from "node:path";
|
|
12
|
-
import { homedir } from "node:os";
|
|
18
|
+
import { homedir, tmpdir } from "node:os";
|
|
13
19
|
import { mkdirSync, readFileSync, writeFileSync, unlinkSync, statSync, } from "node:fs";
|
|
14
20
|
// ── Constants ──────────────────────────────────────────────────────
|
|
15
21
|
export const STATE_DIR = join(homedir(), ".mthds", "state");
|
|
16
|
-
const
|
|
22
|
+
const PRIMARY_CACHE_PATH = join(STATE_DIR, "last-update-check");
|
|
23
|
+
const FALLBACK_DIR = join(tmpdir(), "mthds-agent");
|
|
24
|
+
const FALLBACK_CACHE_PATH = join(FALLBACK_DIR, "last-update-check");
|
|
17
25
|
const TTL_UP_TO_DATE_MS = 60 * 60 * 1000; // 60 min
|
|
18
26
|
const TTL_UPGRADE_AVAILABLE_MS = 720 * 60 * 1000; // 720 min (12 hours)
|
|
19
27
|
const VALID_AGGREGATES = new Set([
|
|
20
28
|
"UP_TO_DATE",
|
|
21
29
|
"UPGRADE_AVAILABLE",
|
|
22
30
|
]);
|
|
31
|
+
const SANDBOX_WRITE_ERRORS = new Set([
|
|
32
|
+
"EPERM",
|
|
33
|
+
"EACCES",
|
|
34
|
+
"EROFS",
|
|
35
|
+
]);
|
|
23
36
|
// ── Validation ──────────────────────────────────────────────────────
|
|
24
37
|
function isValidPayload(p) {
|
|
25
38
|
if (!p || typeof p !== "object")
|
|
@@ -51,6 +64,8 @@ function isValidPayload(p) {
|
|
|
51
64
|
}
|
|
52
65
|
return true;
|
|
53
66
|
}
|
|
67
|
+
// ── Per-process warning latch ──────────────────────────────────────
|
|
68
|
+
let warnedAboutCacheWrite = false;
|
|
54
69
|
// ── Functions ──────────────────────────────────────────────────────
|
|
55
70
|
/** Ensure the state directory exists. */
|
|
56
71
|
export function ensureStateDir() {
|
|
@@ -70,17 +85,13 @@ export function computeAggregate(payload) {
|
|
|
70
85
|
? "UP_TO_DATE"
|
|
71
86
|
: "UPGRADE_AVAILABLE";
|
|
72
87
|
}
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
* Returns null if the file is missing, corrupt, or expired.
|
|
76
|
-
*/
|
|
77
|
-
export function readCache() {
|
|
78
|
-
// Stat first so worst-case TOCTOU treats fresh data as stale (safe direction)
|
|
88
|
+
/** Read a cache file at the given path. Returns null on any failure. */
|
|
89
|
+
function readCacheAt(path) {
|
|
79
90
|
let mtimeMs;
|
|
80
91
|
let content;
|
|
81
92
|
try {
|
|
82
|
-
mtimeMs = statSync(
|
|
83
|
-
content = readFileSync(
|
|
93
|
+
mtimeMs = statSync(path).mtimeMs;
|
|
94
|
+
content = readFileSync(path, "utf-8");
|
|
84
95
|
}
|
|
85
96
|
catch {
|
|
86
97
|
return null;
|
|
@@ -101,35 +112,74 @@ export function readCache() {
|
|
|
101
112
|
catch {
|
|
102
113
|
return null;
|
|
103
114
|
}
|
|
104
|
-
|
|
105
|
-
const ttl = aggregate === "UP_TO_DATE"
|
|
106
|
-
? TTL_UP_TO_DATE_MS
|
|
107
|
-
: TTL_UPGRADE_AVAILABLE_MS;
|
|
115
|
+
const ttl = aggregate === "UP_TO_DATE" ? TTL_UP_TO_DATE_MS : TTL_UPGRADE_AVAILABLE_MS;
|
|
108
116
|
const age = Date.now() - mtimeMs;
|
|
109
117
|
// Negative age beyond 1 minute means clock skew — treat as expired
|
|
110
118
|
if (age < -60_000 || age > ttl)
|
|
111
119
|
return null;
|
|
112
120
|
return { aggregate: aggregate, payload };
|
|
113
121
|
}
|
|
114
|
-
/**
|
|
115
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Read the update-check cache.
|
|
124
|
+
*
|
|
125
|
+
* Tries the primary path first; on miss / corrupt / expired falls back to
|
|
126
|
+
* the $TMPDIR location. Returns null only when both lookups fail.
|
|
127
|
+
*/
|
|
128
|
+
export function readCache() {
|
|
129
|
+
return readCacheAt(PRIMARY_CACHE_PATH) ?? readCacheAt(FALLBACK_CACHE_PATH);
|
|
130
|
+
}
|
|
131
|
+
function writeCacheAt(dir, file, content) {
|
|
116
132
|
try {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
133
|
+
mkdirSync(dir, { recursive: true });
|
|
134
|
+
writeFileSync(file, content, "utf-8");
|
|
135
|
+
return { ok: true };
|
|
120
136
|
}
|
|
121
137
|
catch (err) {
|
|
122
|
-
const code = err.code;
|
|
123
|
-
|
|
138
|
+
const code = err.code ?? String(err);
|
|
139
|
+
return { ok: false, code };
|
|
124
140
|
}
|
|
125
141
|
}
|
|
126
|
-
/**
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Write cache. Tries the primary path first; on sandbox / permission failures
|
|
144
|
+
* falls back to $TMPDIR. Both failing emits at most one warning per process.
|
|
145
|
+
*/
|
|
146
|
+
export function writeCache(result) {
|
|
147
|
+
const content = result.aggregate + "\n" + JSON.stringify(result.payload) + "\n";
|
|
148
|
+
const primary = writeCacheAt(STATE_DIR, PRIMARY_CACHE_PATH, content);
|
|
149
|
+
if (primary.ok)
|
|
150
|
+
return;
|
|
151
|
+
// Only fall back for the sandbox/perm family of errors. Other failures
|
|
152
|
+
// (ENOSPC, IO errors, ...) are not improved by retrying in $TMPDIR, so we
|
|
153
|
+
// surface them via the same one-shot warning path.
|
|
154
|
+
if (primary.code && SANDBOX_WRITE_ERRORS.has(primary.code)) {
|
|
155
|
+
const fallback = writeCacheAt(FALLBACK_DIR, FALLBACK_CACHE_PATH, content);
|
|
156
|
+
if (fallback.ok)
|
|
157
|
+
return;
|
|
158
|
+
emitWriteWarning(primary.code, fallback.code);
|
|
159
|
+
return;
|
|
130
160
|
}
|
|
131
|
-
|
|
132
|
-
|
|
161
|
+
emitWriteWarning(primary.code);
|
|
162
|
+
}
|
|
163
|
+
function emitWriteWarning(primaryCode, fallbackCode) {
|
|
164
|
+
if (warnedAboutCacheWrite)
|
|
165
|
+
return;
|
|
166
|
+
warnedAboutCacheWrite = true;
|
|
167
|
+
const detail = fallbackCode
|
|
168
|
+
? `primary=${primaryCode ?? "?"}, fallback=${fallbackCode}`
|
|
169
|
+
: (primaryCode ?? "?");
|
|
170
|
+
process.stderr.write(`Warning: could not write update-check cache (${detail}). Check will run again next time.\n`);
|
|
171
|
+
}
|
|
172
|
+
/** Delete cache files (used by --force and after upgrade). */
|
|
173
|
+
export function clearCache() {
|
|
174
|
+
for (const p of [PRIMARY_CACHE_PATH, FALLBACK_CACHE_PATH]) {
|
|
175
|
+
try {
|
|
176
|
+
unlinkSync(p);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// File may not exist, or the sandbox blocks the unlink — neither
|
|
180
|
+
// matters here: writeCache also can't have written there, so there's
|
|
181
|
+
// nothing to remove.
|
|
182
|
+
}
|
|
133
183
|
}
|
|
134
184
|
}
|
|
135
185
|
//# sourceMappingURL=update-cache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-cache.js","sourceRoot":"","sources":["../../src/agent/update-cache.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"update-cache.js","sourceRoot":"","sources":["../../src/agent/update-cache.ts"],"names":[],"mappings":"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"}
|