{"_id":"@adhd/sox-service-proxy","_rev":"9-10e28fa610d0dc4f0fa408e4ac027f40","name":"@adhd/sox-service-proxy","dist-tags":{"latest":"0.5.0"},"versions":{"0.2.0":{"name":"@adhd/sox-service-proxy","version":"0.2.0","license":"MIT","_id":"@adhd/sox-service-proxy@0.2.0","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"dist":{"shasum":"67961210f9d4f52a02de3231002dfbfb5250aad5","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.2.0.tgz","fileCount":38,"integrity":"sha512-xY4ctTY9mm/1pgJvfB1lkKWKovYMNJlY9F1vi6/x/DqyBgMLPlk9RJeI1U4icVRzi9n7WljnGdeANafy/iP65A==","signatures":[{"sig":"MEUCIQCWbyuqD+vUYw4IoCcg5+GNCrc4Ma4PS5NWLe9/iPAUYwIgcWOdyagZqAamtWwXE5+IX+luCpbIKFM9UphLtwos5GM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120523},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.2.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/3c2f91e4e24a3f549cdab06c8f694c03/adhd-sox-service-proxy-0.2.0.tgz","_integrity":"sha512-xY4ctTY9mm/1pgJvfB1lkKWKovYMNJlY9F1vi6/x/DqyBgMLPlk9RJeI1U4icVRzi9n7WljnGdeANafy/iP65A==","_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.2.0_1782451185966_0.8333018500880138","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@adhd/sox-service-proxy","version":"0.3.0","license":"MIT","_id":"@adhd/sox-service-proxy@0.3.0","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"dist":{"shasum":"e4d4bf85ccf416e5d0f712f3d1016a0865d763cb","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.3.0.tgz","fileCount":38,"integrity":"sha512-g3Gm0b4+eZhQMMzUybTRYFkZcMr/EZUbr/+ODn9mvVczS5Zt1Gi0ZrEzZ2wWIZ+ABlwZRoi+GOXf0lO8x5vcXA==","signatures":[{"sig":"MEQCIFGQU6LYU8/vs3YQYynFOecyj5FtiMItkabU+JzxHw9LAiBqrlTktG7KVNhh0AB5JsFqLr5Ek2AotQhA1E8XpVHn0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":156561},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.3.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/4fabe5ffb42c425c6b076c037a913075/adhd-sox-service-proxy-0.3.0.tgz","_integrity":"sha512-g3Gm0b4+eZhQMMzUybTRYFkZcMr/EZUbr/+ODn9mvVczS5Zt1Gi0ZrEzZ2wWIZ+ABlwZRoi+GOXf0lO8x5vcXA==","_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.3.0_1786144737952_0.4048426141489385","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@adhd/sox-service-proxy","version":"0.3.1","license":"MIT","_id":"@adhd/sox-service-proxy@0.3.1","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"dist":{"shasum":"759c39f94585db20c85c06ffd220c021c381a004","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.3.1.tgz","fileCount":38,"integrity":"sha512-uKrzbYNu6i30TrjmdnGuh+rJn7DJBHDAY4RROT8YjP2e1OvsShGkjQCXKkH+M+exS0ek4ZPJ4eCpQIiMfejNpQ==","signatures":[{"sig":"MEYCIQCwyYbQC4tIVfWt9R3EUoSXFobi/EMjEwobu3Yrr+zlgwIhAJsC5N2/xXinMEnmoecpS9AuryWOFbxT8j1Q20fr6CSA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":167180},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.3.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/d657a1dad13addb77a3860a633ab2581/adhd-sox-service-proxy-0.3.1.tgz","_integrity":"sha512-uKrzbYNu6i30TrjmdnGuh+rJn7DJBHDAY4RROT8YjP2e1OvsShGkjQCXKkH+M+exS0ek4ZPJ4eCpQIiMfejNpQ==","_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.3.1_1787113047821_0.5493551993994432","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@adhd/sox-service-proxy","version":"0.4.0","keywords":["mcp","proxy","stdio","uds","typescript"],"license":"MIT","_id":"@adhd/sox-service-proxy@0.4.0","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"c0d79eda175a87c09c585140b2c10215c3b18c71","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.4.0.tgz","fileCount":40,"integrity":"sha512-NW+J/6xGV6w+Alip6sRmvlpo2ke6IF2vn/P9xNrvFNzGOwWNSR64uZ8NiexrfdCVTQwrf4qiBhDZPf8MYczkGQ==","signatures":[{"sig":"MEYCIQDA4MWipyxa8K25pE7+X05dxUlb736LzqklLIkF5s7vfAIhAPHuzib4HM7yOOG8a3B/7YKxSzfIj7E15dAqinNeYKuP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCfZcN2D2sjQdgcRezMDFkK3Eq5xbXMK0oPXzuF3ahwwwIhAJ8WUF0G+WIAlfYmqoTm1MmpcHs7Iov08hVheRrkiH+q","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":185631},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.4.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/802a6a6aa7679ad2fc9fb2c68d042533/adhd-sox-service-proxy-0.4.0.tgz","_integrity":"sha512-NW+J/6xGV6w+Alip6sRmvlpo2ke6IF2vn/P9xNrvFNzGOwWNSR64uZ8NiexrfdCVTQwrf4qiBhDZPf8MYczkGQ==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.4.0_1788566542411_0.2893235991291587","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@adhd/sox-service-proxy","version":"0.4.1","keywords":["mcp","proxy","stdio","uds","typescript"],"license":"MIT","_id":"@adhd/sox-service-proxy@0.4.1","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"fb3dc1f83695c147a2c9a46792c0a24e668b044d","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.4.1.tgz","fileCount":40,"integrity":"sha512-qz/cdkakISzUVa5ZrqnaPNUSOSYH/McZRRIGYUxNS8f/eUdYzRQ+mcoOpIFpuPXU3zWHV1RlD2JsxRZX9bU9tg==","signatures":[{"sig":"MEUCIQC/S2xEH3PgsaLGwjhAX7YbDxVS746HBDebSoLSqDPqEQIgBz4iNaHos6/1aqDO31SZ45uRoWiokJAYxIzkAPqF0L4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDrChoyboEBzlZz2AoBEGoR9XUTAm7RBuLWONK3oXFFaAIgBkjGUi2z2COd5hQzq4Y07feL8gbxejvmlLmeIyHDAUE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187087},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.4.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/f7e6b8fde64b1091adcc5e88f7a691c1/adhd-sox-service-proxy-0.4.1.tgz","_integrity":"sha512-qz/cdkakISzUVa5ZrqnaPNUSOSYH/McZRRIGYUxNS8f/eUdYzRQ+mcoOpIFpuPXU3zWHV1RlD2JsxRZX9bU9tg==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.4.1_1790114627436_0.9221100629111789","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@adhd/sox-service-proxy","version":"0.4.2","keywords":["mcp","proxy","stdio","uds","typescript"],"license":"MIT","_id":"@adhd/sox-service-proxy@0.4.2","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"49194162b983b878bd344b8ad7ce178865a17e0b","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.4.2.tgz","fileCount":40,"integrity":"sha512-2WJ4U/vyotngyuf1jKbAHUlaY13BPxjRhShoSIKCZijr77CQuxmNqTSxA5Mtc9lfLpKpScWNYJOoefaDRFNtGQ==","signatures":[{"sig":"MEUCIQCwIUqySgZrreqAKl71j77nkakXJ0SrJI9dfFyW7/tgVQIgTXAuDW4ErNbdpngDmHR8fBT9v0ke7cURYEQR3eVRvhY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCmQiDcQgLQbdGCZUFkxcHTavkuyYT9dJMAADwiQA1aYQIgfH62TrvdVoXl0hFjpincY5XZjpC/zBD888QTCbuXxXM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187890},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.4.2.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/14e75d0f65aeb771f010d22798d24b1e/adhd-sox-service-proxy-0.4.2.tgz","_integrity":"sha512-2WJ4U/vyotngyuf1jKbAHUlaY13BPxjRhShoSIKCZijr77CQuxmNqTSxA5Mtc9lfLpKpScWNYJOoefaDRFNtGQ==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.4.2_1790117695043_0.04775624645858989","host":"s3://npm-registry-packages-npm-production"}},"0.4.3":{"name":"@adhd/sox-service-proxy","version":"0.4.3","keywords":["mcp","proxy","stdio","uds","typescript"],"license":"MIT","_id":"@adhd/sox-service-proxy@0.4.3","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"d136ce9c3c0e9718cefdd22b37af83ceb65e4fab","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.4.3.tgz","fileCount":40,"integrity":"sha512-KzgQR3GhG0p5SorFJNHMHkfoEyL8VyN9BtkiBLuZABJfK2f0CrJtJ1KKIZ1d4sHp/3mHI5/XCdzT77Q+sAcLpQ==","signatures":[{"sig":"MEQCIB7q3N2D8TWRq91teuPV8IGv1l2UddBCs/SNGWHOmBSVAiAYNpBl9EA0HcJfr7lhZW05f3aHxpnP7F1yNjWwMpzM0w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDjXH25pgTyFvXgkwoP1uDQWegW/D4wZTQ308w1NkZAvwIgIVfGotJ5wNic748qn0Zo3Zc8VuVpaj1/fpdknIcAw24=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":190453},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.4.3.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/1b4fe1e039e3097ea34a20f24c170345/adhd-sox-service-proxy-0.4.3.tgz","_integrity":"sha512-KzgQR3GhG0p5SorFJNHMHkfoEyL8VyN9BtkiBLuZABJfK2f0CrJtJ1KKIZ1d4sHp/3mHI5/XCdzT77Q+sAcLpQ==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.4.3_1790118600757_0.3525071011724443","host":"s3://npm-registry-packages-npm-production"}},"0.4.4":{"name":"@adhd/sox-service-proxy","version":"0.4.4","keywords":["mcp","proxy","stdio","uds","typescript"],"license":"MIT","_id":"@adhd/sox-service-proxy@0.4.4","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"homepage":"https://github.com/PseudoSky/adhd","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"1894060dfc5af9d514fa1320254973b95f122f6d","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.4.4.tgz","fileCount":40,"integrity":"sha512-AYKiQGS0jX91uu/LHLdphuZddQORm+v0VigHvygvJp11Aci+P/mOB5uKVJ+S9GD5tArl1zXgJqH+VTOdlvUYxw==","signatures":[{"sig":"MEQCIA9xL7IWYT0ZNH+1bLC27JrEq22jWGagkphLzffcSvCtAiAz21qN4XLHblebR+mO/2RHWzKjE0WtU8KWwBCp7kTAyw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCfUCYccSP31Bvfoxq2C1QQLE/6WQSd1sLoZeSlcSLtyAIhAPhsdbswdDx/54pAeMA3dvfTGIUdDmjJ5eyrvqEVZOx6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":194504},"main":"./dist/index.js","_from":"file:adhd-sox-service-proxy-0.4.4.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/75539334007043f8afe247ba70bd675f/adhd-sox-service-proxy-0.4.4.tgz","_integrity":"sha512-AYKiQGS0jX91uu/LHLdphuZddQORm+v0VigHvygvJp11Aci+P/mOB5uKVJ+S9GD5tArl1zXgJqH+VTOdlvUYxw==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sox-service-proxy_0.4.4_1790391144922_0.9497712117197286","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"_id":"@adhd/sox-service-proxy@0.5.0","bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"dist":{"shasum":"e603c70e128b26cb3f4908d0c9285177c33e3928","tarball":"https://registry.npmjs.org/@adhd/sox-service-proxy/-/sox-service-proxy-0.5.0.tgz","fileCount":44,"integrity":"sha512-BuefAZrsPrADlnQ351ehNxK8DrpcJZ67VtahPqm7r2AaBGt3EEBZBBbf9FsWZpb+P198Uk7zqTlCbeF4K/Kn9g==","signatures":[{"sig":"MEUCIQCp+288UpX9l68SmaIbwMZTRYCw4medipy5GzB8m/B9WAIgWRoLoxNk0OqMMutC797P36M6D9YUe9DSKL3iSqKrpMY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCycmhA3/kEmKfIpLR4eH8/VMJL5Fj3vWDG36xKE6WubQIhALLVhcZZGM53Sed8di2A0TL5/k3oD0kwR1GLU5c4XcP0"}],"unpackedSize":250448},"main":"./dist/index.js","name":"@adhd/sox-service-proxy","_from":"file:adhd-sox-service-proxy-0.5.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"license":"MIT","version":"0.5.0","_npmUser":{"name":"pseudosky","email":"skywinston.sk@gmail.com"},"homepage":"https://github.com/PseudoSky/adhd","keywords":["mcp","proxy","stdio","uds","typescript"],"_resolved":"/private/var/folders/yg/cfczgtx54bzfh74lx2_mv0z80000gp/T/afb9dcd9c4a61ab7e548284c61530c4b/adhd-sox-service-proxy-0.5.0.tgz","_integrity":"sha512-BuefAZrsPrADlnQ351ehNxK8DrpcJZ67VtahPqm7r2AaBGt3EEBZBBbf9FsWZpb+P198Uk7zqTlCbeF4K/Kn9g==","repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"_npmVersion":"11.6.2","description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","directories":{},"maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"_nodeVersion":"24.11.1","dependencies":{"@adhd/sox-listen-guard":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sox-service-proxy_0.5.0_1790650392452_0.7614770086979685"}}},"time":{"created":"2026-06-26T05:19:45.799Z","modified":"2026-09-29T02:53:12.727Z","0.2.0":"2026-06-26T05:19:46.136Z","0.3.0":"2026-08-07T23:18:58.101Z","0.3.1":"2026-08-19T04:17:27.957Z","0.4.0":"2026-09-05T00:02:22.501Z","0.4.1":"2026-09-22T22:03:47.533Z","0.4.2":"2026-09-22T22:54:55.124Z","0.4.3":"2026-09-22T23:10:00.843Z","0.4.4":"2026-09-26T02:52:25.014Z","0.5.0":"2026-09-29T02:53:12.547Z"},"bugs":{"url":"https://github.com/PseudoSky/adhd/issues"},"license":"MIT","homepage":"https://github.com/PseudoSky/adhd","keywords":["mcp","proxy","stdio","uds","typescript"],"repository":{"url":"git+https://github.com/PseudoSky/adhd.git","type":"git"},"description":"Front-shim service-proxy (spec §9.5, Slice 1.5): stdio↔UDS MCP proxy enabling zero-downtime backend upgrades without client reconnects. Dependency-free leaf (node builtins only).","maintainers":[{"name":"pseudosky","email":"skywinston.sk@gmail.com"}],"readme":"# @adhd/sox-service-proxy\n\nA stdio↔UDS proxy that lets an MCP server's backend be upgraded — new code, new\nprocess — **without the MCP client ever reconnecting**. The client spawns a thin\nfront-shim over stdio; the shim serves `initialize`/`tools/list` from a cached\nschema and relays everything else to a long-lived backend process over a Unix\ndomain socket. Roll the backend, and the same stdio pipe the client is already\nholding keeps working: in-flight and new requests re-dial automatically and\nresume the moment the new backend is live. A dependency-free leaf — Node\nbuiltins only (`net`, `crypto`, `fs`, `path`), plus one workspace dependency for\nguarded HTTP binding.\n\n```bash\npnpm add @adhd/sox-service-proxy\n```\n\n## Quick start\n\nThis is the whole shape end-to-end in one process: a backend, a front-shim in\nfront of it, and a client driving the shim exactly the way an MCP host would\n(newline-delimited JSON-RPC over a pair of streams).\n\n```typescript\nimport { PassThrough } from 'node:stream';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { serveBackend, runFrontShim, type BackendHandler } from '@adhd/sox-service-proxy';\n\nasync function main() {\n  const socketPath = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'sox-proxy-')), 'backend.sock');\n\n  // 1. The backend: the real, upgradeable process holding your tool implementation.\n  const handler: BackendHandler = (req) => {\n    if (req.method === 'initialize') {\n      return { jsonrpc: '2.0', id: req.id ?? null, result: { serverInfo: { name: 'demo', version: '1.0.0' }, capabilities: {} } };\n    }\n    if (req.method === 'tools/list') {\n      return { jsonrpc: '2.0', id: req.id ?? null, result: { tools: [{ name: 'echo', description: 'Echoes its input', inputSchema: { type: 'object' } }] } };\n    }\n    if (req.method === 'tools/call') {\n      return { jsonrpc: '2.0', id: req.id ?? null, result: { echoed: req.params } };\n    }\n    return { jsonrpc: '2.0', id: req.id ?? null, result: null };\n  };\n  const backend = await serveBackend({ socketPath, handler });\n\n  // 2. The front-shim: what the MCP client actually spawns over stdio. It answers\n  //    initialize/tools/list instantly from a cached schema, then relays every\n  //    other call to the backend above over the UDS socket.\n  const toShim = new PassThrough();   // client -> shim\n  const fromShim = new PassThrough(); // shim -> client\n  const shim = runFrontShim({ id: 'demo-server', socketPath, input: toShim, output: fromShim });\n\n  // 3. Drive it like an MCP client would.\n  fromShim.on('data', (chunk) => process.stdout.write(`client received: ${chunk}`));\n  toShim.write(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { v: 'hi' } }) + '\\n');\n\n  // Later: ship a new backend build. Start it on the SAME socketPath and close\n  // the old one — dialBackend re-dials automatically, so the shim above (and\n  // the MCP client attached to it) never see a disconnect.\n\n  await new Promise((r) => setTimeout(r, 50));\n  shim.close();\n  await backend.close();\n}\n\nmain();\n```\n\n## API reference\n\n### Front-shim (client-facing)\n\n```typescript\nfunction runFrontShim(opts: FrontShimOptions): FrontShimHandle;\n\ninterface FrontShimOptions {\n  id: string;                    // extension id, for diagnostics + serve-record\n  socketPath: string;            // backend UDS path\n  schemaCachePath?: string;      // published schema.json to serve tools/list from before the backend is up\n  input?: NodeJS.ReadableStream;  // default: process.stdin\n  output?: NodeJS.WritableStream; // default: process.stdout\n  onDiagnostic?: (line: string) => void; // stderr sink — see \"no-stdout-diagnostics\" below\n  backoff?: BackoffOptions;\n  ensure?: () => Promise<void>;  // auto-spawn hook, called before dialing and after a drop\n  httpPort?: number;             // also serve JSON-RPC over HTTP POST /mcp on this port\n  onHttpBindResult?: (outcome: ListenOutcome) => void;\n  listenFailureRecordFile?: string;\n  clientProjectPath?: string;    // injects client_context.project_path into every tools/call frame\n}\n\ninterface FrontShimHandle {\n  done: Promise<void>;           // resolves when the client's input stream ends\n  close(): void;\n  backend: BackendConnection;\n}\n\ninterface ClientContext {\n  project_path: string;\n}\n```\n\n### Backend (server-facing)\n\n```typescript\nfunction serveBackend(opts: ServeBackendOptions): Promise<BackendHandle>;\n\ninterface ServeBackendOptions {\n  socketPath: string;\n  handler: BackendHandler;       // (req) => JsonRpcResponse | undefined\n  onDiagnostic?: (line: string) => void;\n  inheritFd?: number;            // listen on a pre-bound fd from an OS supervisor (launchd socket activation)\n}\n\ntype BackendHandler = (request: JsonRpcRequest) => Promise<JsonRpcResponse | undefined> | JsonRpcResponse | undefined;\n\ninterface BackendHandle {\n  socketPath: string;\n  close(): Promise<void>;\n}\n```\n\n`serveBackend` never unlinks a live socket. If the socket file already exists it\nprobe-connects first; a live socket is refused with a structured `E_LIVE_SOCKET`\nerror rather than being stolen out from under a running backend.\n\n### Re-dialing connection (the zero-downtime mechanism)\n\n```typescript\nfunction dialBackend(opts: DialOptions): BackendConnection;\n\ninterface DialOptions {\n  socketPath: string;\n  backoff?: BackoffOptions;\n  onDiagnostic?: (line: string) => void;\n  onConnect?: () => void;\n  onDisconnect?: () => void;\n}\n\ninterface BackoffOptions {\n  initialMs?: number;      // default 50\n  maxMs?: number;          // default 2000\n  giveUpAfterMs?: number;  // default 10000 — after this, pending requests fast-fail with -32001\n  maxQueue?: number;       // default 256 — oldest buffered requests are fast-failed beyond this\n}\n\ninterface BackendConnection {\n  send(request: JsonRpcRequest): Promise<JsonRpcResponse>; // buffers while disconnected, never rejects/hangs\n  notify(request: JsonRpcRequest): void;                   // dropped if the backend is unavailable\n  isConnected(): boolean;\n  close(): void;\n}\n```\n\n`dialBackend` returns synchronously and starts connecting immediately; calls to\n`send()` issued before the first connect are queued and flushed on connect. If\nthe backend stays down past `giveUpAfterMs`, pending calls resolve with a\n`-32001` (backend-unavailable) error response instead of hanging — the loop\nkeeps re-dialing in the background and recovers automatically.\n\n### Auto-managed backend lifecycle\n\n```typescript\nfunction ensureBackend(opts: EnsureBackendOptions): Promise<EnsureBackendResult>;\nfunction probeSocketLive(socketPath: string, timeoutMs?: number): Promise<boolean>;\nfunction handshakeBackend(socketPath: string, timeoutMs?: number): Promise<boolean>;\n\ntype EnsureBackendDisposition = 'already-live' | 'spawned' | 'adopted-after-wait' | 'failed';\n\ninterface EnsureBackendResult {\n  disposition: EnsureBackendDisposition;\n  pid?: number;    // only set when disposition === 'spawned'\n  detail: string;\n}\n\ninterface EnsureBackendOptions {\n  socketPath: string;\n  singletonKey: string;     // identical keys -> identical spawn lock -> one backend\n  command: string;          // e.g. process.execPath\n  args: string[];           // e.g. ['--enable-source-maps', entrypointPath]\n  cwd?: string;\n  env?: NodeJS.ProcessEnv;  // must carry the backend-mode signal + SOX_CONFIG_* env\n  lockDir?: string;\n  onDiagnostic?: (line: string) => void;\n  readyTimeoutMs?: number;  // default 10000\n  probeTimeoutMs?: number;  // default 250\n  lockTtlMs?: number;       // default 30000\n  stderrLogPath?: string;   // NEVER 'inherit' for a detached backend — see gotchas\n}\n```\n\n`ensureBackend` makes \"start a backend if one isn't already running\" safe under\na thundering herd of concurrent shims: it probes for liveness first (no spawn if\nalready live), then races an `O_EXCL` spawn lock — the winner spawns detached\nand waits for the socket; losers wait for the winner's socket instead of\nspawning their own. Exactly one backend process comes up per `singletonKey`,\nno matter how many shims start at once.\n\n### Schema-hash change detection\n\n```typescript\nfunction computeSchemaHash(toolsListPayload: unknown): string;\nfunction canonicalize(value: unknown): string;\n```\n\nBoth the shim and the backend compute `sha256` of the *canonicalized* (keys\nsorted recursively) `tools/list` payload. A backend upgrade that changes\nbehaviour but not its tool interface leaves the hash unchanged, so the shim\nkeeps serving its cached schema with zero client-visible change. A real\ninterface change (a tool added/removed, or a schema edit) changes the hash —\nthe shim then emits a stderr notice and, if the client declared the\ncapability, a `notifications/tools/list_changed`.\n\n### Frame codec (shim↔backend wire format)\n\n```typescript\nconst HEADER_BYTES = 4;\nconst MAX_FRAME_BYTES: number; // 16 MiB\n\nfunction encodeFrame(value: unknown): Buffer;\n\nclass FrameDecoder {\n  constructor(onMessage: (value: unknown) => void, onError: (err: Error) => void);\n  push(chunk: Buffer): void;\n  reset(): void;\n}\n```\n\nUDS is a byte stream with no message boundaries, so every payload crossing the\nshim↔backend socket is framed as a 4-byte big-endian length prefix followed by\nthat many bytes of UTF-8 JSON. `FrameDecoder` is decoupled from any socket —\nfeed it raw chunks (even one byte at a time) via `push()` and it emits each\ncomplete frame to `onMessage`; a declared length over `MAX_FRAME_BYTES` is\ntreated as a protocol violation via `onError`, not an allocation to honor.\n\n```typescript\nconst decoder = new FrameDecoder(\n  (msg) => console.log('got frame', msg),\n  (err) => socket.destroy(err),\n);\nsocket.on('data', (chunk) => decoder.push(chunk));\n```\n\n### Socket path derivation\n\n```typescript\nfunction backendSocketPath(socketDir: string, singletonKey: string): string;\n```\n\nComposes a deterministic backend UDS path from a resolved socket directory and\na singleton key, sanitizing the result to fit within the platform's\n`sun_path` limit (108 bytes on Linux, 104 on macOS) — a socket path derived\nfrom a deeply nested scratch directory can otherwise silently overflow it and\nfail `bind(2)` with `EINVAL`.\n\nThree tiers, first fit wins: `<socketDir>/proxy-<key>-<digest>.sock`, then\n`<socketDir>/proxy-<digest>.sock`, then — when `socketDir` alone is too long —\n`/tmp/sox-<uid>/p-<digest>.sock` under the fixed per-uid root\n`udsFallbackRoot()`. The result never depends on `TMPDIR`, so every peer\nderives the same path for the same key. On a platform without\n`process.getuid` the tier-3 root throws `E_UDS_UNSUPPORTED_PLATFORM`.\n\n### Socket-directory trust check\n\n```typescript\nfunction ensurePrivateSocketDir(dir: string, opts: { create: boolean; deps?: Partial<SocketDirDeps> }): void;\nfunction assertPrivateSocketDir(dir: string, deps?: Partial<SocketDirDeps>): void;\nfunction isUdsDirUnsafeError(err: unknown): err is UdsDirUnsafeError;\nfunction tightenOwnedSocketDir(dir: string, opts?: TightenOwnedSocketDirOptions): TightenOutcome;\nfunction udsFallbackRoot(uid?: number): string; // '/tmp/sox-<uid>'\n```\n\nA socket is only as private as its directory. `serveBackend` calls\n`ensurePrivateSocketDir(dirname(socketPath), { create: true })` before binding.\n`dialBackend`, `probeSocketLive`, `handshakeBackend`, and `ensureBackend` check\nthe directory before they connect. The directory must pass `lstat`:\n\n- it is not a symlink, and it is a directory;\n- it is owned by the current uid;\n- the `/tmp/sox-<uid>` root is exactly `0700` (created non-recursively);\n- any other directory has no group or other write bit.\n\nA failure throws `E_UDS_DIR_UNSAFE` with\n`{ reason, dir, expectedUid, actualUid, mode, isSymlink }`. The check never\nchmods, chowns, deletes, or swaps the directory for another path. The message\ndepends on `reason`, and no message suggests a recursive delete:\n\n| `reason` | Meaning | Remediation in the message |\n|---|---|---|\n| `foreign` | A symlink, a non-directory, or owned by another uid | Check `ls -ld`. Treat it as a possible impostor. `rm <dir>` removes only a symlink. Under sticky `/tmp`, only the owner or an admin can remove it. Inside the data root, `mv` it aside and restart. For the `/tmp/sox-<uid>` root, the message also says to point `SOX_ECOSYSTEM_HOME` at a shorter path. |\n| `own-writable` | Yours, but group/other-writable (usually umask 002) | `chmod go-w <dir>`. Do not delete it: it holds live runtime state. |\n| `fallback-mode` | `/tmp/sox-<uid>` is yours but not exactly `0700` | `chmod 700 /tmp/sox-<uid>` |\n\nThe refusal is non-retryable:\n\n- `serveBackend` rejects without binding.\n- `dialBackend` fast-fails pending requests with `-32001` and\n  `data.code: 'E_UDS_DIR_UNSAFE'`. It does not re-dial, and the next `send()`\n  re-checks the directory.\n- `probeSocketLive` and `handshakeBackend` reject instead of resolving `false`\n  when the socket file exists in an unsafe directory. They still resolve\n  `false`, without checking the directory, when no socket file exists.\n- `ensureBackend` returns `{ disposition: 'failed', errorCode: 'E_UDS_DIR_UNSAFE' }`\n  and spawns nothing.\n\nA directory that does not exist yet is not unsafe. Dialing into it keeps the\nordinary re-dial behaviour.\n\n**Repair: `tightenOwnedSocketDir`.** This removes group/other write from a\ndirectory it can prove is yours. It opens the directory once with\n`O_RDONLY|O_DIRECTORY|O_NOFOLLOW`, then runs `fstat` and `fchmod(mode & 0o7755)`\non that same descriptor. It returns one of:\n\n- `'absent'`: the directory does not exist;\n- `'ok'`: it was already tight;\n- `'tightened'`: the mode was changed, and `onTightened` receives `{dir, oldMode, newMode}` for the caller's telemetry;\n- `'skipped-not-owned'`: it was the fallback root, a symlink, a non-directory, or another uid's directory.\n\nThe checks above never call it. Only the process that owns the data root does,\nonce at start-up: `soxe` CLI init on `runDir()` and `socketDir()`, and the\nembedding funnel on `$SOX_ECOSYSTEM_HOME/run`.\n\n### JSON-RPC 2.0 types + helpers\n\n```typescript\ntype JsonRpcId = string | number | null;\n\ninterface JsonRpcRequest {\n  jsonrpc: '2.0';\n  id?: JsonRpcId;\n  method: string;\n  params?: unknown;\n}\n\ninterface JsonRpcError {\n  code: number;\n  message: string;\n  data?: unknown;\n}\n\ninterface JsonRpcResponse {\n  jsonrpc: '2.0';\n  id: JsonRpcId;\n  result?: unknown;\n  error?: JsonRpcError;\n}\n\nconst ERR_BACKEND_UNAVAILABLE = -32001;\n\nfunction isJsonRpcRequest(v: unknown): v is JsonRpcRequest;\nfunction isJsonRpcResponse(v: unknown): v is JsonRpcResponse;\nfunction isNotification(req: JsonRpcRequest): boolean; // true iff req.id is absent\nfunction errorResponse(id: JsonRpcId, code: number, message: string, data?: unknown): JsonRpcResponse;\n```\n\n## Invariants / gotchas\n\n- **No stdout diagnostics.** The front-shim's stdout carries *only*\n  newline-delimited JSON-RPC to the client — every diagnostic goes to\n  `onDiagnostic` (stderr by default). A stray stdout byte corrupts the\n  client's JSON-RPC stream.\n- **Never `stderrLogPath`-less with `'inherit'`.** A detached backend spawned\n  by `ensureBackend` must fully sever inherited stdio. If the spawning\n  process's own stderr is connected to a pipe (e.g.\n  `soxe upgrade --all 2>&1 | tail`), a detached child inheriting that pipe\n  holds it open forever and the pipeline hangs. By default stderr goes to\n  `/dev/null`; pass `stderrLogPath` to redirect it to a real file instead.\n- **`serveBackend` never unlinks a live socket.** A pre-existing socket file\n  is probe-connected before any bind; a live one is refused\n  (`E_LIVE_SOCKET`) rather than stolen. Only a stale socket (no process\n  listening) is cleaned up.\n- **`dialBackend.send()` never rejects and never hangs.** Past\n  `giveUpAfterMs` it resolves with a `-32001` error response instead — the\n  caller always gets a response object to inspect, and the re-dial loop\n  keeps trying in the background so a returning backend recovers\n  automatically.\n- **This package has no CLI and no MCP SDK dependency.** It is a\n  transport-agnostic JSON-RPC relay; the actual MCP tool dispatcher lives\n  behind the `handler` you pass to `serveBackend`.\n","readmeFilename":"README.md"}