From 3f0f910f7b3efdd0b7836a5812821973bbe15817 Mon Sep 17 00:00:00 2001 From: Yuu Toriyama Date: Thu, 14 Aug 2025 04:46:21 +0900 Subject: [PATCH] Fix: Error [ERR_DLOPEN_FAILED] (#1546) --- .github/workflows/deploy.yml | 2 +- .github/workflows/publish-vscode.yml | 2 +- bun.lock | 6 +++ package.json | 7 ++- packages/opencode/package.json | 1 + packages/opencode/src/tool/bash.ts | 27 +++++++++-- packages/opencode/src/tool/test.ts | 69 +++++++++++++++++----------- 7 files changed, 79 insertions(+), 35 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 314ae624..a2e69410 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,7 +17,7 @@ jobs: - uses: oven-sh/setup-bun@v1 with: - bun-version: 1.2.17 + bun-version: 1.2.19 - run: bun install diff --git a/.github/workflows/publish-vscode.yml b/.github/workflows/publish-vscode.yml index 9f98f906..5cb406f6 100644 --- a/.github/workflows/publish-vscode.yml +++ b/.github/workflows/publish-vscode.yml @@ -21,7 +21,7 @@ jobs: - uses: oven-sh/setup-bun@v2 with: - bun-version: 1.2.17 + bun-version: 1.2.19 - run: git fetch --force --tags - run: bun install -g @vscode/vsce diff --git a/bun.lock b/bun.lock index 9dd75254..929e81b8 100644 --- a/bun.lock +++ b/bun.lock @@ -113,6 +113,7 @@ "tree-sitter-bash": "0.23.3", "turndown": "7.2.0", "vscode-jsonrpc": "8.2.1", + "web-tree-sitter": "0.22.6", "xdg-basedir": "5.1.0", "yargs": "18.0.0", "zod": "catalog:", @@ -189,6 +190,9 @@ "sharp", "esbuild", "protobufjs", + "tree-sitter", + "web-tree-sitter", + "tree-sitter-bash", ], "catalog": { "@hono/zod-validator": "0.4.2", @@ -2481,6 +2485,8 @@ "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], + "web-tree-sitter": ["web-tree-sitter@0.22.6", "", {}, "sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q=="], + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], diff --git a/package.json b/package.json index d26b9c06..bfd1976f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "name": "opencode", "private": true, "type": "module", - "packageManager": "bun@1.2.14", + "packageManager": "bun@1.2.19", "scripts": { "dev": "bun run --conditions=development packages/opencode/src/index.ts", "typecheck": "bun run --filter='*' typecheck", @@ -46,7 +46,10 @@ "trustedDependencies": [ "esbuild", "protobufjs", - "sharp" + "sharp", + "tree-sitter", + "tree-sitter-bash", + "web-tree-sitter" ], "patchedDependencies": {} } diff --git a/packages/opencode/package.json b/packages/opencode/package.json index be7664e8..e7853e7a 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -52,6 +52,7 @@ "remeda": "catalog:", "tree-sitter": "0.22.4", "tree-sitter-bash": "0.23.3", + "web-tree-sitter": "0.22.6", "turndown": "7.2.0", "vscode-jsonrpc": "8.2.1", "xdg-basedir": "5.1.0", diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts index b0fe920b..da1559c5 100644 --- a/packages/opencode/src/tool/bash.ts +++ b/packages/opencode/src/tool/bash.ts @@ -19,11 +19,28 @@ const MAX_TIMEOUT = 10 * 60 * 1000 const log = Log.create({ service: "bash-tool" }) const parser = lazy(async () => { - const { default: Parser } = await import("tree-sitter") - const Bash = await import("tree-sitter-bash") - const p = new Parser() - p.setLanguage(Bash.language as any) - return p + try { + const { default: Parser } = await import("tree-sitter") + const Bash = await import("tree-sitter-bash") + const p = new Parser() + p.setLanguage(Bash.language as any) + return p + } catch (e) { + const { default: Parser } = await import("web-tree-sitter") + const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, { with: { type: "wasm" } }) + await Parser.init({ + locateFile() { + return treeWasm + }, + }) + const { default: bashWasm } = await import("tree-sitter-bash/tree-sitter-bash.wasm" as string, { + with: { type: "wasm" }, + }) + const bashLanguage = await Parser.Language.load(bashWasm) + const p = new Parser() + p.setLanguage(bashLanguage) + return p + } }) export const BashTool = Tool.define("bash", { diff --git a/packages/opencode/src/tool/test.ts b/packages/opencode/src/tool/test.ts index 4ac81982..138d92fb 100644 --- a/packages/opencode/src/tool/test.ts +++ b/packages/opencode/src/tool/test.ts @@ -1,53 +1,70 @@ -import Parser from "tree-sitter"; -import Bash from "tree-sitter-bash"; +const parser = async () => { + try { + const { default: Parser } = await import("tree-sitter") + const Bash = await import("tree-sitter-bash") + const p = new Parser() + p.setLanguage(Bash.language as any) + return p + } catch (e) { + const { default: Parser } = await import("web-tree-sitter") + const { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm" as string, { with: { type: "wasm" } }) + await Parser.init({ + locateFile() { + return treeWasm + }, + }) + const { default: bashWasm } = await import("tree-sitter-bash/tree-sitter-bash.wasm" as string, { + with: { type: "wasm" }, + }) + const bashLanguage = await Parser.Language.load(bashWasm) + const p = new Parser() + p.setLanguage(bashLanguage) + return p + } +} -const parser = new Parser(); -parser.setLanguage(Bash.language as any); +const sourceCode = `cd --foo foo/bar && echo "hello" && cd ../baz` -const sourceCode = `cd --foo foo/bar && echo "hello" && cd ../baz`; - -const tree = parser.parse(sourceCode); +const tree = await parser().then((p) => p.parse(sourceCode)) // Function to extract commands and arguments -function extractCommands( - node: any, -): Array<{ command: string; args: string[] }> { - const commands: Array<{ command: string; args: string[] }> = []; +function extractCommands(node: any): Array<{ command: string; args: string[] }> { + const commands: Array<{ command: string; args: string[] }> = [] function traverse(node: any) { if (node.type === "command") { - const commandNode = node.child(0); + const commandNode = node.child(0) if (commandNode) { - const command = commandNode.text; - const args: string[] = []; + const command = commandNode.text + const args: string[] = [] // Extract arguments for (let i = 1; i < node.childCount; i++) { - const child = node.child(i); + const child = node.child(i) if (child && child.type === "word") { - args.push(child.text); + args.push(child.text) } } - commands.push({ command, args }); + commands.push({ command, args }) } } // Traverse children for (let i = 0; i < node.childCount; i++) { - traverse(node.child(i)); + traverse(node.child(i)) } } - traverse(node); - return commands; + traverse(node) + return commands } // Extract and display commands -console.log("Source code: " + sourceCode); -const commands = extractCommands(tree.rootNode); -console.log("Extracted commands:"); +console.log("Source code: " + sourceCode) +const commands = extractCommands(tree.rootNode) +console.log("Extracted commands:") commands.forEach((cmd, index) => { - console.log(`${index + 1}. Command: ${cmd.command}`); - console.log(` Args: [${cmd.args.join(", ")}]`); -}); + console.log(`${index + 1}. Command: ${cmd.command}`) + console.log(` Args: [${cmd.args.join(", ")}]`) +})