@uniqbit/mate-core 0.17.0-canary.5 → 0.17.0-canary.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniqbit/mate-core",
3
- "version": "0.17.0-canary.5",
3
+ "version": "0.17.0-canary.6",
4
4
  "description": "Core framework and plugin APIs for Mate.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -8,7 +8,9 @@ import { validateGuidanceData, type MateGuidanceFile } from "../../../runtime/gu
8
8
  import {
9
9
  getOpenCodePluginPackageReference,
10
10
  isMateOpenCodePluginReference,
11
+ OPENCODE_PLUGIN_PACKAGE_NAME,
11
12
  } from "../../opencode-plugin-package";
13
+ import { installedVersionAt, isPreinstalledPluginPath } from "../../preinstalled-plugins";
12
14
  import {
13
15
  getOpenCodePluginReferences,
14
16
  mergeOpenCodeConfigContent,
@@ -129,6 +131,27 @@ export class OpenCodeAdapter extends LaunchAdapter {
129
131
  return [];
130
132
  }
131
133
 
134
+ // Setup writes one of two spellings, and both are current: the published
135
+ // spec on an ordinary workstation, and an absolute path into the
136
+ // machine-local workspace where the distribution supplied an installed
137
+ // copy. Comparing only against the spec would refuse the launch on exactly
138
+ // the deployments preinstalled binding exists for.
139
+ //
140
+ // A bound reference carries its version in the package it points at rather
141
+ // than in the string, so staleness is read off disk. It is still caught,
142
+ // and now names the version actually installed.
143
+ const expectedVersion = expectedPluginReference.slice(OPENCODE_PLUGIN_PACKAGE_NAME.length + 1);
144
+ const bound = mateReferences.find((reference) =>
145
+ isPreinstalledPluginPath(reference, OPENCODE_PLUGIN_PACKAGE_NAME),
146
+ );
147
+ if (bound !== undefined) {
148
+ const version = await installedVersionAt(bound);
149
+ if (version === expectedVersion) return [];
150
+ return [
151
+ `Stale Mate plugin package reference in ${configFile}: it points at ${bound}, which is ${version ?? "not installed"} rather than ${expectedVersion}.`,
152
+ ];
153
+ }
154
+
132
155
  if (mateReferences.length > 0) {
133
156
  return [
134
157
  `Stale Mate plugin package reference in ${configFile}: found ${mateReferences.join(", ")}.`,
@@ -36,6 +36,25 @@ export function isPreinstalledPluginPath(entry: unknown, packageName: string): b
36
36
  return normalized.endsWith(`/${packageName}`);
37
37
  }
38
38
 
39
+ /**
40
+ * The version behind a reference bound to an installed copy.
41
+ *
42
+ * A published reference carries its version in the string; a bound one carries
43
+ * it in the package it points at, so staleness has to be read off disk. Shared
44
+ * by every site that validates a bound reference, so they cannot disagree about
45
+ * what "stale" means.
46
+ */
47
+ export async function installedVersionAt(packageRoot: string): Promise<string | undefined> {
48
+ try {
49
+ const manifest = JSON.parse(
50
+ await fs.readFile(path.join(packageRoot, "package.json"), "utf8"),
51
+ ) as { version?: string };
52
+ return manifest.version;
53
+ } catch {
54
+ return undefined;
55
+ }
56
+ }
57
+
39
58
  export class PreinstalledPluginMismatchError extends Error {}
40
59
 
41
60
  /**
@@ -11,7 +11,7 @@ import {
11
11
  validateContextModePackage,
12
12
  } from "../../../lib/context-mode-package";
13
13
  import { warmOpenCodePackageCache } from "../../../lib/opencode-plugin-package";
14
- import { isPreinstalledPluginPath } from "../../../lib/preinstalled-plugins";
14
+ import { installedVersionAt, isPreinstalledPluginPath } from "../../../lib/preinstalled-plugins";
15
15
  import type {
16
16
  CapabilityPlugin,
17
17
  LaunchPreflightContext,
@@ -71,23 +71,6 @@ async function assertNoMcpConflict(ctx: SetupContext, provider: "claude" | "open
71
71
  }
72
72
  }
73
73
 
74
- /**
75
- * The version behind a reference bound to an installed copy.
76
- *
77
- * A published reference carries its version in the string; a bound one carries
78
- * it in the package it points at, so staleness has to be read off disk.
79
- */
80
- async function installedVersionAt(packageRoot: string): Promise<string | undefined> {
81
- try {
82
- const manifest = JSON.parse(
83
- await fs.readFile(path.join(packageRoot, "package.json"), "utf8"),
84
- ) as { version?: string };
85
- return manifest.version;
86
- } catch {
87
- return undefined;
88
- }
89
- }
90
-
91
74
  /**
92
75
  * Both spellings of a current reference are accepted, because the Runtime
93
76
  * Surface writes either one: the published spec on an ordinary workstation, and