admin08077 commited on
Commit
01ae808
·
verified ·
1 Parent(s): f1ccd57

Upload 18 files

Browse files
Files changed (18) hide show
  1. App.tsx +164 -0
  2. Dockerfile +13 -0
  3. README.md +52 -11
  4. constants.ts +67 -0
  5. globals.d.ts +24 -0
  6. index.css +100 -0
  7. index.html +38 -0
  8. index.tsx +24 -0
  9. metadata.json +8 -0
  10. package-lock.json +0 -0
  11. package.json +34 -0
  12. postcss.config.js +6 -0
  13. services +0 -0
  14. tailwind.config.js +33 -0
  15. tsconfig.json +27 -0
  16. tsconfig.server.json +16 -0
  17. types.ts +47 -0
  18. vite.config.ts +37 -0
App.tsx ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { Suspense, useCallback, useMemo, useState, useEffect } from 'react';
2
+ import { ErrorBoundary } from './components/ErrorBoundary.tsx';
3
+ import { useGlobalState } from './contexts/GlobalStateContext.tsx';
4
+ import { logEvent } from './services/telemetryService.ts';
5
+ import { ALL_FEATURES, FEATURES_MAP } from './components/features/index.ts';
6
+ import type { ViewType, FeatureId, SidebarItem } from './types.ts';
7
+ import { DownloadManager } from './components/DownloadManager.tsx';
8
+ import { LeftSidebar } from './components/LeftSidebar.tsx';
9
+ import { StatusBar } from './components/StatusBar.tsx';
10
+ import { CommandPalette } from './components/CommandPalette.tsx';
11
+ import { SettingsView } from './components/SettingsView.tsx';
12
+ import { Cog6ToothIcon, HomeIcon } from './components/icons/InterfaceIcons.tsx';
13
+ import { AiCommandCenter } from './components/features/AiCommandCenter.tsx';
14
+ import { LoginView } from './components/LoginView.tsx';
15
+
16
+
17
+ export const LoadingIndicator: React.FC = () => (
18
+ <div className="w-full h-full flex items-center justify-center bg-surface">
19
+ <div className="flex items-center justify-center space-x-2">
20
+ <div className="w-4 h-4 rounded-full bg-primary animate-pulse" style={{ animationDelay: '0s' }}></div>
21
+ <div className="w-4 h-4 rounded-full bg-primary animate-pulse" style={{ animationDelay: '0.2s' }}></div>
22
+ <div className="w-4 h-4 rounded-full bg-primary animate-pulse" style={{ animationDelay: '0.4s' }}></div>
23
+ <span className="text-text-secondary ml-2">Loading Feature...</span>
24
+ </div>
25
+ </div>
26
+ );
27
+
28
+ interface LocalStorageConsentModalProps {
29
+ onAccept: () => void;
30
+ onDecline: () => void;
31
+ }
32
+
33
+ const LocalStorageConsentModal: React.FC<LocalStorageConsentModalProps> = ({ onAccept, onDecline }) => {
34
+ return (
35
+ <div className="fixed inset-0 bg-gray-900/80 backdrop-blur-sm z-50 flex items-center justify-center fade-in">
36
+ <div
37
+ className="bg-surface border border-border rounded-2xl shadow-2xl shadow-black/50 w-full max-w-md m-4 p-8 text-center animate-pop-in"
38
+ >
39
+ <h2 className="text-2xl mb-4">Store Data Locally?</h2>
40
+ <p className="text-text-secondary mb-6">
41
+ This application uses your browser's local storage to save your settings and remember your progress between sessions. This data stays on your computer and is not shared.
42
+ </p>
43
+ <div className="flex justify-center gap-4">
44
+ <button
45
+ onClick={onDecline}
46
+ className="px-6 py-2 bg-surface border border-border text-text-primary font-bold rounded-md hover:bg-gray-100 transition-colors"
47
+ >
48
+ Decline
49
+ </button>
50
+ <button
51
+ onClick={onAccept}
52
+ className="btn-primary px-6 py-2"
53
+ >
54
+ Accept
55
+ </button>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ );
60
+ };
61
+
62
+ const App: React.FC = () => {
63
+ const { state, dispatch } = useGlobalState();
64
+ const { activeView, viewProps, hiddenFeatures, isAuthenticated } = state;
65
+ const [isCommandPaletteOpen, setCommandPaletteOpen] = useState(false);
66
+ const [showConsentModal, setShowConsentModal] = useState(false);
67
+
68
+ useEffect(() => {
69
+ try {
70
+ const consent = localStorage.getItem('devcore_ls_consent');
71
+ if (!consent) {
72
+ setShowConsentModal(true);
73
+ }
74
+ } catch (e) {
75
+ console.warn("Could not access localStorage.", e);
76
+ }
77
+ }, []);
78
+
79
+ useEffect(() => {
80
+ const handleKeyDown = (e: KeyboardEvent) => {
81
+ if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
82
+ e.preventDefault();
83
+ setCommandPaletteOpen(isOpen => !isOpen);
84
+ }
85
+ };
86
+ window.addEventListener('keydown', handleKeyDown);
87
+ return () => window.removeEventListener('keydown', handleKeyDown);
88
+ }, []);
89
+
90
+ const handleAcceptConsent = () => {
91
+ try {
92
+ localStorage.setItem('devcore_ls_consent', 'granted');
93
+ window.location.reload();
94
+ } catch (e) {
95
+ console.error("Could not write to localStorage.", e);
96
+ setShowConsentModal(false);
97
+ }
98
+ };
99
+
100
+ const handleDeclineConsent = () => {
101
+ try {
102
+ localStorage.setItem('devcore_ls_consent', 'denied');
103
+ } catch (e) {
104
+ console.error("Could not write to localStorage.", e);
105
+ }
106
+ setShowConsentModal(false);
107
+ };
108
+
109
+ const handleViewChange = useCallback((view: ViewType, props: any = {}) => {
110
+ dispatch({ type: 'SET_VIEW', payload: { view, props } });
111
+ logEvent('view_changed', { view });
112
+ setCommandPaletteOpen(false);
113
+ }, [dispatch]);
114
+
115
+ const sidebarItems: SidebarItem[] = useMemo(() => [
116
+ { id: 'ai-command-center', label: 'Command Center', icon: <HomeIcon />, view: 'ai-command-center' },
117
+ ...ALL_FEATURES
118
+ .filter(feature => !hiddenFeatures.includes(feature.id) && feature.id !== 'ai-command-center')
119
+ .map(feature => ({
120
+ id: feature.id,
121
+ label: feature.name,
122
+ icon: feature.icon,
123
+ view: feature.id as ViewType,
124
+ })),
125
+ { id: 'settings', label: 'Settings', icon: <Cog6ToothIcon />, view: 'settings' },
126
+ ], [hiddenFeatures]);
127
+
128
+ const ActiveComponent = useMemo(() => {
129
+ if (activeView === 'settings') return SettingsView;
130
+ // Fallback to command center if no view is matched.
131
+ return FEATURES_MAP.get(activeView as string)?.component ?? AiCommandCenter;
132
+ }, [activeView]);
133
+
134
+ if (!isAuthenticated) {
135
+ return <LoginView />;
136
+ }
137
+
138
+ return (
139
+ <div className="h-screen w-screen font-sans overflow-hidden bg-background">
140
+ {showConsentModal && <LocalStorageConsentModal onAccept={handleAcceptConsent} onDecline={handleDeclineConsent} />}
141
+ <div className="relative flex h-full w-full">
142
+ <LeftSidebar items={sidebarItems} activeView={state.activeView} onNavigate={handleViewChange} />
143
+ <div className="flex-1 flex min-w-0">
144
+ <div className="flex-1 flex flex-col min-w-0">
145
+ <main className="relative flex-1 min-w-0 bg-surface/50 overflow-y-auto">
146
+ <ErrorBoundary>
147
+ <Suspense fallback={<LoadingIndicator />}>
148
+ <div key={activeView} className="fade-in w-full h-full">
149
+ <ActiveComponent {...viewProps} />
150
+ </div>
151
+ </Suspense>
152
+ </ErrorBoundary>
153
+ <DownloadManager />
154
+ </main>
155
+ <StatusBar bgImageStatus="loaded" />
156
+ </div>
157
+ </div>
158
+ <CommandPalette isOpen={isCommandPaletteOpen} onClose={() => setCommandPaletteOpen(false)} onSelect={handleViewChange} />
159
+ </div>
160
+ </div>
161
+ );
162
+ };
163
+
164
+ export default App;
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Build Stage
2
+ FROM node:18-alpine AS build
3
+ WORKDIR /app
4
+ COPY package*.json ./
5
+ RUN npm install
6
+ COPY . .
7
+ RUN npm run build
8
+
9
+ # Production Stage
10
+ FROM nginx:stable-alpine AS production
11
+ COPY --from=build /app/build /usr/share/nginx/html
12
+ EXPOSE 80
13
+ CMD ["nginx", "-g", "daemon off;"]
README.md CHANGED
@@ -1,11 +1,52 @@
1
- ---
2
- title: '0'
3
- emoji: 🐢
4
- colorFrom: blue
5
- colorTo: red
6
- sdk: docker
7
- pinned: false
8
- license: other
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DevCore AI Toolkit
2
+
3
+ DevCore is a developer-centric web application designed to showcase the power of AI in the development process. It's a static application that can be deployed to any modern hosting provider.
4
+
5
+ ## Key Features
6
+
7
+ - **Purely Static**: Runs entirely in the browser with no server backend required.
8
+ - **Easy Deployment**: Deploy to any static hosting provider like Hugging Face Spaces, Vercel, or Netlify.
9
+ - **AI Feature Builder**: Describe a new UI component, and the AI will generate the TSX/JSX code, unit tests, and a conventional commit message.
10
+ - **AI Code Explainer**: Paste any code snippet and get a detailed, easy-to-understand explanation and a visual flowchart generated by Gemini.
11
+ - **Comprehensive Tooling**: Includes a RegEx Sandbox, Snippet Vault, Code Migrator, and dozens of other AI-powered and simulated developer tools.
12
+
13
+ ## Local Development Setup
14
+
15
+ **Prerequisites:** [Node.js](https://nodejs.org/)
16
+
17
+ 1. **Clone the repository.**
18
+
19
+ 2. **Install dependencies:**
20
+ ```bash
21
+ npm install
22
+ ```
23
+
24
+ 3. **Set up your local environment variables:**
25
+ Create a file named `.env.local` in the root of the project and add your Gemini API key:
26
+ ```
27
+ GEMINI_API_KEY=your_gemini_api_key_here
28
+ ```
29
+
30
+ 4. **Run the development server:**
31
+ ```bash
32
+ npm run dev
33
+ ```
34
+ The application will be available at `http://localhost:5173`.
35
+
36
+ ## Deployment
37
+
38
+ This is a static web application that calls the Gemini API directly from the client. To deploy it, you need to:
39
+
40
+ 1. **Build the Project**:
41
+ ```bash
42
+ npm run build
43
+ ```
44
+ This creates a `web` directory with your static app.
45
+
46
+ 2. **Set Environment Variable**:
47
+ Your hosting provider (like Hugging Face Spaces, Vercel, Netlify, etc.) needs to have the `GEMINI_API_KEY` environment variable set during the build process.
48
+ - **Name**: `GEMINI_API_KEY`
49
+ - **Value**: Your actual Gemini API key.
50
+
51
+ 3. **Deploy**:
52
+ Deploy the contents of the `web` directory as a static site. Ensure your hosting provider's build command is `npm run build`.
constants.ts ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import {
3
+ CommandCenterIcon, CodeExplainerIcon, FeatureBuilderIcon, CodeMigratorIcon, ThemeDesignerIcon, SnippetVaultIcon,
4
+ DevNotesIcon, UnitTestGeneratorIcon, CommitGeneratorIcon, GitLogAnalyzerIcon, ConcurrencyAnalyzerIcon, RegexSandboxIcon,
5
+ PromptCraftPadIcon, CodeFormatterIcon, JsonTreeIcon, CssGridEditorIcon, SchemaDesignerIcon, PwaManifestEditorIcon,
6
+ MarkdownSlidesIcon, ScreenshotToComponentIcon, FontPreviewIcon, SvgPathEditorIcon, StyleTransferIcon, CodingChallengeIcon,
7
+ FontPairingIcon, CodeReviewBotIcon, PrSummaryGeneratorIcon, ChangelogGeneratorIcon, CronJobBuilderIcon, MoodboardIcon,
8
+ AsyncCallTreeIcon, AudioToCodeIcon, CodeDiffGhostIcon, CodeSpellCheckerIcon, ColorPaletteGeneratorIcon, LogicFlowBuilderIcon,
9
+ MetaTagEditorIcon, NetworkVisualizerIcon, PrGeneratorIcon, ResponsiveTesterIcon, SassCompilerIcon, ImageGeneratorIcon, XbrlConverterIcon
10
+ } from './components/icons/CustomFeatureIcons.tsx';
11
+
12
+ export const CHROME_VIEW_IDS = ['features-list'] as const;
13
+
14
+ export const SLOTS = ['Core', 'AI Tools', 'Frontend', 'Testing', 'Database', 'Productivity'] as const;
15
+ export type SlotCategory = typeof SLOTS[number];
16
+
17
+ export const FEATURE_CATEGORIES = ['Core', 'AI Tools', 'Frontend', 'Testing', 'Database', 'Data', 'Productivity', 'Git', 'Deployment', 'Security', 'Workflow'] as const;
18
+ export type FeatureCategory = typeof FEATURE_CATEGORIES[number];
19
+
20
+ // This is the raw data, to be "compiled" by features/index.ts
21
+ export const RAW_FEATURES = [
22
+ { id: "ai-command-center", name: "AI Command Center", description: "Use natural language to navigate and control the toolkit.", icon: React.createElement(CommandCenterIcon), category: "Core" },
23
+ { id: "ai-image-generator", name: "AI Image Generator", description: "Generate high-quality images from a text prompt.", icon: React.createElement(ImageGeneratorIcon), category: "AI Tools" },
24
+ { id: "ai-code-explainer", name: "AI Code Explainer", description: "Get a structured analysis of code, including complexity.", icon: React.createElement(CodeExplainerIcon), category: "AI Tools" },
25
+ { id: "ai-feature-builder", name: "AI Feature Builder", description: "Generate code, tests, and commit messages.", icon: React.createElement(FeatureBuilderIcon), category: "AI Tools" },
26
+ { id: "ai-code-migrator", name: "AI Code Migrator", description: "Translate code between languages & frameworks.", icon: React.createElement(CodeMigratorIcon), category: "AI Tools" },
27
+ { id: "theme-designer", name: "AI Theme Designer", description: "Generate, fine-tune, and export UI color themes from a text description.", icon: React.createElement(ThemeDesignerIcon), category: "AI Tools" },
28
+ { id: "portable-snippet-vault", name: "Snippet Vault", description: "Store, search, tag, and enhance reusable code snippets with AI.", icon: React.createElement(SnippetVaultIcon), category: "Productivity" },
29
+ { id: "dev-notes-sticky-panel", name: "Dev Notes Sticky Panel", description: "Sticky notes with AI summarization.", icon: React.createElement(DevNotesIcon), category: "Productivity" },
30
+ { id: "ai-unit-test-generator", name: "AI Unit Test Generator", description: "Generate unit tests from source code.", icon: React.createElement(UnitTestGeneratorIcon), category: "AI Tools" },
31
+ { id: "ai-commit-generator", name: "AI Commit Message Generator", description: "Smart, conventional commits via AI.", icon: React.createElement(CommitGeneratorIcon), category: "AI Tools" },
32
+ { id: "visual-git-tree", name: "Visual Git Tree", description: "Visually trace your git commit history with an interactive graph and an AI-powered summary.", icon: React.createElement(GitLogAnalyzerIcon), category: "Git" },
33
+ { id: "worker-thread-debugger", name: "AI Concurrency Analyzer", description: "Analyze JS for Web Worker issues like race conditions.", icon: React.createElement(ConcurrencyAnalyzerIcon), category: "Testing" },
34
+ { id: "regex-sandbox", name: "RegEx Sandbox", description: "Visually test regular expressions, generate them with AI, and inspect match groups.", icon: React.createElement(RegexSandboxIcon), category: "Testing" },
35
+ { id: "prompt-craft-pad", name: "Prompt Craft Pad", description: "Save, edit, and manage your custom AI prompts with variable testing.", icon: React.createElement(PromptCraftPadIcon), category: "AI Tools" },
36
+ { id: "linter-formatter", name: "AI Code Formatter", description: "AI-powered, real-time code formatting.", icon: React.createElement(CodeFormatterIcon), category: "Core" },
37
+ { id: "json-tree-navigator", name: "JSON Tree Navigator", description: "Navigate large JSON objects as a collapsible tree.", icon: React.createElement(JsonTreeIcon), category: "Core" },
38
+ { id: "xbrl-converter", name: "XBRL Converter", description: "Convert JSON data to a simplified XBRL-like XML format using AI.", icon: React.createElement(XbrlConverterIcon), category: "Data" },
39
+ { id: "css-grid-editor", name: "CSS Grid Visual Editor", description: "Drag-based layout builder for CSS Grid.", icon: React.createElement(CssGridEditorIcon), category: "Frontend" },
40
+ { id: "schema-designer", name: "Schema Designer", description: "Visually design a database schema with a drag-and-drop interface and SQL export.", icon: React.createElement(SchemaDesignerIcon), category: "Database" },
41
+ { id: "pwa-manifest-editor", name: "PWA Manifest Editor", description: "Configure and preview Progressive Web App manifests with a home screen simulator.", icon: React.createElement(PwaManifestEditorIcon), category: "Frontend" },
42
+ { id: "markdown-slides-generator", name: "Markdown Slides", description: "Turn markdown into a fullscreen presentation with an interactive overlay.", icon: React.createElement(MarkdownSlidesIcon), category: "Productivity" },
43
+ { id: "screenshot-to-component", name: "Screenshot-to-Component", description: "Turn UI screenshots into functional code via paste or upload.", icon: React.createElement(ScreenshotToComponentIcon), category: "AI Tools" },
44
+ { id: "font-preview-picker", name: "Font Preview & Picker", description: "Preview fonts and get CSS import rules.", icon: React.createElement(FontPreviewIcon), category: "Frontend" },
45
+ { id: "svg-path-editor", name: "SVG Path Editor", description: "Visually create and manipulate SVG path data with an interactive canvas.", icon: React.createElement(SvgPathEditorIcon), category: "Frontend" },
46
+ { id: "ai-style-transfer", name: "AI Code Style Transfer", description: "Rewrite code to match a specific style guide.", icon: React.createElement(StyleTransferIcon), category: "AI Tools" },
47
+ { id: "ai-coding-challenge", name: "AI Coding Challenge Generator", description: "Generate unique coding exercises.", icon: React.createElement(CodingChallengeIcon), category: "AI Tools" },
48
+ { id: "font-pairing-tool", name: "Font Pairing Tool", description: "Suggest and preview font combinations.", icon: React.createElement(FontPairingIcon), category: "Frontend" },
49
+ { id: "code-review-bot", name: "AI Code Review Bot", description: "Get an automated code review from an AI.", icon: React.createElement(CodeReviewBotIcon), category: "AI Tools" },
50
+ { id: "pr-summary-generator", name: "AI PR Summary Generator", description: "Generate a structured PR summary from code diffs, ready to copy as markdown.", icon: React.createElement(PrSummaryGeneratorIcon), category: "AI Tools" },
51
+ { id: "changelog-generator", name: "AI Changelog Generator", description: "Auto-build changelogs from raw git logs.", icon: React.createElement(ChangelogGeneratorIcon), category: "Git" },
52
+ { id: "cron-job-builder", name: "AI Cron Job Builder", description: "Visually tool to configure cron jobs, with AI.", icon: React.createElement(CronJobBuilderIcon), category: "Deployment" },
53
+ { id: "project-moodboard", name: "Project Moodboard", description: "Organize ideas with interactive, multi-colored sticky notes.", icon: React.createElement(MoodboardIcon), category: "Productivity" },
54
+ { id: "async-call-tree-viewer", name: "Async Call Tree Viewer", description: "Visualize a tree of asynchronous function calls from JSON data.", icon: React.createElement(AsyncCallTreeIcon), category: "Testing" },
55
+ { id: "audio-to-code", name: "AI Audio-to-Code", description: "Speak your programming ideas and watch them turn into code.", icon: React.createElement(AudioToCodeIcon), category: "AI Tools" },
56
+ { id: "code-diff-ghost", name: "Code Diff Ghost", description: "Visualize code changes with a 'ghost typing' effect.", icon: React.createElement(CodeDiffGhostIcon), category: "Git" },
57
+ { id: "code-spell-checker", name: "Code Spell Checker", description: "A spell checker that finds common typos in code.", icon: React.createElement(CodeSpellCheckerIcon), category: "Testing" },
58
+ { id: "color-palette-generator", name: "AI Color Palette Generator", description: "Pick a base color and let Gemini design a beautiful palette.", icon: React.createElement(ColorPaletteGeneratorIcon), category: "Frontend" },
59
+ { id: "logic-flow-builder", name: "Logic Flow Builder", description: "A visual tool for building application logic flows.", icon: React.createElement(LogicFlowBuilderIcon), category: "Workflow" },
60
+ { id: "meta-tag-editor", name: "Meta Tag Editor", description: "Generate SEO/social media meta tags with a live social card preview.", icon: React.createElement(MetaTagEditorIcon), category: "Frontend" },
61
+ { id: "network-visualizer", name: "Network Visualizer", description: "Inspect network resources with a summary and visual waterfall chart.", icon: React.createElement(NetworkVisualizerIcon), category: "Testing" },
62
+ { id: "pr-generator", name: "PR Generator", description: "Draft a professional pull request from a structured template.", icon: React.createElement(PrGeneratorIcon), category: "Git" },
63
+ { id: "responsive-tester", name: "Responsive Tester", description: "Preview your web pages at different screen sizes and custom resolutions.", icon: React.createElement(ResponsiveTesterIcon), category: "Frontend" },
64
+ { id: "sass-scss-compiler", name: "SASS/SCSS Compiler", description: "A real-time SASS/SCSS to CSS compiler.", icon: React.createElement(SassCompilerIcon), category: "Frontend" },
65
+ ];
66
+
67
+ export const ALL_FEATURE_IDS = RAW_FEATURES.map(f => f.id);
globals.d.ts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // globals.d.ts
2
+ declare global {
3
+ /**
4
+ * Loads the Pyodide WebAssembly module.
5
+ * @param config Optional configuration for Pyodide.
6
+ */
7
+ function loadPyodide(config?: { indexURL?: string }): Promise<any>;
8
+
9
+ interface Window {
10
+ google?: {
11
+ accounts: {
12
+ id: {
13
+ initialize: (config: { client_id: string; callback: (response: any) => void; }) => void;
14
+ renderButton: (parent: HTMLElement, options: any) => void;
15
+ disableAutoSelect: () => void;
16
+ prompt: () => void;
17
+ };
18
+ };
19
+ };
20
+ }
21
+ }
22
+
23
+ // This export statement is required to make the file a module.
24
+ export {};
index.css ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /* Custom global styles */
6
+ body {
7
+ -webkit-font-smoothing: antialiased;
8
+ -moz-osx-font-smoothing: grayscale;
9
+ background-image: linear-gradient(135deg, #FFFFFF 0%, #F5F7FA 100%);
10
+ }
11
+
12
+ #root {
13
+ position: relative;
14
+ z-index: 1;
15
+ }
16
+
17
+ #root::before {
18
+ content: 'CitiBank demo business inc';
19
+ position: fixed;
20
+ top: 50%;
21
+ left: 50%;
22
+ transform: translate(-50%, -50%) rotate(-30deg);
23
+ font-family: theme('fontFamily.serif');
24
+ font-size: clamp(2rem, 8vw, 6rem); /* Responsive font size */
25
+ font-weight: bold;
26
+ color: theme('colors.gold');
27
+ opacity: 0.08;
28
+ pointer-events: none;
29
+ z-index: -1;
30
+ white-space: nowrap;
31
+ }
32
+
33
+ h1, h2, h3, h4, h5, h6 {
34
+ @apply font-serif text-text-primary;
35
+ }
36
+
37
+ h1 {
38
+ @apply text-text-primary;
39
+ }
40
+
41
+ /* Update primary buttons for a professional look */
42
+ .btn-primary {
43
+ @apply bg-primary text-text-on-primary font-bold rounded-md hover:opacity-90 transition-all disabled:opacity-50 shadow-md;
44
+ }
45
+
46
+ /* Custom scrollbars for the new light theme */
47
+ ::-webkit-scrollbar {
48
+ width: 8px;
49
+ height: 8px;
50
+ }
51
+ ::-webkit-scrollbar-track {
52
+ @apply bg-gray-100;
53
+ }
54
+ ::-webkit-scrollbar-thumb {
55
+ @apply bg-gray-400 rounded;
56
+ }
57
+ ::-webkit-scrollbar-thumb:hover {
58
+ @apply bg-gray-500;
59
+ }
60
+
61
+ /* Base transitions for interactive elements */
62
+ button, a, input, textarea, select {
63
+ transition: all 0.2s ease-in-out;
64
+ }
65
+
66
+ /* Keyframe Animations */
67
+ @keyframes fadeIn {
68
+ from { opacity: 0; }
69
+ to { opacity: 1; }
70
+ }
71
+
72
+ @keyframes shake {
73
+ 10%, 90% { transform: translateX(-1px); }
74
+ 20%, 80% { transform: translateX(2px); }
75
+ 30%, 50%, 70% { transform: translateX(-3px); }
76
+ 40%, 60% { transform: translateX(3px); }
77
+ }
78
+
79
+ @keyframes pop-in {
80
+ from {
81
+ opacity: 0;
82
+ transform: scale(0.95) translateY(10px);
83
+ }
84
+ to {
85
+ opacity: 1;
86
+ transform: scale(1) translateY(0);
87
+ }
88
+ }
89
+
90
+ .fade-in { animation: fadeIn 0.5s ease-in-out forwards; }
91
+ .animate-shake { animation: shake 0.4s ease-in-out; }
92
+ .animate-pop-in { animation: pop-in 0.3s ease-out forwards; }
93
+
94
+ /* For hiding scrollbar but keeping functionality */
95
+ .no-scrollbar::-webkit-scrollbar { display: none; }
96
+ .no-scrollbar {
97
+ -ms-overflow-style: none;
98
+ scrollbar-width: none;
99
+ scroll-behavior: smooth;
100
+ }
index.html ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="./vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>DevCore AI Toolkit</title>
8
+
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link href="https://fonts.googleapis.com/css2?family=EB+Garamond:wght@700&family=Inter:wght@400;500;700&family=Great+Vibes&display=swap" rel="stylesheet">
12
+ <script src="https://accounts.google.com/gsi/client" async defer></script>
13
+ <script type="importmap">
14
+ {
15
+ "imports": {
16
+ "react": "https://esm.sh/react@^19.1.1",
17
+ "react-dom/": "https://esm.sh/react-dom@^19.1.1/",
18
+ "react/": "https://esm.sh/react@^19.1.1/",
19
+ "path": "https://esm.sh/path@^0.12.7",
20
+ "vite": "https://esm.sh/vite@^7.1.1",
21
+ "url": "https://esm.sh/url@^0.11.4",
22
+ "@google/genai": "https://esm.sh/@google/genai@^1.13.0",
23
+ "marked": "https://esm.sh/marked@^16.1.2",
24
+ "diff": "https://esm.sh/diff@^8.0.2",
25
+ "react-colorful": "https://esm.sh/react-colorful@^5.6.1",
26
+ "idb": "https://esm.sh/idb@^8.0.3",
27
+ "jszip": "https://esm.sh/jszip@^3.10.1"
28
+ }
29
+ }
30
+ </script>
31
+ <link rel="stylesheet" href="/index.css">
32
+ </head>
33
+ <body class="bg-background text-text-primary font-sans">
34
+ <div id="root"></div>
35
+ <script type="module" src="./index.tsx"></script>
36
+ <script type="module" src="/index.tsx"></script>
37
+ </body>
38
+ </html>
index.tsx ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @license
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import React from 'react';
7
+ import ReactDOM from 'react-dom/client';
8
+ import App from './App.tsx';
9
+ import { GlobalStateProvider } from './contexts/GlobalStateContext.tsx';
10
+ import './index.css';
11
+
12
+ const rootElement = document.getElementById('root');
13
+ if (!rootElement) {
14
+ throw new Error("Could not find root element to mount to");
15
+ }
16
+
17
+ const root = ReactDOM.createRoot(rootElement);
18
+ root.render(
19
+ <React.StrictMode>
20
+ <GlobalStateProvider>
21
+ <App />
22
+ </GlobalStateProvider>
23
+ </React.StrictMode>
24
+ );
metadata.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "requestFramePermissions": [
3
+ "microphone"
4
+ ],
5
+ "name": "0",
6
+ "description": "",
7
+ "prompt": ""
8
+ }
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "devcore-ai-toolkit",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "@google/genai": "^1.12.0",
13
+ "diff": "^5.2.0",
14
+ "idb": "^8.0.0",
15
+ "jszip": "^3.10.1",
16
+ "marked": "^13.0.2",
17
+ "react": "^18.2.0",
18
+ "react-colorful": "^5.6.1",
19
+ "react-dom": "^18.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/diff": "^5.2.1",
23
+ "@types/jszip": "^3.4.1",
24
+ "@types/marked": "^6.0.0",
25
+ "@types/node": "^20.14.9",
26
+ "@types/react": "^18.2.0",
27
+ "@types/react-dom": "^18.2.0",
28
+ "autoprefixer": "^10.4.19",
29
+ "postcss": "^8.4.38",
30
+ "tailwindcss": "^3.4.3",
31
+ "typescript": "^5.5.2",
32
+ "vite": "^5.2.0"
33
+ }
34
+ }
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
services ADDED
File without changes
tailwind.config.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: [
4
+ "./index.html",
5
+ "./**/*.{js,ts,jsx,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {
9
+ fontFamily: {
10
+ sans: ['Inter', 'sans-serif'],
11
+ serif: ['"EB Garamond"', 'serif'],
12
+ calligraphy: ['"Great Vibes"', 'cursive'],
13
+ },
14
+ colors: {
15
+ 'primary': '#0047AB', // Cobalt Blue
16
+ 'background': '#F5F7FA', // Light silver-blue
17
+ 'surface': '#FFFFFF',
18
+ 'text': {
19
+ 'primary': '#111827', // Gray 900
20
+ 'secondary': '#6B7280', // Gray 500
21
+ 'on-primary': '#FFFFFF',
22
+ },
23
+ 'border': '#E5E7EB', // Gray 200
24
+ 'gold': '#B8860B', // DarkGoldenRod - better for watermark
25
+ },
26
+ boxShadow: {
27
+ 'focus-primary': '0 0 0 3px rgba(0, 71, 171, 0.4)',
28
+ 'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
29
+ },
30
+ },
31
+ },
32
+ plugins: [],
33
+ }
tsconfig.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {
3
+ "compilerOptions": {
4
+ "target": "ES2022",
5
+ "experimentalDecorators": true,
6
+ "useDefineForClassFields": false,
7
+ "module": "ES2022",
8
+ "lib": [
9
+ "ES2022",
10
+ "DOM",
11
+ "DOM.Iterable"
12
+ ],
13
+ "skipLibCheck": true,
14
+ "moduleResolution": "bundler",
15
+ "isolatedModules": true,
16
+ "moduleDetection": "force",
17
+ "allowJs": true,
18
+ "jsx": "react-jsx",
19
+ "paths": {
20
+ "@/*": [
21
+ "./*"
22
+ ]
23
+ },
24
+ "allowImportingTsExtensions": true,
25
+ "noEmit": true
26
+ }
27
+ }
tsconfig.server.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ {
3
+ "compilerOptions": {
4
+ "target": "ES2022",
5
+ "module": "CommonJS",
6
+ "moduleResolution": "node",
7
+ "outDir": "./hf-api",
8
+ "esModuleInterop": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "strict": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": [
14
+ "hf-api/server.ts"
15
+ ]
16
+ }
types.ts ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type React from 'react';
2
+ import { CHROME_VIEW_IDS } from './constants.ts';
3
+
4
+ export type ChromeViewType = typeof CHROME_VIEW_IDS[number];
5
+ export type FeatureId = string;
6
+
7
+ export interface Feature {
8
+ id: FeatureId;
9
+ name: string;
10
+ description: string;
11
+ icon: React.ReactNode;
12
+ category: string;
13
+ component: React.FC<any>;
14
+ aiConfig?: {
15
+ model: string;
16
+ systemInstruction?: string;
17
+ };
18
+ }
19
+
20
+ export type ViewType = FeatureId | ChromeViewType;
21
+
22
+ export interface GeneratedFile {
23
+ filePath: string;
24
+ content: string;
25
+ description: string;
26
+ }
27
+
28
+ export interface SidebarItem {
29
+ id: string;
30
+ label: string;
31
+ icon: React.ReactNode;
32
+ view: ViewType;
33
+ props?: any;
34
+ action?: () => void;
35
+ }
36
+
37
+ export interface StructuredPrSummary {
38
+ title: string;
39
+ summary: string;
40
+ changes: string[];
41
+ }
42
+
43
+ export interface User {
44
+ name: string;
45
+ email: string;
46
+ picture: string;
47
+ }
vite.config.ts ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import path from 'path';
3
+ import { defineConfig, loadEnv } from 'vite';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+
8
+ export default defineConfig(({ mode }) => {
9
+ const env = loadEnv(mode, '.', '');
10
+
11
+ return {
12
+ define: {
13
+ // The API key is injected into the app during the build process.
14
+ // It's crucial that this variable is set in your deployment environment.
15
+ 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
16
+ },
17
+ resolve: {
18
+ alias: {
19
+ '@': path.resolve(__dirname, '.'),
20
+ }
21
+ },
22
+ build: {
23
+ outDir: 'web', // Emit assets to a 'web' directory.
24
+ sourcemap: true, // Enable source maps for easier debugging in production.
25
+ rollupOptions: {
26
+ output: {
27
+ // Improve caching by splitting vendor code into separate chunks.
28
+ manualChunks(id) {
29
+ if (id.includes('node_modules')) {
30
+ return id.toString().split('node_modules/')[1].split('/')[0].toString();
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ };
37
+ });