Skip to content

Dashboard UI refresh, editor/workspace refactor, Docker executor and external-import tooling#4

Open
Huynhthuongg wants to merge 1 commit into
mainfrom
codex/review-files-and-design-additions
Open

Dashboard UI refresh, editor/workspace refactor, Docker executor and external-import tooling#4
Huynhthuongg wants to merge 1 commit into
mainfrom
codex/review-files-and-design-additions

Conversation

@Huynhthuongg

@Huynhthuongg Huynhthuongg commented Jun 12, 2026

Copy link
Copy Markdown
Member

Motivation

  • Modernize the dashboard UI and project cards to better surface project status, AndroidX contribution workflow steps, and workspace health.
  • Improve the in-browser editor experience by consolidating the editor workspace and exposing a clean editor route.
  • Replace internal Docker library usage with a small CLI-based runner and harden local JS/Python executors for safer, time-limited runs.
  • Add tooling to import large external Terkix/RKIX repositories into a local external/ workspace without committing their sources.

Description

  • Revamped dashboard page (app/(dashboard)/page.tsx) with refreshed layout, status/stats cards, AndroidX checklist, and polished project cards.
  • Added an editor route and component split: new route app/editor/[projectId]/page.tsx and reusable components/ide/EditorWorkspace.tsx, and updated IDE components including EditorPanel, FileExplorer, Navbar, Terminal, Preview, and editor adapters (MonacoEditor, CodeMirrorEditor).
  • Refactored server execution stack: server/services/dockerExecutor.ts now uses the docker CLI via child_process.spawn with resource limits and label cleanup; jsExecutor and pythonExecutor were hardened for timeouts, safer output handling, and clearer error reporting; server/controllers/executeController.ts and server/middleware/errorHandler.ts contain small fixes/formatting updates.
  • Added external-import tooling and docs: integrations/terkix-repositories.json, scripts/import-terkix-repositories.mjs, docs/terkix-repository-imports.md, and an ignored external/ workspace (external/.gitkeep) with .gitignore updated to exclude external/* but keep .gitkeep.
  • Project and build config updates: updated package.json scripts (typecheck, import:terkix-repos), next.config.js adjustments for headers/rewrites/images and server externals, tsconfig.json path/style cleanups, added postcss.config.js, and updated tailwind.config.js and README.md to document the new import workflow.

Testing

  • Ran TypeScript type checking with npm run typecheck (maps to tsc --noEmit) and the checks completed successfully.
  • Performed a dry-run of the import script with npm run import:terkix-repos -- --dry-run to verify generated git/clone commands and the manifest parsing, which completed without errors.
  • No additional automated unit tests were modified or added as part of this change set.

Codex Task


Summary by cubic

Refreshes the dashboard UI and adds a dedicated editor route, while hardening code execution with a CLI-based Docker runner. Introduces an external/ import workflow to clone Terkix/RKIX repos locally without vendoring them.

  • New Features

    • New dashboard with status cards, AndroidX checklist, and clearer project cards.
    • New editor route app/editor/[projectId] using EditorWorkspace for a cleaner IDE URL.
    • External import tooling: manifest integrations/terkix-repositories.json, script npm run import:terkix-repos, ignored external/ workspace, and docs.
  • Refactors

    • Execution stack: switch Docker executor to docker CLI with memory/CPU limits and 10s timeout; label-based cleanup; safer JS/Python executors with timeouts and clearer errors.
    • IDE polish: streamlined Monaco/CodeMirror configs, improved tabs, file explorer, navbar (shows project ID), preview, and terminal.
    • Config and build: next.config.js headers/rewrites/image patterns, PostCSS (tailwindcss, autoprefixer), tsconfig.json path/style cleanup, package.json scripts (typecheck, import:terkix-repos), and .gitignore for external/*.

Written for commit 1726433. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
terkix-builder Ready Ready Preview, Comment Jun 12, 2026 8:28pm
terkix-builder-xgy4 Ready Ready Preview, Comment Jun 12, 2026 8:28pm

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

Cập Nhật Phiên Bản

  • New Features

    • Bổ sung giao diện dashboard mới với danh sách kiểm tra thiết lập, thống kê dự án và bố cục thẻ dự án cải tiến.
    • Thêm trình soạn thảo chuyên dụng với bố cục tab cho Code, Preview và Terminal.
    • Hỗ trợ nhập kho lưu trữ bên ngoài thông qua lệnh npm.
  • Improvements

    • Cập nhật cấu hình hỗ trợ Tailwind CSS và PostCSS.
    • Tối ưu hóa xử lý Docker và thực thi code.

Walkthrough

PR tái cấu trúc kiến trúc editor với routing động, bổ sung cơ chế import repository bên ngoài, và cập nhật các dịch vụ thực thi code qua Docker/JavaScript/Python. Đồng thời chuẩn hóa quote style và cấu hình toàn bộ codebase.

Changes

Editor Architecture Refactoring

Layer / File(s) Summary
Dashboard và editor page routing
app/(dashboard)/page.tsx, app/editor/[projectId]/page.tsx
Dashboard được cập nhật sang dữ liệu tĩnh với projects/setupSteps/stats hằng, viết lại giao diện bao gồm workflow checklist, stats card động. Tạo mới trang /editor/[projectId] async để đồng bộ lấy projectId và render EditorWorkspace.
EditorWorkspace component refactoring
components/ide/EditorWorkspace.tsx
EditorWorkspace được chuyển từ nhận params.projectId sang nhận projectId trực tiếp qua prop với interface EditorWorkspaceProps. Phần handleRun, handleShare, và wiring child component (Navbar, FileExplorer, EditorPanel, Terminal) cập nhật để dùng projectId prop.
Editor implementations (Monaco, CodeMirror)
components/editors/MonacoEditor.tsx, components/editors/CodeMirrorEditor.tsx, components/ide/EditorPanel.tsx
MonacoEditor mở rộng theme hỗ trợ "vs" và cập nhật onChange logic. CodeMirrorEditor tái cấu trúc để dựng lại EditorView trong useEffect dependency. EditorPanel quản lý activeTab, dùng output hằng, và cập nhật renderEditor mapping theme.
IDE UI components
components/ide/FileExplorer.tsx, components/ide/Navbar.tsx, components/ide/Preview.tsx, components/ide/Terminal.tsx
FileExplorer cập nhật files cấu trúc lồng nhau, hiển thị Project ID. Navbar định dạng breadcrumb và projectId có điều kiện. Preview hiển thị "Preview · {projectId}". Terminal bỏ state output, dùng output hằng, thêm guard sớm isOpen. Tất cả chuẩn hóa double-quote.

External Repository Integration

Layer / File(s) Summary
Manifest configuration and import script
integrations/terkix-repositories.json, scripts/import-terkix-repositories.mjs
Tạo manifest JSON chứa danh sách repository với id, name, url, localPath, purpose. Script Node.js CLI đọc manifest, xử lý git clone hoặc git pull --ff-only theo flag --update-only, hỗ trợ --dry-run, thu thập failure reports.
Documentation and tooling
docs/terkix-repository-imports.md, package.json, .gitignore, README.md
Tạo hướng dẫn chi tiết cách dùng import script với các lệnh npm (import:terkix-repos), flags, và lý do ignore external/. Cập nhật package.json thay lint sang tsc --noEmit, thêm typecheck. Cập nhật .gitignore cho tmp/, temp/, .tsbuildinfo, external/. Cập nhật README mục External Repository Imports.

Execution Services Refactoring

Layer / File(s) Summary
Docker executor migration
server/services/dockerExecutor.ts
Chuyển từ dockerode sang child_process.spawn("docker", ...). Loại bỏ default export instance. Thêm runDockerCommand xử lý spawn, timeout SIGKILL, event handling. executeJavaScript/executePython gọi runContainer dựng docker run argument. Cleanup dùng docker container prune --force --filter label=terkix=true.
JavaScript and Python executors
server/services/jsExecutor.ts, server/services/pythonExecutor.ts
JSExecutor bỏ unused import, chuẩn hóa double-quote, đổi timeout output/error format, cập nhật mockConsole. PythonExecutor chuẩn hóa quote, reorganize event handling, chuyển cleanup từ close handler sang timeout/error handlers, chuẩn hóa output format.
Controller and middleware
server/controllers/executeController.ts, server/middleware/errorHandler.ts
ExecuteController chuẩn hóa import quote, buildProject narrowing destructure {projectId, language} (loại bỏ files). ErrorHandler chuẩn hóa import, parameter _next, error message quote style.

Configuration and Style Normalization

Layer / File(s) Summary
App layout and Next.js config
app/layout.tsx, next.config.js
RootLayout bỏ Inter font, chuẩn hóa metadata formatting. Next.js config thêm serverExternalPackages, cập nhật webpack webassembly, CORS headers/rewrites, đổi images.domains sang images.remotePatterns. Chuẩn hóa quote style sang double.
PostCSS, Tailwind, TypeScript config
postcss.config.js, tailwind.config.js, tsconfig.json
PostCSS config enable tailwindcss/autoprefixer. Tailwind config chuẩn hóa quote, bỏ tailwindcss-animate. TypeScript config rút gọn lib/paths từ nhiều dòng sang inline, bỏ references, rút gọn exclude.
README và .gitignore
README.md, .gitignore
README cập nhật bố cục Features/Getting Started/Tech Stack/API/Development/Deployment, thêm mục External Repository Imports. .gitignore thêm tmp/, temp/, .tsbuildinfo, external/ (trừ .gitkeep).

🎯 4 (Complex) | ⏱️ ~60 minutes

Với chập chùng nhảy từ editor,
Repo bên ngoài đến gọi,
Docker lạm dùng spawn xối,
Cấu hình chuẩn bị ngôn ngữ,
Terkix Builder bay cao thăng! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Tiêu đề PR tập trung vào ba khía cạnh chính của thay đổi: Dashboard UI refresh, editor/workspace refactor, và Docker executor cùng external-import tooling - điều này phản ánh chính xác các thay đổi lớn trong pull request.
Description check ✅ Passed Mô tả PR chi tiết về động lực, nội dung thay đổi, và việc kiểm thử. Nó liên quan trực tiếp đến tất cả các thành phần chính của changeset bao gồm dashboard UI, editor route, Docker executor, external-import tooling, và config updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/review-files-and-design-additions
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch codex/review-files-and-design-additions
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/review-files-and-design-additions
  • 🛠️ Aethon

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.

Warning

Review ran into problems

🔥 Problems

Linked repositories: Your configuration references 1 linked repositories, but your current plan allows 0. Analyzed ``, skipped Aethon/backend-api.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kilo-code-bot

kilo-code-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

Kilo Code Review could not run — your account is out of credits.

Add credits or switch to a free model to enable reviews on this change.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1726433246

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread server/services/dockerExecutor.ts
Comment thread components/editors/CodeMirrorEditor.tsx
Comment thread server/services/dockerExecutor.ts
Comment thread server/services/dockerExecutor.ts
Comment thread server/services/dockerExecutor.ts
@Huynhthuongg Huynhthuongg self-assigned this Jun 12, 2026
@Huynhthuongg Huynhthuongg added bug Something isn't working documentation Improvements or additions to documentation duplicate This issue or pull request already exists enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers invalid This doesn't seem right question Further information is requested wontfix This will not be worked on dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Jun 12, 2026
@Huynhthuongg Huynhthuongg moved this from To triage to In review in @Huynhthuongg's untitled project Jun 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
server/services/pythonExecutor.ts (1)

23-23: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tên file tạm ở Line 23 có thể va chạm khi nhiều request cùng mili-giây.

terkix_${Date.now()}.py không đảm bảo duy nhất trong tải đồng thời, có thể dẫn tới ghi đè chéo giữa 2 phiên chạy.

Đề xuất tạo tên file tạm duy nhất
+import { randomUUID } from "crypto";
 ...
-      const tempFile = path.join(tempDir, `terkix_${Date.now()}.py`);
+      const tempFile = path.join(tempDir, `terkix_${randomUUID()}.py`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/services/pythonExecutor.ts` at line 23, The temp file naming using
`terkix_${Date.now()}.py` in the `tempFile` assignment can collide under
concurrent requests; change the generation to a truly unique filename (e.g., use
a UUID or a random suffix and/or include `process.pid` or use `fs.mkdtemp`) when
building `path.join(tempDir, ...)` so each invocation of the function that
creates `tempFile` yields a unique path and prevents cross-request overwrites;
update the `tempFile` creation site accordingly (replace reliance on
`Date.now()` with a secure unique id generator such as `crypto.randomUUID()` or
similar).
server/controllers/executeController.ts (1)

8-8: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

useDocker đang bị client điều khiển và mặc định rơi vào local execution.

Ở Line 8, useDocker = false lấy từ request body. Với luồng client hiện tại (hooks/useExecutor.ts:13-34) không gửi useDocker, nên mặc định luôn chạy nhánh local ở Line 31-37; đồng thời attacker cũng có thể ép useDocker=false để bypass sandbox.

Đề xuất khóa quyết định sandbox ở phía server
-    const { code, language, projectId, useDocker = false } = req.body;
+    const { code, language, projectId } = req.body;
+    const useDocker = process.env.EXECUTION_MODE !== "local";

Also applies to: 19-37

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/controllers/executeController.ts` at line 8, The controller currently
trusts client-supplied useDocker from req.body (const { code, language,
projectId, useDocker = false }), allowing clients to force local execution;
remove useDocker from the client destructure and instead decide sandboxing
server-side (e.g., compute a server-only flag like const useDocker =
determineExecutionMode(projectId, req.user) or enforce const useDocker =
true/DEFAULT_DOCKER), update executeController.ts where the execution branch
uses useDocker (the local vs docker decision around the lines handling local
execution), and add/consume a server-side helper (determineExecutionMode or
isSandboxedExecution) so attacker-controlled requests cannot bypass the sandbox.
server/services/jsExecutor.ts (1)

14-23: ⚠️ Potential issue | 🔴 Critical

Timeout không chặn được vòng lặp vô hạn khi JS executor chạy đồng bộ trên main thread

  • setTimeout (lines 14-23) chỉ được xử lý nếu event loop còn chạy; nhưng đoạn thực thi tạo hàm bằng new Function(...) rồi gọi executeCode(mockConsole) (lines 50-53) chạy đồng bộ, nên code như while(true){} sẽ khóa event loop và callback timeout không kịp hoạt động.
  • server/services/jsExecutor.ts không có cơ chế isolation/cưỡng chế dừng (không thấy worker_threads/Worker/child_process.fork/vm).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/services/jsExecutor.ts` around lines 14 - 23, The current timeout
implemented with setTimeout cannot stop synchronous infinite loops because
execution happens on the main thread; refactor so code execution runs inside a
separate isolate (e.g., a worker thread or child process) instead of calling new
Function(...) synchronously in executeCode/whatever method that currently
invokes executeCode(mockConsole); spawn a Worker (worker_threads) or fork a
child_process, send the source to that worker, start a timer in the parent that
calls worker.terminate()/child.kill() on timeout, and handle success/error
messages back to the parent (clear the timeout on normal completion). Ensure you
replace the direct synchronous call site (the code that creates new Function and
calls executeCode) with IPC to the worker and wire up duration, output, error,
and success fields accordingly.
components/ide/Terminal.tsx (1)

20-30: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Mảng output được tạo lại mỗi lần render, gây chạy useEffect không cần thiết.

Biến output được định nghĩa là constant array bên trong component body (dòng 20-23), nên nó được tạo lại với reference mới mỗi lần component render. useEffect ở dòng 26-30 phụ thuộc vào output, dẫn đến việc effect chạy sau mỗi lần render thay vì chỉ khi nội dung output thay đổi.

🔧 Đề xuất sửa: di chuyển `output` ra ngoài component
+const getTerminalOutput = (projectId: string) => [
+  "$ Welcome to Terkix Builder Terminal",
+  `$ Attached to project ${projectId}`,
+];
+
 export default function Terminal({
   projectId,
   isOpen = true,
   onClose,
   height = "200px",
 }: TerminalProps) {
   const terminalRef = useRef<HTMLDivElement>(null);
-  const output = [
-    "$ Welcome to Terkix Builder Terminal",
-    `$ Attached to project ${projectId}`,
-  ];
+  const output = useMemo(() => getTerminalOutput(projectId), [projectId]);
   const [isMaximized, setIsMaximized] = useState(false);

Hoặc đơn giản hơn, nếu chỉ cần scroll một lần khi mount:

   const terminalRef = useRef<HTMLDivElement>(null);
   const output = [
     "$ Welcome to Terkix Builder Terminal",
     `$ Attached to project ${projectId}`,
   ];
   const [isMaximized, setIsMaximized] = useState(false);
 
   useEffect(() => {
     if (terminalRef.current) {
       terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
     }
-  }, [output]);
+  }, [projectId]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ide/Terminal.tsx` around lines 20 - 30, The local constant output
is recreated on every render, causing the useEffect that scrolls terminalRef
(useEffect referencing output) to run unnecessarily; fix by making output
stable—either move the output array declaration out of the component or memoize
it with useMemo (e.g., const output = useMemo(() => [...], [projectId]) ) and
then keep the useEffect dependency on output (or if you only need to scroll on
mount, change the effect to an empty dependency array and run once). Ensure you
update references to output and keep terminalRef.scrollTop logic inside the same
useEffect that now depends on the stable output.
components/ide/EditorWorkspace.tsx (1)

15-32: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

State editor đang bị dùng chung giữa các project, dễ chạy nhầm mã theo projectId cũ.

useEditorStore đang giữ code/language ở scope global; khi đổi project, workspace mới vẫn có thể dùng state của project trước. Điều này làm lệch dữ liệu thực thi theo projectId.

Đề xuất chỉnh nhanh
-import { useState } from "react";
+import { useEffect, useState } from "react";
@@
 export default function EditorWorkspace({ projectId }: EditorWorkspaceProps) {
-  const { code, language } = useEditorStore();
+  const { code, language, reset } = useEditorStore();
@@
+  useEffect(() => {
+    reset();
+  }, [projectId, reset]);
+
   const { execute, isExecuting } = useExecutor();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ide/EditorWorkspace.tsx` around lines 15 - 32, The editor state
(code/language) is global via useEditorStore causing cross-project leakage;
update EditorWorkspace to use project-scoped editor state by making
useEditorStore accept projectId (or provide a project-specific selector) and
read/write code and language for that project only, then ensure handleSave and
handleRun use those project-scoped values when calling execute(code, language,
projectId); change any set/update calls in the store to key by projectId (e.g.,
getEditorState(projectId)/setEditorState(projectId,...)) so each project has
isolated code/language state.
components/editors/CodeMirrorEditor.tsx (1)

31-69: ⚠️ Potential issue | 🟠 Major

Tránh recreate EditorView khi code prop đổi (giữ ổn định cursor/undo)

Hiện tại useEffect tạo EditorState/new EditorView(...) đang phụ thuộc [code, language, onChange, readOnly, theme], và cleanup view.destroy(). Vì vậy mỗi khi code thay đổi (thường là theo từng lần gõ nếu parent set state từ onChange) sẽ destroy/recreate editor → tốn tài nguyên và dễ gây giật UI/mất trạng thái (cursor/undo).

Đề xuất tách lifecycle init và sync nội dung
 export default function CodeMirrorEditorComponent({
@@
 }: CodeMirrorEditorProps) {
   const editorRef = useRef<HTMLDivElement>(null);
+  const viewRef = useRef<EditorView | null>(null);

   useEffect(() => {
     if (!editorRef.current) return undefined;
@@
-    const view = new EditorView({
+    viewRef.current = new EditorView({
       state,
       parent: editorRef.current,
     });

     return () => {
-      view.destroy();
+      viewRef.current?.destroy();
+      viewRef.current = null;
     };
-  }, [code, language, onChange, readOnly, theme]);
+  }, [language, onChange, readOnly, theme]);
+
+  useEffect(() => {
+    const view = viewRef.current;
+    if (!view) return;
+    const current = view.state.doc.toString();
+    if (current !== code) {
+      view.dispatch({
+        changes: { from: 0, to: current.length, insert: code },
+      });
+    }
+  }, [code]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/editors/CodeMirrorEditor.tsx` around lines 31 - 69, Initialize the
EditorView only once instead of recreating it on every code prop change: move
the EditorState.create / new EditorView(...) call into an effect that runs on
mount (using editorRef and creating the view, and calling view.destroy() on
unmount), and separate a second effect that watches the code prop and updates
the editor content via the existing EditorView instance (use view.dispatch to
apply a document replacement only when the current view state doc differs from
the incoming code). Keep other extensions (getLanguageExtension(), theme
handling, EditorView.updateListener.of, EditorView.editable.of) attached on init
and avoid reattaching the update listener on every code change so cursor/undo
state is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/`(dashboard)/page.tsx:
- Around line 110-116: The "Open editor" Link is hardcoded to "/editor/1";
update it to use a dynamic project ID instead (either the first project's id or
route to create a new project) so it matches how projects are rendered elsewhere
(e.g., the project list using project.id). Locate the Link in
app/(dashboard)/page.tsx (the "Open editor" button) and replace the static href
with a computed value: if projects array exists and has at least one item use
`/editor/${projects[0].id}` (or equivalent firstProject.id), otherwise use the
new-project route (or a create project fallback); ensure the variable you use
(projects or firstProject) is available in the component scope.

In `@components/ide/Terminal.tsx`:
- Around line 20-23: The Terminal component currently initializes a hardcoded
const output array (lines with "$ Welcome..." and `$ Attached to project
${projectId}`) so it never shows dynamic logs; change this to accept an output
prop (e.g. output?: string[] or outputText?: string) or use internal state
(useState<string[]>) named output and expose a setter/append method so execution
results can be wired in, update places referencing output and projectId
accordingly, and add a TODO comment in Terminal to indicate where the
execute/logging stream should push new lines (or prop should be provided) so the
terminal becomes dynamic.

In `@docs/terkix-repository-imports.md`:
- Around line 19-36: Add a short system-requirements note to the docs near the
npm run import:terkix-repos examples stating that git must be installed and
available on the PATH (e.g., “Requires git installed and accessible via PATH”),
so users running npm run import:terkix-repos (and its flags --dry-run and
--update-only) get a clear error cause if git is missing.

In `@integrations/terkix-repositories.json`:
- Around line 1-42: Add a fail-fast JSON schema/field validation in
scripts/import-terkix-repositories.mjs before iterating manifest.repositories:
verify manifest is an object and manifest.repositories is a non-empty array and
manifest.defaultDirectory is a non-empty string, then for each repository ensure
required fields id, name, url, localPath, and purpose exist and are strings
(reject empty values). If validation fails, throw or processLogger.error and
exit with a clear message describing which repository index/id and which field
is missing/invalid so the import loop never attempts git operations with
undefined values.

In `@next.config.js`:
- Around line 56-57: The rewrite is hard-coded to
"http://localhost:3001/api/:path*"—update the rewrites() destination to use the
NEXT_PUBLIC_API_URL env var instead: read NEXT_PUBLIC_API_URL from process.env
(or from the exported env object) and build the destination as
`${NEXT_PUBLIC_API_URL}/api/:path*` so rewrites() proxies to the configured API
host in staging/production rather than localhost; target the rewrites() entry
that currently maps source: "/api/:path*" and destination:
"http://localhost:3001/api/:path*".

In `@package.json`:
- Around line 13-16: The package.json currently has both "lint" and "typecheck"
set to "tsc --noEmit" while eslint remains in devDependencies; update scripts
and related configs to remove duplication and align tooling: either (A) restore
"lint" to run ESLint (e.g., "eslint . --ext .ts,.tsx") and keep "typecheck" as
"tsc --noEmit", ensure CI workflows call npm run lint, and keep eslint
devDependency and config, or (B) make "lint" a typecheck alias (remove eslint
from devDependencies and delete/disable ESLint config and any CI lint job/docs
referencing it). Also search CI workflows (".github/workflows") and docs to
update or remove npm run lint references accordingly and clean up remaining
eslint config files if you choose option B.

In `@scripts/import-terkix-repositories.mjs`:
- Line 10: Dòng tạo manifest bằng const manifest =
JSON.parse(readFileSync(manifestPath, "utf8")); thiếu xử lý lỗi; bọc cuộc gọi
readFileSync/JSON.parse trong try/catch (xung quanh biểu thức tạo manifest), khi
lỗi xảy ra gọi console.error hoặc processLogger.error mô tả rõ manifestPath và
lỗi, và kết thúc script với process.exit(1); tham chiếu tới manifest,
manifestPath, readFileSync và JSON.parse để xác định vị trí sửa.
- Around line 42-75: The loop over manifest.repositories uses
repository.localPath and repository.url without validating repository shape, so
add schema/field checks before using them: implement a small validator (e.g.,
validateRepository or isValidRepository) that ensures repository is an object
and has required string fields localPath and url (and optionally name), call it
before resolving paths in the loop, log and push a failure or skip the entry
when validation fails (include repository index or JSON.stringify(repository) in
the log), and avoid accessing repository.localPath/repository.url when
validation fails; update any places referencing manifest.repositories to use the
validated/filtered list or guard branches accordingly.
- Around line 42-75: Validate and sanitize repository.localPath before using it:
after computing localPath with resolve(rootDir, repository.localPath) (and
gitDir via resolve(localPath, ".git")), ensure the resolved localPath is a child
of rootDir (e.g., compare
path.normalize(localPath).startsWith(path.normalize(rootDir) + path.sep)) and
reject or record a failure if it is outside rootDir or an absolute/traversal
path; also handle and log invalid paths early in the loop (the same place where
run, existsSync, updateOnly, failures, and console messages are used) so
cloning/pulling never operates on unexpected filesystem locations.

In `@server/services/dockerExecutor.ts`:
- Around line 81-94: The code accumulates unbounded stdout/stderr into strings
(stdout, stderr) via child.stdout.on and child.stderr.on which can OOM; fix by
introducing a max buffer size constant (e.g., MAX_CAPTURE_BYTES) and in the
child.stdout.on/child.stderr.on handlers only append until that limit (e.g.,
keep last N bytes or stop appending and set a truncated flag), and once the
limit is hit remove or no-op the corresponding listener to stop growth; update
any downstream uses of stdout/stderr to account for possible truncation and keep
existing timeoutId/child.kill behavior intact.
- Around line 48-59: The container invocation currently only sets
--memory/--cpus in the args array and leaves network/capabilities/pids and
stdout/stderr unbounded; update the args (the array named "args" in
server/services/dockerExecutor.ts) to harden the container by adding flags such
as --network=none, --pids-limit=<small>, --cap-drop=ALL,
--security-opt=no-new-privileges, --read-only and appropriate tmpfs/volume flags
(or minimal --cap-add if a specific capability is required) to reduce attack
surface, and then limit runtime resources as needed; also modify the
stdout/stderr handling logic (the streaming/buffering code around lines handling
output in server/services/dockerExecutor.ts) to enforce a maximum aggregated
output size (implement a byte counter that stops/terminates the container once a
threshold is exceeded or truncates additional output) and stream output
incrementally rather than buffering unboundedly to prevent DoS/OOM.

In `@server/services/pythonExecutor.ts`:
- Around line 45-59: The timeout handler currently calls process.kill() and
resolve() immediately (using timeoutId and process.kill()), causing possible
double-resolve and duplicate cleanup because
process.on("close")/process.on("error") also resolve and unlink the tempFile;
change the lifecycle so the timeout handler only marks the process as timed out,
calls process.kill(), and waits for the existing process.on("close") handler to
perform the single resolve/cleanup (or use a single shared "settled"
flag/cleanup function checked by all handlers to ensure exactly one
resolve/unlink and to clear the timeoutId). Also make temp file names truly
unique by replacing the Date.now()-based name with a UUID or other random id
(e.g., crypto.randomUUID()) when creating tempFile so concurrent requests won't
collide. Ensure timeoutId is cleared in the close/error paths and that unlink is
only executed once.

---

Outside diff comments:
In `@components/editors/CodeMirrorEditor.tsx`:
- Around line 31-69: Initialize the EditorView only once instead of recreating
it on every code prop change: move the EditorState.create / new EditorView(...)
call into an effect that runs on mount (using editorRef and creating the view,
and calling view.destroy() on unmount), and separate a second effect that
watches the code prop and updates the editor content via the existing EditorView
instance (use view.dispatch to apply a document replacement only when the
current view state doc differs from the incoming code). Keep other extensions
(getLanguageExtension(), theme handling, EditorView.updateListener.of,
EditorView.editable.of) attached on init and avoid reattaching the update
listener on every code change so cursor/undo state is preserved.

In `@components/ide/EditorWorkspace.tsx`:
- Around line 15-32: The editor state (code/language) is global via
useEditorStore causing cross-project leakage; update EditorWorkspace to use
project-scoped editor state by making useEditorStore accept projectId (or
provide a project-specific selector) and read/write code and language for that
project only, then ensure handleSave and handleRun use those project-scoped
values when calling execute(code, language, projectId); change any set/update
calls in the store to key by projectId (e.g.,
getEditorState(projectId)/setEditorState(projectId,...)) so each project has
isolated code/language state.

In `@components/ide/Terminal.tsx`:
- Around line 20-30: The local constant output is recreated on every render,
causing the useEffect that scrolls terminalRef (useEffect referencing output) to
run unnecessarily; fix by making output stable—either move the output array
declaration out of the component or memoize it with useMemo (e.g., const output
= useMemo(() => [...], [projectId]) ) and then keep the useEffect dependency on
output (or if you only need to scroll on mount, change the effect to an empty
dependency array and run once). Ensure you update references to output and keep
terminalRef.scrollTop logic inside the same useEffect that now depends on the
stable output.

In `@server/controllers/executeController.ts`:
- Line 8: The controller currently trusts client-supplied useDocker from
req.body (const { code, language, projectId, useDocker = false }), allowing
clients to force local execution; remove useDocker from the client destructure
and instead decide sandboxing server-side (e.g., compute a server-only flag like
const useDocker = determineExecutionMode(projectId, req.user) or enforce const
useDocker = true/DEFAULT_DOCKER), update executeController.ts where the
execution branch uses useDocker (the local vs docker decision around the lines
handling local execution), and add/consume a server-side helper
(determineExecutionMode or isSandboxedExecution) so attacker-controlled requests
cannot bypass the sandbox.

In `@server/services/jsExecutor.ts`:
- Around line 14-23: The current timeout implemented with setTimeout cannot stop
synchronous infinite loops because execution happens on the main thread;
refactor so code execution runs inside a separate isolate (e.g., a worker thread
or child process) instead of calling new Function(...) synchronously in
executeCode/whatever method that currently invokes executeCode(mockConsole);
spawn a Worker (worker_threads) or fork a child_process, send the source to that
worker, start a timer in the parent that calls worker.terminate()/child.kill()
on timeout, and handle success/error messages back to the parent (clear the
timeout on normal completion). Ensure you replace the direct synchronous call
site (the code that creates new Function and calls executeCode) with IPC to the
worker and wire up duration, output, error, and success fields accordingly.

In `@server/services/pythonExecutor.ts`:
- Line 23: The temp file naming using `terkix_${Date.now()}.py` in the
`tempFile` assignment can collide under concurrent requests; change the
generation to a truly unique filename (e.g., use a UUID or a random suffix
and/or include `process.pid` or use `fs.mkdtemp`) when building
`path.join(tempDir, ...)` so each invocation of the function that creates
`tempFile` yields a unique path and prevents cross-request overwrites; update
the `tempFile` creation site accordingly (replace reliance on `Date.now()` with
a secure unique id generator such as `crypto.randomUUID()` or similar).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 00ff0388-822d-4544-b641-74c6c3116257

📥 Commits

Reviewing files that changed from the base of the PR and between 6d83a1e and 1726433.

📒 Files selected for processing (27)
  • .gitignore
  • README.md
  • app/(dashboard)/page.tsx
  • app/editor/[projectId]/page.tsx
  • app/layout.tsx
  • components/editors/CodeMirrorEditor.tsx
  • components/editors/MonacoEditor.tsx
  • components/ide/EditorPanel.tsx
  • components/ide/EditorWorkspace.tsx
  • components/ide/FileExplorer.tsx
  • components/ide/Navbar.tsx
  • components/ide/Preview.tsx
  • components/ide/Terminal.tsx
  • docs/terkix-repository-imports.md
  • external/.gitkeep
  • integrations/terkix-repositories.json
  • next.config.js
  • package.json
  • postcss.config.js
  • scripts/import-terkix-repositories.mjs
  • server/controllers/executeController.ts
  • server/middleware/errorHandler.ts
  • server/services/dockerExecutor.ts
  • server/services/jsExecutor.ts
  • server/services/pythonExecutor.ts
  • tailwind.config.js
  • tsconfig.json

Comment thread app/(dashboard)/page.tsx
Comment thread components/ide/Terminal.tsx
Comment thread docs/terkix-repository-imports.md
Comment thread integrations/terkix-repositories.json
Comment thread next.config.js
Comment thread scripts/import-terkix-repositories.mjs
Comment thread scripts/import-terkix-repositories.mjs
Comment thread server/services/dockerExecutor.ts
Comment thread server/services/dockerExecutor.ts
Comment thread server/services/pythonExecutor.ts
@github-project-automation github-project-automation Bot moved this from In review to In progress in @Huynhthuongg's untitled project Jun 12, 2026
@Huynhthuongg Huynhthuongg moved this from Todo to In Progress in @Huynhthuongg's untitled project Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working codex dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation duplicate This issue or pull request already exists enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed invalid This doesn't seem right javascript Pull requests that update javascript code question Further information is requested wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant