- $ npx ccrewind +
⟡ CC REWIND ⟡
+ +$361
+cost
+585M
+tokens
+8.4K
+messages
++ ─── ACTIVITY BY HOUR ───
- {lines >= 1 &&◆ CC REWIND ◆
} - {lines >= 2 &&Reading ~/.claude...
} - {lines >= 3 && ( -- Your character: The Quant -
- )} - {lines >= 4 && ( -- Claude Elo: 847 / 1000 -
- )} - {lines >= 5 &&→ ccrewind.com for the full story
} -
-
- npx ccrewind --setup
-
-
- # registers slash commands
+
+
+
+
+
+
+
+
+
+
+ $ npx ccrewind --setup
-
-
-
-
-
- /ccrewind
+
-
- /ccrewind-ui
+
+
+ # Then use inside any Claude Code session ↓
+
+
+
+ ─── SLASH COMMANDS ───
+
+
+
+
+ ✓ /ccrewind{" "}
+ — TUI report in your terminal
+
+
+ ✓ /ccrewind-ui{" "}
+ — Open web UI in browser
+
+
+ registered to ~/.local/share/ccrewind/
);
@@ -295,9 +359,35 @@ export default function UploadScreen({ onDataParsed }: UploadScreenProps) {
const [showHiddenHelp, setShowHiddenHelp] = useState(false);
const inputRef = useRef(null);
- const [activeTab, setActiveTab] = useState<"npm" | "web" | "claude">("web");
- const [everExpandedNpm, setEverExpandedNpm] = useState(false);
+ const [activeTab, setActiveTab] = useState<"npm" | "web" | "claude">("npm");
const [hasInteracted, setHasInteracted] = useState(false);
+ const [cycleKey, setCycleKey] = useState(0);
+ const [cycleActive, setCycleActive] = useState(true);
+ const TABS = ["npm", "web", "claude"] as const;
+ const CYCLE_MS = 6000;
+
+ useEffect(() => {
+ if (!cycleActive) return;
+ const timer = setInterval(() => {
+ setActiveTab((prev) => {
+ const idx = TABS.indexOf(prev);
+ return TABS[(idx + 1) % TABS.length];
+ });
+ setCycleKey((k) => k + 1);
+ }, CYCLE_MS);
+ return () => clearInterval(timer);
+ }, [cycleKey, cycleActive]);
+
+ useEffect(() => {
+ const stop = () => setCycleActive(false);
+ window.addEventListener("click", stop, { once: true });
+ return () => window.removeEventListener("click", stop);
+ }, []);
+
+ const handleTabClick = (t: "npm" | "web" | "claude") => {
+ setActiveTab(t);
+ setCycleActive(false);
+ };
useEffect(() => {
fetch("/api/local-data/status")
@@ -438,7 +528,7 @@ export default function UploadScreen({ onDataParsed }: UploadScreenProps) {
onClick={handleDemo}
className="w-full bg-surface-container-low hover:bg-surface-container border border-on-surface/8 text-on-surface/60 hover:text-on-surface rounded-xl px-4 py-3 font-label text-[11px] font-bold uppercase tracking-wider transition-all duration-200"
>
- Try demo
+ Try a demo!
@@ -538,7 +628,7 @@ export default function UploadScreen({ onDataParsed }: UploadScreenProps) {
return (
-
+
-
+
{(["npm", "web", "claude"] as const).map((t, idx) => (
))}
-
{activeTab === "npm" && (
@@ -718,22 +810,29 @@ export default function UploadScreen({ onDataParsed }: UploadScreenProps) {
)}
-
-
+
+
-
-
-
-
)}
+ {/* Preview cards — fixed to viewport center, independent of tab height */}
+ {!isLoading && (
+
+
+
+
+
+
+
+ )}
+
{isDragging && (