mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-24 01:05:49 +00:00
Fix type (#1274)
* 完善所有用到的type对象,并添加中文注释 * 补充遗失的type * 修改pipe模式卡死的问题,增加trycatch捕获错误信息。 * 修改为英文报错信息。
This commit is contained in:
10
src/setup.ts
10
src/setup.ts
@@ -94,10 +94,20 @@ export async function setup(
|
|||||||
// (SessionStart in particular) can spawn and snapshot process.env.
|
// (SessionStart in particular) can spawn and snapshot process.env.
|
||||||
if (feature('UDS_INBOX')) {
|
if (feature('UDS_INBOX')) {
|
||||||
const m = await import('./utils/udsMessaging.js')
|
const m = await import('./utils/udsMessaging.js')
|
||||||
|
try {
|
||||||
await m.startUdsMessaging(
|
await m.startUdsMessaging(
|
||||||
messagingSocketPath ?? m.getDefaultUdsSocketPath(),
|
messagingSocketPath ?? m.getDefaultUdsSocketPath(),
|
||||||
{ isExplicit: messagingSocketPath !== undefined },
|
{ isExplicit: messagingSocketPath !== undefined },
|
||||||
)
|
)
|
||||||
|
} catch (error) {
|
||||||
|
logError(error)
|
||||||
|
console.error(
|
||||||
|
chalk.red(
|
||||||
|
`Error: Failed to start messaging socket (UDS_INBOX): ${errorMessage(error)}`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import {
|
|||||||
MAX_UDS_INBOX_BYTES,
|
MAX_UDS_INBOX_BYTES,
|
||||||
MAX_UDS_FRAME_BYTES,
|
MAX_UDS_FRAME_BYTES,
|
||||||
MAX_UDS_CLIENTS,
|
MAX_UDS_CLIENTS,
|
||||||
|
MAX_UNIX_SOCKET_PATH_LENGTH,
|
||||||
|
assertValidUnixSocketPath,
|
||||||
formatUdsAddress,
|
formatUdsAddress,
|
||||||
parseUdsTarget,
|
parseUdsTarget,
|
||||||
sendUdsMessage,
|
sendUdsMessage,
|
||||||
@@ -34,11 +36,23 @@ let previousConfigDir: string | undefined
|
|||||||
let tempConfigDir = ''
|
let tempConfigDir = ''
|
||||||
|
|
||||||
function socketPath(label: string): string {
|
function socketPath(label: string): string {
|
||||||
const suffix = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}-${label}`
|
const suffix = `${process.pid}-${Math.random().toString(16).slice(2)}-${label}`
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
return `\\\\.\\pipe\\claude-code-test-${suffix}`
|
return `\\\\.\\pipe\\claude-code-test-${suffix}`
|
||||||
}
|
}
|
||||||
return join(tmpdir(), 'claude-code-test', `${suffix}.sock`)
|
const base =
|
||||||
|
process.platform === 'darwin'
|
||||||
|
? '/tmp/claude-uds-test'
|
||||||
|
: join(tmpdir(), 'cc-uds-test')
|
||||||
|
return join(base, `${suffix}.sock`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function shortTestDir(prefix: string): string {
|
||||||
|
const id = `${process.pid}-${Math.random().toString(16).slice(2)}`
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
return join('/tmp', `${prefix}-${id}`)
|
||||||
|
}
|
||||||
|
return join(tmpdir(), `${prefix}-${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function sleep(ms: number): Promise<void> {
|
function sleep(ms: number): Promise<void> {
|
||||||
@@ -499,6 +513,27 @@ describe('UDS inbox retention', () => {
|
|||||||
expect(getDefaultUdsSocketPath()).not.toBe(firstPath)
|
expect(getDefaultUdsSocketPath()).not.toBe(firstPath)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('default socket path stays within AF_UNIX length limit', () => {
|
||||||
|
const path = getDefaultUdsSocketPath()
|
||||||
|
if (process.platform === 'win32') return
|
||||||
|
expect(Buffer.byteLength(path, 'utf8')).toBeLessThanOrEqual(
|
||||||
|
MAX_UNIX_SOCKET_PATH_LENGTH,
|
||||||
|
)
|
||||||
|
expect(() => assertValidUnixSocketPath(path)).not.toThrow()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('rejects socket paths longer than AF_UNIX limit', () => {
|
||||||
|
if (process.platform === 'win32') return
|
||||||
|
const longPath = `/tmp/${'x'.repeat(MAX_UNIX_SOCKET_PATH_LENGTH)}.sock`
|
||||||
|
expect(() => assertValidUnixSocketPath(longPath)).toThrow(/max 104/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('default socket path can bind on Node.js', async () => {
|
||||||
|
const path = getDefaultUdsSocketPath()
|
||||||
|
await startUdsMessaging(path, { isExplicit: true })
|
||||||
|
await stopUdsMessaging()
|
||||||
|
})
|
||||||
|
|
||||||
test('rejects oversized receiver responses before retaining them', async () => {
|
test('rejects oversized receiver responses before retaining them', async () => {
|
||||||
const path = socketPath('oversized-response')
|
const path = socketPath('oversized-response')
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
@@ -688,10 +723,7 @@ describe('UDS inbox retention', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('fails closed when an explicit socket parent is not private', async () => {
|
test('fails closed when an explicit socket parent is not private', async () => {
|
||||||
const parent = join(
|
const parent = shortTestDir('uds-sp')
|
||||||
tmpdir(),
|
|
||||||
`uds-socket-parent-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
||||||
)
|
|
||||||
await mkdir(parent, { recursive: true, mode: 0o755 })
|
await mkdir(parent, { recursive: true, mode: 0o755 })
|
||||||
await chmod(parent, 0o755)
|
await chmod(parent, 0o755)
|
||||||
|
|
||||||
@@ -707,10 +739,7 @@ describe('UDS inbox retention', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('fails closed when an explicit socket parent is a file', async () => {
|
test('fails closed when an explicit socket parent is a file', async () => {
|
||||||
const parentFile = join(
|
const parentFile = shortTestDir('uds-spf')
|
||||||
tmpdir(),
|
|
||||||
`uds-socket-parent-file-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
||||||
)
|
|
||||||
await writeFile(parentFile, 'not a directory', 'utf-8')
|
await writeFile(parentFile, 'not a directory', 'utf-8')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -85,13 +85,26 @@ export const MAX_UDS_CLIENTS = 128
|
|||||||
export const UDS_AUTH_TIMEOUT_MS = 2_000
|
export const UDS_AUTH_TIMEOUT_MS = 2_000
|
||||||
export const UDS_IDLE_TIMEOUT_MS = 30_000
|
export const UDS_IDLE_TIMEOUT_MS = 30_000
|
||||||
|
|
||||||
|
/** macOS/BSD AF_UNIX `sun_path` limit (bytes, excluding NUL). */
|
||||||
|
export const MAX_UNIX_SOCKET_PATH_LENGTH = 104
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Public API — socket path helpers
|
// Public API — socket path helpers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export function assertValidUnixSocketPath(path: string): void {
|
||||||
|
if (process.platform === 'win32') return
|
||||||
|
const byteLength = Buffer.byteLength(path, 'utf8')
|
||||||
|
if (byteLength > MAX_UNIX_SOCKET_PATH_LENGTH) {
|
||||||
|
throw new Error(
|
||||||
|
`[udsMessaging] socket path is ${byteLength} bytes (max ${MAX_UNIX_SOCKET_PATH_LENGTH}): ${path}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default socket path based on PID, placed in a tmpdir subdirectory so it
|
* Default socket path based on PID. Uses a flat file under a short temp
|
||||||
* survives across config-home changes and avoids polluting ~/.claude.
|
* directory so the path stays within the AF_UNIX limit on macOS.
|
||||||
*
|
*
|
||||||
* On Windows, Node.js requires named pipe paths in the `\\.\pipe\` namespace;
|
* On Windows, Node.js requires named pipe paths in the `\\.\pipe\` namespace;
|
||||||
* file-system paths like `C:\...\Temp\x.sock` cause EACCES. Bun handles both
|
* file-system paths like `C:\...\Temp\x.sock` cause EACCES. Bun handles both
|
||||||
@@ -99,17 +112,19 @@ export const UDS_IDLE_TIMEOUT_MS = 30_000
|
|||||||
*/
|
*/
|
||||||
export function getDefaultUdsSocketPath(): string {
|
export function getDefaultUdsSocketPath(): string {
|
||||||
if (defaultSocketPath) return defaultSocketPath
|
if (defaultSocketPath) return defaultSocketPath
|
||||||
const nonce = randomBytes(16).toString('hex')
|
const nonce = randomBytes(8).toString('hex')
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
defaultSocketPath = `\\\\.\\pipe\\claude-code-${process.pid}-${nonce}`
|
defaultSocketPath = `\\\\.\\pipe\\claude-code-${process.pid}-${nonce}`
|
||||||
return defaultSocketPath
|
return defaultSocketPath
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultSocketPath = join(
|
defaultSocketPath = join(
|
||||||
tmpdir(),
|
tmpdir(),
|
||||||
'claude-code-socks',
|
'cc-socks',
|
||||||
`${process.pid}-${nonce}`,
|
`${process.pid}-${nonce}`,
|
||||||
'messaging.sock',
|
'messaging.sock',
|
||||||
)
|
)
|
||||||
|
assertValidUnixSocketPath(defaultSocketPath)
|
||||||
return defaultSocketPath
|
return defaultSocketPath
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,6 +431,8 @@ export async function startUdsMessaging(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertValidUnixSocketPath(path)
|
||||||
|
|
||||||
// Ensure parent directory exists (skip on Windows — pipe paths aren't files)
|
// Ensure parent directory exists (skip on Windows — pipe paths aren't files)
|
||||||
if (process.platform !== 'win32') {
|
if (process.platform !== 'win32') {
|
||||||
await ensureSocketParent(path)
|
await ensureSocketParent(path)
|
||||||
|
|||||||
Reference in New Issue
Block a user