Skip to content

Conversation

zardoy
Copy link
Owner

@zardoy zardoy commented Aug 21, 2025

Summary by CodeRabbit

  • New Features

    • Introduced an in-app code editor modal with syntax highlighting and dark theme.
    • Automatically opens for editable content and supports saving changes.
    • Preserves cursor position and displays error notifications if saving fails.
  • UI/Style

    • Added full-screen, responsive overlay with refined styling and a prominent close control.
    • Improved mobile layout for a better editing experience on small screens.
  • Chores

    • Updated dependencies to include the Monaco editor integration.

Copy link

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds a Monaco-based IDE feature: introduces global reactive IDE state and two custom channels (ide-open, ide-save), registers them during bot setup, adds a React modal with Monaco Editor bound to that state, styles the modal, and mounts it into the React UI. Also adds @monaco-editor/react dependency.

Changes

Cohort / File(s) Summary
Dependency update
package.json
Adds dependency: @monaco-editor/react@^4.7.0.
IDE channels (core)
src/core/ideChannels.ts
New module defining global ideState (valtio), registers ide-open and ide-save channels, exports saveIde and registerIdeChannels.
Channel registration wiring
src/customChannels.ts
Imports and invokes registerIdeChannels() within existing custom channel setup.
Monaco modal UI
src/react/MonacoEditor.tsx, src/react/MonacoEditor.css
New React modal component rendering Monaco Editor tied to ideState; handles open/close and save on close; CSS styles for modal overlay and responsive behavior.
UI integration
src/reactUi.tsx
Imports and mounts MonacoEditor within a portal in the main React UI.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Bot as Bot/Client
  participant Channels as IdeChannels
  participant State as ideState (valtio)
  participant UI as React MonacoEditor
  participant Modal as Modal Manager
  participant Srv as Channel Server

  Note over Channels,UI: Initialization
  Bot->>Channels: registerIdeChannels()
  Channels->>Bot: register ide-open / ide-save

  Note over Srv,Channels: Open flow
  Srv-->>Bot: ide-open packet {id, language?, contents, line, column, title}
  Bot->>Channels: emit ide-open data
  Channels->>State: update {id, language, contents, line, column, title}
  UI->>State: subscribes (valtio)
  State-->>UI: state change (id set)
  UI->>Modal: showModal(monaco-editor)

  Note over UI,Srv: Edit + Save on close
  UI->>UI: user edits (onChange -> State.contents)
  UI->>Modal: hide (close)
  alt id present on close
    UI->>Channels: saveIde()
    Channels->>Bot: writeChannel ide-save {id, contents, language, line, column}
    Bot-->>Srv: ide-save packet
    Channels->>State: clear id, contents
  else no active doc
    UI->>State: no-op
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

In a moonlit modal, I type with delight,
Monaco sparkles in the pixel night.
Channels hum softly—open, then save—
Packets hop tunnels, brave little waves.
I twitch my ears, review is done—
Carrots compiled. Ship it, run! 🥕✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch monaco

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@zardoy zardoy changed the title add monaco add simple monaco Aug 21, 2025
@zardoy zardoy merged commit a12c61b into next Aug 21, 2025
2 of 3 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (14)
src/react/MonacoEditor.css (3)

20-30: Prevent overflow from border/padding with box-sizing.

The wrapper has width/height 100% with padding and border. Without box-sizing: border-box, it can exceed max-width/height and cause scrollbars.

 .monaco-editor-wrapper {
   position: relative;
   width: 100%;
   height: 100%;
   max-width: 80vw;
   max-height: 80vh;
   border: 3px solid #000;
   background-color: #000;
   padding: 3px;
+  box-sizing: border-box;
   box-shadow: inset 0 0 0 1px #fff, inset 0 0 0 2px #000;
 }

32-39: Account for iOS safe areas for the close button.

On devices with notches, the fixed button may collide with the unsafe area. Use env(safe-area-inset-*) offsets.

 .monaco-editor-close {
   position: fixed;
-  top: 16px;
-  left: 16px;
+  top: calc(env(safe-area-inset-top, 0px) + 16px);
+  left: calc(env(safe-area-inset-left, 0px) + 16px);
   z-index: 1001;
   cursor: pointer;
   padding: 8px;
 }

48-49: Remove dead style or set a matching radius.

You unset border-radius in the mobile block, but there’s no border-radius set for desktop. Either remove this line or define a non-zero radius for desktop to make the mobile override meaningful.

-    border-radius: 0;
+    /* no radius on mobile; define desktop radius if desired */
src/core/ideChannels.ts (3)

