Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ pnpm-debug.log*

# Supabase
supabase/.temp/

# Next.js
.next/
out/
next-env.d.ts
7 changes: 7 additions & 0 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# GitHub (temporary -- will be replaced by GitHub App)
GITHUB_TOKEN=ghp_your-token
3 changes: 3 additions & 0 deletions apps/web/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
6 changes: 6 additions & 0 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@wright/shared'],
}

export default nextConfig
32 changes: 32 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@wright/web",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "next dev --port 3000",
"build": "next build",
"start": "next start",
"lint": "next lint",
"clean": "rm -rf .next .turbo"
},
"dependencies": {
"@supabase/ssr": "^0.6.0",
"@supabase/supabase-js": "^2.49.0",
"@wright/shared": "workspace:*",
"next": "^14.2.0",
"react": "^18.3.0",
"react-dom": "^18.3.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^10.4.0",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.0",
"postcss": "^8.4.0",
"tailwindcss": "^3.4.0",
"typescript": "^5.7.0"
}
}
9 changes: 9 additions & 0 deletions apps/web/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

export default config
25 changes: 25 additions & 0 deletions apps/web/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--foreground-rgb: 15, 23, 42;
--background-start-rgb: 248, 250, 252;
--background-end-rgb: 241, 245, 249;
}

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}

@layer utilities {
.text-balance {
text-wrap: balance;
}
}
70 changes: 70 additions & 0 deletions apps/web/src/app/jobs/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Link from 'next/link'

/**
* Job detail page -- shows status, events timeline, and test results.
*
* This is a scaffold. The full implementation will:
* - Fetch job details from Supabase
* - Subscribe to real-time job_events updates
* - Show test result diffs between loops
* - Link to the created PR
*/
export default function JobDetailPage({
params,
}: {
params: { id: string }
}) {
return (
<main className="min-h-screen">
{/* Navigation */}
<nav className="w-full border-b border-slate-200 bg-white/80 backdrop-blur-sm">
<div className="mx-auto flex max-w-6xl items-center justify-between px-6 py-4">
<Link href="/" className="flex items-center gap-2">
<span className="text-xl font-bold text-wright-700">Wright</span>
<span className="rounded-full bg-wright-100 px-2 py-0.5 text-xs font-medium text-wright-700">
beta
</span>
</Link>
<Link
href="/new"
className="rounded-lg bg-wright-600 px-4 py-2 text-sm font-medium text-white hover:bg-wright-700"
>
New Task
</Link>
</div>
</nav>

<div className="mx-auto max-w-4xl px-6 py-16">
<div className="flex items-center gap-3">
<h1 className="text-2xl font-bold text-slate-900">Job Details</h1>
<code className="rounded bg-slate-100 px-2 py-1 font-mono text-sm text-slate-600">
{params.id}
</code>
</div>

{/* Placeholder for job details */}
<div className="mt-8 rounded-xl border border-slate-200 bg-white p-8">
<div className="space-y-4 text-slate-600">
<p>
This page will show real-time job status, event timeline, and test
results once connected to Supabase.
</p>
<div className="rounded-lg bg-slate-50 p-4">
<h3 className="text-sm font-semibold text-slate-700">
Coming Soon
</h3>
<ul className="mt-2 list-inside list-disc space-y-1 text-sm">
<li>Real-time status updates via Supabase Realtime</li>
<li>Event timeline (claimed, cloning, editing, testing...)</li>
<li>Test results per loop iteration</li>
<li>Cost tracking (API spend per loop)</li>
<li>Link to created PR</li>
<li>Cancel / retry controls</li>
</ul>
</div>
</div>
</div>
</div>
</main>
)
}
20 changes: 20 additions & 0 deletions apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Metadata } from 'next'
import './globals.css'

export const metadata: Metadata = {
title: 'Wright — AI Dev Automation',
description:
'Submit a task, get a pull request. Wright uses Claude to edit code, run tests, and create PRs automatically.',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className="min-h-screen antialiased">{children}</body>
</html>
)
}
Loading
Loading