Skip to content

Commit 1a4e970

Browse files
fix: 修复类型问题(#267) (#271)
* fix: 修复 Bun 的 polyfill 问题 * fix: 类型修复完成 * feat: 统一所有包的类型文件 * fix: 修复构建问题
1 parent 2273a0b commit 1a4e970

File tree

39 files changed

+187
-131
lines changed

39 files changed

+187
-131
lines changed

CLAUDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ bun run health
5555
# Check unused exports
5656
bun run check:unused
5757

58+
bun run typecheck
59+
5860
# Remote Control Server
5961
bun run rcs
6062

build.ts

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,27 @@ for (const file of files) {
8888
}
8989
}
9090

91+
// Also patch unguarded globalThis.Bun destructuring from third-party deps
92+
// (e.g. @anthropic-ai/sandbox-runtime) so Node.js doesn't crash at import time.
93+
let bunPatched = 0
94+
const BUN_DESTRUCTURE = /var \{([^}]+)\} = globalThis\.Bun;?/g
95+
const BUN_DESTRUCTURE_SAFE = 'var {$1} = typeof globalThis.Bun !== "undefined" ? globalThis.Bun : {};'
96+
for (const file of files) {
97+
if (!file.endsWith('.js')) continue
98+
const filePath = join(outdir, file)
99+
const content = await readFile(filePath, 'utf-8')
100+
if (BUN_DESTRUCTURE.test(content)) {
101+
await writeFile(
102+
filePath,
103+
content.replace(BUN_DESTRUCTURE, BUN_DESTRUCTURE_SAFE),
104+
)
105+
bunPatched++
106+
}
107+
}
108+
BUN_DESTRUCTURE.lastIndex = 0
109+
91110
console.log(
92-
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for Node.js compat)`,
111+
`Bundled ${result.outputs.length} files to ${outdir}/ (patched ${patched} for import.meta.require, ${bunPatched} for Bun destructure)`,
93112
)
94113

95114
// Step 4: Copy native .node addon files (audio-capture)
@@ -119,46 +138,7 @@ const cliNode = join(outdir, 'cli-node.js')
119138

120139
await writeFile(cliBun, '#!/usr/bin/env bun\nimport "./cli.js"\n')
121140

122-
// Node.js entry needs a Bun API polyfill because Bun.build({ target: 'bun' })
123-
// emits globalThis.Bun references (e.g. Bun.$ shell tag in computer-use-input,
124-
// Bun.which in chunk-ys6smqg9) that crash at import time under plain Node.js.
125-
const NODE_BUN_POLYFILL = `#!/usr/bin/env node
126-
// Bun API polyfill for Node.js runtime
127-
if (typeof globalThis.Bun === "undefined") {
128-
const { execFileSync } = await import("child_process");
129-
const { resolve, delimiter } = await import("path");
130-
const { accessSync, constants: { X_OK } } = await import("fs");
131-
function which(bin) {
132-
const isWin = process.platform === "win32";
133-
const pathExt = isWin ? (process.env.PATHEXT || ".EXE").split(";") : [""];
134-
for (const dir of (process.env.PATH || "").split(delimiter)) {
135-
for (const ext of pathExt) {
136-
const candidate = resolve(dir, bin + ext);
137-
try { accessSync(candidate, X_OK); return candidate; } catch {}
138-
}
139-
}
140-
return null;
141-
}
142-
// Bun.$ is the shell template tag (e.g. $\`osascript ...\`). Only used by
143-
// computer-use-input/darwin — stub it so the top-level destructuring
144-
// \`var { $ } = globalThis.Bun\` doesn't crash.
145-
function $(parts, ...args) {
146-
throw new Error("Bun.$ shell API is not available in Node.js. Use Bun runtime for this feature.");
147-
}
148-
function hash(data, seed) {
149-
let h = ((seed || 0) ^ 0x811c9dc5) >>> 0;
150-
for (let i = 0; i < data.length; i++) {
151-
h ^= data.charCodeAt(i);
152-
h = Math.imul(h, 0x01000193) >>> 0;
153-
}
154-
return h;
155-
}
156-
globalThis.Bun = { which, $, hash };
157-
}
158-
import "./cli.js"
159-
`
160-
await writeFile(cliNode, NODE_BUN_POLYFILL)
161-
// NOTE: when new Bun-specific globals appear in bundled output, add them here.
141+
await writeFile(cliNode, '#!/usr/bin/env node\nimport "./cli.js"\n')
162142

163143
// Make both executable
164144
const { chmodSync } = await import('fs')

bun.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "claude-code-best",
3-
"version": "1.3.6",
3+
"version": "1.3.7",
44
"description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant in the terminal",
55
"type": "module",
66
"author": "claude-code-best <claude-code-best@proton.me>",
@@ -52,17 +52,14 @@
5252
"health": "bun run scripts/health-check.ts",
5353
"postinstall": "node scripts/postinstall.cjs && node scripts/setup-chrome-mcp.mjs",
5454
"docs:dev": "npx mintlify dev",
55+
"typecheck": "tsc --noEmit",
5556
"rcs": "bun run scripts/rcs.ts"
5657
},
5758
"dependencies": {
5859
"ws": "^8.20.0",
5960
"@claude-code-best/mcp-chrome-bridge": "^2.0.7"
6061
},
6162
"devDependencies": {
62-
"@types/he": "^1.2.3",
63-
"@langfuse/otel": "^5.1.0",
64-
"@langfuse/tracing": "^5.1.0",
65-
"@types/lodash-es": "^4.17.12",
6663
"@alcalzone/ansi-tokenize": "^0.3.0",
6764
"@ant/claude-for-chrome-mcp": "workspace:*",
6865
"@ant/computer-use-input": "workspace:*",
@@ -76,18 +73,20 @@
7673
"@anthropic-ai/sdk": "^0.80.0",
7774
"@anthropic-ai/vertex-sdk": "^0.14.4",
7875
"@anthropic/ink": "workspace:*",
79-
"@claude-code-best/builtin-tools": "workspace:*",
80-
"@claude-code-best/agent-tools": "workspace:*",
81-
"@claude-code-best/mcp-client": "workspace:*",
8276
"@aws-sdk/client-bedrock": "^3.1020.0",
8377
"@aws-sdk/client-bedrock-runtime": "^3.1020.0",
8478
"@aws-sdk/client-sts": "^3.1020.0",
8579
"@aws-sdk/credential-provider-node": "^3.972.28",
8680
"@aws-sdk/credential-providers": "^3.1020.0",
8781
"@azure/identity": "^4.13.1",
8882
"@biomejs/biome": "^2.4.10",
83+
"@claude-code-best/agent-tools": "workspace:*",
84+
"@claude-code-best/builtin-tools": "workspace:*",
85+
"@claude-code-best/mcp-client": "workspace:*",
8986
"@commander-js/extra-typings": "^14.0.0",
9087
"@growthbook/growthbook": "^1.6.5",
88+
"@langfuse/otel": "^5.1.0",
89+
"@langfuse/tracing": "^5.1.0",
9190
"@modelcontextprotocol/sdk": "^1.29.0",
9291
"@opentelemetry/api": "^1.9.1",
9392
"@opentelemetry/api-logs": "^0.214.0",
@@ -110,8 +109,11 @@
110109
"@sentry/node": "^10.47.0",
111110
"@smithy/core": "^3.23.13",
112111
"@smithy/node-http-handler": "^4.5.1",
113-
"@types/bun": "^1.3.11",
112+
"@types/bun": "^1.3.12",
114113
"@types/cacache": "^20.0.1",
114+
"@types/he": "^1.2.3",
115+
"@types/lodash-es": "^4.17.12",
116+
"@types/node": "^25.6.0",
115117
"@types/picomatch": "^4.0.3",
116118
"@types/plist": "^3.0.5",
117119
"@types/proper-lockfile": "^4.1.4",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"include": ["src/**/*.ts"],
4+
"exclude": ["node_modules", "dist"]
5+
}

packages/@ant/computer-use-input/src/backends/darwin.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
* mouse and keyboard via CoreGraphics events and System Events.
66
*/
77

8-
import { $ } from 'bun'
8+
import { execFile, execFileSync } from 'child_process'
9+
import { promisify } from 'util'
910
import type { FrontmostAppInfo, InputBackend } from '../types.js'
1011

12+
const execFileAsync = promisify(execFile)
13+
1114
const KEY_MAP: Record<string, number> = {
1215
return: 36, enter: 36, tab: 48, space: 49, delete: 51, backspace: 51,
1316
escape: 53, esc: 53,
@@ -25,13 +28,17 @@ const MODIFIER_MAP: Record<string, string> = {
2528
}
2629

2730
async function osascript(script: string): Promise<string> {
28-
const result = await $`osascript -e ${script}`.quiet().nothrow().text()
29-
return result.trim()
31+
const { stdout } = await execFileAsync('osascript', ['-e', script], {
32+
encoding: 'utf-8',
33+
})
34+
return stdout.trim()
3035
}
3136

3237
async function jxa(script: string): Promise<string> {
33-
const result = await $`osascript -l JavaScript -e ${script}`.quiet().nothrow().text()
34-
return result.trim()
38+
const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', '-e', script], {
39+
encoding: 'utf-8',
40+
})
41+
return stdout.trim()
3542
}
3643

3744
function buildMouseJxa(eventType: string, x: number, y: number, btn: number, clickState?: number): string {
@@ -115,19 +122,14 @@ export const typeText: InputBackend['typeText'] = async (text) => {
115122

116123
export const getFrontmostAppInfo: InputBackend['getFrontmostAppInfo'] = () => {
117124
try {
118-
const result = Bun.spawnSync({
119-
cmd: ['osascript', '-e', `
120-
tell application "System Events"
121-
set frontApp to first application process whose frontmost is true
122-
set appName to name of frontApp
123-
set bundleId to bundle identifier of frontApp
124-
return bundleId & "|" & appName
125-
end tell
126-
`],
127-
stdout: 'pipe',
128-
stderr: 'pipe',
129-
})
130-
const output = new TextDecoder().decode(result.stdout).trim()
125+
const output = execFileSync('osascript', ['-e', `
126+
tell application "System Events"
127+
set frontApp to first application process whose frontmost is true
128+
set appName to name of frontApp
129+
set bundleId to bundle identifier of frontApp
130+
return bundleId & "|" & appName
131+
end tell
132+
`], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim()
131133
if (!output || !output.includes('|')) return null
132134
const [bundleId, appName] = output.split('|', 2)
133135
return { bundleId: bundleId!, appName: appName! }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"include": ["src/**/*.ts"],
4+
"exclude": ["node_modules", "dist"]
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"include": ["src/**/*.ts"],
4+
"exclude": ["node_modules", "dist"]
5+
}

packages/@ant/computer-use-swift/src/backends/darwin.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,9 @@ export const screenshot: ScreenshotAPI = {
274274
if (displayId !== undefined) args.push('-D', String(displayId))
275275
return captureScreenToBase64(args)
276276
},
277+
278+
captureWindowTarget(_titleOrHwnd: string | number): ScreenshotResult | null {
279+
// Window capture not supported on macOS via this backend
280+
return null
281+
},
277282
}

packages/@ant/computer-use-swift/src/backends/linux.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,9 @@ export const screenshot: ScreenshotAPI = {
275275
return { base64: '', width: 0, height: 0 }
276276
}
277277
},
278+
279+
captureWindowTarget(_titleOrHwnd: string | number): ScreenshotResult | null {
280+
// Window capture not supported on Linux via this backend
281+
return null
282+
},
278283
}

0 commit comments

Comments
 (0)