Initialize PromptArch: The Prompt Enhancer (Fork of ClavixDev/Clavix)

This commit is contained in:
Gemini AI
2025-12-25 16:58:36 +04:00
Unverified
commit c0a01b5840
35 changed files with 11054 additions and 0 deletions

69
app/globals.css Normal file
View File

@@ -0,0 +1,69 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

22
app/layout.tsx Normal file
View File

@@ -0,0 +1,22 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "PromptArch - AI Prompt Engineering Platform",
description: "Transform vague ideas into production-ready prompts and PRDs",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}

92
app/page.tsx Normal file
View File

@@ -0,0 +1,92 @@
"use client";
import { useState, useEffect } from "react";
import Sidebar from "@/components/Sidebar";
import type { View } from "@/components/Sidebar";
import PromptEnhancer from "@/components/PromptEnhancer";
import PRDGenerator from "@/components/PRDGenerator";
import ActionPlanGenerator from "@/components/ActionPlanGenerator";
import HistoryPanel from "@/components/HistoryPanel";
import SettingsPanel from "@/components/SettingsPanel";
import useStore from "@/lib/store";
import modelAdapter from "@/lib/services/adapter-instance";
export default function Home() {
const [currentView, setCurrentView] = useState<View>("enhance");
const { setQwenTokens, setApiKey } = useStore();
useEffect(() => {
// Handle OAuth callback
if (typeof window !== "undefined") {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get("code");
if (code) {
// In a real app, you would exchange the code for tokens here
// Since we don't have a backend or real client secret, we'll simulate it
console.log("OAuth code received:", code);
// Mock token exchange
const mockAccessToken = "mock_access_token_" + Math.random().toString(36).substr(2, 9);
const tokens = {
accessToken: mockAccessToken,
expiresAt: Date.now() + 3600 * 1000, // 1 hour
};
setQwenTokens(tokens);
modelAdapter.setQwenOAuthTokens(tokens.accessToken, undefined, 3600);
// Save to localStorage
localStorage.setItem("promptarch-qwen-tokens", JSON.stringify(tokens));
// Clear the code from URL
window.history.replaceState({}, document.title, window.location.pathname);
// Switch to settings to show success (optional)
setCurrentView("settings");
}
// Load tokens from localStorage on init
const savedTokens = localStorage.getItem("promptarch-qwen-tokens");
if (savedTokens) {
try {
const tokens = JSON.parse(savedTokens);
if (tokens.expiresAt > Date.now()) {
setQwenTokens(tokens);
modelAdapter.setQwenOAuthTokens(tokens.accessToken, tokens.refreshToken, (tokens.expiresAt - Date.now()) / 1000);
}
} catch (e) {
console.error("Failed to load Qwen tokens:", e);
}
}
}
}, []);
const renderContent = () => {
switch (currentView) {
case "enhance":
return <PromptEnhancer />;
case "prd":
return <PRDGenerator />;
case "action":
return <ActionPlanGenerator />;
case "history":
return <HistoryPanel />;
case "settings":
return <SettingsPanel />;
default:
return <PromptEnhancer />;
}
};
return (
<div className="flex min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800">
<Sidebar currentView={currentView} onViewChange={setCurrentView} />
<main className="flex-1 overflow-auto p-8">
<div className="mx-auto max-w-7xl">
{renderContent()}
</div>
</main>
</div>
);
}

27
app/test.css Normal file
View File

@@ -0,0 +1,27 @@
.test-page {
background: linear-gradient(to bottom right, rgb(248, 250, 252), rgb(241, 245, 249));
min-height: 100vh;
}
.test-card {
background: white;
border: 1px solid rgb(229, 231, 235);
border-radius: 0.5rem;
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
padding: 1.5rem;
}
.test-button {
background: rgb(24, 24, 27);
color: white;
padding: 0.5rem 1rem;
border-radius: 0.375rem;
font-weight: 500;
font-size: 0.875rem;
border: none;
cursor: pointer;
}
.test-button:hover {
background: rgb(38, 38, 42);
}