Skip to main content

Overview

The Desktop API provides type-safe Electron IPC communication via tRPC for managing workspaces, terminals, file systems, and git operations. Location: apps/desktop/src/lib/trpc/routers/

Router Structure

The desktop app router is created in apps/desktop/src/lib/trpc/routers/index.ts:29:
export const createAppRouter = (getWindow: () => BrowserWindow | null) => {
  return router({
    workspaces: createWorkspacesRouter(),
    terminal: createTerminalRouter(),
    filesystem: createFilesystemRouter(),
    changes: createChangesRouter(),
    projects: createProjectsRouter(getWindow),
    auth: createAuthRouter(),
    browser: createBrowserRouter(),
    // ... more routers
  });
};

export type AppRouter = ReturnType<typeof createAppRouter>;

Workspaces API

Manage git worktrees and workspace lifecycle. Source: apps/desktop/src/lib/trpc/routers/workspaces/

Procedures

workspaces.getAll

none
void
Returns all workspaces
workspaces
Workspace[]
Array of workspace objects
Example:
const { data: workspaces } = trpc.workspaces.getAll.useQuery();

workspaces.create

name
string
required
Workspace name
projectId
string
required
Project UUID
branchName
string
Branch name (auto-generated if not provided)
baseBranch
string
default:"main"
Branch to create from
Returns: Created workspace object Example:
const createWorkspace = trpc.workspaces.create.useMutation();

await createWorkspace.mutateAsync({
  name: 'feature-auth',
  projectId: 'proj-123',
  branchName: 'feature/auth',
  baseBranch: 'main'
});

workspaces.delete

id
string
required
Workspace UUID
Example:
await trpc.workspaces.delete.mutate({ id: 'ws-123' });

workspaces.refreshGitStatus

id
string
required
Workspace UUID
Returns: Git status information (branch, ahead/behind commits, dirty status)

Terminal API

Manage terminal sessions with daemon-backed runtime. Source: apps/desktop/src/lib/trpc/routers/terminal/terminal.ts:48

Environment Variables

Terminal sessions receive these environment variables:
  • PATH: Prepends ~/.superset/bin for agent command wrappers
  • SUPERSET_PANE_ID: Pane identifier
  • SUPERSET_TAB_ID: Tab identifier
  • SUPERSET_WORKSPACE_ID: Workspace UUID
  • SUPERSET_WORKSPACE_NAME: Workspace name
  • SUPERSET_WORKSPACE_PATH: Worktree path
  • SUPERSET_ROOT_PATH: Main repo path
  • SUPERSET_PORT: Hooks server port

Procedures

terminal.createOrAttach

paneId
string
required
Pane identifier (safe ID, no slashes)
tabId
string
required
Tab identifier
workspaceId
string
required
Workspace UUID
cols
number
Terminal columns
rows
number
Terminal rows
cwd
string
Working directory override
themeType
'dark' | 'light'
Terminal theme
Returns: { sessionKey: string } Example:
const { mutate: createTerminal } = trpc.terminal.createOrAttach.useMutation();

const { sessionKey } = await createTerminal({
  paneId: 'pane-1',
  tabId: 'tab-1',
  workspaceId: 'ws-123',
  cols: 80,
  rows: 24,
  themeType: 'dark'
});

terminal.write

paneId
string
required
Pane identifier
data
string
required
Data to write to terminal
Example:
await trpc.terminal.write.mutate({
  paneId: 'pane-1',
  data: 'npm install\n'
});

terminal.resize

paneId
string
required
Pane identifier
cols
number
required
New column count
rows
number
required
New row count

terminal.subscribe

Uses observable pattern (required by trpc-electron for Electron IPC subscriptions).
paneId
string
required
Pane identifier
Returns: Observable stream of terminal events Example:
const { data } = trpc.terminal.subscribe.useSubscription(
  { paneId: 'pane-1' },
  {
    onData: (event) => {
      if (event.type === 'data') {
        console.log(event.data);
      }
    }
  }
);

File System API

File operations with search capabilities. Source: apps/desktop/src/lib/trpc/routers/filesystem/index.ts:582

Procedures

filesystem.readDirectory

