From b7d108a85476a38e4ee79adcc8e8d96b724e9c9b Mon Sep 17 00:00:00 2001 From: RosieOh Date: Sun, 27 Sep 2026 03:10:25 +0900 Subject: [PATCH] =?UTF-8?q?FIX:=20=EC=8A=B9=EC=9D=B8=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=20=EC=A0=9C=EB=AA=A9=EC=9D=98=20=ED=8C=8C=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=20=EA=B8=80=EC=9E=90=20=EC=A4=91=EA=B0=84?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A4=84=EB=B0=94=EA=BF=88=EB=90=98?= =?UTF-8?q?=EB=8D=98=20=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 제목 전체에 break-all이 걸려 'OwnerController.jav / a'처럼 꺾였음. 제목을 동작·파일 이름·폴더로 나눠 이름은 한 덩어리로 두고, 폴더는 흐리게 '/' 뒤에서만 줄을 바꿈. Closes #10 --- app/src/chat.ts | 18 +++++++++++++++++- app/src/locales/en.json | 2 ++ app/src/styles.css | 4 +++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/src/chat.ts b/app/src/chat.ts index 2e9df56..e69036c 100644 --- a/app/src/chat.ts +++ b/app/src/chat.ts @@ -328,6 +328,22 @@ function impactRow(diff: string, onTouched: (names: string[]) => void): HTMLElem return row; } +/** + * 승인 카드 제목. 파일 수정은 "파일 수정: 경로"를 이름과 폴더로 나눠, 이름은 한 덩어리로 두고 + * 폴더는 흐리게 `/` 뒤에서만 줄을 바꾼다 (글자 중간에서 "tokenize.r / s"로 꺾이지 않게). + */ +function approvalTitle(title: string, isEdit: boolean): HTMLElement { + const m = isEdit ? title.match(/^(.+?): (.+)$/) : null; + if (!m) return h("span", { class: "atitle" }, title); + const [, label, path] = m; + const dir = dirname(path); + const parts = dir ? dir.split("/").flatMap((p) => [p + "/", h("wbr")]) : []; + return h("span", { class: "atitle", title: path }, + h("span", { class: "alabel" }, label), " ", + h("span", { class: "aname" }, basename(path)), + dir ? h("span", { class: "adir" }, ...parts) : null); +} + /** 되돌리기. 그 뒤로 다른 곳에서 바뀐 파일이 있으면 한 번 더 묻는다. 취소하면 null */ export async function revertSafely(cp: string): Promise { try { @@ -450,7 +466,7 @@ function handle(ev: AgentEvent) { const newPath = isEdit ? ev.detail.match(/^\+\+\+ (?:b\/)?(.+)$/m)?.[1]?.trim() : undefined; if (newPath) task.approvalPaths.set(ev.id, newPath); const el = h("div", { class: "approval", role: "group", "aria-label": ev.title }, - h("div", { class: "ahead" }, codicon(isEdit ? "edit" : "terminal"), h("span", { class: "atitle" }, ev.title), h("span", { class: "verdict" })), + h("div", { class: "ahead" }, codicon(isEdit ? "edit" : "terminal"), approvalTitle(ev.title, isEdit), h("span", { class: "verdict" })), isEdit ? renderDiff(ev.detail) : h("pre", { class: "diff" }, h("div", {}, ev.detail)), target && !replaying ? impactRow(ev.detail, (names) => { task.approvalTouched.set(ev.id, names); diff --git a/app/src/locales/en.json b/app/src/locales/en.json index 8b55817..5c554c1 100644 --- a/app/src/locales/en.json +++ b/app/src/locales/en.json @@ -159,6 +159,8 @@ "새 키를 누르세요 (Esc 취소)": "Press a new key (Esc to cancel)", "새 터미널": "New Terminal", "새 파일": "New File", + "파일 수정": "Edit file", + "파일 덮어쓰기": "Overwrite file", "새 파일…": "New File…", "새 폴더": "New Folder", "새 폴더…": "New Folder…", diff --git a/app/src/styles.css b/app/src/styles.css index 2a52c7b..b09f0d7 100644 --- a/app/src/styles.css +++ b/app/src/styles.css @@ -437,7 +437,9 @@ kbd { font: 11px/1 var(--ui-font); display: inline-block; background: var(--sunk .approval { border: 1px solid var(--warning); border-radius: var(--radius); background: var(--elevated); overflow: hidden; } .approval .ahead { padding: 8px 10px; display: flex; align-items: center; gap: 8px; border-bottom: 1px solid var(--border); font-size: 12px; background: var(--warning-soft); } .approval .ahead .codicon { font-size: 14px; color: var(--warning); } -.approval .atitle { flex: 1; word-break: break-all; font-weight: 600; } +.approval .atitle { flex: 1; min-width: 0; font-weight: 600; overflow-wrap: anywhere; } +/* 파일 이름은 한 덩어리로, 폴더는 흐리게 `/` 뒤에서만 줄바꿈 (이름이 칸보다 길 때만 글자 단위) */ +.approval .adir { margin-left: 6px; font-weight: 400; color: var(--muted); } .approval .actions { display: flex; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--border); align-items: center; } .approval .actions .hint { margin-left: auto; font-size: 11.5px; color: var(--muted); } .approval.resolved { border-color: var(--border); }