agentreel 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/browser_demo.py +2 -2
- package/scripts/cli_demo.py +23 -4
- package/src/CastVideo.tsx +10 -23
- package/src/types.ts +0 -1
package/package.json
CHANGED
package/scripts/browser_demo.py
CHANGED
|
@@ -54,7 +54,7 @@ def generate_playwright_script(url, task):
|
|
|
54
54
|
[claude, "-p", prompt, "--output-format", "text"],
|
|
55
55
|
capture_output=True,
|
|
56
56
|
text=True,
|
|
57
|
-
timeout=
|
|
57
|
+
timeout=300,
|
|
58
58
|
)
|
|
59
59
|
|
|
60
60
|
text = result.stdout.strip()
|
|
@@ -88,7 +88,7 @@ def extract_highlights(video_path, task):
|
|
|
88
88
|
[claude, "-p", prompt, "--output-format", "text"],
|
|
89
89
|
capture_output=True,
|
|
90
90
|
text=True,
|
|
91
|
-
timeout=
|
|
91
|
+
timeout=300,
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
text = result.stdout.strip()
|
package/scripts/cli_demo.py
CHANGED
|
@@ -4,10 +4,13 @@ CLI demo recorder. Uses `claude` CLI to plan the demo, then records it.
|
|
|
4
4
|
Usage:
|
|
5
5
|
python cli_demo.py <command> <workdir> <output_cast> [context]
|
|
6
6
|
"""
|
|
7
|
+
import getpass
|
|
7
8
|
import json
|
|
8
9
|
import os
|
|
9
10
|
import pty
|
|
11
|
+
import re
|
|
10
12
|
import select
|
|
13
|
+
import socket
|
|
11
14
|
import subprocess
|
|
12
15
|
import sys
|
|
13
16
|
import time
|
|
@@ -97,7 +100,24 @@ def record_demo(steps: list[dict], workdir: str, output_path: str):
|
|
|
97
100
|
}
|
|
98
101
|
f.write(json.dumps(header) + "\n")
|
|
99
102
|
|
|
100
|
-
|
|
103
|
+
# Build patterns to strip user identity from output
|
|
104
|
+
_user = getpass.getuser()
|
|
105
|
+
_host = socket.gethostname().split(".")[0]
|
|
106
|
+
_home = os.path.expanduser("~")
|
|
107
|
+
_title_seq = re.compile(r'\x1b\][\d;]*[^\x07\x1b]*(?:\x07|\x1b\\)')
|
|
108
|
+
_identity = re.compile(
|
|
109
|
+
r'|'.join(re.escape(s) for s in {_user, _host, _home} if s),
|
|
110
|
+
re.IGNORECASE,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def _sanitize(text: str) -> str:
|
|
114
|
+
text = _title_seq.sub('', text)
|
|
115
|
+
text = _identity.sub('user', text)
|
|
116
|
+
return text
|
|
117
|
+
|
|
118
|
+
def write_event(event_type: str, data: str, sanitize: bool = False):
|
|
119
|
+
if sanitize:
|
|
120
|
+
data = _sanitize(data)
|
|
101
121
|
elapsed = time.time() - start_time
|
|
102
122
|
f.write(json.dumps([round(elapsed, 6), event_type, data]) + "\n")
|
|
103
123
|
f.flush()
|
|
@@ -140,7 +160,7 @@ def record_demo(steps: list[dict], workdir: str, output_path: str):
|
|
|
140
160
|
try:
|
|
141
161
|
data = os.read(fd, 4096)
|
|
142
162
|
if data:
|
|
143
|
-
write_event("o", data.decode("utf-8", errors="replace"))
|
|
163
|
+
write_event("o", data.decode("utf-8", errors="replace"), sanitize=True)
|
|
144
164
|
else:
|
|
145
165
|
break
|
|
146
166
|
except OSError:
|
|
@@ -154,7 +174,7 @@ def record_demo(steps: list[dict], workdir: str, output_path: str):
|
|
|
154
174
|
if r:
|
|
155
175
|
data = os.read(fd, 4096)
|
|
156
176
|
if data:
|
|
157
|
-
write_event("o", data.decode("utf-8", errors="replace"))
|
|
177
|
+
write_event("o", data.decode("utf-8", errors="replace"), sanitize=True)
|
|
158
178
|
else:
|
|
159
179
|
break
|
|
160
180
|
else:
|
|
@@ -192,7 +212,6 @@ def extract_highlights(cast_path: str, context: str) -> list[dict]:
|
|
|
192
212
|
|
|
193
213
|
raw_output = "".join(lines_output)
|
|
194
214
|
# Clean ANSI for Claude to read, but keep the raw for display
|
|
195
|
-
import re
|
|
196
215
|
clean = re.sub(r'\x1b\[[0-9;]*[a-zA-Z]', '', raw_output)
|
|
197
216
|
|
|
198
217
|
prompt = f"""You are creating a highlights reel for a CLI tool demo video. Here is the full terminal output:
|
package/src/CastVideo.tsx
CHANGED
|
@@ -121,22 +121,6 @@ export const CastVideo: React.FC<CastProps> = ({
|
|
|
121
121
|
{/* Subtle animated glow blobs in background */}
|
|
122
122
|
<AnimatedBackground frame={frame} duration={durationInFrames} />
|
|
123
123
|
|
|
124
|
-
{/* Global watermark — always visible */}
|
|
125
|
-
<div
|
|
126
|
-
style={{
|
|
127
|
-
position: "absolute",
|
|
128
|
-
top: 16,
|
|
129
|
-
right: 20,
|
|
130
|
-
zIndex: 5,
|
|
131
|
-
fontFamily: MONO,
|
|
132
|
-
fontSize: 11,
|
|
133
|
-
color: "rgba(255,255,255,0.2)",
|
|
134
|
-
letterSpacing: 2,
|
|
135
|
-
}}
|
|
136
|
-
>
|
|
137
|
-
made with agentreel
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
124
|
<MusicTrack />
|
|
141
125
|
|
|
142
126
|
<Sequence durationInFrames={titleFrames}>
|
|
@@ -694,7 +678,9 @@ const HighlightClip: React.FC<{
|
|
|
694
678
|
const lineOpacity = interpolate(lineSpring, [0, 1], [0, 1]);
|
|
695
679
|
const lineX = interpolate(lineSpring, [0, 1], [12, 0]);
|
|
696
680
|
|
|
697
|
-
|
|
681
|
+
// Strip leading "$ " from text — renderer adds its own $ prefix
|
|
682
|
+
const cleanText = line.isPrompt ? line.text.replace(/^\$\s*/, "") : line.text;
|
|
683
|
+
let displayText = cleanText;
|
|
698
684
|
let isTyping = false;
|
|
699
685
|
if (line.isPrompt) {
|
|
700
686
|
const typingEnd = lineFrame + fps * 0.6;
|
|
@@ -705,9 +691,9 @@ const HighlightClip: React.FC<{
|
|
|
705
691
|
[0, 1],
|
|
706
692
|
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
|
707
693
|
);
|
|
708
|
-
const chars = Math.floor(progress *
|
|
709
|
-
displayText =
|
|
710
|
-
isTyping = chars <
|
|
694
|
+
const chars = Math.floor(progress * cleanText.length);
|
|
695
|
+
displayText = cleanText.slice(0, chars);
|
|
696
|
+
isTyping = chars < cleanText.length;
|
|
711
697
|
}
|
|
712
698
|
}
|
|
713
699
|
|
|
@@ -1166,11 +1152,12 @@ const EndCard: React.FC<{ text: string; url?: string }> = ({ text, url }) => {
|
|
|
1166
1152
|
<div
|
|
1167
1153
|
style={{
|
|
1168
1154
|
position: "absolute",
|
|
1169
|
-
|
|
1155
|
+
top: 24,
|
|
1156
|
+
right: 28,
|
|
1170
1157
|
opacity: brandSpring * 0.4,
|
|
1171
|
-
transform: `translateY(${interpolate(brandSpring, [0, 1], [10, 0])}px)`,
|
|
1158
|
+
transform: `translateY(${interpolate(brandSpring, [0, 1], [-10, 0])}px)`,
|
|
1172
1159
|
fontFamily: MONO,
|
|
1173
|
-
fontSize:
|
|
1160
|
+
fontSize: 16,
|
|
1174
1161
|
color: DIM,
|
|
1175
1162
|
letterSpacing: 3,
|
|
1176
1163
|
}}
|