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
2 changes: 2 additions & 0 deletions apps/api/src/containers/CustomSandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ export class CustomSandbox extends Sandbox<AppContext['Bindings']> {
}
})();

console.log('runner', runner);
await runner.setup();
const result = await runner.execute();
console.log('result', result);
Comment thread
RogutKuba marked this conversation as resolved.
this.ctx.waitUntil(runner.cleanup());

return result;
Expand Down
15 changes: 7 additions & 8 deletions apps/api/src/containers/images/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ RUN uv pip install --system --break-system-packages \
find /usr -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true && \
find /usr -type f -name "*.pyc" -delete

# Install Node.js global packages
RUN npm install -g \
typescript \
ts-node \
@types/node && \
npm cache clean --force

# Install Ruby gems (minimal set)
RUN gem install bundler --no-document
Expand Down Expand Up @@ -112,9 +106,14 @@ RUN uv pip install --system --break-system-packages \
find /usr -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true && \
find /usr -type f -name "*.pyc" -delete

# Install Node.js global packages in runtime stage
RUN npm install -g \
typescript \
ts-node \
@types/node && \
npm cache clean --force

# Copy language installations
COPY --from=builder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/lib/ruby/gems /usr/lib/ruby/gems
COPY --from=builder /usr/local/bin/bundle* /usr/local/bin/
COPY --from=builder /root/go /root/go
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/routes/room/publicRoom.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export const publicRoomRouter = new Hono<AppContext>()

const codeRunService = new CodeRunService(ctx);

console.log('running code', code, language);
const result = await codeRunService.runCode({ roomId, code, language });

return ctx.json(result);
Expand Down
5 changes: 5 additions & 0 deletions apps/api/src/schema/room.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export const RoomLanguageSchema = z.enum([
'go',
'php',
'ruby',

// web frameworks
'react',
'vue',
'svelte',
]);

export const RoomSchema = z.object({
Expand Down
35 changes: 27 additions & 8 deletions apps/api/src/services/CodeRun.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,34 @@ export class CodeRunService {
// this.ctx.executionCtx.waitUntil(roomDo.handleCodeExecutioMessage({ type: 'start' }));

const sandbox = await this.getSandbox(roomId);
const raw = await sandbox.runCode({ language, code });
const result = formatExecOutput(raw);

// // Broadcast execution complete
// this.ctx.executionCtx.waitUntil(
// roomDo.handleCodeExecutioMessage({ type: 'complete', output: result?.stdout || result?.stderr || 'No output from execution' }),
// );

return result;
try {
const raw = await sandbox.runCode({ language, code });

const result = formatExecOutput(raw);
return result;
} catch (error) {
console.error('error', error);
return {
success: false,
timestamp: new Date().toISOString(),
stdout: '',
stderr: 'Error running code',
exitCode: 1,
elapsedTime: -1,
compileTime: undefined,
};
}

// throw new Error('test');
// console.log('result', result);

// // // Broadcast execution complete
// // this.ctx.executionCtx.waitUntil(
// // roomDo.handleCodeExecutioMessage({ type: 'complete', output: result?.stdout || result?.stderr || 'No output from execution' }),
// // );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Error Masking and Debug Line Leak

The runCode method's error handling returns a generic "Error running code" message and hardcoded values, masking original error details. This makes debugging difficult as the client doesn't receive meaningful error information, even though the actual error is logged internally. Additionally, a commented debug line was accidentally committed.

Fix in Cursor Fix in Web

// return result;
}

private async getSandbox(roomId: Id<'room'>) {
Expand Down
5 changes: 3 additions & 2 deletions apps/web/biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"$schema": "../../node_modules/@biomejs/biome/configuration_schema.json",
"extends": "//",
"root": false,
"files": {
"includes": ["src/**/*.ts", "src/**/*.tsx", "!src/routeTree.gen.ts"]
},
"extends": ["../../biome.json"]
}
}
19 changes: 19 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,24 @@
},
"dependencies": {
"@cloudflare/vite-plugin": "^1.7.5",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-cpp": "^6.0.3",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-go": "^6.0.1",
"@codemirror/lang-html": "^6.4.10",
"@codemirror/lang-java": "^6.0.2",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.3.4",
"@codemirror/lang-php": "^6.0.2",
"@codemirror/lang-python": "^6.2.1",
"@codemirror/lang-rust": "^6.0.2",
"@codemirror/state": "^6.5.2",
"@codemirror/theme-one-dark": "^6.1.3",
"@codemirror/view": "^6.38.1",
"@coderscreen/ui": "workspace:^",
"@codesandbox/sandpack-client": "^2.19.8",
"@codesandbox/sandpack-react": "^2.20.0",
"@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-checkbox": "^1.1.4",
Expand Down Expand Up @@ -67,6 +84,7 @@
"better-auth": "^1.2.10",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"codemirror": "^6.0.2",
"date-fns": "^4.1.0",
"dayjs": "^1.11.13",
"devicons-react": "^1.4.1",
Expand All @@ -91,6 +109,7 @@
"tldraw": "^3.14.0",
"unist-util-visit": "^5.0.0",
"wrangler": "^4.22.0",
"y-codemirror.next": "^0.3.5",
"y-monaco": "^0.1.6",
"y-partykit": "^0.0.33",
"y-prosemirror": "^1.3.5",
Expand Down
5 changes: 5 additions & 0 deletions apps/web/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@
margin-top: 5px;
}

