You cannot use exec() here. You must use spawn() to properly pass in and close stdin. This also solves the problem of spaces or quotes in the result filename. Here's the drop in code replacement:

        child = spawn('zip', ['-r', result, '-@'], { cwd: cwd });
        child.stdin.write(targets.map(function (p) {
            var x = p.indexOf(cwd);
            if (x >= 0) {
                p = p.replace(cwd, '');
                if (/^\//.test(p)) {
                    p = p.substring(1);
                }
            }
            if (!p) {
                p = '.';
            }
            return p;
        }).join('\n'));
        child.stdin.end();
        child.stdout.on('data', function (data) {
            stdout += data.toString();
        });
        child.stderr.on('data', function (data) {
            stderr += data.toString();
        });
        child.on('exit', function (code) {
            if (code) {
                callback(stderr);
            } else {
                callback();
            }
        });