Download packages/subprocess/subprocess-local/src/runner-launch.ts from SaylorTwift/deepseek-harness: direct link, hf CLI and curl.
- Browser
- Download file 11.9 kB
-
https://huggingface.co/SaylorTwift/deepseek-harness/resolve/main/packages/subprocess/subprocess-local/src/runner-launch.ts
- Command line
-
hf download hf://SaylorTwift/deepseek-harness/packages/subprocess/subprocess-local/src/runner-launch.ts
-
curl -L -o runner-launch.ts https://huggingface.co/SaylorTwift/deepseek-harness/resolve/main/packages/subprocess/subprocess-local/src/runner-launch.ts
11.9 kB
| /** Parent-side invocation and bootstrap state for the private native runner. */ | |
| import type { StdioOptions } from 'node:child_process' | |
| import { accessSync, constants as fsConstants, lstatSync, statSync } from 'node:fs' | |
| import { extname, isAbsolute } from 'node:path' | |
| import { inspect } from 'node:util' | |
| import { fileURLToPath } from 'node:url' | |
| import type { SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess' | |
| import { childEnv } from './spawn.ts' | |
| import { controlEnvironment } from './control-spawn.ts' | |
| import { SUBPROCESS_CONTROL_FD } from '@deepseek-ai/dsh-subprocess/control' | |
| /** The one private environment variable consumed before target state is restored. */ | |
| export const SUBPROCESS_RUNNER_ENV = 'DSH_SUBPROCESS_RUNNER' as const | |
| /** Sentinel used by the packaged bootstrap for the Windows IPC runner. */ | |
| export const WINDOWS_RUNNER_SELECTION = 'windows' as const | |
| /** Non-empty command tuple used to launch the private runner entry. */ | |
| export type RunnerInvocation = [string, ...string[]] | |
| const SOURCE_TSCONFIG_PATH = fileURLToPath(new URL('../../../../tsconfig.base.json', import.meta.url)) | |
| const RUNNER_CONTROL_ENV_PREFIXES = ['NODE_', 'TSX_'] as const | |
| /** | |
| * Resolve the source, built, or packaged entry that calls the same runner core. | |
| * @returns executable and arguments for the active runtime form. | |
| */ | |
| export function spawnRunnerInvocation(): RunnerInvocation { | |
| if ('pkg' in process) return [process.execPath] | |
| /* v8 ignore next -- built-artifact smoke imports the emitted JavaScript runner entry; | |
| * source-unit coverage cannot change import.meta.url. */ | |
| if (extname(fileURLToPath(import.meta.url)) !== '.ts') { | |
| return [process.execPath, fileURLToPath(import.meta.resolve('@deepseek-ai/dsh-subprocess-local/runner'))] | |
| } | |
| return [ | |
| process.execPath, | |
| '--import', | |
| import.meta.resolve('tsx/esm'), | |
| fileURLToPath(new URL('./bin.ts', import.meta.url)), | |
| ] | |
| } | |
| /** | |
| * Check the concrete runner executable and entry paths without executing a probe mode. | |
| * @param invocation - resolved executable and runner-entry arguments. | |
| * @returns whether every concrete executable or entry path is accessible. | |
| */ | |
| export function runnerInvocationAvailable(invocation: RunnerInvocation = spawnRunnerInvocation()): boolean { | |
| try { | |
| if (isAbsolute(invocation[0])) accessSync(invocation[0], fsConstants.X_OK) | |
| const entry = invocation.at(-1) | |
| if (entry !== undefined && entry !== invocation[0] && isAbsolute(entry)) { | |
| accessSync(entry, fsConstants.R_OK) | |
| } | |
| return true | |
| } catch { | |
| return false | |
| } | |
| } | |
| /** | |
| * Build the bootstrap-safe environment; target overrides arrive through request/IPC. | |
| * @param selection - private runner selector or Linux launch-request locator. | |
| * @param invocation - resolved runner invocation whose source form needs the workspace paths map. | |
| * @returns environment for the runner before target state is restored. | |
| */ | |
| export function runnerEnvironment( | |
| selection: string, | |
| invocation?: RunnerInvocation, | |
| ): NodeJS.ProcessEnv { | |
| const entry = invocation?.at(-1) | |
| const env = childEnv() | |
| for (const name of Object.keys(env)) { | |
| const normalized = name.toUpperCase() | |
| if (RUNNER_CONTROL_ENV_PREFIXES.some(prefix => normalized.startsWith(prefix))) { | |
| Reflect.deleteProperty(env, name) | |
| } | |
| } | |
| return { | |
| ...env, | |
| [SUBPROCESS_RUNNER_ENV]: selection, | |
| SYSTEMD_LOG_TARGET: 'null', | |
| ...entry?.endsWith('.ts') === true ? { TSX_TSCONFIG_PATH: SOURCE_TSCONFIG_PATH } : {}, | |
| } | |
| } | |
| /** | |
| * Read and delete the private selector before importing or restoring target state. | |
| * @param env - mutable environment containing the private selector. | |
| * @returns the consumed selector, or undefined when no runner was requested. | |
| */ | |
| export function consumeRunnerSelection(env: NodeJS.ProcessEnv = process.env): string | undefined { | |
| const selection = env[SUBPROCESS_RUNNER_ENV] | |
| Reflect.deleteProperty(env, SUBPROCESS_RUNNER_ENV) | |
| return selection | |
| } | |
| /** | |
| * Require the private argv delimiter and at least one target argv entry. | |
| * @param argv - private runner arguments. | |
| * @returns copied target argv after the private delimiter. | |
| */ | |
| export function parseRunnerTargetArgv(argv: readonly string[]): string[] { | |
| if (argv[0] !== '--' || argv.length < 2) { | |
| throw new Error('subprocess runner requires target argv after a private -- delimiter') | |
| } | |
| return [...argv.slice(1)] | |
| } | |
| /** | |
| * Build direct Linux target stdio, or isolated Windows runner stdio with IPC | |
| * on fd 3 and target carriers on fd 4 through fd 6; optional control uses fd 7. | |
| * @param spec - ordinary subprocess request whose stdio modes are preserved. | |
| * @param ipc - whether to isolate the runner and add its private Node IPC descriptor. | |
| * @param stdinCarrier - runner fd 4 carrier; Windows ignore passes an opened null-device fd. | |
| * @returns child-process stdio options for the runner. | |
| */ | |
| export function runnerStdio( | |
| spec: SubprocessSpawnSpec, | |
| ipc: boolean, | |
| stdinCarrier: 'pipe' | number = 'pipe', | |
| ): StdioOptions { | |
| const targetStdio: StdioOptions = [ | |
| spec.stdio.stdin === 'ignore' ? 'ignore' : 'pipe', | |
| spec.stdio.stdout === 'inherit' ? 'inherit' : 'pipe', | |
| spec.stdio.stderr === 'inherit' ? 'inherit' : 'pipe', | |
| ] | |
| if (!ipc) { | |
| if (spec.stdio.control === 'pipe') { | |
| while (targetStdio.length < SUBPROCESS_CONTROL_FD) targetStdio.push('ignore') | |
| targetStdio.push('overlapped') | |
| } | |
| return targetStdio | |
| } | |
| const runner: StdioOptions = [ | |
| 'ignore', | |
| 'ignore', | |
| 'ignore', | |
| 'ipc', | |
| stdinCarrier, | |
| spec.stdio.stdout === 'inherit' ? 1 : 'pipe', | |
| spec.stdio.stderr === 'inherit' ? 2 : 'pipe', | |
| ] | |
| if (spec.stdio.control === 'pipe') runner.push('overlapped') | |
| return runner | |
| } | |
| function windowsEnvironmentValue( | |
| env: Readonly<Record<string, string | undefined>>, | |
| name: 'PATH' | 'NODEFAULTCURRENTDIRECTORYINEXEPATH', | |
| ): string | undefined { | |
| for (const key of Object.keys(env).sort()) { | |
| if (key.toUpperCase() === name) return env[key] | |
| } | |
| return undefined | |
| } | |
| function executableCandidateExists(candidate: string): boolean { | |
| try { | |
| return !statSync(candidate).isDirectory() | |
| } catch { | |
| try { | |
| const entry = lstatSync(candidate) | |
| return entry.isFile() || entry.isSymbolicLink() | |
| } catch { | |
| return false | |
| } | |
| } | |
| } | |
| function windowsPathDirectories(path: string): string[] { | |
| const directories: string[] = [] | |
| let start = 0 | |
| while (start < path.length) { | |
| if (path.charAt(start) === ';') { | |
| start += 1 | |
| continue | |
| } | |
| const quote = path.charAt(start) | |
| const quoted = quote === '"' || quote === "'" | |
| const quoteEnd = quoted | |
| ? path.indexOf(quote, start + 1) | |
| : -1 | |
| const separator = path.indexOf(';', quoted ? quoteEnd < 0 ? path.length : quoteEnd : start) | |
| const end = separator < 0 ? path.length : separator | |
| let directory = path.slice(start, end) | |
| if (directory.startsWith('"') || directory.startsWith("'")) directory = directory.slice(1) | |
| if (directory.endsWith('"') || directory.endsWith("'")) directory = directory.slice(0, -1) | |
| if (directory.length > 0) directories.push(directory) | |
| start = end + 1 | |
| } | |
| return directories | |
| } | |
| function windowsFileNameStart(command: string): number { | |
| let start = command.length | |
| while (start > 0 && !/[\\/:]/u.test(command.charAt(start - 1))) start -= 1 | |
| return start | |
| } | |
| function windowsSearchPathJoin(directory: string, name: string, cwd: string): string { | |
| let prefix = cwd | |
| let adjustedDirectory = directory | |
| const slash = (value: string): boolean => value === '\\' || value === '/' | |
| if (directory.length > 2 && slash(directory.charAt(0)) && slash(directory.charAt(1))) { | |
| prefix = '' | |
| } else if (directory.length >= 1 && slash(directory.charAt(0))) { | |
| prefix = cwd.slice(0, 2) | |
| } else if ( | |
| directory.length >= 2 | |
| && directory.charAt(1) === ':' | |
| && (directory.length < 3 || !slash(directory.charAt(2))) | |
| ) { | |
| if (cwd.length < 2 || cwd.slice(0, 2).toLowerCase() !== directory.slice(0, 2).toLowerCase()) { | |
| prefix = '' | |
| } else { | |
| adjustedDirectory = directory.slice(2) | |
| } | |
| } else if (directory.length > 2 && directory.charAt(1) === ':') { | |
| prefix = '' | |
| } | |
| const append = (base: string, part: string): string => { | |
| if (base.length === 0 || part.length === 0) return base + part | |
| return /[\\/:]$/u.test(base) ? base + part : `${base}\\${part}` | |
| } | |
| return append(append(prefix, adjustedDirectory), name) | |
| } | |
| function windowsExecutableNames(command: string, name: string): string[] { | |
| const dot = name.indexOf('.') | |
| const hasExtension = dot >= 0 && dot < name.length - 1 | |
| const separator = name.endsWith('.') ? '' : '.' | |
| return [ | |
| ...hasExtension ? [command] : [], | |
| `${command}${separator}com`, | |
| `${command}${separator}exe`, | |
| ] | |
| } | |
| /** | |
| * Resolve the executable path with libuv/Node Windows spawn search order while | |
| * preserving the caller's original command-line argv entry separately. | |
| * @param command - original target argv[0]. | |
| * @param cwd - final target working directory used for relative search roots. | |
| * @param env - final target environment containing the child PATH. | |
| * @param exists - injectable non-directory candidate probe used by tests. | |
| * @param currentEnv - runner environment supplying PATH fallback and cwd-search policy. | |
| * @returns a resolved application name suitable for `CreateProcessW`, or undefined when no candidate exists. | |
| */ | |
| export function resolveWindowsExecutable( | |
| command: string, | |
| cwd: string, | |
| env: Readonly<Record<string, string>>, | |
| exists: (candidate: string) => boolean = executableCandidateExists, | |
| currentEnv: Readonly<Record<string, string | undefined>> = process.env, | |
| ): string | undefined { | |
| const nameStart = windowsFileNameStart(command) | |
| const directory = command.slice(0, nameStart) | |
| const name = command.slice(nameStart) | |
| const hasPath = nameStart !== 0 | |
| const roots: string[] = [] | |
| if (hasPath) { | |
| roots.push(directory) | |
| } else { | |
| if (windowsEnvironmentValue(currentEnv, 'NODEFAULTCURRENTDIRECTORYINEXEPATH') === undefined) { | |
| roots.push('') | |
| } | |
| const path = windowsEnvironmentValue(env, 'PATH') ?? windowsEnvironmentValue(currentEnv, 'PATH') ?? '' | |
| roots.push(...windowsPathDirectories(path)) | |
| } | |
| for (const root of roots) { | |
| const base = windowsSearchPathJoin(root, name, cwd) | |
| for (const candidate of windowsExecutableNames(base, name)) { | |
| if (exists(candidate)) return candidate | |
| } | |
| } | |
| return undefined | |
| } | |
| function throwNullByteError(property: string, value: string, argument: boolean): never { | |
| const subject = argument ? `The argument '${property}'` : `The property '${property}'` | |
| const error = new TypeError(`${subject} must be a string without null bytes. Received ${inspect(value)}`) | |
| Object.assign(error, { code: 'ERR_INVALID_ARG_VALUE' }) | |
| throw error | |
| } | |
| function validateNoNullByte(property: string, value: string, argument = false): void { | |
| if (value.includes('\0')) throwNullByteError(property, value, argument) | |
| } | |
| /** | |
| * Materialize and synchronously validate the final target environment. | |
| * @param spec - final target argv, cwd, and environment overrides. | |
| * @returns complete target environment after Node-equivalent validation. | |
| */ | |
| export function targetEnvironment( | |
| spec: Pick<SubprocessSpawnSpec, 'argv' | 'cwd' | 'env'> & { stdio?: SubprocessSpawnSpec['stdio'] }, | |
| ): Record<string, string> { | |
| spec.argv.forEach((value, index) => { | |
| validateNoNullByte(index === 0 ? 'file' : `args[${String(index - 1)}]`, value, true) | |
| }) | |
| validateNoNullByte('options.cwd', spec.cwd) | |
| const env = Object.fromEntries( | |
| Object.entries(childEnv(spec.env)).filter((entry): entry is [string, string] => entry[1] !== undefined), | |
| ) | |
| for (const [key, value] of Object.entries(env)) { | |
| validateNoNullByte(`options.env['${key}']`, key) | |
| validateNoNullByte(`options.env['${key}']`, value) | |
| } | |
| return controlEnvironment(env, spec.stdio?.control) | |
| } | |