21-49: Confirm server-client packet compatibility and payload size.

The container includes a new "title" field; mixing server/client versions will break decoding. Also, pstring with i16 length caps content to ~32KB; large files will truncate/fail.

  • Ensure the server sending minecraft-web-client:ide-open matches this exact structure.
  • If you expect larger documents, consider chunking or switching to a streaming/chunk protocol (e.g., ide-open-meta + ide-open-chunk packets), or increase countType where supported.

64-65: Minor log wording.

"registered custom channel ... channel" repeats “channel”.

-console.debug(`registered custom channel ${CHANNEL_NAME} channel`)
+console.debug(`registered custom channel ${CHANNEL_NAME}`)

67-95: Consider an ACK for save flow or error reporting.

You register the save channel but don’t listen for a server ACK or error. If persistence fails, the UI won’t know.

  • Add an ide-save-result clientbound channel with { id, ok: bool, message?: string } so the UI can show success/failure.
  • I can draft the client and a sample server handler if helpful.
src/customChannels.ts (1)

21-21: Confirm desired timing: IDE channels don’t wait for worldReady.

Other helpers often defer handlers until appViewer.worldReady. If you want IDE to be available pre-world (e.g., on title screen), this is fine. If not, consider reusing registerChannel with waitForWorld = true.

src/reactUi.tsx (3)

70-70: Defer Monaco payload with lazy loading to avoid large initial bundle.

Monaco is heavy; statically importing the editor pulls it into the main bundle even when never opened. Lazy load and render only when needed.

-import MonacoEditor from './react/MonacoEditor'
+import { Suspense } from 'react'
+import { ideState } from './core/ideChannels'
+const MonacoEditor = React.lazy(() => import('./react/MonacoEditor'))

257-264: Render Monaco only when opened and behind Suspense.

Hook into ideState to conditionally mount the lazy component; prevents fetching the Monaco chunk until actually needed.

-            <DebugEdges />
-            <MonacoEditor />
-            <DebugResponseTimeIndicator />
+            <DebugEdges />
+            {useSnapshot(ideState).id && (
+              <Suspense fallback={null}>
+                <MonacoEditor />
+              </Suspense>
+            )}
+            <DebugResponseTimeIndicator />

Note: Ensure React is in scope for React.lazy (import React or use the new JSX runtime appropriately).


256-264: Ensure Monaco styles are included.

If not already imported inside MonacoEditor.tsx, import its CSS or the modal will be unstyled.

Add at the top of src/react/MonacoEditor.tsx:

import './MonacoEditor.css'
src/react/MonacoEditor.tsx (4)

14-15: SSR-safe, stable font detection

Directly calling getComputedStyle(document.body) during render can break in non-DOM environments and recomputes on every render. Memoize and guard for SSR.

Apply this diff:

-import { useEffect } from 'react'
+import { useEffect, useMemo } from 'react'
@@
-  const bodyFont = getComputedStyle(document.body).fontFamily
+  const bodyFont = useMemo(() => {
+    if (typeof window === 'undefined' || !document?.body) return 'monospace'
+    return getComputedStyle(document.body).fontFamily
+  }, [])

Also applies to: 2-2


16-23: Effect references isModalActive but doesn’t declare it as a dependency

While the current logic works on id changes, this will trigger a hooks linter warning and can read stale isModalActive values. Include it in deps to keep intent explicit.

Apply this diff:

-  }, [id])
+  }, [id, isModalActive])

41-49: Make the close control accessible

Expose button semantics and keyboard handling so users can close the modal without a mouse.

Apply this diff:

-      <PixelartIcon
+      <PixelartIcon
         iconName={pixelartIcons.close}
         width={26}
         onClick={() => {
           hideModal()
         }}
+        role="button"
+        tabIndex={0}
+        aria-label="Close editor"
+        onKeyDown={(e) => {
+          if (e.key === 'Enter' || e.key === ' ') hideModal()
+        }}
       />

11-13: Name the component for better DevTools and error stacks

Anonymous default exports reduce debuggability. Give the component a name.

Apply this diff:

