mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 20:04:55 +00:00
Fix Windows terminal background rendering and add /debug command
- Strip carriage return characters from bash tool output to fix background padding on Windows - Add hidden /debug command to write rendered lines to debug log for TUI debugging - Document /debug command in README.md development section
This commit is contained in:
parent
4432fc9b72
commit
7b1f975ca1
3 changed files with 63 additions and 3 deletions
|
|
@ -1156,6 +1156,19 @@ import { getPackageDir, getThemeDir, getPackageJsonPath, getReadmePath, getChang
|
||||||
|
|
||||||
**Never use `__dirname` directly** for resolving package assets. The `paths.ts` module handles the differences between execution modes automatically.
|
**Never use `__dirname` directly** for resolving package assets. The `paths.ts` module handles the differences between execution modes automatically.
|
||||||
|
|
||||||
|
### Debug Command
|
||||||
|
|
||||||
|
The `/debug` command is a hidden development feature (not shown in autocomplete) that writes all currently rendered lines with their visible widths and ANSI escape sequences to `~/.pi/agent/pi-debug.log`. This is useful for debugging TUI rendering issues, especially when lines don't extend to the terminal edge or contain unexpected invisible characters.
|
||||||
|
|
||||||
|
```
|
||||||
|
/debug
|
||||||
|
```
|
||||||
|
|
||||||
|
The debug log includes:
|
||||||
|
- Terminal width at time of capture
|
||||||
|
- Total number of rendered lines
|
||||||
|
- Each line with its index, visible width, and JSON-escaped content showing all ANSI codes
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,9 @@ export class ToolExecutionComponent extends Container {
|
||||||
const textBlocks = this.result.content?.filter((c: any) => c.type === "text") || [];
|
const textBlocks = this.result.content?.filter((c: any) => c.type === "text") || [];
|
||||||
const imageBlocks = this.result.content?.filter((c: any) => c.type === "image") || [];
|
const imageBlocks = this.result.content?.filter((c: any) => c.type === "image") || [];
|
||||||
|
|
||||||
// Strip ANSI codes from raw output (bash may emit colors/formatting)
|
// Strip ANSI codes and carriage returns from raw output
|
||||||
let output = textBlocks.map((c: any) => stripAnsi(c.text || "")).join("\n");
|
// (bash may emit colors/formatting, and Windows may include \r)
|
||||||
|
let output = textBlocks.map((c: any) => stripAnsi(c.text || "").replace(/\r/g, "")).join("\n");
|
||||||
|
|
||||||
// Add indicator for images
|
// Add indicator for images
|
||||||
if (imageBlocks.length > 0) {
|
if (imageBlocks.length > 0) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
import * as os from "node:os";
|
||||||
|
import * as path from "node:path";
|
||||||
import type { Agent, AgentEvent, AgentState, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
import type { Agent, AgentEvent, AgentState, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
||||||
import type { AssistantMessage, Message, Model } from "@mariozechner/pi-ai";
|
import type { AssistantMessage, Message, Model } from "@mariozechner/pi-ai";
|
||||||
import type { SlashCommand } from "@mariozechner/pi-tui";
|
import type { SlashCommand } from "@mariozechner/pi-tui";
|
||||||
|
|
@ -12,8 +15,8 @@ import {
|
||||||
Text,
|
Text,
|
||||||
TruncatedText,
|
TruncatedText,
|
||||||
TUI,
|
TUI,
|
||||||
|
visibleWidth,
|
||||||
} from "@mariozechner/pi-tui";
|
} from "@mariozechner/pi-tui";
|
||||||
|
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { getChangelogPath, parseChangelog } from "../changelog.js";
|
import { getChangelogPath, parseChangelog } from "../changelog.js";
|
||||||
import { exportSessionToHtml } from "../export-html.js";
|
import { exportSessionToHtml } from "../export-html.js";
|
||||||
|
|
@ -415,6 +418,13 @@ export class TuiRenderer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for /debug command
|
||||||
|
if (text === "/debug") {
|
||||||
|
this.handleDebugCommand();
|
||||||
|
this.editor.setText("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for file-based slash commands
|
// Check for file-based slash commands
|
||||||
text = expandSlashCommand(text, this.fileCommands);
|
text = expandSlashCommand(text, this.fileCommands);
|
||||||
|
|
||||||
|
|
@ -1530,6 +1540,42 @@ export class TuiRenderer {
|
||||||
this.ui.requestRender();
|
this.ui.requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleDebugCommand(): void {
|
||||||
|
// Force a render and capture all lines with their widths
|
||||||
|
const width = (this.ui as any).terminal.columns;
|
||||||
|
const allLines = this.ui.render(width);
|
||||||
|
|
||||||
|
const debugLogPath = path.join(os.homedir(), ".pi", "agent", "pi-debug.log");
|
||||||
|
const debugData = [
|
||||||
|
`Debug output at ${new Date().toISOString()}`,
|
||||||
|
`Terminal width: ${width}`,
|
||||||
|
`Total lines: ${allLines.length}`,
|
||||||
|
"",
|
||||||
|
"=== All rendered lines with visible widths ===",
|
||||||
|
...allLines.map((line, idx) => {
|
||||||
|
const vw = visibleWidth(line);
|
||||||
|
const escaped = JSON.stringify(line);
|
||||||
|
return `[${idx}] (w=${vw}) ${escaped}`;
|
||||||
|
}),
|
||||||
|
"",
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
fs.mkdirSync(path.dirname(debugLogPath), { recursive: true });
|
||||||
|
fs.writeFileSync(debugLogPath, debugData);
|
||||||
|
|
||||||
|
// Show confirmation
|
||||||
|
this.chatContainer.addChild(new Spacer(1));
|
||||||
|
this.chatContainer.addChild(
|
||||||
|
new Text(
|
||||||
|
theme.fg("accent", "✓ Debug log written") + "\n" + theme.fg("muted", `~/.pi/agent/pi-debug.log`),
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
this.ui.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
private updatePendingMessagesDisplay(): void {
|
private updatePendingMessagesDisplay(): void {
|
||||||
this.pendingMessagesContainer.clear();
|
this.pendingMessagesContainer.clear();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue