Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license

This commit is contained in:
2026-09-05 13:26:46 +03:00
commit 03634b1ca3
11340 changed files with 3442369 additions and 0 deletions
@@ -0,0 +1,164 @@
import { type DragEvent as ReactDragEvent, useRef, useState } from 'react'
import { triggerHaptic } from '@/lib/haptics'
import { extractDroppedFiles, HERMES_PATHS_MIME, partitionDroppedFiles } from '../../hooks/use-composer-actions'
import { dragHasAttachments, droppedFileInlineRefs, type InlineRefInput } from '../inline-refs'
import type { ChatBarProps } from '../types'
interface UseComposerDropArgs {
cwd: ChatBarProps['cwd']
insertInlineRefs: (refs: InlineRefInput[]) => boolean
onAttachDroppedItems: ChatBarProps['onAttachDroppedItems']
requestMainFocus: () => void
}
/**
* Drag-and-drop attachment engine. Splits drops by origin: in-app drags
* (project tree / gutter) stay inline `@file:`/`@line:` refs the gateway
* resolves directly; OS/Finder drops (absolute local paths a remote gateway
* can't read, image bytes vision needs) route through the upload pipeline.
* Off the keystroke path; consumes `insertInlineRefs` + the attach handler.
*/
export function useComposerDrop({
cwd,
insertInlineRefs,
onAttachDroppedItems,
requestMainFocus
}: UseComposerDropArgs) {
const [dragActive, setDragActive] = useState(false)
const dragDepthRef = useRef(0)
const resetDragState = () => {
dragDepthRef.current = 0
setDragActive(false)
}
const handleDragEnter = (event: ReactDragEvent<HTMLFormElement>) => {
if (!onAttachDroppedItems || !dragHasAttachments(event.dataTransfer, HERMES_PATHS_MIME)) {
return
}
event.preventDefault()
dragDepthRef.current += 1
if (!dragActive) {
setDragActive(true)
}
}
const handleDragOver = (event: ReactDragEvent<HTMLFormElement>) => {
if (!onAttachDroppedItems || !dragHasAttachments(event.dataTransfer, HERMES_PATHS_MIME)) {
return
}
event.preventDefault()
event.dataTransfer.dropEffect = 'copy'
}
const handleDragLeave = (event: ReactDragEvent<HTMLFormElement>) => {
if (!onAttachDroppedItems) {
return
}
event.preventDefault()
dragDepthRef.current = Math.max(0, dragDepthRef.current - 1)
if (dragDepthRef.current === 0) {
setDragActive(false)
}
}
const handleDrop = (event: ReactDragEvent<HTMLFormElement>) => {
if (!onAttachDroppedItems) {
return
}
event.preventDefault()
resetDragState()
const candidates = extractDroppedFiles(event.dataTransfer)
if (candidates.length === 0) {
return
}
// In-app drags (project tree / gutter) are workspace-relative paths the
// gateway resolves directly, so they stay inline @file:/@line: refs. OS
// drops are absolute local paths a remote gateway can't read (and images
// need byte upload for vision), so route them through the upload pipeline.
const { inAppRefs, osDrops } = partitionDroppedFiles(candidates)
const refs = droppedFileInlineRefs(inAppRefs, cwd)
if (refs.length && insertInlineRefs(refs)) {
triggerHaptic('selection')
}
if (osDrops.length) {
void Promise.resolve(onAttachDroppedItems(osDrops)).then(attached => {
if (attached) {
triggerHaptic('selection')
requestMainFocus()
}
})
}
}
const handleInputDragOver = (event: ReactDragEvent<HTMLDivElement>) => {
if (!dragHasAttachments(event.dataTransfer, HERMES_PATHS_MIME)) {
return
}
event.preventDefault()
event.stopPropagation()
event.dataTransfer.dropEffect = 'copy'
}
const handleInputDrop = (event: ReactDragEvent<HTMLDivElement>) => {
if (!dragHasAttachments(event.dataTransfer, HERMES_PATHS_MIME)) {
return
}
const candidates = extractDroppedFiles(event.dataTransfer)
if (!candidates.length) {
return
}
event.preventDefault()
event.stopPropagation()
resetDragState()
// Dropping straight onto the text box used to inline-ref *every* file —
// including OS/Finder drops, whose absolute local path a remote gateway
// can't read and whose image bytes never reached vision. Split by origin:
// in-app drags stay inline refs; OS drops go through the upload pipeline.
// (When no upload handler is wired, fall back to inline refs for all.)
const attach = onAttachDroppedItems
const { inAppRefs, osDrops } = partitionDroppedFiles(candidates)
const refs = droppedFileInlineRefs(attach ? inAppRefs : candidates, cwd)
if (refs.length && insertInlineRefs(refs)) {
triggerHaptic('selection')
}
if (attach && osDrops.length) {
void Promise.resolve(attach(osDrops)).then(attached => {
if (attached) {
triggerHaptic('selection')
requestMainFocus()
}
})
}
}
return {
dragActive,
handleDragEnter,
handleDragLeave,
handleDragOver,
handleDrop,
handleInputDragOver,
handleInputDrop
}
}