Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/aipoch/open-science/llms.txt

Use this file to discover all available pages before exploring further.

All renderer↔main communication in Open Science flows through window.api — a typed object exposed by the Electron preload script via contextBridge.exposeInMainWorld('api', api). Never import from src/main/ in renderer code; every capability you need is available through window.api and the corresponding types in src/shared/.

Namespace overview

NamespaceDescription
window.api.acpAgent runtime: connect, sessions, prompts, permissions, events
window.api.artifactsArtifact storage: finalize runs, open files, read previews
window.api.notebookPython kernel: state, cells, execution, lifecycle, events
window.api.projectsProject CRUD (SQLite-backed)
window.api.previewPer-project preview panel state (SQLite-backed)
window.api.uploadsFile attachment staging and finalization
window.api.sessionsChat session persistence (disk-based)
window.api.saveBlobFileSave a blob to disk via the system file picker
window.api.getRuntimeVersionsGet Electron, Chrome, and Node version strings

Top-level methods

saveBlobFile(request)

Saves binary or text blob data to a user-chosen location via the OS file-save dialog. The request parameter is SaveBlobFileRequest and the return value is Promise<SaveBlobFileResult>.

getRuntimeVersions()

Returns an object with the running version strings for the three Electron runtime layers:
const versions = window.api.getRuntimeVersions()
// { electron: '29.0.0', chrome: '122.0.0', node: '20.9.0' }
This is a synchronous call — no promise wrapping required.

Event listener pattern

Methods prefixed with on (e.g., onState, onEvent, onPermissionRequest) register an IPC listener and return an unsubscribe function. Always call the unsubscribe function in your cleanup effect to prevent memory leaks and duplicate event delivery:
import { useEffect } from 'react'
import type { AcpStateSnapshot } from '../../../../shared/acp'

useEffect(() => {
  const unsubscribe = window.api.acp.onState((snapshot: AcpStateSnapshot) => {
    // handle state update
  })

  // Cleanup on unmount or dependency change:
  return () => unsubscribe()
}, [])
The same pattern applies to all event listeners across every namespace:
// Notebook events
const unsub = window.api.notebook.onAvailable((event) => { /* ... */ })
return () => unsub()

// Permission requests
const unsub = window.api.acp.onPermissionRequest((request) => { /* ... */ })
return () => unsub()

IPC error handling

All invoke-based methods return Promises. Wrap them in try/catch to handle main-process errors gracefully:
try {
  const projects = await window.api.projects.list()
  setProjects(projects)
} catch (error) {
  console.error('Failed to load projects:', error)
}
Errors are serialized across the IPC boundary by Electron — the message property is preserved, but custom error subclasses are not.

Type imports

Shared types live in src/shared/ and can be imported directly in renderer code without going through the preload. Import only types — never runtime values — from shared modules:
import type { AcpStateSnapshot } from '../../../../shared/acp'
import type { ArtifactFile, ArtifactPreviewResult } from '../../../../shared/artifacts'
import type { PersistedChatSession } from '../../../../shared/session-persistence'
import type { Project } from '../../../../shared/projects'
import type { UploadedAttachment } from '../../../../shared/uploads'
import type { NotebookSessionState, NotebookRunSummary } from '../../../../shared/notebook'
window.api is only available inside the Electron renderer process. It is not defined in Node.js test environments or in the main process. If you need to call a function in tests, mock window.api directly or use the handler factories exported from each src/main/*/ipc.ts module.

IPC channel reference

The following table maps each window.api method to its underlying IPC channel for debugging with Electron DevTools or ipcMain traces:
MethodIPC Channel
acp.getState()acp:get-state
acp.connect()acp:connect
acp.disconnect()acp:disconnect
acp.createSession()acp:create-session
acp.resumeSession()acp:resume-session
acp.sendPrompt()acp:send-prompt
acp.cancel()acp:cancel
acp.deleteSession()acp:delete-session
acp.respondToPermission()acp:respond-permission
acp.onState()acp:state (push)
acp.onEvent()acp:event (push)
acp.onPermissionRequest()acp:permission-request (push)
artifacts.finalizeRunArtifacts()artifacts:finalize-run
artifacts.openFile()artifacts:open-file
artifacts.readPreview()artifacts:read-preview
notebook.state()notebook:state
notebook.beginCodeCell()notebook:begin-code-cell
notebook.appendCodeCell()notebook:append-code-cell
notebook.finishCodeCell()notebook:finish-code-cell
notebook.runCell()notebook:run-cell
notebook.execute()notebook:execute
notebook.restart()notebook:restart
notebook.shutdown()notebook:shutdown
notebook.onAvailable()notebook:available (push)
notebook.onChanged()notebook:changed (push)
projects.list()projects:list
projects.get()projects:get
projects.create()projects:create
projects.update()projects:update
projects.delete()projects:delete
preview.load()preview:load
preview.save()preview:save
preview.delete()preview:delete
uploads.stageFiles()uploads:stage-files
uploads.deleteUpload()uploads:delete
uploads.finalizeSession()uploads:finalize-session
uploads.readPreview()uploads:read-preview
sessions.loadAll()sessions:load-all
sessions.saveSession()sessions:save-session
sessions.deleteSession()sessions:delete-session
sessions.deleteProjectSessions()sessions:delete-project-sessions
sessions.saveManifest()sessions:save-manifest
saveBlobFile()file:save-blob

Build docs developers (and LLMs) love