fix(cli): awaited config JSON stdout flush
- Waited for the stdout write callback before the config command exits. - Covered JSON output larger than the 64 KiB pipe buffer. Fixes #5309
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
|
||||
- Updated status event log to prioritize the most recent entries in the display window
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `omp config list --json` truncating output at 64 KiB when stdout is piped ([#5309](https://github.com/can1357/oh-my-pi/issues/5309))
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the unreliable Bing and Yahoo HTML-scraping web search providers
|
||||
|
||||
@@ -241,7 +241,7 @@ export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
|
||||
|
||||
switch (cmd.action) {
|
||||
case "list":
|
||||
handleList(cmd.flags);
|
||||
await handleList(cmd.flags);
|
||||
break;
|
||||
case "get":
|
||||
handleGet(cmd.key, cmd.flags);
|
||||
@@ -261,7 +261,19 @@ export async function runConfigCommand(cmd: ConfigCommandArgs): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function handleList(flags: { json?: boolean }): void {
|
||||
async function writeStdout(text: string): Promise<void> {
|
||||
const pending = Promise.withResolvers<void>();
|
||||
process.stdout.write(text, error => {
|
||||
if (error) {
|
||||
pending.reject(error);
|
||||
return;
|
||||
}
|
||||
pending.resolve();
|
||||
});
|
||||
await pending.promise;
|
||||
}
|
||||
|
||||
async function handleList(flags: { json?: boolean }): Promise<void> {
|
||||
const defs = ALL_SETTING_PATHS.map(path => findSettingDef(path)).filter((def): def is CliSettingDef => !!def);
|
||||
|
||||
if (flags.json) {
|
||||
@@ -273,7 +285,7 @@ function handleList(flags: { json?: boolean }): void {
|
||||
description: def.description,
|
||||
};
|
||||
}
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
await writeStdout(`${JSON.stringify(result, null, 2)}\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getConfigRootDir, setAgentDir, TempDir } from "@oh-my-pi/pi-utils";
|
||||
let testAgentDir: TempDir | undefined;
|
||||
const originalAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
const fallbackAgentDir = path.join(getConfigRootDir(), "agent");
|
||||
const cliEntry = path.join(import.meta.dir, "..", "src", "cli.ts");
|
||||
|
||||
beforeEach(() => {
|
||||
resetSettingsForTest();
|
||||
@@ -166,4 +167,25 @@ describe("config CLI schema coverage", () => {
|
||||
expect(parsed.type).toBe("enum");
|
||||
expect(parsed.value).toBe("max");
|
||||
});
|
||||
it("fully flushes JSON larger than a pipe buffer", async () => {
|
||||
if (!testAgentDir) throw new Error("Test agent directory was not initialized");
|
||||
const proc = Bun.spawn([process.execPath, cliEntry, "config", "list", "--json"], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
env: {
|
||||
...process.env,
|
||||
NO_COLOR: "1",
|
||||
PI_CODING_AGENT_DIR: testAgentDir.path(),
|
||||
},
|
||||
});
|
||||
const stdout = new Response(proc.stdout).text();
|
||||
const stderr = new Response(proc.stderr).text();
|
||||
const [exitCode, output, error] = await Promise.all([proc.exited, stdout, stderr]);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(error).toBe("");
|
||||
expect(Buffer.byteLength(output)).toBeGreaterThan(65_536);
|
||||
const parsed: unknown = JSON.parse(output);
|
||||
expect(parsed).toMatchObject({ modelRoles: { type: "record" } });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user