mirror of
https://github.com/stablyai/orca.git
synced 2026-10-03 00:02:19 +00:00
Merge fully verified: desktop/mobile focused suites, node and mobile typechecks, changed-code quality, hosted RPC recording pin, package checks, all test shards, and verify pass. This fixes #20389 across composer, drop, picker, and mobile clipboard-accessory paths.
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import {
|
|
imagePasteWritesFollowedByText,
|
|
separateImagePasteFromFollowingText
|
|
} from './image-paste-following-text'
|
|
import { isWindowsAbsolutePathLike } from './cross-platform-path'
|
|
import { filesystemPathToFileUri } from './file-uri-path'
|
|
|
|
// Whether raw-path paste is verified to create an attachment; others use file references.
|
|
export type AgentImageHandling = 'attachment' | 'unsupported'
|
|
|
|
const IMAGE_ATTACHMENT_AGENTS: ReadonlySet<string> = new Set<string>([
|
|
'claude',
|
|
'openclaude',
|
|
'codex',
|
|
'gemini',
|
|
'cursor',
|
|
'copilot',
|
|
'droid',
|
|
// Why: Grok CLI pastes images via bracketed path / image chips (see xAI
|
|
// terminal docs + pager paste.rs). Keep it on the same attachment path as
|
|
// Claude/Codex rather than treating path paste as unsupported text.
|
|
'grok'
|
|
])
|
|
|
|
export function getAgentImageHandling(agent: string | null | undefined): AgentImageHandling {
|
|
return agent && IMAGE_ATTACHMENT_AGENTS.has(agent) ? 'attachment' : 'unsupported'
|
|
}
|
|
|
|
export function formatNativeChatFileReference(filePath: string): string {
|
|
if (!/[\s@]/.test(filePath)) {
|
|
return `@${filePath}`
|
|
}
|
|
if (!filePath.includes('"')) {
|
|
return `@"${filePath}"`
|
|
}
|
|
if (!filePath.includes("'")) {
|
|
return `@'${filePath}'`
|
|
}
|
|
const escaped = filePath.replace(/"/g, '\\"')
|
|
return `@"${escaped}"`
|
|
}
|
|
|
|
export function formatAgentImagePath(agent: string | null | undefined, filePath: string): string {
|
|
if (
|
|
agent === 'omp' &&
|
|
/[\s@]/.test(filePath) &&
|
|
filePath.includes('"') &&
|
|
filePath.includes("'") &&
|
|
(filePath.startsWith('/') || isWindowsAbsolutePathLike(filePath))
|
|
) {
|
|
// OMP's mention lexer cannot escape quotes, but its path resolver decodes file URLs.
|
|
return `@"${filesystemPathToFileUri(filePath)}"`
|
|
}
|
|
return getAgentImageHandling(agent) === 'attachment'
|
|
? filePath
|
|
: formatNativeChatFileReference(filePath)
|
|
}
|
|
|
|
export function agentImagePasteWrites(
|
|
agent: string | null | undefined,
|
|
framedPastes: readonly string[],
|
|
followedByText: boolean
|
|
): string[] {
|
|
if (getAgentImageHandling(agent) === 'attachment') {
|
|
return imagePasteWritesFollowedByText(framedPastes, followedByText)
|
|
}
|
|
// TUI paste frames disappear in the editor; file mentions still need word boundaries.
|
|
return framedPastes.map((paste, index) =>
|
|
separateImagePasteFromFollowingText(paste, index < framedPastes.length - 1 || followedByText)
|
|
)
|
|
}
|