/* CODEMIRROR */
.ͼ1.cm-focused {
outline: none;
}

/* Cursor selection background */
.yRemoteSelection {
opacity: 0.5;
Expand Down
46 changes: 39 additions & 7 deletions apps/web/src/components/common/LanguageIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { RoomSchema } from '@coderscreen/api/schema/room';
import BashPlain from 'devicons-react/icons/BashPlain';
import CPlain from 'devicons-react/icons/CPlain';
import CplusplusPlain from 'devicons-react/icons/CplusplusPlain';
import Css3Plain from 'devicons-react/icons/Css3Plain';
import GoPlain from 'devicons-react/icons/GoPlain';
import Html5Plain from 'devicons-react/icons/Html5Plain';
import JavaPlain from 'devicons-react/icons/JavaPlain';
import JavascriptPlain from 'devicons-react/icons/JavascriptPlain';
import JavascriptOriginal from 'devicons-react/icons/JavascriptOriginal';
import MarkdownOriginal from 'devicons-react/icons/MarkdownOriginal';
import NextjsPlain from 'devicons-react/icons/NextjsPlain';
import PhpPlain from 'devicons-react/icons/PhpPlain';
import PythonPlain from 'devicons-react/icons/PythonPlain';
import ReactPlain from 'devicons-react/icons/ReactOriginal';
import RubyPlain from 'devicons-react/icons/RubyPlain';
import RustOriginal from 'devicons-react/icons/RustOriginal';
import SolidjsPlain from 'devicons-react/icons/SolidjsPlain';
import SveltePlain from 'devicons-react/icons/SveltePlain';
import TypescriptPlain from 'devicons-react/icons/TypescriptPlain';
import VueOriginal from 'devicons-react/icons/VuejsOriginal';
import { useMemo } from 'react';
import { cn } from '@/lib/utils';
import { cn, cx } from '@/lib/utils';
import type { FileType } from '@/query/realtime/editor.query';

const BASE_ICON_STYLE = 'h-4 w-4';
const BASE_ICON_STYLE = '';

export const LanguageIcon = ({
language,
className,
}: {
language: RoomSchema['language'];
language: string | FileType;
className?: string;
}) => {
const iconStyle = useMemo(() => cn(BASE_ICON_STYLE, className), [className]);
Expand All @@ -28,7 +36,7 @@ export const LanguageIcon = ({
const icon = (() => {
switch (language) {
case 'javascript':
return <JavascriptPlain className={iconStyle} />;
return <JavascriptOriginal className={iconStyle} />;
case 'typescript':
return <TypescriptPlain className={iconStyle} />;
case 'python':
Expand All @@ -50,10 +58,34 @@ export const LanguageIcon = ({
return <RubyPlain className={iconStyle} />;
case 'bash':
return <BashPlain className={iconStyle} />;
case 'react':
return <ReactPlain className={iconStyle} />;
case 'vue':
return <VueOriginal className={iconStyle} />;
case 'nextjs':
return <NextjsPlain className={iconStyle} />;
case 'svelte':
return <SveltePlain className={iconStyle} />;
case 'solidjs':
return <SolidjsPlain className={iconStyle} />;
case 'css':
return <Css3Plain className={iconStyle} />;
case 'html':
return <Html5Plain className={iconStyle} />;
case 'json':
return <div className={cx(iconStyle, 'text-amber-600')}>{`{ }`}</div>;
case 'markdown':
return <MarkdownOriginal className={iconStyle} />;
case 'jsx':
return <ReactPlain className={iconStyle} />; // JSX uses React icon
case 'tsx':
return <TypescriptPlain className={iconStyle} />; // TSX uses TypeScript icon
case 'unknown':
return <div className={cn(iconStyle, 'bg-gray-200')} />;
default:
return <div className={cn(iconStyle, 'bg-gray-200')} />;
}
})();

return <div className='flex items-center bg-gray-100 rounded-md p-0.5'>{icon}</div>;
return <div className='flex items-center bg-gray-100 rounded-md p-0.5 h-4 w-4'>{icon}</div>;
};
2 changes: 0 additions & 2 deletions apps/web/src/components/org/CreateOrgDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,13 @@ export const CreateOrgDialog = (props: CreateOrgDialogProps) => {
});

const handleLogoFileChange = async (file: File | null) => {
console.log('file', file);
if (file) {
const reader = new FileReader();
reader.onload = async (e) => {
const result = e.target?.result as string;
setLogoPreview(result);

const asset = await uploadLogo(result);
console.log('asset', asset);
form.setFieldValue('logo', asset.url);
};
reader.readAsDataURL(file);
Expand Down
16 changes: 9 additions & 7 deletions apps/web/src/components/room/Dockview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import {
RiStickyNoteLine,
RiTerminalLine,
} from '@remixicon/react';
import { DockviewTheme, IDockviewPanelHeaderProps, IDockviewPanelProps } from 'dockview';
import type { DockviewTheme, IDockviewPanelHeaderProps, IDockviewPanelProps } from 'dockview';
import { useMemo } from 'react';
import { AiChatView } from '@/components/room/ai-chat/AiChatView';
import { CodeOutput } from '@/components/room/CodeOutput';
import { CodeEditor } from '@/components/room/editor/CodeEditor';
import { EditorView } from '@/components/room/editor/EditorView';
import { CodeOutput } from '@/components/room/output/CodeOutput';
import { InstructionEditor } from '@/components/room/tiptap/InstructionEditor';
import { NotesEditor } from '@/components/room/tiptap/NotesEditor';
import { WhiteboardView } from '@/components/room/whiteboard/WhiteboardView';
Expand All @@ -19,7 +19,7 @@ import { cx } from '@/lib/utils';
export const DOCKVIEW_PANEL_IDS = {
CODE_EDITOR: 'code-editor',
INSTRUCTIONS: 'instructions',
PROGRAM_OUTPUT: 'program-output',
CODE_OUTPUT: 'code-output',
WHITEBOARD: 'whiteboard',
AI_CHAT: 'ai-chat',
NOTES: 'notes',
Expand All @@ -38,7 +38,7 @@ export const getTabIcon = (panelId: string) => {
return <RiCodeLine className='size-4' />;
case DOCKVIEW_PANEL_IDS.INSTRUCTIONS:
return <RiPencilLine className='size-4' />;
case DOCKVIEW_PANEL_IDS.PROGRAM_OUTPUT:
case DOCKVIEW_PANEL_IDS.CODE_OUTPUT:
return <RiTerminalLine className='size-4' />;
case DOCKVIEW_PANEL_IDS.WHITEBOARD:
return <RiSlideshowLine className='size-4' />;
Expand All @@ -57,15 +57,17 @@ export const useDockviewComponents = (isGuest: boolean) =>
() => ({
'code-editor': (_: IDockviewPanelProps) => (
<div className='h-full'>
<CodeEditor />
{/* <CodeEditor /> */}
{/* <MultiFileCodeEditor /> */}
<EditorView />
</div>
),
instructions: (_: IDockviewPanelProps) => (
<div className='h-full overflow-y-auto'>
<InstructionEditor isGuest={isGuest} />
</div>
),
'program-output': (_: IDockviewPanelProps) => (
'code-output': (_: IDockviewPanelProps) => (
<div className='h-full overflow-y-auto'>
<CodeOutput />
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/room/dockview.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@

/* Floating elements */
--dv-floating-box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
}
Loading