@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed final bash tool cards to avoid rendering duplicate full-output truncation paths ([#4819](https://github.com/earendil-works/pi/issues/4819)).
|
||||
|
||||
## [0.75.4] - 2026-05-20
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -200,7 +200,15 @@ function rebuildBashResultRenderComponent(
|
||||
const state = component.state;
|
||||
component.clear();
|
||||
|
||||
const output = getTextOutput(result as any, showImages).trim();
|
||||
let output = getTextOutput(result as any, showImages).trim();
|
||||
const truncation = result.details?.truncation;
|
||||
const fullOutputPath = result.details?.fullOutputPath;
|
||||
if (!options.isPartial && truncation?.truncated && fullOutputPath && output.endsWith("]")) {
|
||||
const footerStart = output.lastIndexOf("\n\n[");
|
||||
if (footerStart !== -1 && output.slice(footerStart).includes(fullOutputPath)) {
|
||||
output = output.slice(0, footerStart).trimEnd();
|
||||
}
|
||||
}
|
||||
|
||||
if (output) {
|
||||
const styledOutput = output
|
||||
@@ -236,8 +244,6 @@ function rebuildBashResultRenderComponent(
|
||||
}
|
||||
}
|
||||
|
||||
const truncation = result.details?.truncation;
|
||||
const fullOutputPath = result.details?.fullOutputPath;
|
||||
if (truncation?.truncated || fullOutputPath) {
|
||||
const warnings: string[] = [];
|
||||
if (fullOutputPath) {
|
||||
|
||||
@@ -123,6 +123,43 @@ describe("ToolExecutionComponent parity", () => {
|
||||
await promise;
|
||||
});
|
||||
|
||||
test("bash renderer does not duplicate final full output truncation details", async () => {
|
||||
const operations: BashOperations = {
|
||||
exec: async (_command, _cwd, { onData }) => {
|
||||
for (let i = 1; i <= 4000; i++) {
|
||||
onData(Buffer.from(`line-${String(i).padStart(4, "0")}\n`));
|
||||
}
|
||||
return { exitCode: 0 };
|
||||
},
|
||||
};
|
||||
const tool = createBashToolDefinition(process.cwd(), { operations });
|
||||
const result = await tool.execute(
|
||||
"tool-bash-1b",
|
||||
{ command: "generate output" },
|
||||
undefined,
|
||||
undefined,
|
||||
{} as never,
|
||||
);
|
||||
const component = new ToolExecutionComponent(
|
||||
"bash",
|
||||
"tool-bash-1b",
|
||||
{ command: "generate output" },
|
||||
{},
|
||||
tool,
|
||||
createFakeTui(),
|
||||
process.cwd(),
|
||||
);
|
||||
component.setExpanded(true);
|
||||
component.updateResult({ ...result, isError: false }, false);
|
||||
|
||||
const rendered = stripAnsi(component.render(200).join("\n"));
|
||||
expect(rendered.match(/Full output:/g)?.length ?? 0).toBe(1);
|
||||
expect(rendered).toMatch(/line-4000[^\n]*\n[^\S\n]*\n \[Full output:/);
|
||||
expect(rendered).not.toMatch(/line-4000[^\n]*\n[^\S\n]*\n[^\S\n]*\n \[Full output:/);
|
||||
expect(rendered).toContain("Truncated: showing 2000 of 4001 lines");
|
||||
expect(rendered).not.toContain("[Showing lines 2002-4001 of 4001. Full output:");
|
||||
});
|
||||
|
||||
test("does not duplicate built-in headers when passed the active built-in definition", () => {
|
||||
const component = new ToolExecutionComponent(
|
||||
"read",
|
||||
|
||||
Reference in New Issue
Block a user