fix(e2b): close remote lifecycle gaps
This commit is contained in:
@@ -200,6 +200,16 @@ export async function readE2BSource(
|
||||
return { canonicalPath, text }
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode one absolute remote Linux path as a host-independent file URI.
|
||||
* @param path - Canonical POSIX path inside E2B.
|
||||
* @returns The equivalent percent-encoded file URI.
|
||||
*/
|
||||
export function e2bFileUri(path: string): string {
|
||||
if (!posix.isAbsolute(path)) throw new Error(`lsp-e2b: expected an absolute remote path, received ${JSON.stringify(path)}`)
|
||||
return `file://${path.split('/').map(segment => encodeURIComponent(segment)).join('/')}`
|
||||
}
|
||||
|
||||
/* jscpd:ignore-start -- Provider identity mirrors the seam while remote source and process ownership stay local. */
|
||||
/** One pooled remote provider with an isolated server per canonical workspace. */
|
||||
export class E2BLspProvider implements LspProvider {
|
||||
@@ -298,6 +308,7 @@ export class E2BLspProvider implements LspProvider {
|
||||
shutdownTimeoutMs: this.config.shutdownTimeoutMs,
|
||||
killGraceMs: this.config.killGraceMs,
|
||||
clientProcessId: null,
|
||||
pathToFileUri: e2bFileUri,
|
||||
}, (spec: SubprocessSpawnSpec) => {
|
||||
const originalArgv = Buffer.from(JSON.stringify(spec.argv)).toString('base64')
|
||||
const inner = this.subprocess.spawn({
|
||||
|
||||
@@ -69,6 +69,7 @@ import {
|
||||
E2BLspProvider,
|
||||
apply,
|
||||
canonicalizeE2BWorkspace,
|
||||
e2bFileUri,
|
||||
readE2BSource,
|
||||
} from '@deepseek-ai/dsh-lsp-e2b'
|
||||
import type { LspE2BServerConfig } from '@deepseek-ai/dsh-lsp-e2b'
|
||||
@@ -234,6 +235,10 @@ describe('E2BLspProvider pooling and lifecycle', () => {
|
||||
await expect(current.query(query())).resolves.toEqual({ kind: 'hover', hover: { contents: 'ok' } })
|
||||
expect(mockedLsp.FakeLspInstance.instances).toHaveLength(1)
|
||||
expect(mockedLsp.FakeLspInstance.instances[0]?.spec).toMatchObject({ clientProcessId: null, cwd: '/workspace' })
|
||||
expect(e2bFileUri('/workspace/a b#c.ts')).toBe('file:///workspace/a%20b%23c.ts')
|
||||
expect(() => e2bFileUri('relative.ts')).toThrow('absolute remote path')
|
||||
const pathToFileUri = mockedLsp.FakeLspInstance.instances[0]?.spec.pathToFileUri as (path: string) => string
|
||||
expect(pathToFileUri('/workspace/a b#c.ts')).toBe('file:///workspace/a%20b%23c.ts')
|
||||
expect(spawn).toHaveBeenCalledWith(expect.objectContaining({
|
||||
argv: ['/usr/bin/node', '/workspace/.dsh-e2b/lsp-proxy.mjs', expect.any(String)],
|
||||
stdio: { stdin: 'pipe', stdout: 'pipe', stderr: { maxBytes: 128 } },
|
||||
|
||||
Reference in New Issue
Block a user