feat(presentation): add PresenterNotesPage component and update metadata for prompts.chat talk
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 177 KiB |
@@ -0,0 +1,141 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { ChevronLeft, ChevronRight, RadioTower, WifiOff } from "lucide-react";
|
||||
|
||||
type DeckState = {
|
||||
currentSlide: number;
|
||||
totalSlides: number;
|
||||
notes: string[];
|
||||
};
|
||||
|
||||
export default function PresenterNotesPage() {
|
||||
const channelRef = useRef<BroadcastChannel | null>(null);
|
||||
const [state, setState] = useState<DeckState | null>(null);
|
||||
const [connected, setConnected] = useState(false);
|
||||
|
||||
const send = useCallback((message: Record<string, unknown>) => {
|
||||
channelRef.current?.postMessage(message);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined" || typeof BroadcastChannel === "undefined") return;
|
||||
|
||||
const channel = new BroadcastChannel("prompts-presentation");
|
||||
channelRef.current = channel;
|
||||
|
||||
channel.onmessage = (event) => {
|
||||
const data = event.data;
|
||||
if (data?.type === "state") {
|
||||
setConnected(true);
|
||||
setState({
|
||||
currentSlide: data.currentSlide ?? 0,
|
||||
totalSlides: data.totalSlides ?? 0,
|
||||
notes: Array.isArray(data.notes) ? data.notes : [],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
channel.postMessage({ type: "request" });
|
||||
const retry = setInterval(() => {
|
||||
if (!channelRef.current) return;
|
||||
channelRef.current.postMessage({ type: "request" });
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(retry);
|
||||
channel.close();
|
||||
channelRef.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === "ArrowRight" || event.key === " " || event.key === "PageDown") {
|
||||
event.preventDefault();
|
||||
send({ type: "next" });
|
||||
} else if (event.key === "ArrowLeft" || event.key === "PageUp") {
|
||||
event.preventDefault();
|
||||
send({ type: "prev" });
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [send]);
|
||||
|
||||
const current = state?.currentSlide ?? 0;
|
||||
const total = state?.totalSlides ?? 0;
|
||||
const notes = state?.notes ?? [];
|
||||
const currentNote = notes[current];
|
||||
const nextNote = notes[current + 1];
|
||||
const atStart = current <= 0;
|
||||
const atEnd = total > 0 && current >= total - 1;
|
||||
|
||||
return (
|
||||
<div className="flex h-[100dvh] w-screen flex-col bg-zinc-950 text-zinc-100">
|
||||
<header className="flex items-center justify-between border-b border-white/10 px-6 py-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm font-bold uppercase tracking-[0.28em] text-primary">Presenter notes</span>
|
||||
<span
|
||||
className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-semibold ${
|
||||
connected ? "bg-emerald-500/15 text-emerald-300" : "bg-amber-500/15 text-amber-300"
|
||||
}`}
|
||||
>
|
||||
{connected ? <RadioTower className="h-3.5 w-3.5" /> : <WifiOff className="h-3.5 w-3.5" />}
|
||||
{connected ? "Synced" : "Waiting for deck…"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="rounded-full border border-white/15 px-4 py-1.5 text-sm font-semibold text-zinc-300">
|
||||
{total > 0 ? `Slide ${current + 1} / ${total}` : "—"}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex flex-1 flex-col gap-6 overflow-hidden p-6 sm:p-8">
|
||||
<section className="flex min-h-0 flex-1 flex-col rounded-3xl border border-white/10 bg-white/[0.03] p-6 sm:p-8">
|
||||
<div className="mb-4 text-xs font-bold uppercase tracking-[0.24em] text-primary">Now</div>
|
||||
<div className="min-h-0 flex-1 overflow-y-auto pr-2">
|
||||
{connected ? (
|
||||
<p className="text-2xl font-medium leading-relaxed text-zinc-100 sm:text-3xl">
|
||||
{currentNote || "No note for this slide."}
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-xl text-zinc-400">
|
||||
Open the presentation in another window and this view will sync automatically.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="rounded-3xl border border-white/10 bg-white/[0.02] p-5 sm:p-6">
|
||||
<div className="mb-2 text-xs font-bold uppercase tracking-[0.24em] text-zinc-500">Next</div>
|
||||
<p className="line-clamp-3 text-base leading-relaxed text-zinc-400 sm:text-lg">
|
||||
{atEnd ? "End of deck." : nextNote || "—"}
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer className="flex items-center justify-center gap-5 border-t border-white/10 px-6 py-5">
|
||||
<button
|
||||
onClick={() => send({ type: "prev" })}
|
||||
disabled={atStart}
|
||||
className="inline-flex h-12 w-12 items-center justify-center rounded-full border border-white/15 bg-white/5 text-zinc-200 transition hover:bg-white/10 disabled:cursor-not-allowed disabled:opacity-30"
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<ChevronLeft className="h-6 w-6" />
|
||||
</button>
|
||||
<span className="min-w-[5rem] text-center text-sm font-medium text-zinc-400">
|
||||
{total > 0 ? `${current + 1} / ${total}` : "—"}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => send({ type: "next" })}
|
||||
disabled={atEnd}
|
||||
className="inline-flex h-12 w-12 items-center justify-center rounded-full border border-white/15 bg-white/5 text-zinc-200 transition hover:bg-white/10 disabled:cursor-not-allowed disabled:opacity-30"
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<ChevronRight className="h-6 w-6" />
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+237
-347
@@ -1,29 +1,24 @@
|
||||
import {
|
||||
Blocks,
|
||||
ArrowRight,
|
||||
Bot,
|
||||
BrainCircuit,
|
||||
CheckCircle2,
|
||||
CircleDotDashed,
|
||||
ClipboardCheck,
|
||||
Clock3,
|
||||
DatabaseZap,
|
||||
FileText,
|
||||
Filter,
|
||||
BookOpen,
|
||||
Boxes,
|
||||
Code2,
|
||||
GitBranch,
|
||||
Gamepad2,
|
||||
Globe,
|
||||
Layers3,
|
||||
Lightbulb,
|
||||
Lock,
|
||||
MessageSquareText,
|
||||
Network,
|
||||
PackageCheck,
|
||||
Puzzle,
|
||||
RefreshCw,
|
||||
Route,
|
||||
Scissors,
|
||||
Rocket,
|
||||
Search,
|
||||
Share2,
|
||||
ShieldCheck,
|
||||
Sparkles,
|
||||
Target,
|
||||
TimerReset,
|
||||
WandSparkles,
|
||||
Star,
|
||||
Workflow,
|
||||
} from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
@@ -31,31 +26,24 @@ import type { ReactNode } from "react";
|
||||
import { SlideContent, SlideDeck, SlideHighlight, SlideTitle } from "@/components/presentation/SlideDeck";
|
||||
|
||||
export const metadata = {
|
||||
title: "Prompt Tasarımı ve Context Yönetimi | Presentation",
|
||||
description: "30 dakikalık Türkçe konuşma: prompt tasarımı, context yönetimi ve prompts.chat.",
|
||||
title: "prompts.chat: An Open Prompt Ecosystem for the Age of Agents | Microsoft Build",
|
||||
description:
|
||||
"15-minute lightning talk at Microsoft Build: how prompts.chat grew from a GitHub repo into an open prompt ecosystem — platform, book, and game — for the age of agents.",
|
||||
};
|
||||
|
||||
const speakerNotes = [
|
||||
"Açılışta sunumun amacını netleştir: Bu konuşma prompt ezberlemek değil, bağlamı bilinçli yönetmek üzerine. 30 dakika sonunda herkesin kendi işine uygulayabileceği bir kontrol listesi olacak.",
|
||||
"Konuşmacı slaytı kısa tutulmalı. Kişisel hikaye: Awesome ChatGPT Prompts ile başlayan topluluk deneyimi, prompts.chat ile promptların paylaşılabilir, sürümlenebilir ve geliştirilebilir varlıklara dönüşmesi.",
|
||||
"Akışı anlat: önce zihinsel model, sonra promptun anatomisi, sonra context yönetimi ve ölçüm. prompts.chat bölümünü ürün demosu gibi değil, bu prensiplerin pratik karşılığı olarak konumlandır.",
|
||||
"Ana mesaj: Modeli sadece cevap makinesi gibi değil, sınırlı dikkat alanına sahip bir ekip arkadaşı gibi düşünün. Prompt tasarımı görevi tanımlar; context yönetimi modelin neye bakacağını seçer.",
|
||||
"Prompt tasarımının yalnızca güzel cümle yazmak olmadığını vurgula. Rol, hedef, veri, sınır, örnek ve çıktı sözleşmesi bir araya geldiğinde modelin çalışma alanı oluşur.",
|
||||
"Bu slaytta kötü prompt / iyi prompt farkını canlı okuyarak göster. İyi örneğin daha uzun olduğu için değil, karar yükünü azalttığı için iyi olduğunu söyle.",
|
||||
"Context penceresini dosya dolabı değil, toplantı masası metaforu ile anlat. Masaya her şeyi koymak odak kaybettirir; doğru şeyleri doğru sırayla koymak performansı artırır.",
|
||||
"Bağlam katmanlarını sırayla açıkla. Sistem ve geliştirici talimatlarının politikayı, kullanıcı mesajının amacı, araç sonuçlarının kanıtı, geçmişin ise sürekliliği taşıdığını anlat.",
|
||||
"Önemli ayrım: Context çokluğu kalite demek değildir. Gürültü, eski kararlar ve çelişkili talimatlar modeli kararsızlaştırır. Context tasarrufu aynı zamanda kalite kontrolüdür.",
|
||||
"Kısa bir teknik çerçeve ver: seç, sırala, sıkıştır, doğrula. Bu dört fiil context yönetiminin günlük pratiği olabilir.",
|
||||
"Örnekler model davranışını güçlü biçimde kilitler. Ancak yanlış örnekler de yanlış davranışı kilitler. Örnekleri az ama temsil gücü yüksek seçmek gerektiğini vurgula.",
|
||||
"Çıktı sözleşmesi özellikle ekiplerde önemlidir. JSON, tablo, diff, adım adım plan gibi formatlar otomasyon ve tekrar üretilebilirlik sağlar.",
|
||||
"Araç kullanan ajanlarda prompt, sadece cevap formatını değil yetki sınırını da belirler. Ne zaman arama yapmalı, ne zaman sormalı, ne zaman durmalı gibi kararları açık yazın.",
|
||||
"Context yönetiminin operasyonel tarafı: uzun konuşmalarda özet, dosya tabanlı işlerde ilgili parçalar, arama tabanlı işlerde kaynak ve alıntı. Her şeyi tek mesaja doldurmak yerine akış tasarla.",
|
||||
"Hata modlarını örneklerle anlat: belirsiz hedef, eski bağlam, çelişki, görünmez varsayım, format eksikliği. Bunlar model hatası gibi görünür ama çoğu zaman tasarım hatasıdır.",
|
||||
"Ölçüm slaytında küçük bir test setinin değerini anlat. Aynı promptu birkaç gerçek senaryo ile denemek, tek seferlik iyi cevaptan daha güvenilirdir.",
|
||||
"prompts.chat'i bağlamla ilişkilendir: iyi promptlar tek kişide kalmamalı. Paylaşım, sürümleme ve geri bildirim prompt kalitesini artırır.",
|
||||
"Ekip pratiğine geç: promptlar kod gibi yaşamalı. Sahiplik, değişiklik geçmişi, review ve örnek çıktılar promptun güvenilirliğini artırır.",
|
||||
"Kapanış kontrol listesini yavaş oku. Dinleyicilerin kendi promptlarını bu beş soruyla gözden geçirmesini iste.",
|
||||
"Son slaytta tek cümlelik kapanış: İyi prompt, modele ne yapacağını söyler; iyi context yönetimi, neye dayanarak yapacağını belirler.",
|
||||
"Okay, hi everyone. So I want to start with a mistake that, honestly, a lot of people make. They think that when AI models get smarter, prompts will not matter anymore — like, prompting is just a temporary trick and the next model will make it useless. But actually, for me, it's the opposite. Even the best models give you better answers when you give them better prompts. And in the age of agents, prompts are kind of like atoms — every agent is basically made of them. So no, prompts are not going away. They actually matter more than before. So in the next fifteen minutes, I want to show you why, and the open ecosystem I'm building around them: prompts.chat.",
|
||||
"But first, a quick hello. I'm Fatih. I'm a developer advocate on the WordPress team at Automattic. I also created the Awesome ChatGPT Prompts project, and I'm a GitHub Star. Okay, that's enough about me — let's actually talk about prompts.",
|
||||
"So, this whole thing actually started as a tiny GitHub repo. Just a simple list of prompts you could copy and paste. And one detail people are always surprised by — this is not new at all. I created it almost four years ago, literally about one week after OpenAI announced ChatGPT. The book came later. Honestly, back then I didn't expect much. But it kind of exploded — it became one of the most starred AI projects on GitHub, used by tens of millions of people. And that told me something: a good prompt is actually worth sharing.",
|
||||
"But here's the problem, right? Most prompts just get lost. They're hidden in screenshots, random gists, old chat history. No version, no owner, no review. That great prompt you wrote last week? It's probably gone the second you closed the tab. And okay, that's annoying for us as people — but honestly, it completely falls apart once agents are involved.",
|
||||
"So why does it fall apart for agents? Well, when an agent acts for you, the prompt is not just a casual message anymore. It's actually the plan. It's the contract. It's basically the source code for how that agent behaves. Look at this one — a role, a goal, the sources it can use, the limits, and when to stop. You really want to save and improve something like this, right? Not lose it somewhere in a chat.",
|
||||
"So this is exactly what prompts.chat does. It treats prompts as real, shareable things. You can discover good ones, fork them, keep versions, reuse them. And it's open source, so you can even host it yourself — your team actually owns its own prompt library.",
|
||||
"Now, why does being open matter so much, especially for agents? I'd say three reasons. First, you can actually read what the agent was told to do. Second, the same prompt works across different models and tools. And third, open prompts plug right into agents, editors, an MCP layer. So basically, a world full of agents needs an open world of prompts.",
|
||||
"Okay, now two things people don't really expect. The first one is a book. It's called The Interactive Book of Prompting. It's free, and it's not some boring PDF — it's actually interactive, with live demos you can try right there on the page, from the basics all the way to agents.",
|
||||
"And the second one is a game. So, this is Promi — a little robot — on an adventure through Prompt Land. It's a fun way for kids to learn how to talk to AI. Because, honestly, this skill shouldn't only be for engineers, right? It kind of belongs to everyone, including the next generation.",
|
||||
"So if you put it all together, you actually get one open loop. The repo where it all began, the platform to discover and reuse, the book to learn, the game to bring in new people, and an API and MCP layer that feeds everything back to both humans and agents. So good prompts come in, the community makes them better, and they go back out.",
|
||||
"Okay, so here's the big picture. As agents start doing real work, the prompt is how we steer them — it's becoming the interface to these systems. Now, around those prompts you need some tooling — a way to manage them, version them, test them, serve them. And a lot of people now call this the \"harness\". So, just to be clear, the harness is not the prompt itself — it's actually the tooling that keeps your prompts accurate and well-tuned. And honestly, the same model can give you very different results depending on how good that harness is. So let's keep this whole thing open, shared, and easy to improve — together.",
|
||||
"And that's pretty much it. So, come build this open prompt ecosystem with us. Check out prompts.chat, read the book, play the game with your kids, and take a look at the project on GitHub. Thank you so much — and I think we have a moment for maybe one question.",
|
||||
];
|
||||
|
||||
type CardProps = {
|
||||
@@ -113,45 +101,39 @@ function FlowStep({ icon: Icon, title, text }: { icon: LucideIcon; title: string
|
||||
);
|
||||
}
|
||||
|
||||
function ContextLayer({ label, description, tone }: { label: string; description: string; tone: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
|
||||
<div className={`h-14 w-2 rounded-full ${tone}`} />
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{label}</h3>
|
||||
<p className="text-base text-muted-foreground">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MiniChecklist({ items }: { items: string[] }) {
|
||||
return (
|
||||
<div className="grid gap-3">
|
||||
{items.map((item) => (
|
||||
<div key={item} className="flex items-start gap-3 rounded-2xl border border-border/70 bg-background/70 p-4 text-xl font-semibold">
|
||||
<CheckCircle2 className="mt-1 h-6 w-6 flex-none text-primary" />
|
||||
<span>{item}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PresentationPage() {
|
||||
return (
|
||||
<SlideDeck notes={speakerNotes}>
|
||||
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
|
||||
<div className="mb-8 flex h-24 w-24 rotate-6 items-center justify-center rounded-[2rem] bg-primary/10 text-primary shadow-xl shadow-primary/10">
|
||||
<WandSparkles className="h-12 w-12" />
|
||||
<div className="mb-8 flex items-center justify-center">
|
||||
<Image
|
||||
src="/logo.svg"
|
||||
alt="prompts.chat logo"
|
||||
width={160}
|
||||
height={160}
|
||||
unoptimized
|
||||
className="h-40 w-40 object-contain dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src="/logo-dark.svg"
|
||||
alt="prompts.chat logo"
|
||||
width={160}
|
||||
height={160}
|
||||
unoptimized
|
||||
className="hidden h-40 w-40 object-contain dark:block"
|
||||
/>
|
||||
</div>
|
||||
<SlideTitle className="max-w-5xl">Prompt Tasarımı ve Context Yönetimi</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-3xl">
|
||||
30 dakikalık pratik bir çerçeve: daha iyi talimat, daha temiz bağlam, daha güvenilir AI çıktısı.
|
||||
<SlideTitle className="max-w-5xl">prompts.chat</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-4xl">
|
||||
Building an <SlideHighlight>Open Prompt Ecosystem</SlideHighlight> for the Age of Agents
|
||||
</SlideContent>
|
||||
<p className="mx-auto mt-6 max-w-3xl text-lg font-medium text-muted-foreground/80 md:text-xl">
|
||||
Smarter models don't make prompts obsolete — prompts are the{" "}
|
||||
<SlideHighlight>atoms of every agent</SlideHighlight>.
|
||||
</p>
|
||||
<div className="mt-10 flex flex-wrap justify-center gap-3">
|
||||
<Pill>prompts.chat/presentation</Pill>
|
||||
<Pill>Ok tuşları, boşluk, F, N</Pill>
|
||||
<Pill>Microsoft Build</Pill>
|
||||
<Pill>15-min lightning talk</Pill>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -163,7 +145,7 @@ export default function PresentationPage() {
|
||||
<div className="relative overflow-hidden rounded-[3rem] border border-border bg-background shadow-2xl">
|
||||
<Image
|
||||
src="https://github.com/f.png"
|
||||
alt="Fatih Kadir Akın profil fotoğrafı"
|
||||
alt="Fatih Kadir Akın profile photo"
|
||||
width={900}
|
||||
height={900}
|
||||
priority
|
||||
@@ -171,33 +153,23 @@ export default function PresentationPage() {
|
||||
className="aspect-square w-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 via-black/45 to-transparent p-8 text-white">
|
||||
<p className="text-sm font-bold uppercase tracking-[0.35em] text-white/70">Konuşmacı</p>
|
||||
<h2 className="mt-2 text-5xl font-black tracking-tight">Fatih Kadir Akın</h2>
|
||||
<p className="mt-3 max-w-md text-lg font-semibold leading-snug text-white/85">
|
||||
WordPress Developer Advocate, Automattic - Creator of prompts.chat
|
||||
Developer Advocate, WordPress @ Automattic
|
||||
<br /> Creator of prompts.chat
|
||||
<br /> GitHub Star
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order-1 lg:order-2">
|
||||
<SlideTitle className="mb-5">Merhaba, ben Fatih.</SlideTitle>
|
||||
<SlideTitle className="mb-5">Hi, I'm Fatih.</SlideTitle>
|
||||
<SlideContent className="max-w-2xl">
|
||||
Geliştiricilerin hayatını kolaylaştıran uygulamalar geliştiriyorum; bunlardan biri de{" "}
|
||||
I build tools that make developers' lives easier — one of them is{" "}
|
||||
<SlideHighlight>prompts.chat</SlideHighlight>.
|
||||
</SlideContent>
|
||||
<div className="mt-10 flex flex-wrap items-center gap-5">
|
||||
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
|
||||
<Image
|
||||
src="https://cdn.simpleicons.org/wordpress/21759B"
|
||||
alt="WordPress"
|
||||
width={40}
|
||||
height={40}
|
||||
unoptimized
|
||||
className="h-10 w-10"
|
||||
/>
|
||||
<span className="text-xl font-bold text-foreground">WordPress</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
|
||||
<Image
|
||||
src="https://cdn.simpleicons.org/automattic/000000"
|
||||
@@ -209,319 +181,237 @@ export default function PresentationPage() {
|
||||
/>
|
||||
<span className="text-xl font-bold text-foreground">Automattic</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
|
||||
<Star className="h-9 w-9 text-yellow-500" />
|
||||
<span className="text-xl font-bold text-foreground">GitHub Star</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Bugünkü rota</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
<FlowStep icon={BrainCircuit} title="Zihinsel model" text="Modelin neyi, ne sırayla ve hangi amaçla görmesi gerektiğini düşünmek." />
|
||||
<FlowStep icon={MessageSquareText} title="Prompt anatomisi" text="Rol, hedef, bağlam, kısıtlar, örnekler ve çıktı sözleşmesi." />
|
||||
<FlowStep icon={Layers3} title="Context yönetimi" text="Sınırlı dikkat alanını seçmek, sıralamak, sıkıştırmak ve temizlemek." />
|
||||
<FlowStep icon={ClipboardCheck} title="Ölçüm ve paylaşım" text="Promptu tek seferlik cümle değil, iyileştirilebilir artefact yapmak." />
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>It started as a GitHub repo</SlideTitle>
|
||||
<SlideContent>
|
||||
<SlideHighlight>Awesome ChatGPT Prompts</SlideHighlight> — a simple list of copy-paste prompts that grew
|
||||
into one of the most-starred AI repositories in the world.
|
||||
</SlideContent>
|
||||
<p className="mt-6 max-w-2xl text-lg font-medium text-muted-foreground/80 md:text-xl">
|
||||
And it's not new — the repo (and later the book) are almost{" "}
|
||||
<SlideHighlight>four years old</SlideHighlight>, born just a week after OpenAI announced ChatGPT.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
<Card icon={Star} title="Hundreds of thousands of stars" accent="text-yellow-500">
|
||||
One of GitHub's most popular AI projects.
|
||||
</Card>
|
||||
<Card icon={Globe} title="Tens of millions of developers">
|
||||
People copied these prompts into every AI tool imaginable.
|
||||
</Card>
|
||||
<Card icon={MessageSquareText} title="A new kind of artifact">
|
||||
The prompt itself became something worth sharing.
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>AI ile çalışmak: çok zeki ama bağlama bağımlı bir ekip arkadaşı</SlideTitle>
|
||||
<SlideTitle>But prompts get lost</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={Target} title="Amaç net olmalı">
|
||||
Modelin optimizasyon hedefi belirsizse cevap da belirsizleşir.
|
||||
<Card icon={Share2} title="Scattered" accent="text-orange-500">
|
||||
Trapped in screenshots, gists, and DMs.
|
||||
</Card>
|
||||
<Card icon={ShieldCheck} title="Sınırlar görünür olmalı">
|
||||
Ne yapılmayacağı, ne yapılacağı kadar önemlidir.
|
||||
<Card icon={GitBranch} title="Unversioned" accent="text-sky-500">
|
||||
No history, no review, no ownership.
|
||||
</Card>
|
||||
<Card icon={DatabaseZap} title="Kanıt seçilmeli">
|
||||
Model en son ve en belirgin bağlama fazla ağırlık verir.
|
||||
<Card icon={Lock} title="Locked in chats" accent="text-red-500">
|
||||
The good ones disappear when the tab closes.
|
||||
</Card>
|
||||
</div>
|
||||
<SlideContent className="mt-10 max-w-4xl">
|
||||
İyi prompt <SlideHighlight>ne yapılacağını</SlideHighlight>, iyi context yönetimi ise{" "}
|
||||
<SlideHighlight>neye dayanarak yapılacağını</SlideHighlight> belirler.
|
||||
Annoying for humans — and <SlideHighlight>broken for agents</SlideHighlight>.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Prompt tasarımı cümle süslemek değildir</SlideTitle>
|
||||
<SlideTitle>In the age of agents, a prompt is a spec</SlideTitle>
|
||||
<SlideContent>
|
||||
Prompt, modelle aranızdaki <SlideHighlight>çalışma sözleşmesidir</SlideHighlight>.
|
||||
Cevabın amacı, kapsamı, kaynakları, formatı ve kalite barı bu sözleşmede yer alır.
|
||||
When an agent acts on your behalf, the prompt stops being a casual message. It becomes the{" "}
|
||||
<SlideHighlight>contract</SlideHighlight> — the source code of behavior.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
{[
|
||||
["Rol", "Hangi perspektiften düşünecek?"],
|
||||
["Görev", "Tam olarak neyi üretecek?"],
|
||||
["Bağlam", "Hangi bilgiye dayanacak?"],
|
||||
["Kısıt", "Neyi yapmayacak veya aşmayacak?"],
|
||||
["Çıktı", "Nasıl teslim edecek?"],
|
||||
].map(([label, text]) => (
|
||||
<div key={label} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 font-black text-primary">{label[0]}</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{label}</h3>
|
||||
<p className="text-muted-foreground">{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Kötü prompt / iyi prompt</SlideTitle>
|
||||
<SlideContent>
|
||||
Uzun olan değil, <SlideHighlight>karar yükünü azaltan</SlideHighlight> prompt daha iyidir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="space-y-5">
|
||||
<CodePanel title="belirsiz.prompt">
|
||||
{`Bana context management hakkında iyi bir yazı yaz.`}
|
||||
</CodePanel>
|
||||
<CodePanel title="tasarlanmis.prompt">
|
||||
{`Rol: Kıdemli AI ürün danışmanı.
|
||||
Amaç: Teknik olmayan ürün ekibine context management anlat.
|
||||
Bağlam: 30 dakikalık şirket içi eğitim.
|
||||
Kısıt: Jargon kullanma, 3 örnek ver, riskleri belirt.
|
||||
Çıktı: Başlık, 5 maddelik özet, uygulanabilir kontrol listesi.`}
|
||||
</CodePanel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Context penceresi dosya dolabı değil, toplantı masasıdır</SlideTitle>
|
||||
<SlideContent className="max-w-5xl">
|
||||
Masaya her şeyi koyarsanız ekip odaklanamaz. Doğru belgeleri, doğru sırayla, doğru ayrıntı seviyesinde getirirsiniz.
|
||||
</SlideContent>
|
||||
<div className="mt-10 grid gap-5 md:grid-cols-4">
|
||||
<FlowStep icon={Filter} title="Seç" text="İlgili olanı ayır." />
|
||||
<FlowStep icon={Route} title="Sırala" text="Önceliği görünür yap." />
|
||||
<FlowStep icon={Scissors} title="Sıkıştır" text="Gürültüyü azalt." />
|
||||
<FlowStep icon={CheckCircle2} title="Doğrula" text="Kaynak ve sonucu kontrol et." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.9fr_1.1fr]">
|
||||
<div>
|
||||
<SlideTitle>Bağlam katmanları</SlideTitle>
|
||||
<SlideContent>
|
||||
Model tek bir metni değil, üst üste binmiş talimat ve kanıt katmanlarını yorumlar.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-3">
|
||||
<ContextLayer label="Sistem" description="Kimlik, güvenlik ve en üst kurallar." tone="bg-red-500" />
|
||||
<ContextLayer label="Geliştirici" description="Uygulama davranışı, araç kullanımı, format kuralları." tone="bg-orange-500" />
|
||||
<ContextLayer label="Kullanıcı" description="Anlık amaç, ihtiyaç ve başarı tanımı." tone="bg-primary" />
|
||||
<ContextLayer label="Araç sonuçları" description="Arama, dosya, API veya veritabanından gelen kanıt." tone="bg-emerald-500" />
|
||||
<ContextLayer label="Geçmiş" description="Konuşma sürekliliği ve önceki kararlar." tone="bg-sky-500" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Daha fazla context her zaman daha iyi değildir</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={CircleDotDashed} title="Gürültü" accent="text-orange-500">
|
||||
Alakasız detaylar, önemli sinyali gömer.
|
||||
</Card>
|
||||
<Card icon={RefreshCw} title="Eski kararlar" accent="text-sky-500">
|
||||
Geçmişte doğru olan bilgi bugün yanlış olabilir.
|
||||
</Card>
|
||||
<Card icon={Puzzle} title="Çelişkiler" accent="text-red-500">
|
||||
Model hangi talimata uyacağını tahmin etmek zorunda kalır.
|
||||
</Card>
|
||||
</div>
|
||||
<SlideContent className="mt-10">
|
||||
Context yönetimi, token tasarrufu değil; <SlideHighlight>dikkat yönetimidir</SlideHighlight>.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Pratik yöntem: seç, sırala, sıkıştır, doğrula</SlideTitle>
|
||||
<div className="grid gap-5 lg:grid-cols-4">
|
||||
<FlowStep icon={Filter} title="Seç" text="Bu görev için gerçekten gerekli bilgi ne?" />
|
||||
<FlowStep icon={Layers3} title="Sırala" text="En önemli talimat ve kanıt en görünür yerde mi?" />
|
||||
<FlowStep icon={Scissors} title="Sıkıştır" text="Tekrar, sohbet gürültüsü ve eski kararlar temizlendi mi?" />
|
||||
<FlowStep icon={ClipboardCheck} title="Doğrula" text="Cevap kaynak, format ve başarı kriteriyle uyuşuyor mu?" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Örnekler davranışı kilitler</SlideTitle>
|
||||
<SlideContent>
|
||||
Few-shot örnekler modele sadece formatı değil, <SlideHighlight>neyi iyi saydığınızı</SlideHighlight> gösterir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
|
||||
<div className="mb-6 flex items-center gap-3">
|
||||
<Lightbulb className="h-7 w-7 text-yellow-500" />
|
||||
<h3 className="text-2xl font-bold">Örnek seçerken</h3>
|
||||
</div>
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"Gerçek kullanım senaryosuna benziyor mu?",
|
||||
"Başarılı ve başarısız örnek ayrımı var mı?",
|
||||
"Format, ton ve ayrıntı seviyesi temsil ediliyor mu?",
|
||||
"Yanlış genelleme yaratacak özel durum var mı?",
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Çıktı sözleşmesi otomasyonun kapısıdır</SlideTitle>
|
||||
<SlideContent>
|
||||
İnsan okuyacaksa okunabilirlik, sistem okuyacaksa <SlideHighlight>şema</SlideHighlight> önemlidir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<CodePanel title="output-contract.json">
|
||||
{`{
|
||||
"summary": "en fazla 3 cümle",
|
||||
"risks": ["kanıta dayalı risk listesi"],
|
||||
"next_actions": [
|
||||
{ "owner": "rol", "task": "yapılacak iş", "priority": "P0 | P1 | P2" }
|
||||
],
|
||||
"confidence": "low | medium | high"
|
||||
}`}
|
||||
<CodePanel title="agent-instructions.md">
|
||||
{`Role: Release notes agent for our repo.
|
||||
Goal: Summarize merged PRs since the last tag.
|
||||
Sources: GitHub API, CHANGELOG.md.
|
||||
Limits: No breaking-change claims without a label.
|
||||
Stop: When the draft is posted for review.
|
||||
Output: Markdown, grouped by feature / fix / chore.`}
|
||||
</CodePanel>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Ajanlarda prompt = yetki ve durma kuralları</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={Bot} title="Ne zaman araç?" accent="text-sky-500">
|
||||
Bilgi eksikse arama yap; tahminle doldurma.
|
||||
</Card>
|
||||
<Card icon={ShieldCheck} title="Ne zaman sormalı?" accent="text-emerald-500">
|
||||
Kapsam veya risk davranışı etkiliyorsa kullanıcıya dön.
|
||||
</Card>
|
||||
<Card icon={TimerReset} title="Ne zaman durmalı?" accent="text-purple-500">
|
||||
Başarı kriteri tamamlandıysa yeni iş icat etme.
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-[1fr_1.1fr]">
|
||||
<div>
|
||||
<SlideTitle>Uzun işlerde context akışı tasarla</SlideTitle>
|
||||
<SlideContent>
|
||||
Tek dev prompt yerine, işi aşamalara böl: keşif, plan, uygulama, doğrulama, özet.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
{[
|
||||
{ icon: Network, title: "Keşif", text: "Dosya, kaynak ve kısıtları topla." },
|
||||
{ icon: Route, title: "Plan", text: "Kararları ve bağımlılıkları görünür yap." },
|
||||
{ icon: Blocks, title: "Uygulama", text: "Sadece gerekli bağlamı sonraki adıma taşı." },
|
||||
{ icon: ClipboardCheck, title: "Doğrulama", text: "Çıktıyı ölçüt ve kaynakla kontrol et." },
|
||||
].map(({ icon: Icon, title, text }) => (
|
||||
<div key={title} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 text-primary">
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold">{title}</h3>
|
||||
<p className="text-muted-foreground">{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>En sık görülen hata modları</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-2">
|
||||
<FlowStep icon={Target} title="Belirsiz hedef" text="Başarı tanımı yoksa model kendi hedefini seçer." />
|
||||
<FlowStep icon={Clock3} title="Eski context" text="Önceki kararlar yeni talimatla çakışır." />
|
||||
<FlowStep icon={Puzzle} title="Görünmez varsayım" text="Sizde açık olan bilgi modelde yoktur." />
|
||||
<FlowStep icon={FileText} title="Format eksikliği" text="Doğru bilgi yanlış biçimde gelirse kullanılamaz." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Promptları ölç: tek iyi cevap yetmez</SlideTitle>
|
||||
<SlideContent>
|
||||
Küçük bir test seti, promptun gerçek hayatta dayanıklı olup olmadığını gösterir.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"3 normal senaryo",
|
||||
"2 sınır durum",
|
||||
"1 kasıtlı belirsiz istek",
|
||||
"Beklenen format kontrolü",
|
||||
"İyi cevap nasıl görünür? kısa kontrol listesi",
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[1.05fr_0.95fr]">
|
||||
<div>
|
||||
<SlideTitle>prompts.chat: promptları paylaşılabilir hale getirmek</SlideTitle>
|
||||
<SlideTitle>prompts.chat: an open prompt ecosystem</SlideTitle>
|
||||
<SlideContent>
|
||||
Promptlar kaybolan sohbet parçaları olmamalı. Keşfedilebilir, fork edilebilir, iyileştirilebilir ve tekrar kullanılabilir olmalı.
|
||||
Prompts as <SlideHighlight>first-class assets</SlideHighlight> — discoverable, forkable, versioned, and
|
||||
reusable. Open source and self-hostable.
|
||||
</SlideContent>
|
||||
</div>
|
||||
<div className="grid gap-4">
|
||||
<Card icon={Sparkles} title="Keşif">
|
||||
İyi örneği arayıp bulmak, sıfırdan başlamaktan hızlıdır.
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<Card icon={Search} title="Discover">
|
||||
Find a proven prompt instead of starting from scratch.
|
||||
</Card>
|
||||
<Card icon={GitBranch} title="Değişiklik">
|
||||
Promptlar review ve geri bildirimle olgunlaşır.
|
||||
<Card icon={GitBranch} title="Fork">
|
||||
Branch it, tweak it, make it yours.
|
||||
</Card>
|
||||
<Card icon={PackageCheck} title="Yeniden kullanım">
|
||||
Aynı kaliteyi farklı ekip ve iş akışlarına taşırsınız.
|
||||
<Card icon={Layers3} title="Version">
|
||||
Prompts mature through review and feedback.
|
||||
</Card>
|
||||
<Card icon={PackageCheck} title="Reuse">
|
||||
Carry quality across teams, tools, and agents.
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>Promptlar kod gibi yaşamalı</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-4">
|
||||
<FlowStep icon={FileText} title="Sahiplik" text="Kim güncelliyor?" />
|
||||
<FlowStep icon={GitBranch} title="Sürüm" text="Ne değişti?" />
|
||||
<FlowStep icon={ClipboardCheck} title="Review" text="Kalite barı ne?" />
|
||||
<FlowStep icon={DatabaseZap} title="Örnek" text="Hangi veriyle çalıştı?" />
|
||||
<SlideTitle>Why open matters for agents</SlideTitle>
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
<Card icon={ShieldCheck} title="Inspectable" accent="text-emerald-500">
|
||||
You can read exactly what the agent was told to do.
|
||||
</Card>
|
||||
<Card icon={Globe} title="Portable" accent="text-sky-500">
|
||||
The same instruction travels across models and tools.
|
||||
</Card>
|
||||
<Card icon={Bot} title="Composable" accent="text-purple-500">
|
||||
Open prompts plug into agents, IDEs, and an MCP layer.
|
||||
</Card>
|
||||
</div>
|
||||
<SlideContent className="mt-10">
|
||||
An ecosystem of agents needs an <SlideHighlight>open</SlideHighlight> ecosystem of prompts.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Learn it: The Interactive Book of Prompting</SlideTitle>
|
||||
<SlideContent>
|
||||
A <SlideHighlight>free, interactive</SlideHighlight> prompt-engineering guide — with live, hands-on demos
|
||||
instead of a static PDF.
|
||||
</SlideContent>
|
||||
<div className="mt-7 space-y-3">
|
||||
<div className="flex items-center gap-3 text-lg text-muted-foreground">
|
||||
<BookOpen className="h-5 w-5 flex-none text-primary" />
|
||||
Hands-on chapters, from fundamentals to agents.
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-lg text-muted-foreground">
|
||||
<Code2 className="h-5 w-5 flex-none text-primary" />
|
||||
Runnable demos you can try right on the page.
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Pill>prompts.chat/book</Pill>
|
||||
<Pill>Open & community-driven</Pill>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mx-auto w-full max-w-[34rem]">
|
||||
<div className="absolute -inset-4 -rotate-2 rounded-[3rem] bg-gradient-to-br from-primary/30 via-primary/10 to-transparent" />
|
||||
<div className="relative overflow-hidden rounded-[2rem] border border-border bg-background shadow-2xl">
|
||||
<Image
|
||||
src="/book-cover-photo.jpg"
|
||||
alt="The Interactive Book of Prompting cover"
|
||||
width={1200}
|
||||
height={630}
|
||||
unoptimized
|
||||
className="h-auto w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.95fr_1.05fr]">
|
||||
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
|
||||
<div>
|
||||
<SlideTitle>Kapanış kontrol listesi</SlideTitle>
|
||||
<SlideTitle>Play it: Promi in Prompt Land</SlideTitle>
|
||||
<SlideContent>
|
||||
Bir sonraki promptunuzu göndermeden önce bu beş soruyu sorun.
|
||||
A <SlideHighlight>game-based</SlideHighlight> way for kids to learn how to talk to AI — because this
|
||||
literacy belongs to everyone.
|
||||
</SlideContent>
|
||||
<div className="mt-7 space-y-3">
|
||||
<div className="flex items-center gap-3 text-lg text-muted-foreground">
|
||||
<Gamepad2 className="h-5 w-5 flex-none text-green-500" />
|
||||
Join Promi the robot on an adventure through Prompt Land.
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-lg text-muted-foreground">
|
||||
<Sparkles className="h-5 w-5 flex-none text-amber-500" />
|
||||
Kids practice asking AI for what they actually want.
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Pill>prompts.chat/kids</Pill>
|
||||
<Pill>For the next generation</Pill>
|
||||
</div>
|
||||
</div>
|
||||
<MiniChecklist
|
||||
items={[
|
||||
"Modelin rolü ve hedefi net mi?",
|
||||
"Gerekli context seçildi ve sıralandı mı?",
|
||||
"Kısıtlar ve durma kuralları yazıldı mı?",
|
||||
"Çıktı formatı sözleşmeye bağlandı mı?",
|
||||
"En az birkaç gerçek senaryoyla denendi mi?",
|
||||
]}
|
||||
/>
|
||||
<div className="relative mx-auto w-full max-w-[19rem]">
|
||||
<div className="absolute -inset-4 rotate-2 rounded-[3rem] bg-gradient-to-br from-primary/30 via-primary/10 to-transparent" />
|
||||
<div className="relative overflow-hidden rounded-[2rem] border border-border bg-background shadow-2xl">
|
||||
<Image
|
||||
src="/presentation/kids-screenshot.png"
|
||||
alt="Promi in Prompt Land — the kids game"
|
||||
width={800}
|
||||
height={2026}
|
||||
unoptimized
|
||||
className="h-auto w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col justify-center">
|
||||
<SlideTitle>One open loop</SlideTitle>
|
||||
<div className="grid gap-5 md:grid-cols-5">
|
||||
<FlowStep icon={Star} title="Repo" text="Where it all began." />
|
||||
<FlowStep icon={Boxes} title="Platform" text="Discover, fork, version, reuse." />
|
||||
<FlowStep icon={BookOpen} title="Book" text="Learn the craft." />
|
||||
<FlowStep icon={Gamepad2} title="Game" text="Onboard the next generation." />
|
||||
<FlowStep icon={Network} title="API / MCP" text="Feed humans and agents." />
|
||||
</div>
|
||||
<SlideContent className="mt-10 max-w-4xl">
|
||||
Prompts flow in, get refined by the community, and flow back out to{" "}
|
||||
<SlideHighlight>humans and agents</SlideHighlight>.
|
||||
</SlideContent>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
|
||||
<div className="mb-8 flex h-24 w-24 items-center justify-center rounded-[2rem] bg-primary/10 text-primary">
|
||||
<Workflow className="h-12 w-12" />
|
||||
</div>
|
||||
<SlideTitle className="max-w-5xl">Prompts are the new interface</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-4xl">
|
||||
As agents take action, the prompt is how we steer them — and the tooling that manages those prompts is what
|
||||
people now call the <SlideHighlight>“harness”</SlideHighlight>.
|
||||
</SlideContent>
|
||||
<p className="mx-auto mt-6 max-w-3xl text-lg font-medium text-muted-foreground/80 md:text-xl">
|
||||
The harness isn't the prompt — it's what keeps your prompts accurate and well-tuned. So let's
|
||||
keep it <SlideHighlight>open, shared, and improvable</SlideHighlight>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
|
||||
<div className="mb-8 flex h-24 w-24 items-center justify-center rounded-full bg-primary/10 text-primary">
|
||||
<Sparkles className="h-12 w-12" />
|
||||
<Rocket className="h-12 w-12" />
|
||||
</div>
|
||||
<SlideTitle>Teşekkürler</SlideTitle>
|
||||
<SlideTitle>Thank you</SlideTitle>
|
||||
<SlideContent className="mx-auto max-w-4xl">
|
||||
İyi prompt modele <SlideHighlight>ne yapacağını</SlideHighlight> söyler.
|
||||
<br />
|
||||
İyi context yönetimi <SlideHighlight>neye dayanarak yapacağını</SlideHighlight> belirler.
|
||||
Come build the open prompt ecosystem with us.
|
||||
</SlideContent>
|
||||
<div className="mt-10 flex flex-wrap justify-center gap-3">
|
||||
<Pill>prompts.chat</Pill>
|
||||
<Pill>Q&A</Pill>
|
||||
<Pill>/book</Pill>
|
||||
<Pill>/kids</Pill>
|
||||
<Pill>github.com/f/prompts.chat</Pill>
|
||||
</div>
|
||||
<div className="mt-8 flex items-center gap-2 text-lg font-semibold text-muted-foreground">
|
||||
Questions <ArrowRight className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</SlideDeck>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Children, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ChevronLeft, ChevronRight, Maximize, Minimize, StickyNote, X } from "lucide-react";
|
||||
import { ChevronLeft, ChevronRight, Maximize, Minimize, MonitorPlay, StickyNote, X } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -18,6 +18,8 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
const [showNotes, setShowNotes] = useState(false);
|
||||
const swipeStartX = useRef<number | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const channelRef = useRef<BroadcastChannel | null>(null);
|
||||
const currentSlideRef = useRef(currentSlide);
|
||||
const totalSlides = slides.length;
|
||||
const currentNote = notes?.[currentSlide];
|
||||
|
||||
@@ -29,6 +31,60 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
setCurrentSlide((prev) => Math.max(prev - 1, 0));
|
||||
}, []);
|
||||
|
||||
const broadcastState = useCallback(() => {
|
||||
channelRef.current?.postMessage({
|
||||
type: "state",
|
||||
currentSlide: currentSlideRef.current,
|
||||
totalSlides,
|
||||
notes: notes ?? [],
|
||||
});
|
||||
}, [notes, totalSlides]);
|
||||
|
||||
const openPresenterView = useCallback(() => {
|
||||
window.open(
|
||||
"/presentation/notes",
|
||||
"presentation-notes",
|
||||
"width=960,height=720,menubar=no,toolbar=no,location=no,status=no"
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined" || !notes || typeof BroadcastChannel === "undefined") return;
|
||||
|
||||
const channel = new BroadcastChannel("prompts-presentation");
|
||||
channelRef.current = channel;
|
||||
channel.onmessage = (event) => {
|
||||
const data = event.data;
|
||||
if (!data || typeof data !== "object") return;
|
||||
switch (data.type) {
|
||||
case "request":
|
||||
broadcastState();
|
||||
break;
|
||||
case "next":
|
||||
nextSlide();
|
||||
break;
|
||||
case "prev":
|
||||
prevSlide();
|
||||
break;
|
||||
case "goto":
|
||||
if (typeof data.index === "number") {
|
||||
setCurrentSlide(Math.max(0, Math.min(data.index, totalSlides - 1)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
channel.close();
|
||||
channelRef.current = null;
|
||||
};
|
||||
}, [notes, totalSlides, nextSlide, prevSlide, broadcastState]);
|
||||
|
||||
useEffect(() => {
|
||||
currentSlideRef.current = currentSlide;
|
||||
broadcastState();
|
||||
}, [currentSlide, broadcastState]);
|
||||
|
||||
const toggleFullscreen = useCallback(() => {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
@@ -67,12 +123,15 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
} else if (event.key === "n" || event.key === "N") {
|
||||
event.preventDefault();
|
||||
setShowNotes((value) => !value);
|
||||
} else if (event.key === "p" || event.key === "P") {
|
||||
event.preventDefault();
|
||||
openPresenterView();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [nextSlide, prevSlide, toggleFullscreen, totalSlides]);
|
||||
}, [nextSlide, prevSlide, toggleFullscreen, totalSlides, openPresenterView]);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -100,29 +159,41 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
{currentSlide + 1} / {totalSlides}
|
||||
</div>
|
||||
{notes && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setShowNotes((value) => !value)}
|
||||
className={cn(
|
||||
"rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90",
|
||||
showNotes && "text-primary"
|
||||
)}
|
||||
title="Konuşmacı notları (N)"
|
||||
>
|
||||
<StickyNote className="h-5 w-5" />
|
||||
<span className="sr-only">{showNotes ? "Notları gizle" : "Notları göster"}</span>
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => setShowNotes((value) => !value)}
|
||||
className={cn(
|
||||
"rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90",
|
||||
showNotes && "text-primary"
|
||||
)}
|
||||
title="Speaker notes (N)"
|
||||
>
|
||||
<StickyNote className="h-5 w-5" />
|
||||
<span className="sr-only">{showNotes ? "Hide notes" : "Show notes"}</span>
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={openPresenterView}
|
||||
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
title="Open presenter notes window (P)"
|
||||
>
|
||||
<MonitorPlay className="h-5 w-5" />
|
||||
<span className="sr-only">Open presenter notes window</span>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={toggleFullscreen}
|
||||
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
title="Tam ekran (F)"
|
||||
title="Fullscreen (F)"
|
||||
>
|
||||
{isFullscreen ? <Minimize className="h-5 w-5" /> : <Maximize className="h-5 w-5" />}
|
||||
<span className="sr-only">{isFullscreen ? "Tam ekrandan çık" : "Tam ekran yap"}</span>
|
||||
<span className="sr-only">{isFullscreen ? "Exit fullscreen" : "Enter fullscreen"}</span>
|
||||
</Button>
|
||||
<Link href="/">
|
||||
<Button
|
||||
@@ -131,7 +202,7 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<X className="h-5 w-5" />
|
||||
<span className="sr-only">Kapat</span>
|
||||
<span className="sr-only">Close</span>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
@@ -166,7 +237,7 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<ChevronLeft className="h-5 w-5" />
|
||||
<span className="sr-only">Önceki</span>
|
||||
<span className="sr-only">Previous</span>
|
||||
</Button>
|
||||
|
||||
<div className="flex max-w-[58vw] items-center gap-1.5 overflow-hidden rounded-full border border-border/60 bg-background/60 px-3 py-2 shadow-sm backdrop-blur">
|
||||
@@ -178,7 +249,7 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
"h-2.5 rounded-full transition-all duration-300",
|
||||
index === currentSlide ? "w-8 bg-primary" : "w-2.5 bg-muted-foreground/30 hover:bg-muted-foreground/50"
|
||||
)}
|
||||
aria-label={`${index + 1}. slayta git`}
|
||||
aria-label={`Go to slide ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -191,14 +262,14 @@ export function SlideDeck({ children, notes }: SlideDeckProps) {
|
||||
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
|
||||
>
|
||||
<ChevronRight className="h-5 w-5" />
|
||||
<span className="sr-only">Sonraki</span>
|
||||
<span className="sr-only">Next</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{showNotes && (
|
||||
<div className="absolute inset-x-4 bottom-24 z-50 mx-auto max-w-3xl rounded-2xl border border-border bg-background/95 p-4 shadow-2xl backdrop-blur">
|
||||
<div className="mb-1 text-xs font-bold uppercase tracking-[0.24em] text-primary">Konuşmacı notu</div>
|
||||
<p className="text-sm leading-relaxed text-foreground">{currentNote || "Bu slayt için not yok."}</p>
|
||||
<div className="mb-1 text-xs font-bold uppercase tracking-[0.24em] text-primary">Speaker note</div>
|
||||
<p className="text-sm leading-relaxed text-foreground">{currentNote || "No note for this slide."}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user