dirPath
string
required
Directory path to read
rootPath
string
required
Workspace root path
includeHidden
boolean
default:false
Include hidden files (starting with .)
entries
DirectoryEntry[]
Example:
const { data: entries } = trpc.filesystem.readDirectory.useQuery({
  dirPath: '/home/user/project',
  rootPath: '/home/user/project',
  includeHidden: false
});

filesystem.searchFiles

Fuzzy search for files by name.
rootPath
string
required
Search root directory
query
string
required
Search query
includePattern
string
Glob pattern to include (e.g., "*.ts,*.tsx")
excludePattern
string
Glob pattern to exclude (e.g., "node_modules,dist")
limit
number
default:200
Maximum results (max 500)
Example:
const { data: files } = trpc.filesystem.searchFiles.useQuery({
  rootPath: '/home/user/project',
  query: 'auth',
  includePattern: '*.ts,*.tsx',
  excludePattern: 'node_modules',
  limit: 50
});

filesystem.searchKeyword

Search file contents using ripgrep (falls back to scan if ripgrep unavailable).
rootPath
string
required
Search root directory
query
string
required
Search keyword
includePattern
string
File patterns to include
excludePattern
string
File patterns to exclude
includeHidden
boolean
default:false
Search hidden files
limit
number
default:200
Maximum matches
matches
KeywordSearchMatch[]
Example:
const { data: matches } = trpc.filesystem.searchKeyword.useQuery({
  rootPath: '/home/user/project',
  query: 'TODO',
  includePattern: '*.ts',
  limit: 100
});

filesystem.createFile

dirPath
string
required
Parent directory path
fileName
string
required
File name
content
string
default:""
File content
Returns: { path: string }

filesystem.createDirectory

parentPath
string
required
Parent directory
dirName
string
required
Directory name
Returns: { path: string }

filesystem.delete

paths
string[]
required
Paths to delete
permanent
boolean
default:false
Permanently delete (true) or move to trash (false)
Returns:
deleted
string[]
Successfully deleted paths
errors
Array<{path: string, error: string}>
Failed deletions

Git/Changes API

Git operations and file staging. Source: apps/desktop/src/lib/trpc/routers/changes/

Procedures

changes.status

workspaceId
string
required
Workspace UUID
Returns: Git status (staged, unstaged, untracked files)

changes.stage

workspaceId
string
required
Workspace UUID
files
string[]
required
File paths to stage

changes.unstage

workspaceId
string
required
Workspace UUID
files
string[]
required
File paths to unstage

changes.commit

workspaceId
string
required
Workspace UUID
message
string
required
Commit message

Usage Patterns

React Hooks

import { trpc } from '@/lib/trpc';

function MyComponent() {
  // Query
  const { data, isLoading, error } = trpc.workspaces.getAll.useQuery();
  
  // Mutation
  const createMutation = trpc.workspaces.create.useMutation({
    onSuccess: () => {
      console.log('Workspace created!');
    }
  });
  
  // Subscription
  const { data: terminalData } = trpc.terminal.subscribe.useSubscription(
    { paneId: 'pane-1' },
    { onData: (event) => console.log(event) }
  );
  
  return <div>{/* ... */}</div>;
}

Error Handling

try {
  await trpc.filesystem.createFile.mutate({
    dirPath: '/path',
    fileName: 'test.txt'
  });
} catch (error) {
  if (error instanceof TRPCError) {
    switch (error.code) {
      case 'BAD_REQUEST':
        console.error('Invalid input');
        break;
      case 'INTERNAL_SERVER_ERROR':
        console.error('Server error');
        break;
    }
  }
}

TypeScript Types

import type { AppRouter } from '@/lib/trpc/routers';
import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';

type RouterInputs = inferRouterInputs<AppRouter>;
type RouterOutputs = inferRouterOutputs<AppRouter>;

// Get input type for a specific procedure
type CreateWorkspaceInput = RouterInputs['workspaces']['create'];

// Get output type for a specific procedure
type Workspace = RouterOutputs['workspaces']['get'];

Next Steps

tRPC Endpoints

Explore cloud tRPC API procedures

Build docs developers (and LLMs) love