-export default () => {
+export default function MonacoEditorModal() {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6e0d54e and c1086eb.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • package.json (1 hunks)
  • src/core/ideChannels.ts (1 hunks)
  • src/customChannels.ts (2 hunks)
  • src/react/MonacoEditor.css (1 hunks)
  • src/react/MonacoEditor.tsx (1 hunks)
  • src/reactUi.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/vars-usage.mdc)

src/**/*.ts: You may use the global variable bot directly in any file under the src/ directory (e.g., src/mineflayer/playerState.ts).
In src/ code, you may use the global variable appViewer from src/appViewer.ts directly. Do not import appViewer or use window.appViewer; use the global appViewer variable as-is.

Files:

  • src/customChannels.ts
  • src/core/ideChannels.ts
🧬 Code graph analysis (3)
src/react/MonacoEditor.tsx (4)
src/core/ideChannels.ts (2)
  • ideState (3-10)
  • saveIde (97-106)
src/globalState.ts (2)
  • showModal (42-47)
  • hideModal (55-78)
src/react/NotificationProvider.tsx (1)
  • showNotification (22-39)
src/react/PixelartIcon.tsx (1)
  • pixelartIcons (21-25)
src/customChannels.ts (1)
src/core/ideChannels.ts (1)
  • registerIdeChannels (13-16)
src/core/ideChannels.ts (1)
src/react/TitleProvider.tsx (1)
  • title (33-157)
🔇 Additional comments (2)
src/core/ideChannels.ts (1)

53-62: Good ordering of state updates to avoid flicker.

Setting contents/position before id is a nice touch so the UI sees a fully-populated state when the modal opens.

src/customChannels.ts (1)

5-5: LGTM: IDE channels integrated into custom channel setup.

Import placement and scoping are consistent with the file, and follow the allowed global usage of bot/appViewer per guidelines.

"dependencies": {
"@dimaka/interface": "0.0.3-alpha.0",
"@floating-ui/react": "^0.26.1",
"@monaco-editor/react": "^4.7.0",
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Missing peer dependency: add "monaco-editor" and verify worker bundling with Rsbuild.

@monaco-editor/react requires monaco-editor as a peer. It's not present in dependencies, which will likely break build/runtime or force a fallback you don't want. Also, Monaco needs its web workers bundled/configured for languages to work under Rsbuild/Rspack.

Apply this diff to add monaco-editor (pin to the peer range of your installed @monaco-editor/react):

   "@floating-ui/react": "^0.26.1",
+  "monaco-editor": "^0.52.0",
   "@monaco-editor/react": "^4.7.0",

Follow-ups:

  • Verify the exact peer range by checking @monaco-editor/react’s peerDependencies and adjust the version accordingly.
  • Confirm worker bundling works in your setup (ts.worker.js, editor.worker.js, etc.). If workers don’t load, consider configuring Rspack worker rules or adding a Monaco plugin compatible with Rsbuild/Rspack, or set MonacoEnvironment.getWorker to custom URLs.

🏁 Script executed:

#!/bin/bash
# Verify if monaco-editor is declared in package.json
grep -R "\"monaco-editor\"" -n package.json || echo "monaco-editor not found in package.json"

# Show the context around the @monaco-editor/react entry
grep -R -n -C2 "\"@monaco-editor/react\"" package.json

Length of output: 411


🌐 Web query:

What are the peerDependencies of @monaco-editor/[email protected]?

💡 Result:

The peerDependencies for @monaco-editor/[email protected] are:

If you want, I can show the package.json / package-lock excerpt that contains these entries.

Citations:


Add the missing monaco-editor dependency and verify worker bundling

Your project is currently missing the monaco-editor package, which is a required peer for @monaco-editor/[email protected] (it declares

"peerDependencies": {
  "monaco-editor": ">=0.25.0 <1",
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}

) . Omitting it will lead to runtime errors or unintended fallbacks.

Please update your package.json like so:

  "@floating-ui/react": "^0.26.1",
+ "monaco-editor": "^0.52.0",    // satisfies >=0.25.0 <1
  "@monaco-editor/react": "^4.7.0",

Then:

  • Double-check the exact peer range in your lockfile or node_modules/@monaco-editor/react/package.json and adjust "monaco-editor"’s version if needed (any 0.x ≥ 0.25 will do).
  • Verify that Monaco’s web workers load correctly under your Rsbuild/Rspack setup. If they fail to bundle (e.g., ts.worker.js, editor.worker.js), you’ll need to configure worker rules or use a plugin/override (MonacoEnvironment.getWorkerUrl) to point to the proper URLs.

Comment on lines +3 to +12
export const ideState = proxy({
id: '',
contents: '',
line: 0,
column: 0,
language: 'typescript',
title: '',
})
globalThis.ideState = ideState

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Type error risk: globalThis augmentation missing for ideState.

Assigning globalThis.ideState without a global augmentation will fail type-checking in TS (“Property 'ideState' does not exist on type 'typeof globalThis'”).

Apply this diff to add a typed state shape and a safe global augmentation:

-import { proxy } from 'valtio'
+import { proxy } from 'valtio'
+
+type IdeState = {
+  id: string
+  contents: string
+  line: number   // note: Monaco uses 1-based positions; see comment below
+  column: number // note: Monaco uses 1-based positions; see comment below
+  language: string
+  title: string
+}
 
-export const ideState = proxy({
+export const ideState = proxy<IdeState>({
   id: '',
   contents: '',
   line: 0,
   column: 0,
   language: 'typescript',
   title: '',
 })
-globalThis.ideState = ideState
+declare global {
+  // eslint-disable-next-line no-var
+  var ideState: typeof ideState
+}
+globalThis.ideState = ideState
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const ideState = proxy({
id: '',
contents: '',
line: 0,
column: 0,
language: 'typescript',
title: '',
})
globalThis.ideState = ideState
import { proxy } from 'valtio'
type IdeState = {
id: string
contents: string
line: number // note: Monaco uses 1-based positions; see comment below
column: number // note: Monaco uses 1-based positions; see comment below
language: string
title: string
}
export const ideState = proxy<IdeState>({
id: '',
contents: '',
line: 0,
column: 0,
language: 'typescript',
title: '',
})
declare global {
// eslint-disable-next-line no-var
var ideState: typeof ideState
}
globalThis.ideState = ideState
🤖 Prompt for AI Agents
In src/core/ideChannels.ts around lines 3 to 12, TypeScript will error because
globalThis is not augmented for ideState; add a typed shape and a safe global
augmentation: define an interface/type for the IDE state (fields id, contents,
line, column, language, title), type the proxy return value accordingly, declare
a global augmentation (declare global { var ideState?: IDEStateType }) so the
compiler knows about globalThis.ideState, and then assign to globalThis.ideState
= ideState (or use conditional assignment globalThis.ideState ||= ideState)
without casting to any.

Comment on lines +97 to +106
export const saveIde = () => {
bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
id: ideState.id,
contents: ideState.contents,
language: ideState.language,
// todo: reflect updated
line: ideState.line,
column: ideState.column,
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Harden saveIde against disconnects and sync cursor position.

  • writeChannel will throw if _client is not connected (e.g., user disconnects while modal open).
  • Comment notes line/column aren’t updated; Monaco uses 1-based positions, so ensure you convert and keep them in sync before saving.
-export const saveIde = () => {
-  bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
+export const saveIde = () => {
+  // Guard against disconnects
+  // @ts-expect-error: internal client state
+  if (!bot?._client || bot?._client?.ended) return
+  bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
     id: ideState.id,
     contents: ideState.contents,
     language: ideState.language,
-    // todo: reflect updated
-    line: ideState.line,
-    column: ideState.column,
+    // NOTE: keep these updated from the editor and convert to 1-based if needed.
+    line: ideState.line,
+    column: ideState.column,
   })
}

Follow-ups:

  • Wire editor cursor/selection changes to ideState.line/column and normalize to 1-based before saving.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const saveIde = () => {
bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
id: ideState.id,
contents: ideState.contents,
language: ideState.language,
// todo: reflect updated
line: ideState.line,
column: ideState.column,
})
}
export const saveIde = () => {
// Guard against disconnects
// @ts-expect-error: internal client state
if (!bot?._client || bot?._client?.ended) return
bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
id: ideState.id,
contents: ideState.contents,
language: ideState.language,
// NOTE: keep these updated from the editor and convert to 1-based if needed.
line: ideState.line,
column: ideState.column,
})
}

