Files
zCode-CLI-X/~/.npm-cache/execa@9.6.1@@@1/lib/io/contents.js
admin 875c7f9b91 feat: Complete zCode CLI X with Telegram bot integration
- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
2026-05-05 09:01:26 +00:00

117 lines
3.2 KiB
JavaScript

import {setImmediate} from 'node:timers/promises';
import getStream, {getStreamAsArrayBuffer, getStreamAsArray} from 'get-stream';
import {isArrayBuffer} from '../utils/uint-array.js';
import {shouldLogOutput, logLines} from '../verbose/output.js';
import {iterateForResult} from './iterate.js';
import {handleMaxBuffer} from './max-buffer.js';
import {getStripFinalNewline} from './strip-newline.js';
// Retrieve `result.stdout|stderr|all|stdio[*]`
export const getStreamOutput = async ({stream, onStreamEnd, fdNumber, encoding, buffer, maxBuffer, lines, allMixed, stripFinalNewline, verboseInfo, streamInfo}) => {
const logPromise = logOutputAsync({
stream,
onStreamEnd,
fdNumber,
encoding,
allMixed,
verboseInfo,
streamInfo,
});
if (!buffer) {
await Promise.all([resumeStream(stream), logPromise]);
return;
}
const stripFinalNewlineValue = getStripFinalNewline(stripFinalNewline, fdNumber);
const iterable = iterateForResult({
stream,
onStreamEnd,
lines,
encoding,
stripFinalNewline: stripFinalNewlineValue,
allMixed,
});
const [output] = await Promise.all([
getStreamContents({
stream,
iterable,
fdNumber,
encoding,
maxBuffer,
lines,
}),
logPromise,
]);
return output;
};
const logOutputAsync = async ({stream, onStreamEnd, fdNumber, encoding, allMixed, verboseInfo, streamInfo: {fileDescriptors}}) => {
if (!shouldLogOutput({
stdioItems: fileDescriptors[fdNumber]?.stdioItems,
encoding,
verboseInfo,
fdNumber,
})) {
return;
}
const linesIterable = iterateForResult({
stream,
onStreamEnd,
lines: true,
encoding,
stripFinalNewline: true,
allMixed,
});
await logLines(linesIterable, stream, fdNumber, verboseInfo);
};
// When using `buffer: false`, users need to read `subprocess.stdout|stderr|all` right away
// See https://github.com/sindresorhus/execa/issues/730 and https://github.com/sindresorhus/execa/pull/729#discussion_r1465496310
const resumeStream = async stream => {
await setImmediate();
if (stream.readableFlowing === null) {
stream.resume();
}
};
const getStreamContents = async ({stream, stream: {readableObjectMode}, iterable, fdNumber, encoding, maxBuffer, lines}) => {
try {
if (readableObjectMode || lines) {
return await getStreamAsArray(iterable, {maxBuffer});
}
if (encoding === 'buffer') {
return new Uint8Array(await getStreamAsArrayBuffer(iterable, {maxBuffer}));
}
return await getStream(iterable, {maxBuffer});
} catch (error) {
return handleBufferedData(handleMaxBuffer({
error,
stream,
readableObjectMode,
lines,
encoding,
fdNumber,
}));
}
};
// On failure, `result.stdout|stderr|all` should contain the currently buffered stream
// They are automatically closed and flushed by Node.js when the subprocess exits
// When `buffer` is `false`, `streamPromise` is `undefined` and there is no buffered data to retrieve
export const getBufferedData = async streamPromise => {
try {
return await streamPromise;
} catch (error) {
return handleBufferedData(error);
}
};
// Ensure we are returning Uint8Arrays when using `encoding: 'buffer'`
const handleBufferedData = ({bufferedData}) => isArrayBuffer(bufferedData)
? new Uint8Array(bufferedData)
: bufferedData;