mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
The desktop app now keeps the composer stable while turns are active, reduces low-signal tool noise in the transcript, restores project context under the composer after session creation, and relies on the CLI's own permission requests instead of injecting broader desktop-side Bash asks. This also brings in the supporting desktop app source tree and the server routes/session metadata needed for git info, filesystem browsing, session resume, slash commands, and SDK-backed permission bridging so the UI can operate as a coherent feature instead of a partial patch. Constraint: Desktop transcript needs to stay usable during long multi-tool sessions without hiding file-change diffs Constraint: Permission prompts must mirror CLI behavior closely enough that read-only commands do not get desktop-only prompts Rejected: Keep rendering Read/Bash bodies inline | too noisy and unlike the intended transcript model Rejected: Commit only the touched desktop files | would leave the newly introduced desktop app incomplete in git history Confidence: medium Scope-risk: broad Reversibility: messy Directive: Treat non-writing tools as summary-first transcript events; do not re-expand them by default without validating the UX against long sessions Tested: cd desktop && bun run lint Tested: cd desktop && bun run test -- --run Tested: bun test src/server/__tests__/conversations.test.ts Not-tested: Manual visual regression against the exact screenshots in a live desktop session Not-tested: Full root TypeScript check (repository still has unrelated extracted-native parse failures)
26 lines
666 B
TypeScript
26 lines
666 B
TypeScript
export async function copyTextToClipboard(text: string): Promise<boolean> {
|
|
try {
|
|
if (navigator.clipboard?.writeText) {
|
|
await navigator.clipboard.writeText(text)
|
|
return true
|
|
}
|
|
} catch {
|
|
// Fall through to legacy copy path.
|
|
}
|
|
|
|
try {
|
|
const textarea = document.createElement('textarea')
|
|
textarea.value = text
|
|
textarea.setAttribute('readonly', 'true')
|
|
textarea.style.position = 'fixed'
|
|
textarea.style.opacity = '0'
|
|
document.body.appendChild(textarea)
|
|
textarea.select()
|
|
const copied = document.execCommand('copy')
|
|
document.body.removeChild(textarea)
|
|
return copied
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|