Comment on lines +25 to +36
useEffect(() => {
if (!isModalActive && id) {
try {
saveIde()
} catch (err) {
reportError(err)
showNotification('Failed to save the editor', 'Please try again', true)
}
ideState.id = ''
ideState.contents = ''
}
}, [isModalActive])
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix undefined reportError and prevent data loss on failed save

  • reportError is not imported/defined; this will throw at runtime.
  • ideState.id and ideState.contents are cleared even when saveIde() throws, causing irreversible loss of user edits.
  • The effect also reads id but doesn’t include it in the dependency list.

Refactor to clear state only on successful save, log errors safely, optionally re-open the modal on failure, and include id in deps.

Apply this diff:

   useEffect(() => {
-    if (!isModalActive && id) {
-      try {
-        saveIde()
-      } catch (err) {
-        reportError(err)
-        showNotification('Failed to save the editor', 'Please try again', true)
-      }
-      ideState.id = ''
-      ideState.contents = ''
-    }
-  }, [isModalActive])
+    if (!isModalActive && id) {
+      try {
+        // If saveIde ever becomes async, this will still be safe to convert.
+        saveIde()
+        ideState.id = ''
+        ideState.contents = ''
+      } catch (err) {
+        console.error(err)
+        showNotification('Failed to save the editor', 'Please try again', true)
+        // Keep state intact and re-open so the user can retry saving.
+        showModal({ reactType: 'monaco-editor' })
+      }
+    }
+  }, [isModalActive, id])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
if (!isModalActive && id) {
try {
saveIde()
} catch (err) {
reportError(err)
showNotification('Failed to save the editor', 'Please try again', true)
}
ideState.id = ''
ideState.contents = ''
}
}, [isModalActive])
useEffect(() => {
if (!isModalActive && id) {
try {
// If saveIde ever becomes async, this will still be safe to convert.
saveIde()
ideState.id = ''
ideState.contents = ''
} catch (err) {
console.error(err)
showNotification('Failed to save the editor', 'Please try again', true)
// Keep state intact and re-open so the user can retry saving.
showModal({ reactType: 'monaco-editor' })
}
}
}, [isModalActive, id])
🤖 Prompt for AI Agents
In src/react/MonacoEditor.tsx around lines 25 to 36, fix three issues: import or
define reportError (or replace with safe logging like console.error) so the
catch block cannot throw, move the lines that clear ideState.id and
ideState.contents to run only after a successful save (i.e., inside the try
block after await/save resolves), and include id in the effect dependency array
(change [isModalActive] to [isModalActive, id]); optionally, on save failure
call showNotification and re-open the modal or leave state intact so user edits
are not lost.

