mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Merge pull request #2517 from deepseek-harness/xtr/node-pty-1.2-beta
chore(subprocess-local): bump node-pty beta
This commit is contained in:
@@ -194,6 +194,7 @@ jobs:
|
||||
*) echo "::error::Unsupported Linux runner architecture $RUNNER_ARCH"; exit 1 ;;
|
||||
esac
|
||||
addon_dir="$(realpath packages/subprocess/subprocess-local/node_modules/node-pty)"
|
||||
(cd "$addon_dir" && npm_config_build_from_source=true pnpm run install)
|
||||
addon="$addon_dir/build/Release/pty.node"
|
||||
[ -f "$addon_dir/build/Makefile" ] || {
|
||||
echo "::error::node-pty install did not generate $addon_dir/build/Makefile"
|
||||
|
||||
@@ -93,7 +93,7 @@ External packages that a workspace package resolves at runtime. The tier covers
|
||||
|
||||
pnpm applies local patches to the following packages at install time, so shipped artifacts carry modified copies; each patch file is the complete record of the modification:
|
||||
|
||||
- `node-pty@1.1.0` — [`patches/node-pty@1.1.0.patch`](patches/node-pty@1.1.0.patch)
|
||||
- `node-pty@1.2.0-beta.15` — [`patches/node-pty@1.2.0-beta.15.patch`](patches/node-pty@1.2.0-beta.15.patch)
|
||||
|
||||
## Official Claude Code platform payloads
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"@deepseek-ai/cordis": "workspace:^"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-pty": "^1.1.0"
|
||||
"node-pty": "1.2.0-beta.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
diff --git a/lib/unixTerminal.js b/lib/unixTerminal.js
|
||||
index 1ec12f796a822c78fba9ad7f6448c3987e325c23..5cd6b7d635f4752be5a6c5ff9cf9edf988cf94c5 100644
|
||||
--- a/lib/unixTerminal.js
|
||||
+++ b/lib/unixTerminal.js
|
||||
@@ -26,10 +26,23 @@ var terminal_1 = require("./terminal");
|
||||
var utils_1 = require("./utils");
|
||||
var native = utils_1.loadNativeModule('pty');
|
||||
var pty = native.module;
|
||||
-var helperPath = native.dir + '/spawn-helper';
|
||||
-helperPath = path.resolve(__dirname, helperPath);
|
||||
-helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
-helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+// A current external embedded-runtime consumer supplies a non-sibling helper.
|
||||
+var helperPath = process.env.DSH_NODE_PTY_SPAWN_HELPER;
|
||||
+if (helperPath) {
|
||||
+ helperPath = path.resolve(helperPath);
|
||||
+}
|
||||
+else {
|
||||
+ var executableSibling = process.execPath + '-spawn-helper';
|
||||
+ if (fs.existsSync(executableSibling)) {
|
||||
+ helperPath = executableSibling;
|
||||
+ }
|
||||
+ else {
|
||||
+ helperPath = native.dir + '/spawn-helper';
|
||||
+ helperPath = path.resolve(__dirname, helperPath);
|
||||
+ helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
+ helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+ }
|
||||
+}
|
||||
var DEFAULT_FILE = 'sh';
|
||||
var DEFAULT_NAME = 'xterm';
|
||||
var DESTROY_SOCKET_TIMEOUT_MS = 200;
|
||||
diff --git a/src/unixTerminal.ts b/src/unixTerminal.ts
|
||||
index 98733dc0cd752b554bd94e45904ca341ad141bba..fa234291206617ae5a6d8605abf9771220392d17 100644
|
||||
--- a/src/unixTerminal.ts
|
||||
+++ b/src/unixTerminal.ts
|
||||
@@ -14,10 +14,21 @@ import { assign, loadNativeModule } from './utils';
|
||||
|
||||
const native = loadNativeModule('pty');
|
||||
const pty: IUnixNative = native.module;
|
||||
-let helperPath = native.dir + '/spawn-helper';
|
||||
-helperPath = path.resolve(__dirname, helperPath);
|
||||
-helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
-helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+// A current external embedded-runtime consumer supplies a non-sibling helper.
|
||||
+let helperPath = process.env.DSH_NODE_PTY_SPAWN_HELPER;
|
||||
+if (helperPath) {
|
||||
+ helperPath = path.resolve(helperPath);
|
||||
+} else {
|
||||
+ const executableSibling = process.execPath + '-spawn-helper';
|
||||
+ if (fs.existsSync(executableSibling)) {
|
||||
+ helperPath = executableSibling;
|
||||
+ } else {
|
||||
+ helperPath = native.dir + '/spawn-helper';
|
||||
+ helperPath = path.resolve(__dirname, helperPath);
|
||||
+ helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
+ helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+ }
|
||||
+}
|
||||
|
||||
const DEFAULT_FILE = 'sh';
|
||||
const DEFAULT_NAME = 'xterm';
|
||||
@@ -0,0 +1,32 @@
|
||||
diff --git a/lib/unixTerminal.js b/lib/unixTerminal.js
|
||||
index 6966d24..18f1d25 100644
|
||||
--- a/lib/unixTerminal.js
|
||||
+++ b/lib/unixTerminal.js
|
||||
@@ -28,10 +28,23 @@ var terminal_1 = require("./terminal");
|
||||
var utils_1 = require("./utils");
|
||||
var native = (0, utils_1.loadNativeModule)('pty');
|
||||
var pty = native.module;
|
||||
-var helperPath = native.dir + '/spawn-helper';
|
||||
-helperPath = path.resolve(__dirname, helperPath);
|
||||
-helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
-helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+// A current external embedded-runtime consumer supplies a non-sibling helper.
|
||||
+var helperPath = process.env.DSH_NODE_PTY_SPAWN_HELPER;
|
||||
+if (helperPath) {
|
||||
+ helperPath = path.resolve(helperPath);
|
||||
+}
|
||||
+else {
|
||||
+ var executableSibling = process.execPath + '-spawn-helper';
|
||||
+ if (fs.existsSync(executableSibling)) {
|
||||
+ helperPath = executableSibling;
|
||||
+ }
|
||||
+ else {
|
||||
+ helperPath = native.dir + '/spawn-helper';
|
||||
+ helperPath = path.resolve(__dirname, helperPath);
|
||||
+ helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
+ helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
+ }
|
||||
+}
|
||||
var DEFAULT_FILE = 'sh';
|
||||
var DEFAULT_NAME = 'xterm';
|
||||
var DESTROY_SOCKET_TIMEOUT_MS = 200;
|
||||
Generated
+6
-6
@@ -9,7 +9,7 @@ overrides:
|
||||
'@deepseek-ai/schemastery': link:vendor/schemastery
|
||||
|
||||
patchedDependencies:
|
||||
node-pty@1.1.0: 7a0c04f1f49d798a9ffe2f7f414c01064a44ca2489772d0c3e1235ab336755e6
|
||||
node-pty@1.2.0-beta.15: b40ae545608897914bd25fb009c97eeac478c34e8a910298ddcb01b746534bb0
|
||||
|
||||
importers:
|
||||
|
||||
@@ -7493,8 +7493,8 @@ importers:
|
||||
packages/subprocess/subprocess-local:
|
||||
dependencies:
|
||||
node-pty:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(patch_hash=7a0c04f1f49d798a9ffe2f7f414c01064a44ca2489772d0c3e1235ab336755e6)
|
||||
specifier: 1.2.0-beta.15
|
||||
version: 1.2.0-beta.15(patch_hash=b40ae545608897914bd25fb009c97eeac478c34e8a910298ddcb01b746534bb0)
|
||||
devDependencies:
|
||||
'@deepseek-ai/cordis':
|
||||
specifier: workspace:^
|
||||
@@ -13164,8 +13164,8 @@ packages:
|
||||
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
node-pty@1.1.0:
|
||||
resolution: {integrity: sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg==}
|
||||
node-pty@1.2.0-beta.15:
|
||||
resolution: {integrity: sha512-vORSzHXi4Ofl7HemVWpuudLqCPdaQb4LfpRCUpE5HPxhp4JYscl8zZwxh11p26v2wvW24WMwnMfLjhRLixrfxA==}
|
||||
|
||||
node-releases@2.0.51:
|
||||
resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==}
|
||||
@@ -18588,7 +18588,7 @@ snapshots:
|
||||
fetch-blob: 3.2.0
|
||||
formdata-polyfill: 4.0.10
|
||||
|
||||
node-pty@1.1.0(patch_hash=7a0c04f1f49d798a9ffe2f7f414c01064a44ca2489772d0c3e1235ab336755e6):
|
||||
node-pty@1.2.0-beta.15(patch_hash=b40ae545608897914bd25fb009c97eeac478c34e8a910298ddcb01b746534bb0):
|
||||
dependencies:
|
||||
node-addon-api: 7.1.1
|
||||
|
||||
|
||||
+1
-1
@@ -69,4 +69,4 @@ minimumReleaseAgeExclude:
|
||||
- node-addon-require-builtin@0.1.4
|
||||
|
||||
patchedDependencies:
|
||||
node-pty@1.1.0: patches/node-pty@1.1.0.patch
|
||||
node-pty@1.2.0-beta.15: patches/node-pty@1.2.0-beta.15.patch
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { resolveLinuxNodePtyAddon } from './build-exe-for-python-sdk-native-pty.ts'
|
||||
|
||||
const roots: string[] = []
|
||||
|
||||
afterEach(() => {
|
||||
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
describe('resolveLinuxNodePtyAddon', () => {
|
||||
it('prefers the manylinux build produced by the release workflow', () => {
|
||||
const root = temporaryPackage()
|
||||
const built = createAddon(root, 'build', 'Release', 'pty.node')
|
||||
createAddon(root, 'prebuilds', 'linux-x64', 'pty.node')
|
||||
|
||||
expect(resolveLinuxNodePtyAddon(root, 'x64')).toBe(built)
|
||||
})
|
||||
|
||||
it('uses the target prebuild after an ordinary beta install', () => {
|
||||
const root = temporaryPackage()
|
||||
const prebuilt = createAddon(root, 'prebuilds', 'linux-arm64', 'pty.node')
|
||||
|
||||
expect(resolveLinuxNodePtyAddon(root, 'arm64')).toBe(prebuilt)
|
||||
})
|
||||
|
||||
it('reports both expected locations when no addon is installed', () => {
|
||||
const root = temporaryPackage()
|
||||
|
||||
expect(() => resolveLinuxNodePtyAddon(root, 'x64')).toThrow(
|
||||
`node-pty addon is absent from both ${join(root, 'build', 'Release', 'pty.node')} and ${join(root, 'prebuilds', 'linux-x64', 'pty.node')}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
function temporaryPackage(): string {
|
||||
const root = mkdtempSync(join(tmpdir(), 'dsh-node-pty-addon-'))
|
||||
roots.push(root)
|
||||
return root
|
||||
}
|
||||
|
||||
function createAddon(root: string, ...segments: string[]): string {
|
||||
const path = join(root, ...segments)
|
||||
mkdirSync(dirname(path), { recursive: true })
|
||||
writeFileSync(path, '')
|
||||
return path
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/** Resolve the native node-pty input used by the Python SDK runtime builder. */
|
||||
|
||||
import { existsSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
|
||||
/**
|
||||
* Prefer the workflow's manylinux build and fall back to node-pty's target prebuild.
|
||||
* @param packageDirectory - installed node-pty package directory.
|
||||
* @param arch - Linux target architecture.
|
||||
* @returns the existing addon path.
|
||||
*/
|
||||
export function resolveLinuxNodePtyAddon(
|
||||
packageDirectory: string,
|
||||
arch: 'x64' | 'arm64',
|
||||
): string {
|
||||
const built = join(packageDirectory, 'build', 'Release', 'pty.node')
|
||||
if (existsSync(built)) return built
|
||||
const prebuilt = join(packageDirectory, 'prebuilds', `linux-${arch}`, 'pty.node')
|
||||
if (existsSync(prebuilt)) return prebuilt
|
||||
throw new Error(
|
||||
`build-exe-for-python-sdk: node-pty addon is absent from both ${built} and ${prebuilt}.`,
|
||||
)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { existsSync, statSync } from 'node:fs'
|
||||
import { chmod, copyFile, cp, lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from 'node:fs/promises'
|
||||
import { basename, dirname, join, resolve, sep } from 'node:path'
|
||||
import { parseArgs } from 'node:util'
|
||||
import { resolveLinuxNodePtyAddon } from './build-exe-for-python-sdk-native-pty.ts'
|
||||
|
||||
const root = resolve(import.meta.dirname, '..')
|
||||
|
||||
@@ -409,8 +410,8 @@ class SingleExeBuild {
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the target node-pty addon in the staged closure. Linux npm installs
|
||||
* build it from source, but legacy deploy omits that side-effect directory.
|
||||
* Put the target node-pty addon in the staged closure. The release workflow
|
||||
* provides a manylinux build; ordinary installs use node-pty's target prebuild.
|
||||
* @param target - the pkg target whose native addon is being staged.
|
||||
*/
|
||||
private async prepareNativePty(target: Target): Promise<void> {
|
||||
@@ -418,8 +419,16 @@ class SingleExeBuild {
|
||||
if (this.cli.dryRun) console.log(`build-exe-for-python-sdk: [dry-run] rm -rf ${stagedBuild}`)
|
||||
else await rm(stagedBuild, { recursive: true, force: true })
|
||||
if (target.platform !== 'linux') return
|
||||
const source = join(root, 'packages', 'subprocess', 'subprocess-local', 'node_modules', 'node-pty', 'build', 'Release', 'pty.node')
|
||||
const packageDirectory = join(
|
||||
root,
|
||||
'packages',
|
||||
'subprocess',
|
||||
'subprocess-local',
|
||||
'node_modules',
|
||||
'node-pty',
|
||||
)
|
||||
const destination = join(stagedBuild, 'Release', 'pty.node')
|
||||
const source = resolveLinuxNodePtyAddon(packageDirectory, target.arch)
|
||||
if (this.cli.dryRun) {
|
||||
console.log(`build-exe-for-python-sdk: [dry-run] cp ${source} ${destination}`)
|
||||
return
|
||||
|
||||
@@ -342,6 +342,7 @@ describe('Python release workflows', () => {
|
||||
expect(manylinuxAddon).toMatchObject({ if: "runner.os == 'Linux'" })
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('manylinux_2_28_x86_64')
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('manylinux_2_28_aarch64')
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('npm_config_build_from_source=true pnpm run install')
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('$HOME/setup-pnpm:$HOME/setup-pnpm:ro')
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('node-pty-glibc-versions.txt')
|
||||
expect(JSON.stringify(manylinuxAddon)).toContain('le 2.28')
|
||||
|
||||
Reference in New Issue
Block a user