@uniqbit/mate-core 0.15.4-canary.8 → 0.15.4-canary.9

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.15.4-canary.8",
3
+ "version": "0.15.4-canary.9",
4
4
  "description": "Core framework and plugin APIs for Mate.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -37,7 +37,9 @@ export function isContextModeNodeVersionSupported(version: string): boolean {
37
37
  }
38
38
 
39
39
  export function validateContextModeNodeRuntime(): void {
40
- const result = spawnSync("node", ["--version"], { encoding: "utf8" });
40
+ // env passed explicitly: bun's spawnSync otherwise ignores in-process PATH
41
+ // changes when resolving the executable.
42
+ const result = spawnSync("node", ["--version"], { encoding: "utf8", env: process.env });
41
43
  const version = result.stdout?.trim() ?? "";
42
44
  if (result.status !== 0 || !isContextModeNodeVersionSupported(version)) {
43
45
  throw new Error(
@@ -83,7 +85,7 @@ export async function installContextModePackage(companionPath: string): Promise<
83
85
  const result = spawnSync(
84
86
  "npm",
85
87
  ["install", "--no-audit", "--no-fund", "--silent", "--registry", PUBLIC_NPM_REGISTRY],
86
- { cwd: installDir, encoding: "utf8" },
88
+ { cwd: installDir, encoding: "utf8", env: process.env },
87
89
  );
88
90
  if (result.error || result.status !== 0) {
89
91
  throw new Error(
@@ -9,61 +9,15 @@ import {
9
9
  getOpenCodePluginPackageReference,
10
10
  isMateOpenCodePluginReference,
11
11
  } from "../../opencode-plugin-package";
12
+ import {
13
+ getOpenCodePluginReferences,
14
+ mergeOpenCodeConfigContent,
15
+ readOpenCodeConfig,
16
+ } from "../../../tools/setup/providers/opencode-format";
12
17
  import { buildOpenCodeGuidance } from "../opencode-guidance";
13
18
  import { LaunchPreflightError } from "../types";
14
19
  import { type AdapterContext, LaunchAdapter } from "./base";
15
20
 
16
- function isRecord(value: unknown): value is Record<string, unknown> {
17
- return typeof value === "object" && value !== null && !Array.isArray(value);
18
- }
19
-
20
- function mergeConfig(target: Record<string, unknown>, source: Record<string, unknown>): void {
21
- for (const [key, sourceValue] of Object.entries(source)) {
22
- const targetValue = target[key];
23
- if (isRecord(targetValue) && isRecord(sourceValue)) {
24
- mergeConfig(targetValue, sourceValue);
25
- continue;
26
- }
27
-
28
- target[key] = sourceValue;
29
- }
30
- }
31
-
32
- function mergeOpenCodeConfigContent(
33
- overlay: Record<string, unknown>,
34
- env: NodeJS.ProcessEnv = process.env,
35
- options: { appendSkillPaths?: string[] } = {},
36
- ): string {
37
- let config: Record<string, unknown> = {};
38
- const existing = env.OPENCODE_CONFIG_CONTENT;
39
-
40
- if (existing) {
41
- try {
42
- const parsed = JSON.parse(existing) as unknown;
43
- if (isRecord(parsed)) {
44
- config = parsed;
45
- }
46
- } catch {
47
- // Ignore invalid inherited config content rather than breaking launch.
48
- }
49
- }
50
-
51
- mergeConfig(config, overlay);
52
-
53
- if (options.appendSkillPaths && options.appendSkillPaths.length > 0) {
54
- const skills = isRecord(config.skills) ? config.skills : {};
55
- const paths = Array.isArray(skills.paths) ? skills.paths : [];
56
- const existingPaths = new Set(paths);
57
- skills.paths = [
58
- ...paths,
59
- ...options.appendSkillPaths.filter((skillPath) => !existingPaths.has(skillPath)),
60
- ];
61
- config.skills = skills;
62
- }
63
-
64
- return JSON.stringify(config);
65
- }
66
-
67
21
  export class OpenCodeAdapter extends LaunchAdapter {
68
22
  readonly toolName = "opencode";
69
23
  readonly interactive = true;
@@ -190,18 +144,14 @@ export class OpenCodeAdapter extends LaunchAdapter {
190
144
  ): Promise<string[]> {
191
145
  const configPath = path.join(context.companionPath, configFile);
192
146
 
193
- let config: unknown;
194
- try {
195
- config = JSON.parse(await fs.readFile(configPath, "utf8"));
196
- } catch {
197
- return [`Unreadable OpenCode configuration: ${configPath}`];
198
- }
199
- if (!isRecord(config)) {
147
+ const { present, config } = await readOpenCodeConfig(configPath);
148
+ if (!present) {
200
149
  return [`Unreadable OpenCode configuration: ${configPath}`];
201
150
  }
202
151
 
203
- const plugins = Array.isArray(config.plugin) ? (config.plugin as unknown[]) : [];
204
- const mateReferences = plugins.filter(isMateOpenCodePluginReference) as string[];
152
+ const mateReferences = getOpenCodePluginReferences(config).filter(
153
+ isMateOpenCodePluginReference,
154
+ ) as string[];
205
155
 
206
156
  if (mateReferences.includes(expectedPluginReference)) {
207
157
  return [];