Skip to content

Open sketch source#635

Open
cale-bradbury wants to merge 1 commit intonudibranchrecords:alphafrom
cale-bradbury:open-sketch-source
Open

Open sketch source#635
cale-bradbury wants to merge 1 commit intonudibranchrecords:alphafrom
cale-bradbury:open-sketch-source

Conversation

@cale-bradbury
Copy link
Copy Markdown
Collaborator

@cale-bradbury cale-bradbury commented Mar 28, 2026

Adds a dropdown option to help you quickly open the source index.ts/js for a sketch in it's default program

image

@cale-bradbury cale-bradbury changed the base branch from dev to alpha March 28, 2026 17:15
@cale-bradbury cale-bradbury requested a review from Copilot March 28, 2026 17:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an “Open Source” action for the currently active sketch so users can open the sketch’s index.ts/index.js in the OS-default editor via an IPC call to the Electron main process.

Changes:

  • Add a new IPC event (FileEvents.OpenSketchSourceFile) for opening a sketch source file.
  • Add a renderer-side helper and wire it into the ActiveSketch popout menu (“Open Source”).
  • Implement a main-process handler that resolves index.ts/index.js for a sketch module and opens it via shell.openPath.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/desktop/src/shared/Events.ts Adds a new FileEvents IPC channel for opening sketch source files.
apps/desktop/src/renderer/components/ActiveSketch/openSketchSourceFile.ts Renderer utility that invokes the new IPC handler and reports errors to the user.
apps/desktop/src/renderer/components/ActiveSketch/ActiveSketch.tsx Adds “Open Source” item to the ActiveSketch menu.
apps/desktop/src/main/index.ts Registers an ipcMain.handle for the new file-open action.
apps/desktop/src/main/handlers/openSketchSourceFile.ts Main-process implementation that locates and opens index.ts/js for a sketch module.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import { electronApp, optimizer } from '@electron-toolkit/utils'
import { REDUX_DEVTOOLS, installExtension } from '@tomjs/electron-devtools-installer'
import { ProjectData } from '@hedron-gl/app-store'
import { openSketchSourceFile } from './handlers/openSketchSourceFile'
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

Use the existing @main/handlers/... path alias here for consistency with the other handler imports in this file. Mixing relative and aliased imports makes refactors (like moving index.ts) harder and can lead to duplicate module resolution paths.

Suggested change
import { openSketchSourceFile } from './handlers/openSketchSourceFile'
import { openSketchSourceFile } from '@main/handlers/openSketchSourceFile'

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +24
const tsPath = path.join(sketchesDir, moduleId, 'index.ts')
const jsPath = path.join(sketchesDir, moduleId, 'index.js')
let filePath = tsPath
if (fs.existsSync(tsPath)) {
filePath = tsPath
} else if (fs.existsSync(jsPath)) {
filePath = jsPath
} else {
return { success: false, error: 'Source file not found' }
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

moduleId is used to build a filesystem path without validation. Because the preload exposes a full ipcRenderer API, a compromised renderer could pass values like ../... (or use symlinks) to make the main process open arbitrary files. Please validate moduleId (e.g., reject path separators / ..), and ensure the resolved target path stays within sketchesDir before calling shell.openPath.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +24
const result = await window.electronApi.ipcRenderer.invoke(
FileEvents.OpenSketchSourceFile,
sketchesDir,
moduleId,
)
if (!result?.success) {
alert(result?.error || 'Source file not found for this sketch.')
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

ipcRenderer.invoke can reject (e.g., if the handler throws or IPC is unavailable). Right now that would surface as an unhandled promise rejection from a click handler. Wrap the invoke in a try/catch and surface a controlled error message (or return the error to the caller) so the UI can fail gracefully.

Suggested change
const result = await window.electronApi.ipcRenderer.invoke(
FileEvents.OpenSketchSourceFile,
sketchesDir,
moduleId,
)
if (!result?.success) {
alert(result?.error || 'Source file not found for this sketch.')
try {
const result = await window.electronApi.ipcRenderer.invoke(
FileEvents.OpenSketchSourceFile,
sketchesDir,
moduleId,
)
if (!result?.success) {
alert(result?.error || 'Source file not found for this sketch.')
}
} catch (error: unknown) {
const message =
(error && typeof error === 'object' && 'message' in error
? String((error as { message?: string }).message || '')
: '') || 'An unexpected error occurred.'
alert(`Failed to open source file: ${message}`)

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
const tsPath = path.join(sketchesDir, moduleId, 'index.ts')
const jsPath = path.join(sketchesDir, moduleId, 'index.js')
let filePath = tsPath
Copy link
Copy Markdown
Collaborator Author

@cale-bradbury cale-bradbury Mar 28, 2026

Choose a reason for hiding this comment

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

instead of all this (regenerating the path), do we want to just cache the path on load @funwithtriangles? might be handy if we ever support sketch root files with different names

@cale-bradbury cale-bradbury self-assigned this Mar 28, 2026
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.

2 participants