fix(pi-coding-agent): show full OAuth login URLs
This commit is contained in:
parent
791ce1b35e
commit
f15938ea4c
2 changed files with 54 additions and 2 deletions
|
|
@ -0,0 +1,24 @@
|
|||
import { describe, test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { buildAuthUrlPresentation } from "../login-dialog.js";
|
||||
|
||||
describe("LoginDialogComponent", () => {
|
||||
test("shows the full OAuth URL when the hyperlink label is truncated", () => {
|
||||
const presentation = buildAuthUrlPresentation(
|
||||
"https://auth.example.com/device?code=ABCD-1234&callback=oauth&state=needs-full-visibility",
|
||||
52,
|
||||
);
|
||||
|
||||
assert.notEqual(
|
||||
presentation.displayUrl,
|
||||
"https://auth.example.com/device?code=ABCD-1234&callback=oauth&state=needs-full-visibility",
|
||||
"narrow terminals should still truncate the hyperlink label",
|
||||
);
|
||||
assert.ok(presentation.fullUrlLines.length > 1, "truncated URLs should expose wrapped full-url lines");
|
||||
assert.match(presentation.fullUrlLines[0] ?? "", /https:\/\/auth\.example\.com\/device\?code=ABCD-1234&/);
|
||||
assert.match(
|
||||
presentation.fullUrlLines[presentation.fullUrlLines.length - 1] ?? "",
|
||||
/state=needs-full-visibility/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -7,6 +7,27 @@ import { theme } from "../theme/theme.js";
|
|||
import { DynamicBorder } from "./dynamic-border.js";
|
||||
import { keyHint } from "./keybinding-hints.js";
|
||||
|
||||
function wrapPlainText(text: string, width: number): string[] {
|
||||
const lines: string[] = [];
|
||||
const safeWidth = Math.max(1, width);
|
||||
for (let idx = 0; idx < text.length; idx += safeWidth) {
|
||||
lines.push(text.slice(idx, idx + safeWidth));
|
||||
}
|
||||
return lines.length > 0 ? lines : [""];
|
||||
}
|
||||
|
||||
export function buildAuthUrlPresentation(url: string, terminalColumns: number): {
|
||||
displayUrl: string;
|
||||
fullUrlLines: string[];
|
||||
} {
|
||||
const maxUrlWidth = Math.max(20, terminalColumns - 4);
|
||||
const displayUrl = truncateToWidth(url, maxUrlWidth);
|
||||
return {
|
||||
displayUrl,
|
||||
fullUrlLines: displayUrl === url ? [] : wrapPlainText(url, maxUrlWidth),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Login dialog component - replaces editor during OAuth login flow.
|
||||
*
|
||||
|
|
@ -124,14 +145,21 @@ export class LoginDialogComponent extends Container implements Focusable {
|
|||
|
||||
// Truncate the visible URL text so it never wraps (which would break
|
||||
// the OSC 8 hyperlink). The full URL is still the link target.
|
||||
const maxUrlWidth = Math.max(20, this.tui.terminal.columns - 4);
|
||||
const displayUrl = truncateToWidth(url, maxUrlWidth);
|
||||
const { displayUrl, fullUrlLines } = buildAuthUrlPresentation(url, this.tui.terminal.columns);
|
||||
const urlLink = `\x1b]8;;${url}\x07${theme.fg("accent", displayUrl)}\x1b]8;;\x07`;
|
||||
this.contentContainer.addChild(new Text(urlLink, 1, 0));
|
||||
|
||||
const clickHint = process.platform === "darwin" ? "Cmd+click to open" : "Ctrl+click to open";
|
||||
this.contentContainer.addChild(new Text(theme.fg("dim", clickHint), 1, 0));
|
||||
|
||||
if (fullUrlLines.length > 0) {
|
||||
this.contentContainer.addChild(new Spacer(1));
|
||||
this.contentContainer.addChild(new Text(theme.fg("dim", "Full URL:"), 1, 0));
|
||||
for (const line of fullUrlLines) {
|
||||
this.contentContainer.addChild(new Text(theme.fg("dim", line), 1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (instructions) {
|
||||
this.contentContainer.addChild(new Spacer(1));
|
||||
this.contentContainer.addChild(new Text(theme.fg("warning", instructions), 1, 0));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue