Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
6424600
Consolidate prompts into TypeScript system and remove unused files
Gerome-Elassaad Dec 4, 2025
a9d2c6e
Remove framework restrictions and add support for all frameworks
Gerome-Elassaad Dec 4, 2025
4a4dfe6
Add universal base prompt with framework-agnostic standards
Gerome-Elassaad Dec 4, 2025
973fbc3
Add universal framework-agnostic system prompt
Gerome-Elassaad Dec 4, 2025
8d8f37d
Add chat validation schemas and typed error handling
Gerome-Elassaad Dec 4, 2025
58f111d
Integrate validation and improved error handling in chat API
Gerome-Elassaad Dec 4, 2025
3df88f8
Add ArtifactsStore for artifacts management
Gerome-Elassaad Dec 4, 2025
4020b25
Remove duplicate ArtifactsStore and clean up artifact management
Gerome-Elassaad Dec 4, 2025
a8c2753
Fix Vite dynamic import warnings by using static imports
Gerome-Elassaad Dec 4, 2025
3b64835
Reposition workbench to be just below headers on chat page
Gerome-Elassaad Dec 4, 2025
d14d141
Restore original chat layout - workbench and chat side-by-side
Gerome-Elassaad Dec 4, 2025
fc4564a
Fix icon buttons for light/dark mode compatibility
Gerome-Elassaad Dec 4, 2025
4070cc2
Enhance prompt engineering system to detect design schemes and build …
Gerome-Elassaad Dec 4, 2025
fa68fd5
Fix styling tab layout - replace dynamic classes with inline styles a…
Gerome-Elassaad Dec 4, 2025
c40893e
Fix dark/light mode compatibility issues across SCSS files
Gerome-Elassaad Dec 4, 2025
cf91f57
Fix dark mode design system - improve depth contrast and dropdown vis…
Gerome-Elassaad Dec 4, 2025
2daa934
updated design scheme & context for chats
Gerome-Elassaad Dec 4, 2025
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
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pnpm-lock.yaml
.astro
2 changes: 1 addition & 1 deletion app/components/@settings/core/AvatarDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const AvatarDropdown = ({ onSelectTab }: AvatarDropdownProps) => {
<DropdownMenu.Content
className={classNames(
'min-w-[240px] z-[250]',
'bg-white dark:bg-[#141414]',
'bg-white dark:bg-codinit-elements-background-depth-3',
'rounded-lg shadow-lg',
'border border-gray-200/50 dark:border-gray-800/50',
'animate-in fade-in-0 zoom-in-95',
Expand Down
5 changes: 1 addition & 4 deletions app/components/@settings/tabs/event-logs/EventLogsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,7 @@ const LogEntryItem = ({ log, isExpanded: forceExpanded, use24Hour, showTimestamp
<div className="text-sm font-medium text-gray-900 dark:text-white">{log.message}</div>
{log.details && (
<>
<button
onClick={() => setLocalExpanded(!localExpanded)}
className="text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
>
<button onClick={() => setLocalExpanded(!localExpanded)}>
{localExpanded ? 'Hide' : 'Show'} Details
</button>
{localExpanded && renderDetails(log.details)}
Expand Down
133 changes: 35 additions & 98 deletions app/components/chat/AssistantMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { memo, Fragment } from 'react';
import { memo } from 'react';
import { Markdown } from './Markdown';
import type { JSONValue } from 'ai';
import Popover from '~/components/ui/Popover';
import { workbenchStore } from '~/lib/stores/workbench';
import { WORK_DIR } from '~/utils/constants';
import { ContextIndicator } from './ContextIndicator';
import WithTooltip from '~/components/ui/Tooltip';

interface AssistantMessageProps {
Expand All @@ -14,30 +12,6 @@ interface AssistantMessageProps {
onFork?: (messageId: string) => void;
}

function openArtifactInWorkbench(filePath: string) {
filePath = normalizedFilePath(filePath);

if (workbenchStore.currentView.get() !== 'code') {
workbenchStore.currentView.set('code');
}

workbenchStore.setSelectedFile(`${WORK_DIR}/${filePath}`);
}

function normalizedFilePath(path: string) {
let normalizedPath = path;

if (normalizedPath.startsWith(WORK_DIR)) {
normalizedPath = path.replace(WORK_DIR, '');
}

if (normalizedPath.startsWith('/')) {
normalizedPath = normalizedPath.slice(1);
}

return normalizedPath;
}

export const AssistantMessage = memo(({ content, annotations, messageId, onRewind, onFork }: AssistantMessageProps) => {
const filteredAnnotations = (annotations?.filter(
(annotation: JSONValue) => annotation && typeof annotation === 'object' && Object.keys(annotation).includes('type'),
Expand All @@ -63,78 +37,41 @@ export const AssistantMessage = memo(({ content, annotations, messageId, onRewin

return (
<div className="overflow-hidden w-full">
<>
<div className=" flex gap-2 items-center text-sm text-codinit-elements-textSecondary mb-2">
{(codeContext || chatSummary) && (
<Popover side="right" align="start" trigger={<div className="i-ph:info" />}>
{chatSummary && (
<div className="max-w-chat">
<div className="summary max-h-96 flex flex-col">
<h2 className="border border-codinit-elements-borderColor rounded-md p4">Summary</h2>
<div style={{ zoom: 0.7 }} className="overflow-y-auto m4">
<Markdown>{chatSummary}</Markdown>
</div>
</div>
{codeContext && (
<div className="code-context flex flex-col p4 border border-codinit-elements-borderColor rounded-md">
<h2>Context</h2>
<div className="flex gap-4 mt-4 codinit" style={{ zoom: 0.6 }}>
{codeContext.map((x) => {
const normalized = normalizedFilePath(x);
return (
<Fragment key={normalized}>
<code
className="bg-codinit-elements-artifacts-inlineCode-background text-codinit-elements-artifacts-inlineCode-text px-1.5 py-1 rounded-md text-codinit-elements-item-contentAccent hover:underline cursor-pointer"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
openArtifactInWorkbench(normalized);
}}
>
{normalized}
</code>
</Fragment>
);
})}
</div>
</div>
)}
</div>
)}
<div className="context"></div>
</Popover>
{(codeContext || chatSummary || usage) && (
<ContextIndicator
files={codeContext}
summary={chatSummary}
tokenCount={
usage
? {
prompt: usage.promptTokens,
completion: usage.completionTokens,
total: usage.totalTokens,
}
: undefined
}
/>
)}
{(onRewind || onFork) && messageId && (
<div className="flex gap-2 mb-2 justify-end">
{onRewind && (
<WithTooltip tooltip="Revert to this message">
<button
onClick={() => onRewind(messageId)}
className="i-ph:arrow-u-up-left text-lg text-codinit-elements-textSecondary hover:text-codinit-elements-textPrimary transition-colors"
/>
</WithTooltip>
)}
{onFork && (
<WithTooltip tooltip="Fork chat from this message">
<button
onClick={() => onFork(messageId)}
className="i-ph:git-fork text-lg text-codinit-elements-textSecondary hover:text-codinit-elements-textPrimary transition-colors"
/>
</WithTooltip>
)}
<div className="flex w-full items-center justify-between">
{usage && (
<div>
Tokens: {usage.totalTokens} (prompt: {usage.promptTokens}, completion: {usage.completionTokens})
</div>
)}
{(onRewind || onFork) && messageId && (
<div className="flex gap-2 flex-col lg:flex-row ml-auto">
{onRewind && (
<WithTooltip tooltip="Revert to this message">
<button
onClick={() => onRewind(messageId)}
key="i-ph:arrow-u-up-left"
className="i-ph:arrow-u-up-left text-xl text-codinit-elements-textSecondary hover:text-codinit-elements-textPrimary transition-colors"
/>
</WithTooltip>
)}
{onFork && (
<WithTooltip tooltip="Fork chat from this message">
<button
onClick={() => onFork(messageId)}
key="i-ph:git-fork"
className="i-ph:git-fork text-xl text-codinit-elements-textSecondary hover:text-codinit-elements-textPrimary transition-colors"
/>
</WithTooltip>
)}
</div>
)}
</div>
</div>
</>
)}
<Markdown html>{content}</Markdown>
</div>
);
Expand Down
32 changes: 16 additions & 16 deletions app/components/chat/BaseChat.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@
._Shadow_8mvus_1 {
background: linear-gradient(
to top,
#0f0f0f 0%,
rgba(15, 15, 15, 0.987) 8.1%,
rgba(15, 15, 15, 0.951) 15.5%,
rgba(15, 15, 15, 0.896) 22.5%,
rgba(15, 15, 15, 0.825) 29%,
rgba(15, 15, 15, 0.741) 35.3%,
rgba(15, 15, 15, 0.648) 41.2%,
rgba(15, 15, 15, 0.55) 47.1%,
rgba(15, 15, 15, 0.45) 52.9%,
rgba(15, 15, 15, 0.352) 58.8%,
rgba(15, 15, 15, 0.259) 64.7%,
rgba(15, 15, 15, 0.175) 71%,
rgba(15, 15, 15, 0.104) 77.5%,
rgba(15, 15, 15, 0.049) 84.5%,
rgba(15, 15, 15, 0.013) 91.9%,
rgba(15, 15, 15, 0) 100%
var(--codinit-elements-bg-depth-1) 0%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 98.7%, transparent) 8.1%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 95.1%, transparent) 15.5%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 89.6%, transparent) 22.5%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 82.5%, transparent) 29%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 74.1%, transparent) 35.3%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 64.8%, transparent) 41.2%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 55%, transparent) 47.1%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 45%, transparent) 52.9%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 35.2%, transparent) 58.8%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 25.9%, transparent) 64.7%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 17.5%, transparent) 71%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 10.4%, transparent) 77.5%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 4.9%, transparent) 84.5%,
color-mix(in srgb, var(--codinit-elements-bg-depth-1) 1.3%, transparent) 91.9%,
transparent 100%
);
}

Expand Down
3 changes: 2 additions & 1 deletion app/components/chat/BaseChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ChatHeader } from '~/components/header/ChatHeader';
import { PreviewHeader } from '~/components/workbench/PreviewHeader';
import { CodeModeHeader } from '~/components/workbench/CodeModeHeader';
import { workbenchStore } from '~/lib/stores/workbench';
import { TextShimmer } from '~/components/ui/text-shimmer';
import { classNames } from '~/utils/classNames';
import { PROVIDER_LIST } from '~/utils/constants';
import { Messages } from './Messages.client';
Expand Down Expand Up @@ -632,7 +633,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
<span className="text-codinit-elements-textPrimary"> Deploy</span>
</h1>
<p className="text-md lg:text-xl mb-8 text-codinit-elements-textSecondary animate-fade-in animation-delay-200">
Let your imagination build your next startup idea.
<TextShimmer>Let your imagination build your next startup idea</TextShimmer>
</p>
</div>
)}
Expand Down
86 changes: 58 additions & 28 deletions app/components/chat/ColorSchemeDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
case 'none':
return 'none';
case 'sm':
return '0 1px 2px 0 rgb(0 0 0 / 0.05)';
return '0 1px 2px 0 rgb(0 0 0 / 0.1)';
case 'md':
return '0 4px 6px -1px rgb(0 0 0 / 0.1)';
case 'lg':
Expand Down Expand Up @@ -436,14 +436,48 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
</div>
);

const getBorderRadiusPixels = (key: string): string => {
switch (key) {
case 'none':
return '0px';
case 'sm':
return '0.25rem';
case 'md':
return '0.375rem';
case 'lg':
return '0.5rem';
case 'xl':
return '0.75rem';
case 'full':
return '9999px';
default:
return '0.375rem';
}
};

const getSpacingPixels = (key: string): string => {
switch (key) {
case 'tight':
return '0.5rem';
case 'normal':
return '1rem';
case 'relaxed':
return '1.25rem';
case 'loose':
return '1.5rem';
default:
return '1rem';
}
};

const renderStylingSection = () => (
<div className="space-y-6">
<h3 className="text-lg font-semibold text-codinit-elements-textPrimary flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-codinit-elements-item-contentAccent"></div>
Design Styling
</h3>
<div className="space-y-6 max-h-80 overflow-y-auto pr-4 custom-scrollbar">
<div className="space-y-6 pr-2">
<h3 className="text-lg font-semibold text-codinit-elements-textPrimary flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-codinit-elements-item-contentAccent"></div>
Design Styling
</h3>

<div className="grid grid-cols-3 gap-6">
{/* Border Radius */}
<div className="space-y-3">
<label className="text-sm font-medium text-codinit-elements-textPrimary">Border Radius</label>
Expand All @@ -461,7 +495,8 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
>
<div className="text-center space-y-1">
<div
className={`w-6 h-6 mx-auto rounded-${option.key === 'none' ? 'none' : option.key === 'sm' ? 'sm' : option.key === 'md' ? 'md' : option.key === 'lg' ? 'lg' : option.key === 'xl' ? 'xl' : 'full'} bg-current opacity-80`}
className="w-6 h-6 mx-auto bg-current opacity-80"
style={{ borderRadius: getBorderRadiusPixels(option.key) }}
/>
<div className="text-xs font-medium">{option.label}</div>
</div>
Expand All @@ -483,7 +518,10 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
shadow === option.key
? 'bg-codinit-elements-item-backgroundAccent border-codinit-elements-borderColorActive text-white'
: 'bg-codinit-elements-background-depth-3 dark:bg-codinit-elements-background-depth-3-dark border-codinit-elements-borderColor dark:border-codinit-elements-borderColor-dark hover:border-codinit-elements-borderColorActive text-codinit-elements-textSecondary dark:text-codinit-elements-textSecondary-dark hover:text-codinit-elements-textPrimary dark:hover:text-codinit-elements-textPrimary-dark'
} ${option.key === 'none' ? '' : option.key === 'sm' ? 'shadow-sm' : option.key === 'md' ? 'shadow-md' : option.key === 'lg' ? 'shadow-lg' : 'shadow-xl'}`}
}`}
style={{
boxShadow: shadow === option.key ? getBoxShadow() : 'none',
}}
>
<div className="text-center space-y-1">
<div className="w-6 h-6 mx-auto bg-current rounded opacity-80" />
Expand All @@ -510,10 +548,13 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
}`}
>
<div className="text-center space-y-1">
<div className="flex justify-center space-x-1">
<div className="w-2 h-6 bg-current rounded opacity-80" />
<div className="w-2 h-6 bg-current rounded opacity-80" />
<div className="w-2 h-6 bg-current rounded opacity-80" />
<div
className="flex justify-center items-center opacity-80"
style={{ gap: getSpacingPixels(option.key) }}
>
<div className="w-2 h-6 bg-current rounded" />
<div className="w-2 h-6 bg-current rounded" />
<div className="w-2 h-6 bg-current rounded" />
</div>
<div className="text-xs font-medium">{option.label}</div>
</div>
Expand Down Expand Up @@ -654,27 +695,16 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
{/* Preview Container */}
<div className="flex-1 rounded-xl border border-codinit-elements-borderColor overflow-hidden bg-codinit-elements-background-depth-3">
<div
className="h-full w-full p-6 overflow-y-auto custom-scrollbar"
className="h-full w-full overflow-y-auto custom-scrollbar"
style={{
backgroundColor: palette[mode].background,
color: palette[mode].text,
fontFamily: font.join(', '),
borderRadius:
borderRadius === 'none'
? '0px'
: borderRadius === 'sm'
? '0.25rem'
: borderRadius === 'md'
? '0.375rem'
: borderRadius === 'lg'
? '0.5rem'
: borderRadius === 'xl'
? '0.75rem'
: '1rem',
padding: getSpacingPixels(spacing),
}}
>
{/* Preview Content */}
<div className="space-y-12 mt-4">
<div style={{ display: 'flex', flexDirection: 'column', gap: getSpacingPixels(spacing) }}>
{/* Hero Section */}
<div
className="p-8 text-center"
Expand Down Expand Up @@ -883,7 +913,7 @@ export const ColorSchemeDialog: React.FC<ColorSchemeDialogProps> = ({ setDesignS
className="py-4"
style={{ borderBottom: `1px solid ${palette[mode].accent}` }}
>
<button className="flex w-full items-center justify-between text-left">
<button>
<span
className="text-sm font-medium"
style={{ color: palette[mode].primary, fontFamily: font.join(', ') }}
Expand Down
Loading