Просмотр исходного кода

fix: support the opencode2 beta-18743+ plugin loader

The v2 loader rejects file-path plugin config entries ("configured
plugin path must be a directory"), so the documented dist/server.js
registration no longer activates the plugin. build:v2 now emits the
real bundle at dist/server/index.js (the directory entrypoint) and the
exports map resolves ./server directly to it.

verify-release-artifact now requires dist/server/index.js, imports the
installed ./server subpath from a clean temp install, and parses the
object-form npm pack --json output emitted by npm >= 12.
GoldJohnKing 2 недель назад
Родитель
Сommit
0a04414b27
2 измененных файлов с 43 добавлено и 12 удалено
  1. 2 2
      package.json
  2. 41 10
      scripts/verify-release-artifact.ts

+ 2 - 2
package.json

@@ -11,7 +11,7 @@
       "types": "./dist/index.d.ts"
     },
     "./server": {
-      "import": "./dist/server.js"
+      "import": "./dist/server/index.js"
     },
     "./tui": {
       "import": "./dist/tui2.js",
@@ -57,7 +57,7 @@
   "scripts": {
     "clean:dist": "bun -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
     "build:plugin": "bun build src/index.ts src/tui.ts --outdir dist --target node --format esm --external @opencode-ai/plugin --external @opencode-ai/plugin/tui --external @opencode-ai/sdk --external @opencode-ai/sdk/v2 --external @opentui/core --external @opentui/solid --external solid-js --external jsdom --external zod",
-    "build:v2": "bun build src/index.ts --outfile dist/server.js --target node --format esm --external jsdom",
+    "build:v2": "bun build src/index.ts --outfile dist/server/index.js --target node --format esm --external jsdom",
     "build:tui": "bun build src/v2/tui.ts --outfile dist/tui2.js --target node --format esm --external @opencode-ai/plugin --external @opencode-ai/plugin/tui --external @opencode-ai/sdk --external @opencode-ai/sdk/v2 --external @opentui/core --external @opentui/solid --external solid-js --external jsdom",
     "build:cli": "bun build src/cli/index.ts --outdir dist/cli --target node --format esm --external @opencode-ai/plugin --external @opencode-ai/plugin/tui --external @opencode-ai/sdk --external @opencode-ai/sdk/v2 --external jsdom --external zod",
     "build": "bun run clean:dist && bun run build:plugin && bun run build:v2 && bun run build:tui && bun run build:cli && tsc --emitDeclarationOnly && bun run generate-schema",

+ 41 - 10
scripts/verify-release-artifact.ts

@@ -28,7 +28,7 @@ const packagedRequiredFiles = [
   'LICENSE',
   'dist/index.js',
   'dist/index.d.ts',
-  'dist/server.js',
+  'dist/server/index.js',
   'dist/tui.js',
   'dist/tui.d.ts',
   'dist/cli/index.js',
@@ -65,18 +65,34 @@ function run(command: string, args: string[], options: { cwd?: string } = {}) {
   return result.stdout.trim();
 }
 
-function parsePackJson(output: string) {
-  const start = output.indexOf('[');
-  const end = output.lastIndexOf(']');
+type PackEntry = {
+  filename?: string;
+  files?: Array<{ path: string }>;
+};
 
-  if (start === -1 || end === -1 || end < start) {
-    fail(`Could not locate npm pack JSON output:\n${output}`);
+function parsePackJson(output: string): PackEntry[] {
+  // npm pack --json historically emitted an array of entries; npm >= 12
+  // emits an object keyed by package name. Accept both shapes.
+  const arrayStart = output.indexOf('[');
+  const objectStart = output.indexOf('{');
+
+  if (arrayStart !== -1 && (objectStart === -1 || arrayStart < objectStart)) {
+    const end = output.lastIndexOf(']');
+    if (end === -1 || end < arrayStart) {
+      fail(`Could not locate npm pack JSON output:\n${output}`);
+    }
+    return JSON.parse(output.slice(arrayStart, end + 1)) as PackEntry[];
   }
 
-  return JSON.parse(output.slice(start, end + 1)) as Array<{
-    filename?: string;
-    files?: Array<{ path: string }>;
-  }>;
+  const end = output.lastIndexOf('}');
+  if (objectStart === -1 || end === -1 || end < objectStart) {
+    fail(`Could not locate npm pack JSON output:\n${output}`);
+  }
+  const parsed = JSON.parse(output.slice(objectStart, end + 1)) as Record<
+    string,
+    PackEntry | PackEntry[]
+  >;
+  return Object.values(parsed).flat() as PackEntry[];
 }
 
 function walkFiles(dir: string): string[] {
@@ -202,6 +218,21 @@ function verifyFreshInstall(tarballPath: string) {
     ].join('\n');
     console.log('Importing installed TUI entrypoint...');
     run('bun', ['--eval', tuiSmokeScript], { cwd: installDir });
+
+    // v2 hosts install this package with `subpaths: ["server", ""]`; the
+    // exports map must resolve ./server to the self-contained bundle.
+    const serverSmokeScript = [
+      "import pkg from 'oh-my-opencode-slim/server';",
+      "if (pkg?.id !== 'oh-my-opencode-slim') throw new Error('server export has an unexpected plugin id');",
+      "if (typeof pkg.server !== 'function') throw new Error('server export is missing a v1 plugin factory');",
+      "if (typeof pkg.setup !== 'function') throw new Error('server export is missing a v2 setup factory');",
+      "console.log('server package loads');",
+      'process.exit(0);',
+    ].join('\n');
+    console.log('Importing installed server subpath entrypoint...');
+    run('node', ['--input-type=module', '--eval', serverSmokeScript], {
+      cwd: installDir,
+    });
   } finally {
     rmSync(tempRoot, { recursive: true, force: true });
   }