From 5339369abd69b1254933f2d7bf12a7c0771c189a Mon Sep 17 00:00:00 2001 From: can1357 Date: Fri, 6 Feb 2026 02:51:07 +0100 Subject: [PATCH] style: replaced ASCII ellipsis with Unicode character for improved typography - Replaced ASCII ellipsis characters (three dots '...') with Unicode ellipsis character ('...') throughout the codebase for improved typography. - Adjusted string truncation logic to account for single-character Unicode ellipsis instead of three-character ASCII ellipsis, reducing reserved space from 3 to 1 character in truncation calculations. - Updated truncation offsets in multiple files (session-manager, agent, executor, footer) to preserve 2 additional characters before ellipsis due to more compact Unicode representation. --- packages/ai/src/cli.ts | 2 +- packages/ai/src/providers/openai-codex-responses.ts | 2 +- packages/coding-agent/CHANGELOG.md | 2 ++ packages/coding-agent/examples/extensions/plan-mode.ts | 2 +- packages/coding-agent/examples/hooks/qna.ts | 2 +- packages/coding-agent/examples/hooks/status-line.ts | 2 +- packages/coding-agent/examples/sdk/11-sessions.ts | 2 +- packages/coding-agent/src/cli/update-cli.ts | 4 ++-- packages/coding-agent/src/commit/agentic/agent.ts | 2 +- packages/coding-agent/src/commit/changelog/index.ts | 4 ++-- .../extensibility/custom-commands/bundled/review/index.ts | 2 +- packages/coding-agent/src/lsp/utils.ts | 4 ++-- packages/coding-agent/src/modes/components/footer.ts | 6 +++--- .../src/modes/controllers/selector-controller.ts | 2 +- packages/coding-agent/src/patch/applicator.ts | 5 ++--- packages/coding-agent/src/patch/fuzzy.ts | 2 +- packages/coding-agent/src/sdk.ts | 4 ++-- packages/coding-agent/src/session/session-manager.ts | 2 +- packages/coding-agent/src/task/executor.ts | 2 +- packages/coding-agent/src/utils/frontmatter.ts | 2 +- packages/coding-agent/src/utils/title-generator.ts | 2 +- packages/coding-agent/src/utils/tools-manager.ts | 4 ++-- packages/coding-agent/src/web/scrapers/osv.ts | 5 ++++- packages/coding-agent/src/web/scrapers/youtube.ts | 2 +- packages/coding-agent/src/web/search/index.ts | 2 +- packages/natives/scripts/build-native.ts | 2 +- packages/react-edit-benchmark/generate.ts | 2 +- packages/tui/src/components/box.ts | 4 ++-- scripts/dump-edit-history.ts | 4 ++-- scripts/release.ts | 4 ++-- 30 files changed, 45 insertions(+), 41 deletions(-) diff --git a/packages/ai/src/cli.ts b/packages/ai/src/cli.ts index e7e24da56..c2d8ecf6d 100755 --- a/packages/ai/src/cli.ts +++ b/packages/ai/src/cli.ts @@ -261,7 +261,7 @@ Examples: process.exit(1); } - console.log(`Logging in to ${provider}...`); + console.log(`Logging in to ${provider}…`); await login(provider); return; } diff --git a/packages/ai/src/providers/openai-codex-responses.ts b/packages/ai/src/providers/openai-codex-responses.ts index 664e7e782..ff26610cc 100644 --- a/packages/ai/src/providers/openai-codex-responses.ts +++ b/packages/ai/src/providers/openai-codex-responses.ts @@ -757,7 +757,7 @@ function getString(value: unknown): string | undefined { function truncate(text: string, limit: number): string { if (text.length <= limit) return text; - return `${text.slice(0, limit)}...[truncated ${text.length - limit}]`; + return `${text.slice(0, limit)}…[truncated ${text.length - limit}]`; } function formatCodexFailure(rawEvent: Record): string | null { diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index f36b04539..a0028ecc2 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## [Unreleased] + ### Added - Support for `PI_PACKAGE_DIR` environment variable to override package directory (useful for Nix/Guix store paths) @@ -29,6 +30,7 @@ ### Changed +- Replaced ellipsis string (`...`) with Unicode ellipsis character (`…`) throughout UI text and truncation logic for improved typography - Improved render performance by introducing caching for tool output blocks and search results to avoid redundant text width and padding computations - Enhanced read tool grouping to reset when non-tool content (text/thinking blocks) appears between read calls, preventing unintended coalescing - Improved string preview formatting in scalar values to show line counts and truncation indicators for multi-line strings diff --git a/packages/coding-agent/examples/extensions/plan-mode.ts b/packages/coding-agent/examples/extensions/plan-mode.ts index 5200df2c9..2b64eab4d 100644 --- a/packages/coding-agent/examples/extensions/plan-mode.ts +++ b/packages/coding-agent/examples/extensions/plan-mode.ts @@ -162,7 +162,7 @@ function cleanStepText(text: string): string { // Truncate if too long if (cleaned.length > 50) { - cleaned = `${cleaned.slice(0, 47)}...`; + cleaned = `${cleaned.slice(0, 49)}…`; } return cleaned; diff --git a/packages/coding-agent/examples/hooks/qna.ts b/packages/coding-agent/examples/hooks/qna.ts index b936b7b2f..3dda3e1db 100644 --- a/packages/coding-agent/examples/hooks/qna.ts +++ b/packages/coding-agent/examples/hooks/qna.ts @@ -71,7 +71,7 @@ export default function (pi: HookAPI) { // Run extraction with loader UI const result = await ctx.ui.custom((tui, theme, done) => { - const loader = new BorderedLoader(tui, theme, `Extracting questions using ${ctx.model!.id}...`); + const loader = new BorderedLoader(tui, theme, `Extracting questions using ${ctx.model!.id}…`); loader.onAbort = () => done(null); // Do the work diff --git a/packages/coding-agent/examples/hooks/status-line.ts b/packages/coding-agent/examples/hooks/status-line.ts index 271c3a02f..0699d0624 100644 --- a/packages/coding-agent/examples/hooks/status-line.ts +++ b/packages/coding-agent/examples/hooks/status-line.ts @@ -18,7 +18,7 @@ export default function (pi: HookAPI) { turnCount++; const theme = ctx.ui.theme; const spinner = theme.fg("accent", "●"); - const text = theme.fg("dim", ` Turn ${turnCount}...`); + const text = theme.fg("dim", ` Turn ${turnCount}…`); ctx.ui.setStatus("status-demo", spinner + text); }); diff --git a/packages/coding-agent/examples/sdk/11-sessions.ts b/packages/coding-agent/examples/sdk/11-sessions.ts index 039618d95..f94f2c126 100644 --- a/packages/coding-agent/examples/sdk/11-sessions.ts +++ b/packages/coding-agent/examples/sdk/11-sessions.ts @@ -28,7 +28,7 @@ console.log("Continued session:", continued.sessionFile); const sessions = SessionManager.list(process.cwd()); console.log(`\nFound ${sessions.length} sessions:`); for (const info of sessions.slice(0, 3)) { - console.log(` ${info.id.slice(0, 8)}... - "${info.firstMessage.slice(0, 30)}..."`); + console.log(` ${info.id.slice(0, 8)}… - "${info.firstMessage.slice(0, 30)}…"`); } if (sessions.length > 0) { diff --git a/packages/coding-agent/src/cli/update-cli.ts b/packages/coding-agent/src/cli/update-cli.ts index f717f9d1d..f875d0818 100644 --- a/packages/coding-agent/src/cli/update-cli.ts +++ b/packages/coding-agent/src/cli/update-cli.ts @@ -190,7 +190,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise { const nativePath = path.join(execDir, nativeAddonName); const nativeTempPath = `${nativePath}.new`; - console.log(chalk.dim(`Downloading ${binaryName}...`)); + console.log(chalk.dim(`Downloading ${binaryName}…`)); // Download to temp file const response = await fetch(asset.url, { redirect: "follow" }); @@ -202,7 +202,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise { await pipeline(response.body, fileStream); // Download native addon - console.log(chalk.dim(`Downloading ${nativeAddonName}...`)); + console.log(chalk.dim(`Downloading ${nativeAddonName}…`)); const nativeResponse = await fetch(nativeAsset.url, { redirect: "follow" }); if (!nativeResponse.ok || !nativeResponse.body) { diff --git a/packages/coding-agent/src/commit/agentic/agent.ts b/packages/coding-agent/src/commit/agentic/agent.ts index d16394260..10fa8c1bb 100644 --- a/packages/coding-agent/src/commit/agentic/agent.ts +++ b/packages/coding-agent/src/commit/agentic/agent.ts @@ -307,5 +307,5 @@ Call the missing tool(s) now. function truncateToolArg(value: string): string { if (value.length <= 40) return value; - return `${value.slice(0, 37)}...`; + return `${value.slice(0, 39)}…`; } diff --git a/packages/coding-agent/src/commit/changelog/index.ts b/packages/coding-agent/src/commit/changelog/index.ts index e4282f66c..350df07ed 100644 --- a/packages/coding-agent/src/commit/changelog/index.ts +++ b/packages/coding-agent/src/commit/changelog/index.ts @@ -54,7 +54,7 @@ export async function runChangelogFlow({ const updated: string[] = []; for (const boundary of boundaries) { - onProgress?.(`Generating entries for ${boundary.changelogPath}...`); + onProgress?.(`Generating entries for ${boundary.changelogPath}…`); const diff = await git.getDiffForFiles(boundary.files, true); if (!diff.trim()) continue; const stat = await git.getStatForFiles(boundary.files, true); @@ -108,7 +108,7 @@ export async function applyChangelogProposals({ (!proposal.deletions || Object.keys(proposal.deletions).length === 0) ) continue; - onProgress?.(`Applying entries for ${proposal.path}...`); + onProgress?.(`Applying entries for ${proposal.path}…`); const exists = fs.existsSync(proposal.path); if (!exists) { logger.warn("commit changelog path missing", { path: proposal.path }); diff --git a/packages/coding-agent/src/extensibility/custom-commands/bundled/review/index.ts b/packages/coding-agent/src/extensibility/custom-commands/bundled/review/index.ts index 6f7d60a9d..50593cfa1 100644 --- a/packages/coding-agent/src/extensibility/custom-commands/bundled/review/index.ts +++ b/packages/coding-agent/src/extensibility/custom-commands/bundled/review/index.ts @@ -361,7 +361,7 @@ export class ReviewCommand implements CustomCommand { const stats = parseDiff(diffResult.stdout); // Even if all files filtered, include the custom instructions return `${buildReviewPrompt( - `Custom review: ${instructions.split("\n")[0].slice(0, 60)}...`, + `Custom review: ${instructions.split("\n")[0].slice(0, 60)}…`, stats, diffResult.stdout, )}\n\n### Additional Instructions\n\n${instructions}`; diff --git a/packages/coding-agent/src/lsp/utils.ts b/packages/coding-agent/src/lsp/utils.ts index 5d7d9838c..874ed1ff7 100644 --- a/packages/coding-agent/src/lsp/utils.ts +++ b/packages/coding-agent/src/lsp/utils.ts @@ -371,7 +371,7 @@ export function formatTextEdit(edit: TextEdit, maxLength = 50): string { const range = `${edit.range.start.line + 1}:${edit.range.start.character + 1}`; const preview = edit.newText.length > maxLength - ? `${edit.newText.slice(0, maxLength).replace(/\n/g, "\\n")}...` + ? `${edit.newText.slice(0, maxLength).replace(/\n/g, "\\n")}…` : edit.newText.replace(/\n/g, "\\n"); return `line ${range} ${theme.nav.cursor} "${preview}"`; } @@ -530,7 +530,7 @@ export function extractHoverText( */ export function truncate(str: string, maxLength: number): string { if (str.length <= maxLength) return str; - return `${str.slice(0, maxLength - 3)}...`; + return `${str.slice(0, maxLength - 1)}…`; } /** diff --git a/packages/coding-agent/src/modes/components/footer.ts b/packages/coding-agent/src/modes/components/footer.ts index 69e1b8d39..19280c773 100644 --- a/packages/coding-agent/src/modes/components/footer.ts +++ b/packages/coding-agent/src/modes/components/footer.ts @@ -211,11 +211,11 @@ export class FooterComponent implements Component { // Truncate path if too long to fit width if (pwd.length > width) { - const half = Math.floor(width / 2) - 2; + const half = Math.floor(width / 2) - 1; if (half > 1) { const start = pwd.slice(0, half); const end = pwd.slice(-(half - 1)); - pwd = `${start}...${end}`; + pwd = `${start}…${end}`; } else { pwd = pwd.slice(0, Math.max(1, width)); } @@ -269,7 +269,7 @@ export class FooterComponent implements Component { if (statsLeftWidth > width) { // Truncate statsLeft to fit width (no room for right side) const plainStatsLeft = statsLeft.replace(/\x1b\[[0-9;]*m/g, ""); - statsLeft = `${plainStatsLeft.substring(0, width - 3)}...`; + statsLeft = `${plainStatsLeft.substring(0, width - 1)}…`; statsLeftWidth = visibleWidth(statsLeft); } diff --git a/packages/coding-agent/src/modes/controllers/selector-controller.ts b/packages/coding-agent/src/modes/controllers/selector-controller.ts index 71ac78e2c..9907e3b31 100644 --- a/packages/coding-agent/src/modes/controllers/selector-controller.ts +++ b/packages/coding-agent/src/modes/controllers/selector-controller.ts @@ -547,7 +547,7 @@ export class SelectorController { done(); if (mode === "login") { - this.ctx.showStatus(`Logging in to ${providerId}...`); + this.ctx.showStatus(`Logging in to ${providerId}…`); try { await this.ctx.session.modelRegistry.authStorage.login(providerId as OAuthProvider, { diff --git a/packages/coding-agent/src/patch/applicator.ts b/packages/coding-agent/src/patch/applicator.ts index ccf7d0bcc..f6883e3bf 100644 --- a/packages/coding-agent/src/patch/applicator.ts +++ b/packages/coding-agent/src/patch/applicator.ts @@ -434,8 +434,7 @@ function formatSequenceMatchPreview(lines: string[], startIdx: number): string { return previewLines .map((line, i) => { const num = start + i + 1; - const truncated = - line.length > MATCH_PREVIEW_MAX_LEN ? `${line.slice(0, MATCH_PREVIEW_MAX_LEN - 3)}...` : line; + const truncated = line.length > MATCH_PREVIEW_MAX_LEN ? `${line.slice(0, MATCH_PREVIEW_MAX_LEN - 1)}…` : line; return ` ${num} | ${truncated}`; }) .join("\n"); @@ -1103,7 +1102,7 @@ function computeReplacements( return lines .map((line, i) => { const num = start + i + 1; - const truncated = line.length > maxLineLength ? `${line.slice(0, maxLineLength - 3)}...` : line; + const truncated = line.length > maxLineLength ? `${line.slice(0, maxLineLength - 1)}…` : line; return ` ${num} | ${truncated}`; }) .join("\n"); diff --git a/packages/coding-agent/src/patch/fuzzy.ts b/packages/coding-agent/src/patch/fuzzy.ts index b435db532..7a274aef1 100644 --- a/packages/coding-agent/src/patch/fuzzy.ts +++ b/packages/coding-agent/src/patch/fuzzy.ts @@ -241,7 +241,7 @@ export function findMatch( const preview = previewLines .map((line, idx) => { const num = start + idx + 1; - return ` ${num} | ${line.length > OCCURRENCE_PREVIEW_MAX_LEN ? `${line.slice(0, OCCURRENCE_PREVIEW_MAX_LEN - 3)}...` : line}`; + return ` ${num} | ${line.length > OCCURRENCE_PREVIEW_MAX_LEN ? `${line.slice(0, OCCURRENCE_PREVIEW_MAX_LEN - 1)}…` : line}`; }) .join("\n"); occurrencePreviews.push(preview); diff --git a/packages/coding-agent/src/sdk.ts b/packages/coding-agent/src/sdk.ts index fc710b4af..31d3db17d 100644 --- a/packages/coding-agent/src/sdk.ts +++ b/packages/coding-agent/src/sdk.ts @@ -701,7 +701,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} onConnecting: serverNames => { if (options.hasUI && serverNames.length > 0) { process.stderr.write( - chalk.gray(`Connecting to MCP servers: ${serverNames.join(", ")}... + chalk.gray(`Connecting to MCP servers: ${serverNames.join(", ")}… `), ); } @@ -1076,7 +1076,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} const result = await warmupLspServers(cwd, { onConnecting: serverNames => { if (options.hasUI && serverNames.length > 0) { - process.stderr.write(chalk.gray(`Starting LSP servers: ${serverNames.join(", ")}...\n`)); + process.stderr.write(chalk.gray(`Starting LSP servers: ${serverNames.join(", ")}…\n`)); } }, }); diff --git a/packages/coding-agent/src/session/session-manager.ts b/packages/coding-agent/src/session/session-manager.ts index 626fea103..10b9d984b 100644 --- a/packages/coding-agent/src/session/session-manager.ts +++ b/packages/coding-agent/src/session/session-manager.ts @@ -515,7 +515,7 @@ class RecentSessionInfo { get name(): string { if (this.#name) return this.#name; const fullName = this.fullName; - this.#name = fullName.length <= 40 ? fullName : `${fullName.slice(0, 37)}...`; + this.#name = fullName.length <= 40 ? fullName : `${fullName.slice(0, 39)}…`; return this.#name; } diff --git a/packages/coding-agent/src/task/executor.ts b/packages/coding-agent/src/task/executor.ts index 3a42e9d65..f5854abdb 100644 --- a/packages/coding-agent/src/task/executor.ts +++ b/packages/coding-agent/src/task/executor.ts @@ -270,7 +270,7 @@ function extractToolArgsPreview(args: Record): string { for (const key of previewKeys) { if (args[key] && typeof args[key] === "string") { const value = args[key] as string; - return value.length > 60 ? `${value.slice(0, 57)}...` : value; + return value.length > 60 ? `${value.slice(0, 59)}…` : value; } } diff --git a/packages/coding-agent/src/utils/frontmatter.ts b/packages/coding-agent/src/utils/frontmatter.ts index 54ee3b23d..8533dc320 100644 --- a/packages/coding-agent/src/utils/frontmatter.ts +++ b/packages/coding-agent/src/utils/frontmatter.ts @@ -10,7 +10,7 @@ function toError(value: unknown): Error { } function truncate(content: string, maxLength: number): string { - return content.length > maxLength ? `${content.slice(0, maxLength)}...` : content; + return content.length > maxLength ? `${content.slice(0, maxLength)}…` : content; } export class FrontmatterError extends Error { diff --git a/packages/coding-agent/src/utils/title-generator.ts b/packages/coding-agent/src/utils/title-generator.ts index 69f7d2316..25da56a46 100644 --- a/packages/coding-agent/src/utils/title-generator.ts +++ b/packages/coding-agent/src/utils/title-generator.ts @@ -84,7 +84,7 @@ export async function generateSessionTitle( // Truncate message if too long const truncatedMessage = - firstMessage.length > MAX_INPUT_CHARS ? `${firstMessage.slice(0, MAX_INPUT_CHARS)}...` : firstMessage; + firstMessage.length > MAX_INPUT_CHARS ? `${firstMessage.slice(0, MAX_INPUT_CHARS)}…` : firstMessage; const userMessage = `\n${truncatedMessage}\n`; for (const model of candidates) { diff --git a/packages/coding-agent/src/utils/tools-manager.ts b/packages/coding-agent/src/utils/tools-manager.ts index 3fb89a9f4..d2e2991b3 100644 --- a/packages/coding-agent/src/utils/tools-manager.ts +++ b/packages/coding-agent/src/utils/tools-manager.ts @@ -306,7 +306,7 @@ export async function ensureTool(tool: ToolName, silentOrOptions?: EnsureToolOpt if (!silent) { logger.debug(`${pythonConfig.name} not found. Installing via uv/pip...`); } - notify?.(`Installing ${pythonConfig.name}...`); + notify?.(`Installing ${pythonConfig.name}…`); const success = await installPythonPackage(pythonConfig.package, signal); if (success) { // Re-check for the command after installation @@ -331,7 +331,7 @@ export async function ensureTool(tool: ToolName, silentOrOptions?: EnsureToolOpt if (!silent) { logger.debug(`${config.name} not found. Downloading...`); } - notify?.(`Downloading ${config.name}...`); + notify?.(`Downloading ${config.name}…`); try { const path = await downloadTool(tool, signal); diff --git a/packages/coding-agent/src/web/scrapers/osv.ts b/packages/coding-agent/src/web/scrapers/osv.ts index 8b3c630d3..2677ad811 100644 --- a/packages/coding-agent/src/web/scrapers/osv.ts +++ b/packages/coding-agent/src/web/scrapers/osv.ts @@ -145,8 +145,11 @@ export const handleOsv: SpecialHandler = async ( if (affected.versions?.length) { const versions = affected.versions.length > 10 - ? `${affected.versions.slice(0, 10).join(", ")}... (${affected.versions.length} total)` + ? `${affected.versions.slice(0, 10).join(", ")}… (${affected.versions.length} total)` : affected.versions.join(", "); + affected.versions.length > 10 + ? `${affected.versions.slice(0, 10).join(", ")}… (${affected.versions.length} total)` + : affected.versions.join(", "); md += `- **Versions:** ${versions}\n`; } diff --git a/packages/coding-agent/src/web/scrapers/youtube.ts b/packages/coding-agent/src/web/scrapers/youtube.ts index 285301516..4511e4431 100644 --- a/packages/coding-agent/src/web/scrapers/youtube.ts +++ b/packages/coding-agent/src/web/scrapers/youtube.ts @@ -287,7 +287,7 @@ export const handleYouTube: SpecialHandler = async ( if (description) { // Truncate long descriptions - const descPreview = description.length > 1000 ? `${description.slice(0, 1000)}...` : description; + const descPreview = description.length > 1000 ? `${description.slice(0, 1000)}…` : description; md += `---\n\n## Description\n\n${descPreview}\n\n`; } diff --git a/packages/coding-agent/src/web/search/index.ts b/packages/coding-agent/src/web/search/index.ts index 828db3d89..a0155fe4f 100644 --- a/packages/coding-agent/src/web/search/index.ts +++ b/packages/coding-agent/src/web/search/index.ts @@ -79,7 +79,7 @@ function formatProviderError(error: unknown, provider: SearchProvider): string { /** Truncate text for tool output */ function truncateText(text: string, maxLen: number): string { if (text.length <= maxLen) return text; - return `${text.slice(0, Math.max(0, maxLen - 3))}...`; + return `${text.slice(0, Math.max(0, maxLen - 1))}…`; } function formatCount(label: string, count: number): string { diff --git a/packages/natives/scripts/build-native.ts b/packages/natives/scripts/build-native.ts index e6d6b9b65..6658eccc4 100644 --- a/packages/natives/scripts/build-native.ts +++ b/packages/natives/scripts/build-native.ts @@ -65,7 +65,7 @@ const cargoArgs = ["build"]; if (!isDev) cargoArgs.push("--release"); if (crossTarget) cargoArgs.push("--target", crossTarget); -console.log(`Building pi-natives for ${targetPlatform}-${targetArch}${isDev ? " (debug)" : ""}...`); +console.log(`Building pi-natives for ${targetPlatform}-${targetArch}${isDev ? " (debug)" : ""}…`); const buildResult = await $`cargo ${cargoArgs}`.cwd(rustDir).nothrow(); if (buildResult.exitCode !== 0) { const stderr = diff --git a/packages/react-edit-benchmark/generate.ts b/packages/react-edit-benchmark/generate.ts index ee1fc97e4..8ee94e305 100644 --- a/packages/react-edit-benchmark/generate.ts +++ b/packages/react-edit-benchmark/generate.ts @@ -110,7 +110,7 @@ async function ensureReactSource(reactDir: string): Promise { throw new Error(`Directory exists but missing packages/: ${reactDir}`); } - console.log(`Cloning React repository to ${reactDir}...`); + console.log(`Cloning React repository to ${reactDir}…`); fs.mkdirSync(dirname(reactDir), { recursive: true }); const result = await $`git clone --depth 1 ${REACT_REPO_URL} ${reactDir}`.quiet().nothrow(); if (result.exitCode !== 0) { diff --git a/packages/tui/src/components/box.ts b/packages/tui/src/components/box.ts index 51f42408d..4ed5dafb2 100644 --- a/packages/tui/src/components/box.ts +++ b/packages/tui/src/components/box.ts @@ -1,5 +1,5 @@ import type { Component } from "../tui"; -import { applyBackgroundToLine, padding, visibleWidth } from "../utils"; +import { applyBackgroundToLine, padding, truncateToWidth, visibleWidth } from "../utils"; type Cache = { key: bigint; @@ -79,7 +79,7 @@ export class Box implements Component { for (const child of this.children) { const lines = child.render(contentWidth); for (const line of lines) { - childLines.push(leftPad + line); + childLines.push(leftPad + truncateToWidth(line, contentWidth)); } } diff --git a/scripts/dump-edit-history.ts b/scripts/dump-edit-history.ts index 509a14a4a..1a9f2421a 100644 --- a/scripts/dump-edit-history.ts +++ b/scripts/dump-edit-history.ts @@ -175,7 +175,7 @@ function formatAttempt(attempt: EditAttempt, index: number, options: Options): s if (options.context && attempt.thinkingContext) { const truncated = attempt.thinkingContext.length > 300 - ? `${attempt.thinkingContext.slice(0, 300)}...` + ? `${attempt.thinkingContext.slice(0, 300)}…` : attempt.thinkingContext; lines.push(`${colorize("Thinking:", "dim")} ${truncated}`); } @@ -187,7 +187,7 @@ function formatAttempt(attempt: EditAttempt, index: number, options: Options): s lines.push(``); const resultPreview = attempt.resultText.slice(0, 200); - const truncatedResult = attempt.resultText.length > 200 ? `${resultPreview}...` : resultPreview; + const truncatedResult = attempt.resultText.length > 200 ? `${resultPreview}…` : resultPreview; lines.push(`${colorize("Result:", "dim")} ${truncatedResult}`); lines.push(colorize("-".repeat(80), "dim")); diff --git a/scripts/release.ts b/scripts/release.ts index f6de7dea6..5a4501e3d 100755 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -208,7 +208,7 @@ async function cmdRelease(version: string): Promise { console.log(` Version ${version} > ${latestTag}\n`); // 2. Update package versions - console.log(`Updating package versions to ${version}...`); + console.log(`Updating package versions to ${version}…`); const pkgJsonPaths = await Array.fromAsync(packageJsonGlob.scan(".")); // Filter out private packages @@ -233,7 +233,7 @@ async function cmdRelease(version: string): Promise { console.log(); // 3. Update Rust workspace version - console.log(`Updating Rust workspace version to ${version}...`); + console.log(`Updating Rust workspace version to ${version}…`); await $`sd '^version = "[^"]+"' ${`version = "${version}"`} Cargo.toml`; // Verify