{"_id":"process-proxy","_rev":"6-c60a7c916023e666136f39dcb48d3aef","name":"process-proxy","dist-tags":{"latest":"0.6.0"},"versions":{"0.1.0":{"name":"process-proxy","version":"0.1.0","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","_id":"process-proxy@0.1.0","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"dist":{"shasum":"719e9b81a56287258d88a907ff41f834b4bb94c6","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.1.0.tgz","fileCount":25,"integrity":"sha512-fBzsCef2d04mYLWmEbs0aS8H/LNcmtK4FXt6jPzAR7/75OZdS9Bykx7CDykHXelOcFJvIH4tZ7CtENhllIVmNQ==","signatures":[{"sig":"MEUCIA7xHBvstYTQz2ch2c9sg63hJZZpEqEny5PFHZlicfo4AiEAl4ZozMnPNZyIif8cL/J1p2+0w2AjtrgHN/jqCj0f1ek=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":614064},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"524ef62f24190e36e7c7f7bc3f931c6e70cb5ad4","scripts":{"lint":"prettier --check .","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","build":"npm run build:native && npm run build:ts","clean":"rm -rf dist build","format":"prettier --write .","install":"npm run build:native","prepack":"node script/verify-binaries.mjs","rebuild":"npm run rebuild:native && npm run build:ts","build:ts":"tsc","build:native":"node script/build.mjs","example:basic":"tsx examples/basic.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","prepublishOnly":"npm run build:ts","rebuild:native":"node script/build.mjs --rebuild","example:streams":"tsx examples/streams.ts","build:native:all":"node script/build.mjs --all-archs","example:nonce-validation":"tsx examples/token-validation.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts"},"_npmUser":{"name":"niik","email":"j.markus.olsson@gmail.com"},"_npmVersion":"10.9.4","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","node-gyp":"^11.4.2","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.2"},"_npmOperationalInternal":{"tmp":"tmp/process-proxy_0.1.0_1761925853263_0.1083594396763008","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"process-proxy","version":"0.2.0","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","_id":"process-proxy@0.2.0","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"homepage":"https://github.com/niik/process-proxy#readme","bugs":{"url":"https://github.com/niik/process-proxy/issues"},"dist":{"shasum":"0fba9bab39e78e1152c7f7e7a28ad39d20842f7c","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.2.0.tgz","fileCount":25,"integrity":"sha512-uVyCWKbNiRNafhovUpDpYc46X/+18mYQcVuj1DTxbNt0McCvodSQQDvmjNWIoT6mXj1Y1hMPsZI/Fj3iTsk8ew==","signatures":[{"sig":"MEYCIQCqXiKoDfrMIe9r23x8gfFyMk0o5yquZN3MB3ZEP7Kn8QIhAMOIyUPBaoQKjz1wkaGU7tNOiDa/lZWX/65faGzeQN/F","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/process-proxy@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":614157},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"3a3f1821a20820b3680b1f35dce45761ef72af53","scripts":{"lint":"prettier --check .","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","build":"npm run build:native && npm run build:ts","clean":"rm -rf dist build","format":"prettier --write .","install":"npm run build:native","prepack":"node script/verify-binaries.mjs","rebuild":"npm run rebuild:native && npm run build:ts","build:ts":"tsc","build:native":"node script/build.mjs","example:basic":"tsx examples/basic.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","prepublishOnly":"npm run build:ts","rebuild:native":"node script/build.mjs --rebuild","example:streams":"tsx examples/streams.ts","build:native:all":"node script/build.mjs --all-archs","example:nonce-validation":"tsx examples/token-validation.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d76316a8-02a2-4257-bc4a-fe9a9a40bd95"}},"repository":{"url":"git+https://github.com/niik/process-proxy.git","type":"git"},"_npmVersion":"11.6.2","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","node-gyp":"^11.4.2","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.2"},"_npmOperationalInternal":{"tmp":"tmp/process-proxy_0.2.0_1761941873776_0.9351300738607127","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"process-proxy","version":"0.3.0","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","_id":"process-proxy@0.3.0","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"homepage":"https://github.com/niik/process-proxy#readme","bugs":{"url":"https://github.com/niik/process-proxy/issues"},"dist":{"shasum":"5bdb0cf430214868d395b3a9a5b74f12f519afbb","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.3.0.tgz","fileCount":26,"integrity":"sha512-DNyLMjWYgf8K2zT54XQkTCcoyQfOcWihRRamofYdlV8vOxSik+KcXYwwogrT+DQsJRfEJWFx7/s8te2BsHfmQw==","signatures":[{"sig":"MEYCIQDbdpQCr3D2FCW8aiN2/sBYT9wbDqedNf7hdMC4O5nHagIhANvqjlQSSD/zrFsCTFliEc/1CX/T6qjJdkARbE5J7vgn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/process-proxy@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":614792},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"gitHead":"873d5f111731b6b01e0b5655e70b88e7a7d13329","scripts":{"lint":"prettier --check .","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","build":"npm run build:native && npm run build:ts","clean":"rm -rf dist build","format":"prettier --write .","install":"npm run build:native","prepack":"node script/verify-binaries.mjs","rebuild":"npm run rebuild:native && npm run build:ts","build:ts":"tsc","build:native":"node script/build.mjs","example:basic":"tsx examples/basic.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","prepublishOnly":"npm run build:ts","rebuild:native":"node script/build.mjs --rebuild","example:streams":"tsx examples/streams.ts","build:native:all":"node script/build.mjs --all-archs","example:nonce-validation":"tsx examples/token-validation.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d76316a8-02a2-4257-bc4a-fe9a9a40bd95"}},"repository":{"url":"git+https://github.com/niik/process-proxy.git","type":"git"},"_npmVersion":"11.6.2","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","node-gyp":"^11.4.2","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.2"},"_npmOperationalInternal":{"tmp":"tmp/process-proxy_0.3.0_1762162873278_0.49046021940242057","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"process-proxy","version":"0.4.0","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","_id":"process-proxy@0.4.0","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"homepage":"https://github.com/niik/process-proxy#readme","bugs":{"url":"https://github.com/niik/process-proxy/issues"},"dist":{"shasum":"e6c7867d2bdc458c1032ca8d6d505e708220776f","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.4.0.tgz","fileCount":26,"integrity":"sha512-qqmh7r85xz2+LH+bV93pz5Cx9t+p5bo2ijmP4fWQvfhUnmVMwk5DcKMylHhjX3pgrnJr0/SS1dXfG1/ES6IdYg==","signatures":[{"sig":"MEUCIQDIb2Jwu3GCpQCe7TfxQ7wnlMaBIF5gQsxFdEUmBYu62QIgQK9sbVOf/02fRSH80r5qa8RYJ5pE07wTyjjnSlwildE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/process-proxy@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":619156},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"gitHead":"2d408f7b37e355407167a42a52c7dac515c35b1d","scripts":{"lint":"prettier --check .","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","build":"npm run build:native && npm run build:ts","clean":"rm -rf dist build","format":"prettier --write .","install":"npm run build:native","prepack":"node script/verify-binaries.mjs","rebuild":"npm run rebuild:native && npm run build:ts","build:ts":"tsc","build:native":"node script/build.mjs","example:basic":"tsx examples/basic.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","prepublishOnly":"npm run build:ts","rebuild:native":"node script/build.mjs --rebuild","example:streams":"tsx examples/streams.ts","build:native:all":"node script/build.mjs --all-archs","example:nonce-validation":"tsx examples/token-validation.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d76316a8-02a2-4257-bc4a-fe9a9a40bd95"}},"repository":{"url":"git+https://github.com/niik/process-proxy.git","type":"git"},"_npmVersion":"11.7.0","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","node-gyp":"^11.4.2","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.2"},"_npmOperationalInternal":{"tmp":"tmp/process-proxy_0.4.0_1768485152274_0.15369544315018935","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"process-proxy","version":"0.5.0","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","_id":"process-proxy@0.5.0","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"homepage":"https://github.com/niik/process-proxy#readme","bugs":{"url":"https://github.com/niik/process-proxy/issues"},"dist":{"shasum":"dd927887f6913351ea843405eac942be8510b5d9","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.5.0.tgz","fileCount":26,"integrity":"sha512-XiQ1tajBwjngpJzGraW/3baiGWeorxF8Rcw4nPuKOn6CiEIV7Fx+kqqKRN6f8Y09bxp9IdAAQAbJK9BxWUDVWQ==","signatures":[{"sig":"MEYCIQC+LVf6RRxC/clKg5KNxue2fzt4wOvI78vuosrUbGrgngIhAPaisnMVF50IWILmye+HpOatdT/kmEr6p5ReaP4pXu2S","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/process-proxy@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":619383},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22"},"gitHead":"6d045ff4591ffe9c17550b76433374fd054f3e37","scripts":{"lint":"prettier --check .","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","build":"npm run build:native && npm run build:ts","clean":"rm -rf dist build","format":"prettier --write .","install":"npm run build:native","prepack":"node script/verify-binaries.mjs","rebuild":"npm run rebuild:native && npm run build:ts","build:ts":"tsc","build:native":"node script/build.mjs","example:basic":"tsx examples/basic.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","prepublishOnly":"npm run build:ts","rebuild:native":"node script/build.mjs --rebuild","example:streams":"tsx examples/streams.ts","build:native:all":"node script/build.mjs --all-archs","example:nonce-validation":"tsx examples/token-validation.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d76316a8-02a2-4257-bc4a-fe9a9a40bd95"}},"repository":{"url":"git+https://github.com/niik/process-proxy.git","type":"git"},"_npmVersion":"11.7.0","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","node-gyp":"^11.4.2","prettier":"^3.6.2","typescript":"^5.9.3","@types/node":"^24.9.2"},"_npmOperationalInternal":{"tmp":"tmp/process-proxy_0.5.0_1768492136569_0.0932366412973149","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"process-proxy","version":"0.6.0","description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"install":"npm run build:native","build":"npm run build:native && npm run build:ts","rebuild":"npm run rebuild:native && npm run build:ts","build:native":"node script/build.mjs","build:native:all":"node script/build.mjs --all-archs","rebuild:native":"node script/build.mjs --rebuild","build:ts":"tsc","clean":"rm -rf dist build","prepublishOnly":"npm run build:ts","example:basic":"tsx examples/basic.ts","example:streams":"tsx examples/streams.ts","example:proxy":"tsx examples/proxy.ts","example:secure":"tsx examples/secure.ts","example:handshake-timeout":"tsx examples/handshake-timeout.ts","example:handshake-invalid":"tsx examples/handshake-invalid.ts","example:nonce-validation":"tsx examples/token-validation.ts","prepack":"node script/verify-binaries.mjs","test":"tsx --test --test-reporter=spec --test-timeout 10000 test/*.test.ts","lint":"prettier --check .","format":"prettier --write ."},"keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/niik/process-proxy.git"},"engines":{"node":">=22"},"devDependencies":{"@types/node":"^24.9.2","node-gyp":"^11.4.2","prettier":"^3.6.2","tsx":"^4.20.6","typescript":"^5.9.3"},"gitHead":"9a99b0e26cc3f80df7e298db268ac955a8e94f9d","_id":"process-proxy@0.6.0","bugs":{"url":"https://github.com/niik/process-proxy/issues"},"homepage":"https://github.com/niik/process-proxy#readme","_nodeVersion":"22.22.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-Ic7sU/XQQBJ1mdd8zLcrPakUdg5RrKmJKk3BV+5sLzbVhQRdQxOrG1ycA0dHeGr1TwFWHg37xArYiLEOiBx9kA==","shasum":"6871a14a01218a2ca6f0c348255894dd32415d17","tarball":"https://registry.npmjs.org/process-proxy/-/process-proxy-0.6.0.tgz","fileCount":26,"unpackedSize":620051,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/process-proxy@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGzK2ygGbGmgJ/gSD+adfjlymx6GAAc/GyQbq1J4gT0BAiEAq8onjUzqOW7XzoOrc3v4Qj76+rOSYDkhCotDrLOc+/o="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:d76316a8-02a2-4257-bc4a-fe9a9a40bd95"}},"directories":{},"maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/process-proxy_0.6.0_1772613036855_0.2648896659013955"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-31T15:50:53.262Z","modified":"2026-03-04T08:30:38.329Z","0.1.0":"2025-10-31T15:50:53.489Z","0.2.0":"2025-10-31T20:17:54.023Z","0.3.0":"2025-11-03T09:41:13.526Z","0.4.0":"2026-01-15T13:52:32.435Z","0.5.0":"2026-01-15T15:48:56.768Z","0.6.0":"2026-03-04T08:30:37.074Z"},"bugs":{"url":"https://github.com/niik/process-proxy/issues"},"author":{"name":"Markus Olsson","email":"j.markus.olsson@gmail.com"},"license":"MIT","homepage":"https://github.com/niik/process-proxy#readme","keywords":["process","proxy","stdin","stdout","stderr","native","executable"],"repository":{"type":"git","url":"git+https://github.com/niik/process-proxy.git"},"description":"Control a native executable proxy from Node, reading its stdin, writing to its stdout, and stderr streams","maintainers":[{"name":"niik","email":"j.markus.olsson@gmail.com"}],"readme":"# ProcessProxy\n\nA modern npm package (requiring Node 22+) written in TypeScript that enables developers to interact with a native executable, reading its stdin, writing to its stdout, and stderr streams, reading its exit code, arguments, current directory, and environment variables.\n\n## ⚠️ Development Status\n\n**This project is in early development and relies heavily on automated code generation using GitHub Copilot CLI.** While the implementation follows a clear design specification, it has not been extensively tested in production environments. Users should expect:\n\n- Potential unexpected behaviors or edge cases\n- Limited cross-platform testing (primarily tested on macOS arm64)\n- Possible API changes as the project matures\n- Incomplete error handling for all scenarios\n\n**Use at your own risk.** Contributions, bug reports, and testing on different platforms are highly encouraged.\n\n## Installation\n\n```bash\nnpm install process-proxy\n```\n\n## Building\n\nThis package includes a native executable that must be built before use:\n\n```bash\nnpm run build\n```\n\nThis will compile both the TypeScript library and the native C executable.\n\n## Usage\n\n### Basic Example\n\n```typescript\nimport { createProxyProcessServer, getProxyCommandPath } from 'process-proxy'\nimport { spawn } from 'child_process'\nimport { AddressInfo } from 'net'\n\n// Create server with connection callback (idiomatic Node.js style)\nconst server = createProxyProcessServer((connection) => {\n  console.log('Native process connected!')\n\n  // Get process information\n  connection.getArgs().then((args) => console.log('Arguments:', args))\n  connection.getEnv().then((env) => console.log('Environment:', env))\n  connection.getCwd().then((cwd) => console.log('Working Directory:', cwd))\n\n  // Write to the process stdout\n  connection.stdout.write('Hello from ProcessProxy!\\n')\n\n  // Read from the process stdin\n  connection.stdin.on('data', (data) => {\n    console.log('Received from stdin:', data.toString())\n  })\n\n  // Handle connection close\n  connection.on('close', () => {\n    console.log('Process disconnected')\n  })\n})\n\n// Start listening on a random port\nconst port = await new Promise<number>((resolve) => {\n  server.listen(0, '127.0.0.1', () => {\n    resolve((server.address() as AddressInfo).port)\n  })\n})\n\n// Launch the native executable with the port in environment\nconst nativeExe = getProxyCommandPath()\nconst child = spawn(nativeExe, ['arg1', 'arg2'], {\n  env: {\n    ...process.env,\n    PROCESS_PROXY_PORT: port.toString(),\n  },\n})\n\n// Later, close the server\n// server.close();\n```\n\n### Proxying stdin/stdout/stderr\n\n```typescript\nserver.on('connection', (connection) => {\n  // Pipe process stdin to our stdin\n  process.stdin.pipe(connection.stdout)\n\n  // Pipe process stdout to our stdout\n  connection.stdin.pipe(process.stdout)\n\n  // Pipe process stderr to our stderr\n  // (Note: stderr is a writable stream on the connection)\n  connection.stderr.on('data', (data) => {\n    process.stderr.write(data)\n  })\n})\n```\n\n### Controlling the Process\n\n```typescript\nserver.on('connection', async (connection) => {\n  // Exit the process with a specific code\n  await connection.exit(0)\n})\n```\n\n### Closing Streams\n\n```typescript\nserver.on('connection', async (connection) => {\n  connection.stdin.end()\n})\n```\n\n## API\n\n### createProxyProcessServer()\n\nCreates a TCP server that listens for incoming connections from native processes. Returns a standard Node.js `net.Server` instance.\n\n```typescript\nimport { createProxyProcessServer } from 'process-proxy'\nimport { AddressInfo } from 'net'\n\n// Create server with connection callback\nconst server = createProxyProcessServer((connection) => {\n  console.log('New connection!')\n  connection.getArgs().then(console.log)\n})\n\n// Start listening\nconst port = await new Promise<number>((resolve) => {\n  server.listen(0, '127.0.0.1', () => {\n    resolve((server.address() as AddressInfo).port)\n  })\n})\n\n// Use standard server methods\nserver.on('listening', () => console.log('Server started'))\nserver.on('error', (err) => console.error('Server error:', err))\nserver.close(() => console.log('Server closed'))\n```\n\n**Parameters:**\n\n- `listener: (connection: ProcessProxyConnection) => void` - Callback invoked for each incoming connection\n- `options?: ProxyProcessServerOptions` - Optional configuration object:\n  - `validateConnection?: (token: string) => Promise<boolean>` - Optional callback to validate the connection token during handshake. Receives the token from the handshake and should return a Promise resolving to `true` to accept the connection or `false` to reject it.\n  - All standard Node.js `net.ServerOpts` options are also supported\n\n**Returns:** `Server` - A standard Node.js `net.Server` instance\n\n### getProxyCommandPath()\n\nReturns the absolute path to the native proxy executable.\n\n```typescript\nimport { getProxyCommandPath } from 'process-proxy'\n\nconst executablePath = getProxyCommandPath()\n// Returns: '/path/to/build/Release/process-proxy' (or .exe on Windows)\n```\n\nThis utility function automatically:\n\n- Resolves the correct path relative to the installed package\n- Adds the `.exe` suffix on Windows\n- Works regardless of where the package is installed\n\n### ProcessProxyConnection\n\nRepresents a connection to a single instance of the native executable.\n\n#### Properties\n\n- `stdin: Readable` - Readable stream for the executable's stdin\n- `stdout: Writable` - Writable stream for the executable's stdout\n- `stderr: Writable` - Writable stream for the executable's stderr\n\n#### Methods\n\n- `sendCommand(command: number, payload?: Buffer): Promise<Buffer>` - Sends a raw command to the executable and returns the response\n- `getArgs(): Promise<string[]>` - Retrieves the command line arguments of the executable\n- `getEnv(): Promise<{ [key: string]: string }>` - Retrieves the environment variables of the executable\n- `getCwd(): Promise<string>` - Retrieves the current working directory of the executable\n- `exit(code: number): Promise<void>` - Exits the executable with the specified exit code\n\n#### Events\n\n- `close` - Emitted when the connection is closed\n- `error` - Emitted when an error occurs. Listener signature: `(error: Error) => void`\n\n## Native Executable\n\nThe native executable is written in C and compiled using node-gyp. It connects to the TCP server specified by the `PROCESS_PROXY_PORT` environment variable.\n\n### Building the Native Executable\n\nThe native executable is built automatically when running `npm run build` or `npm run build:native`.\n\n### Usage\n\nThe native executable must be launched with the `PROCESS_PROXY_PORT` environment variable set:\n\n```bash\nPROCESS_PROXY_PORT=12345 ./build/Release/process-proxy [args...]\n```\n\n## Security\n\n⚠️ **IMPORTANT SECURITY NOTE** ⚠️\n\nThe TCP server only listens on localhost (127.0.0.1), but this does not provide complete security. Other processes and users with access to the network stack on the host machine can potentially connect to the TCP server.\n\n### Built-in Token Authentication\n\nProcessProxy includes a built-in authentication mechanism to validate connections during the handshake phase:\n\n1. When the native executable connects, it sends a 146-byte handshake containing:\n   - Protocol header: \"ProcessProxy 0002 \" (18 bytes)\n   - Token: 128 bytes read from the `PROCESS_PROXY_TOKEN` environment variable\n\n2. The server validates this handshake and can optionally verify the token using a `validateConnection` callback\n\n3. If authentication fails, the connection is immediately closed before any commands are processed\n\n**Using Token Authentication:**\n\n```typescript\nimport crypto from 'crypto'\nimport { createProxyProcessServer, getProxyCommandPath } from 'process-proxy'\nimport { spawn } from 'child_process'\nimport { AddressInfo } from 'net'\n\n// Generate a random token for this session\nconst expectedToken = crypto.randomBytes(32).toString('hex')\n\n// Create server with token validation\nconst server = createProxyProcessServer(\n  (connection) => {\n    // Connection is already authenticated at this point\n    console.log('Authenticated connection established')\n  },\n  {\n    // Validate the token during handshake\n    validateConnection: async (token) => {\n      return token === expectedToken\n    },\n  },\n)\n\n// Start listening\nconst port = await new Promise<number>((resolve) => {\n  server.listen(0, '127.0.0.1', () => {\n    resolve((server.address() as AddressInfo).port)\n  })\n})\n\n// Launch native executable with the token\nconst child = spawn(getProxyCommandPath(), ['arg1', 'arg2'], {\n  env: {\n    ...process.env,\n    PROCESS_PROXY_PORT: port.toString(),\n    PROCESS_PROXY_TOKEN: expectedToken, // Token passed to native process\n  },\n})\n```\n\n**How it works:**\n\n- The native executable reads `PROCESS_PROXY_TOKEN` from its environment and includes it in the handshake\n- The server calls your `validateConnection` callback with the received token\n- If the callback returns `false` or rejects, the connection is immediately closed\n- Authentication happens before any commands are processed, preventing unauthorized access\n\n**Additional Security Recommendations:**\n\n1. **Always use `validateConnection`** in production environments\n2. **Generate unique tokens** per session using cryptographically secure random generators\n3. **Use environment variables** to pass tokens (never hardcode them)\n4. **Implement additional authorization** based on your application's security requirements\n5. **Monitor for suspicious connection patterns** and implement rate limiting if needed\n\n## Platform Support\n\n- Windows\n- macOS\n- Linux\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","readmeFilename":"README.md"}