Comment on lines +54 to +71
<Editor
height="100%"
width="100%"
language={language}
theme='vs-dark'
line={line}
onChange={(value) => {
ideState.contents = value ?? ''
}}
value={contents}
options={{
fontFamily: bodyFont,
minimap: {
enabled: true,
},
}}
/>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Monaco Editor: line prop is invalid; use onMount to set cursor and reveal line (also use column)

@monaco-editor/react has no line prop. Passing it won’t position the cursor and may fail type-checking. Use onMount to set the cursor and reveal the requested position. Also leverage column from state and clamp to 1-based indices.

Apply this diff:

       <Editor
         height="100%"
         width="100%"
         language={language}
         theme='vs-dark'
-        line={line}
+        onMount={(editor) => {
+          const lineNumber = Math.max(1, Number(line) || 1)
+          const columnNumber = Math.max(1, Number(column) || 1)
+          editor.setPosition({ lineNumber, column: columnNumber })
+          editor.revealLineInCenter(lineNumber)
+          editor.focus()
+        }}
         onChange={(value) => {
           ideState.contents = value ?? ''
         }}
         value={contents}
         options={{
           fontFamily: bodyFont,
           minimap: {
             enabled: true,
           },
         }}
       />

Optional (helps model re-use, markers, and language services per file/tab): add a stable model path based on id.

-        language={language}
+        language={language}
+        path={id || undefined}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Editor
height="100%"
width="100%"
language={language}
theme='vs-dark'
line={line}
onChange={(value) => {
ideState.contents = value ?? ''
}}
value={contents}
options={{
fontFamily: bodyFont,
minimap: {
enabled: true,
},
}}
/>
</div>
<Editor
height="100%"
width="100%"
language={language}
path={id || undefined}
theme='vs-dark'
onMount={(editor) => {
const lineNumber = Math.max(1, Number(line) || 1)
const columnNumber = Math.max(1, Number(column) || 1)
editor.setPosition({ lineNumber, column: columnNumber })
editor.revealLineInCenter(lineNumber)
editor.focus()
}}
onChange={(value) => {
ideState.contents = value ?? ''
}}
value={contents}
options={{
fontFamily: bodyFont,
minimap: {
enabled: true,
},
}}
/>
🤖 Prompt for AI Agents
In src/react/MonacoEditor.tsx around lines 54 to 71, the Editor is using a
non-existent `line` prop which won’t position the cursor or pass types; replace
this by using the Editor’s onMount callback to get the editor instance, compute
a 1-based line and column from state (clamp both to at least 1 and within model
bounds), call editor.setPosition({ lineNumber, column }) and
editor.revealPositionInCenter({ lineNumber, column }), and optionally set a
stable model path based on the id when creating the model so language services
and tabs remain stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant