import { FileIcon, Icon, IconButton, Logo, Tooltip } from "@/ui" import { Tabs } from "@/ui/tabs" import FileTree from "@/components/file-tree" import { createSignal, For, Match, onCleanup, onMount, Show, Switch } from "solid-js" import { useLocal, useSDK } from "@/context" import { Code } from "@/components/code" import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, createSortable, closestCenter, useDragDropContext, } from "@thisbeyond/solid-dnd" import type { DragEvent, Transformer } from "@thisbeyond/solid-dnd" import type { LocalFile } from "@/context/local" import SessionList from "@/components/session-list" import SessionTimeline from "@/components/session-timeline" export default function Page() { const sdk = useSDK() const local = useLocal() const [clickTimer, setClickTimer] = createSignal() const [activeItem, setActiveItem] = createSignal(undefined) const [inputValue, setInputValue] = createSignal("") const [isDragging, setIsDragging] = createSignal<"left" | "right" | undefined>(undefined) const [leftScrolled, setLeftScrolled] = createSignal(false) // TODO: remove local.model.set({ providerID: "opencode", modelID: "grok-code" }) let inputRef: HTMLInputElement | undefined = undefined const MOD = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) ? "Meta" : "Control" onMount(() => { document.addEventListener("keydown", handleKeyDown) }) onCleanup(() => { document.removeEventListener("keydown", handleKeyDown) }) const handleKeyDown = (e: KeyboardEvent) => { const inputFocused = document.activeElement === inputRef if (inputFocused) { if (e.key === "Escape") { inputRef?.blur() } return } if (local.file.active()) { if (e.getModifierState(MOD)) { if (e.key.toLowerCase() === "a") { return } if (e.key.toLowerCase() === "c") { return } } } if (e.key.length === 1 && e.key !== "Unidentified") { inputRef?.focus() } } const navigateChange = (dir: 1 | -1) => { const active = local.file.active() if (!active) return const current = local.file.changeIndex(active.path) const next = current == undefined ? (dir === 1 ? 0 : -1) : current + dir local.file.setChangeIndex(active.path, next) } const resetClickTimer = () => { if (!clickTimer()) return clearTimeout(clickTimer()) setClickTimer(undefined) } const startClickTimer = () => { const newClickTimer = setTimeout(() => { setClickTimer(undefined) }, 300) setClickTimer(newClickTimer as unknown as number) } const handleFileClick = async (file: LocalFile) => { if (clickTimer()) { resetClickTimer() local.file.update(file.path, { ...file, pinned: true }) } else { local.file.open(file.path) startClickTimer() } } const handleTabChange = (path: string) => { local.file.open(path) } const handleTabClose = (file: LocalFile) => { local.file.close(file.path) } const onDragStart = (event: any) => { setActiveItem(event.draggable.id as string) } const onDragOver = (event: DragEvent) => { const { draggable, droppable } = event if (draggable && droppable) { const currentFiles = local.file.opened().map((f) => f.path) const fromIndex = currentFiles.indexOf(draggable.id.toString()) const toIndex = currentFiles.indexOf(droppable.id.toString()) if (fromIndex !== toIndex) { local.file.move(draggable.id.toString(), toIndex) } } } const onDragEnd = () => { setActiveItem(undefined) } const handleLeftDragStart = (e: MouseEvent) => { e.preventDefault() setIsDragging("left") const startX = e.clientX const startWidth = local.layout.leftWidth() const handleMouseMove = (e: MouseEvent) => { const deltaX = e.clientX - startX const newWidth = startWidth + deltaX local.layout.setLeftWidth(newWidth) } const handleMouseUp = () => { setIsDragging(undefined) document.removeEventListener("mousemove", handleMouseMove) document.removeEventListener("mouseup", handleMouseUp) } document.addEventListener("mousemove", handleMouseMove) document.addEventListener("mouseup", handleMouseUp) } const handleRightDragStart = (e: MouseEvent) => { e.preventDefault() setIsDragging("right") const startX = e.clientX const startWidth = local.layout.rightWidth() const handleMouseMove = (e: MouseEvent) => { const deltaX = startX - e.clientX const newWidth = startWidth + deltaX local.layout.setRightWidth(newWidth) } const handleMouseUp = () => { setIsDragging(undefined) document.removeEventListener("mousemove", handleMouseMove) document.removeEventListener("mouseup", handleMouseUp) } document.addEventListener("mousemove", handleMouseMove) document.addEventListener("mouseup", handleMouseUp) } const handleSubmit = async (e: SubmitEvent) => { e.preventDefault() const prompt = inputValue() setInputValue("") inputRef?.blur() const session = (local.layout.rightPane() ? local.session.active() : undefined) ?? (await sdk.session.create().then((x) => x.data!)) local.session.setActive(session!.id) local.layout.openRightPane() const response = await sdk.session.prompt({ path: { id: session!.id }, body: { agent: local.agent.current()!.name, model: local.model.current(), parts: [ { type: "text", text: prompt, }, ...local.file .opened() .filter((f) => f.selection || local.file.active()?.path === f.path) .flatMap((f) => [ { type: "file" as const, mime: "text/plain", url: `file://${f.absolute}${f.selection ? `?start=${f.selection.startLine}&end=${f.selection.endLine}` : ""}`, filename: f.name, source: { type: "file" as const, text: { value: "@" + f.name, start: 0, // f.start, end: 0, // f.end, }, path: f.absolute, }, }, ]), ], }, }) console.log("response", response) } return (
Files Changes
setLeftScrolled(e.currentTarget.scrollTop > 0)} >
No changes yet
handleLeftDragStart(e)} >
}> {(activeSession) => (
local.session.clearActive()} class="text-text-muted hover:text-text" >

{activeSession().title || "Untitled Session"}

)}
handleRightDragStart(e)} >
f.path)}> {(file) => }
{(() => { const f = local.file.active()! const view = local.file.view(f.path) return (
navigateChange(-1)}> navigateChange(1)}>
local.file.setView(f.path, "raw")} > local.file.setView(f.path, "diff-unified")} > local.file.setView(f.path, "diff-split")} >
) })()}
local.layout.toggleRightPane()}>
{(file) => ( {(() => { const view = local.file.view(file.path) const showRaw = view === "raw" || !file.content?.diff const code = showRaw ? (file.content?.content ?? "") : (file.content?.diff ?? "") return })()} )}
{activeItem() && (() => { const draggedFile = local.file.node(activeItem()!) return (
) })()}
local.file.close(local.file.active()?.path ?? "")} /> x.selection)}> {(file) => local.file.select(file.path, undefined)} />}
(inputRef = el)} type="text" value={inputValue()} onInput={(e) => setInputValue(e.currentTarget.value)} placeholder="It all starts with a prompt..." class="w-full p-1 pb-4 text-text font-light placeholder-text-muted/70 text-sm focus:outline-none" />
{local.agent.current()?.name ?? "unknown"} /{" "} {local.model.parsed().provider} / {local.model.parsed().model}
) } const TabVisual = (props: { file: LocalFile }) => { const local = useLocal() return (
{props.file.name} M A D
) } const SortableTab = (props: { file: LocalFile onTabClick: (file: LocalFile) => void onTabClose: (file: LocalFile) => void }) => { const sortable = createSortable(props.file.path) return ( // @ts-ignore
props.onTabClick(props.file)}> props.onTabClose(props.file)} >
) } const FileTag = (props: { file: LocalFile; default?: boolean; onClose: () => void }) => (
}>
{props.file.name} ({props.file.selection!.startLine}-{props.file.selection!.endLine})
) const ConstrainDragYAxis = () => { const context = useDragDropContext() if (!context) return <> const [, { onDragStart, onDragEnd, addTransformer, removeTransformer }] = context const transformer: Transformer = { id: "constrain-y-axis", order: 100, callback: (transform) => ({ ...transform, y: 0 }), } onDragStart((event: any) => { addTransformer("draggables", event.draggable.id, transformer) }) onDragEnd((event: any) => { removeTransformer("draggables", event.draggable.id, transformer.id) }) return <> }