feat: US-003 — electron-trpc IPC bridge and appRouter scaffold

- Install electron-trpc, @trpc/server, @trpc/client, @trpc/react-query, @tanstack/react-query, zod
- Create appRouter in src/main/router/index.ts with stub routers for: health, clients, projects, tasks, checkpoints, notes, ai
- health.ping procedure returns 'pong'
- All procedure inputs validated with Zod schemas
- Configure IPC handler in main process (createIPCHandler) and preload (exposeElectronTRPC)
- Create renderer trpc client in src/renderer/lib/trpc.ts with ipcLink
- Wrap app with TRPCProvider + QueryClientProvider in src/renderer/index.tsx
- Verify health.ping in HomePage component (shows 'tRPC IPC bridge: pong')
- Typecheck passes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Roberto Musso
2026-02-19 16:41:52 +01:00
parent b5a9b18be4
commit 5254d13e4e
9 changed files with 338 additions and 78 deletions

View File

@@ -1,14 +1,34 @@
import { StrictMode } from 'react';
import { StrictMode, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { RouterProvider } from '@tanstack/react-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ipcLink } from 'electron-trpc/renderer';
import { router } from './router';
import { trpc } from './lib/trpc';
import './globals.css';
function App() {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [ipcLink()],
}),
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
</QueryClientProvider>
</trpc.Provider>
);
}
const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('Root element not found');
createRoot(rootElement).render(
<StrictMode>
<RouterProvider router={router} />
<App />
</StrictMode>,
);

4
src/renderer/lib/trpc.ts Normal file
View File

@@ -0,0 +1,4 @@
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../../main/router';
export const trpc = createTRPCReact<AppRouter>();

View File

@@ -1,10 +1,13 @@
import { createFileRoute } from '@tanstack/react-router';
import { trpc } from '@/lib/trpc';
export const Route = createFileRoute('/')({
component: HomePage,
});
function HomePage() {
const pingQuery = trpc.health.ping.useQuery();
return (
<div className="flex flex-col items-center justify-center h-full gap-4">
<div className="flex items-center gap-3">
@@ -27,6 +30,11 @@ function HomePage() {
<p className="text-muted-foreground text-sm">
Adiuva is ready. Start building.
</p>
{pingQuery.data && (
<p className="text-xs text-muted-foreground">
tRPC IPC bridge: {pingQuery.data}
</p>
)}
</div>
);
}