refactor: resolve merge conflicts — combine main improvements with token normalization

- .gitignore: keep both graphify-out/ entries and main's .gitnexus entry
- ScriptCodeBlock/ScriptPreviewModal: take main's border-border and text-accent-text
  for filename labels; use neutral ghost style for Save button in ScriptCodeBlock;
  use bg-accent (normalized from bg-primary) for Save button in ScriptPreviewModal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-04-06 20:23:36 -04:00
51 changed files with 4039 additions and 2656 deletions

View File

@@ -189,7 +189,7 @@ function ChatItem({
return (
<div
onClick={onSelect}
onClick={confirming ? e => e.stopPropagation() : onSelect}
className={cn(
'group flex items-center gap-2 px-3 py-2.5 mx-1.5 rounded-lg cursor-pointer transition-colors',
confirming

View File

@@ -130,6 +130,14 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
}
}, [handleMouseMove, handleMouseUp])
// Refs so the debounced save always uses the latest questions/actions/tasks
const questionsRef = useRef(questions)
const actionsRef = useRef(actions)
const tasksRef = useRef(tasks)
useEffect(() => { questionsRef.current = questions }, [questions])
useEffect(() => { actionsRef.current = actions }, [actions])
useEffect(() => { tasksRef.current = tasks }, [tasks])
// Save task state to sessionStorage on every change + debounce to backend
const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
useEffect(() => {
@@ -139,9 +147,9 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
if (saveTimerRef.current) clearTimeout(saveTimerRef.current)
saveTimerRef.current = setTimeout(() => {
aiSessionsApi.saveTaskLane(sessionId, {
questions: questions.map(q => ({ text: q.text, context: q.context })),
actions: actions.map(a => ({ label: a.label, command: a.command, description: a.description })),
responses: tasks as unknown as Array<Record<string, unknown>>,
questions: questionsRef.current.map(q => ({ text: q.text, context: q.context })),
actions: actionsRef.current.map(a => ({ label: a.label, command: a.command, description: a.description })),
responses: tasksRef.current as unknown as Array<Record<string, unknown>>,
}).catch(() => { /* silent — best-effort save */ })
}, 2000)
return () => { if (saveTimerRef.current) clearTimeout(saveTimerRef.current) }