Add welcome banner, instructions, and fix submitter display

jasonnovack@jasonnovackJan 7, 2026claude_codeclaude-opus-4-5-20251101ui

Diff

diff --git a/packages/web/src/app/globals.css b/packages/web/src/app/globals.css
index f145fd5..16fa16c 100644
--- a/packages/web/src/app/globals.css
+++ b/packages/web/src/app/globals.css
@@ -703,6 +703,13 @@ h1 {
font-size: 0.8rem;
}
+/* Anonymous author */
+.anonymous-author {
+ color: var(--muted);
+ font-style: italic;
+ margin-right: 0.5rem;
+}
+
/* Preview links */
.preview-links {
display: flex;
@@ -725,3 +732,29 @@ h1 {
background: rgba(74, 222, 128, 0.2);
text-decoration: none;
}
+
+/* Welcome banner */
+.welcome-banner {
+ background: linear-gradient(135deg, rgba(0, 112, 243, 0.15) 0%, rgba(0, 112, 243, 0.05) 100%);
+ border: 1px solid rgba(0, 112, 243, 0.3);
+ border-radius: 12px;
+ padding: 2rem;
+ margin-bottom: 1.5rem;
+ text-align: center;
+}
+
+.welcome-banner h1 {
+ font-size: 2rem;
+ margin-bottom: 0.75rem;
+ background: linear-gradient(135deg, var(--fg) 0%, var(--accent) 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.welcome-banner p {
+ color: var(--muted);
+ font-size: 1.1rem;
+ max-width: 600px;
+ margin: 0 auto;
+}
diff --git a/packages/web/src/app/page.tsx b/packages/web/src/app/page.tsx
index 526d7a0..e27cc62 100644
--- a/packages/web/src/app/page.tsx
+++ b/packages/web/src/app/page.tsx
@@ -102,28 +102,32 @@ export default async function GalleryPage({ searchParams }: Props) {
return (
<div>
- <h1>Oneshot Gallery</h1>
- <p style={{ color: 'var(--muted)', marginBottom: '1.5rem' }}>
- Verified AI code transformations. One prompt, one commit.
- </p>
-
- {/* Getting Started */}
- {showGettingStarted && (
- <div className="getting-started">
- <h2>How to Submit a Shot</h2>
- <ol>
- <li>Use an AI coding tool (Claude Code, Cursor, or Codex) to make a code change</li>
- <li>Commit your changes: <code>git add . && git commit -m "Your change"</code></li>
- <li>Install the CLI: <code>npm install -g @oneshot/cli</code></li>
- <li>Submit: <code>oneshot submit --title "Your title" --type feature</code></li>
- </ol>
- <p style={{ color: 'var(--muted)', fontSize: '0.9rem', marginTop: '1rem' }}>
- The CLI auto-detects your AI session and extracts the prompt, model, and settings.
- <br />
- Types: <code>feature</code> | <code>fix</code> | <code>refactor</code> | <code>ui</code> | <code>test</code> | <code>docs</code> | <code>other</code>
- </p>
- </div>
- )}
+ {/* Welcome Banner */}
+ <div className="welcome-banner">
+ <h1>Welcome to Oneshot</h1>
+ <p>
+ The place to showcase and discover verified AI code transformations.
+ One prompt, one commit, fully reproducible.
+ </p>
+ </div>
+
+ {/* Getting Started - Always visible */}
+ <div className="getting-started">
+ <h2>How to Submit a Shot</h2>
+ <ol>
+ <li>Use an AI coding tool (Claude Code, Cursor, or Codex) to make a code change</li>
+ <li>Commit your changes: <code>git add . && git commit -m "Your change"</code></li>
+ <li>Install the CLI: <code>npm install -g @oneshot/cli</code></li>
+ <li>Submit: <code>oneshot submit --title "Your title" --type feature</code></li>
+ </ol>
+ <p style={{ color: 'var(--muted)', fontSize: '0.9rem', marginTop: '1rem' }}>
+ The CLI auto-detects your AI session and extracts the prompt, model, and settings.
+ <br />
+ Types: <code>feature</code> | <code>fix</code> | <code>refactor</code> | <code>ui</code> | <code>test</code> | <code>docs</code> | <code>other</code>
+ </p>
+ </div>
+
+ <h2 style={{ marginTop: '2rem', marginBottom: '1rem' }}>Gallery</h2>
{/* Filters */}
<GalleryFilters
@@ -144,10 +148,12 @@ export default async function GalleryPage({ searchParams }: Props) {
<Link href={`/shots/${shot.id}`}>
<h2>{shot.title}</h2>
<div className="shot-meta">
- {user && (
+ {user ? (
<Link href={`/u/${user.username}`} className="author-link" onClick={(e) => e.stopPropagation()}>
@{user.username}
</Link>
+ ) : (
+ <span className="anonymous-author">Anonymous</span>
)}
<span className="shot-date">
{new Date(shot.createdAt).toLocaleDateString('en-US', {
diff --git a/packages/web/src/app/shots/[id]/page.tsx b/packages/web/src/app/shots/[id]/page.tsx
index ce9c46c..4ff9ce9 100644
--- a/packages/web/src/app/shots/[id]/page.tsx
+++ b/packages/web/src/app/shots/[id]/page.tsx
@@ -36,7 +36,7 @@ export default async function ShotDetailPage({ params }: Props) {
<div>
<h1>{shot.title}</h1>
<div className="shot-meta">
- {user && (
+ {user ? (
<>
<Link href={`/u/${user.username}`} className="author-link">
@{user.username}
@@ -62,7 +62,16 @@ export default async function ShotDetailPage({ params }: Props) {
</a>
)}
</>
+ ) : (
+ <span className="anonymous-author">Anonymous</span>
)}
+ <span className="shot-date">
+ {new Date(shot.createdAt).toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric',
+ })}
+ </span>
<span className="badge">{shot.harness}</span>
<span className="badge">{shot.model}</span>
<span className="badge">{shot.type}</span>
diff --git a/packages/web/src/components/Header.tsx b/packages/web/src/components/Header.tsx
index 5ae63ba..8632a7c 100644
--- a/packages/web/src/components/Header.tsx
+++ b/packages/web/src/components/Header.tsx
@@ -11,6 +11,9 @@ export function Header() {
<Link href="/" className="logo">Oneshot</Link>
<nav>
<Link href="/">Gallery</Link>
+ <a href="https://github.com/jasonnovack/oneshot" target="_blank" rel="noopener noreferrer">
+ GitHub
+ </a>
{status === 'loading' ? (
<span style={{ marginLeft: '2rem', color: 'var(--muted)' }}>...</span>
) : session ? (

Recipe

Model
claude-opus-4-5-20251101
Harness
Claude Code
Token Usage
Input: 10.6KOutput: 189.4KTotal: 200.0KCache Read: 119.0M
Plugins
Frontend Design vclaude-plugins-officialGithub vclaude-plugins-officialFeature Dev vclaude-plugins-officialSwift Lsp vclaude-plugins-official
Prompt
Let's write a product spec for a web app called Oneshot. There is a huge amount of interest right now in AI model selection, harness selection, prompt engineering, context engineering, MCP, etc., etc. The goal is to create an app where users can showcase what they can do and how they do it. The idea is to let users showcase before/after and how they get amazing results with AI. I am thinking there are 3 key components: 1. we take a repo BEFORE state and host it somewhere, or accept a hosted version like a Vercel build that we can verify corresponds with the repo's BEFORE state. 2. users invoke AI, and we capture a VERIFIED set of attributes that allows full reproducibility of this AI action (model, harness, prompt, context, and anything else that's relevant). 3. we take a repo AFTER state and host it somewhere or accept a user-hosted version that we can verify corresponds with the repo's AFTER state. Once we have those 3 components, we build a simple database of all submitted examples, gallery app to discover and inspect them.
Raw Session Data
Tip: Copy the prompt and adapt it for your own project. The key is understanding why this prompt worked, not reproducing it exactly.

Comments (0)

Loading comments...