diff --git a/packages/studio/.gitignore b/packages/studio/.gitignore
new file mode 100644
index 00000000..9012af4f
--- /dev/null
+++ b/packages/studio/.gitignore
@@ -0,0 +1,3 @@
+dist/
+node_modules/
+data/projects/
diff --git a/packages/studio/src/App.tsx b/packages/studio/src/App.tsx
index 9e181b32..b1716382 100644
--- a/packages/studio/src/App.tsx
+++ b/packages/studio/src/App.tsx
@@ -1,7 +1,10 @@
-import { useState, useCallback, useRef, useEffect } from "react";
+import { useState, useCallback, useRef, useEffect, type ReactNode } from "react";
import { NLELayout } from "./components/nle/NLELayout";
import { SourceEditor } from "./components/editor/SourceEditor";
import { FileTree } from "./components/editor/FileTree";
+import { CompositionThumbnail } from "./player/components/CompositionThumbnail";
+import { VideoThumbnail } from "./player/components/VideoThumbnail";
+import type { TimelineElement } from "./player/store/playerStore";
import {
XIcon,
CodeIcon,
@@ -80,6 +83,24 @@ function LintModal({ findings, onClose }: { findings: LintFinding[]; onClose: ()
const errors = findings.filter((f) => f.severity === "error");
const warnings = findings.filter((f) => f.severity === "warning");
const hasIssues = findings.length > 0;
+ const [copied, setCopied] = useState(false);
+
+ const handleCopyToAgent = async () => {
+ const lines = findings.map((f) => {
+ let line = `[${f.severity}] ${f.message}`;
+ if (f.file) line += `\n File: ${f.file}`;
+ if (f.fixHint) line += `\n Fix: ${f.fixHint}`;
+ return line;
+ });
+ const text = `Fix these HyperFrames lint issues:\n\n${lines.join("\n\n")}`;
+ try {
+ await navigator.clipboard.writeText(text);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ } catch {
+ // ignore
+ }
+ };
return (
) : (
-
-
+
+
)}
@@ -119,7 +140,19 @@ function LintModal({ findings, onClose }: { findings: LintFinding[]; onClose: ()
- {/* Findings */}
+ {/* Copy to agent + findings */}
+ {hasIssues && (
+
+
+
+ )}
{!hasIssues && (
@@ -139,8 +172,8 @@ function LintModal({ findings, onClose }: { findings: LintFinding[]; onClose: ()
{f.file &&
{f.file}
}
{f.fixHint && (
-
-
{f.fixHint}
+
+
{f.fixHint}
)}
@@ -156,8 +189,8 @@ function LintModal({ findings, onClose }: { findings: LintFinding[]; onClose: ()
{f.file &&
{f.file}
}
{f.fixHint && (
-
-
{f.fixHint}
+
+
{f.fixHint}
)}
@@ -202,6 +235,67 @@ export function StudioApp() {
const [editingFile, setEditingFile] = useState
(null);
const [sidebarOpen, setSidebarOpen] = useState(false);
const [fileTree, setFileTree] = useState([]);
+ const [compIdToSrc, setCompIdToSrc] = useState
@@ -488,7 +585,7 @@ export function StudioApp() {