diff --git a/README.md b/README.md
index 8570ebb..b779b51 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-yo world
\ No newline at end of file
+yo world
diff --git a/biome.json b/biome.json
new file mode 100644
index 0000000..e8d99dd
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,3 @@
+{
+ "extends": ["@rubriclab/config/biome"]
+}
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..830fb59
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/next.config.ts b/next.config.ts
new file mode 100644
index 0000000..0f34b5f
--- /dev/null
+++ b/next.config.ts
@@ -0,0 +1,15 @@
+import type { NextConfig } from 'next'
+
+export default {
+ reactStrictMode: true,
+ transpilePackages: [
+ '@rubriclab/actions',
+ '@rubriclab/agents',
+ '@rubriclab/auth',
+ '@rubriclab/blocks',
+ '@rubriclab/chains',
+ '@rubriclab/events',
+ '@rubriclab/shapes',
+ '@rubriclab/webhooks'
+ ]
+} satisfies NextConfig
diff --git a/package.json b/package.json
index 3196d02..955c54a 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,40 @@
{
- "name": "test",
- "module": "index.ts",
- "type": "module",
- "private": true,
- "scripts": {
- "start": "bun run index.ts"
- },
- "devDependencies": {
- "@types/bun": "latest"
- },
- "peerDependencies": {
- "typescript": "^5"
- }
+ "dependencies": {
+ "@prisma/client": "^6.14.0",
+ "@rubriclab/agents": "^0.0.58",
+ "@rubriclab/auth": "^0.0.50",
+ "@rubriclab/events": "^0.0.37",
+ "@t3-oss/env-nextjs": "^0.13.8",
+ "dotenv": "^17.2.1",
+ "next": "^15.5.1",
+ "react": "^19.1.1",
+ "react-dom": "^19.1.1"
+ },
+ "description": "This project was bootstrapped with create-rubric-app",
+ "devDependencies": {
+ "@rubriclab/config": "^0.0.22",
+ "@types/node": "^24.3.0",
+ "@types/react": "^19.1.11",
+ "@types/react-dom": "^19.1.8",
+ "prisma": "^6.14.0",
+ "typescript": "^5.9.2",
+ "zod": "^4.1.3"
+ },
+ "license": "go nuts",
+ "name": "my-app",
+ "private": true,
+ "scripts": {
+ "bleed": "bun x npm-check-updates -u --dep prod,dev,optional,peer",
+ "build": "next build",
+ "check": "bun x biome check .",
+ "clean": "rm -rf .next && rm -rf node_modules",
+ "db:generate": "prisma generate",
+ "db:push": "bun --env-file=.env prisma generate && prisma db push",
+ "db:seed": "prisma db seed",
+ "db:studio": "prisma studio",
+ "dev": "next dev",
+ "format": "bun x biome check --write .",
+ "start": "next start"
+ },
+ "version": "0.0.0"
}
diff --git a/postcss.config.mjs b/postcss.config.mjs
new file mode 100644
index 0000000..fc6c4d8
--- /dev/null
+++ b/postcss.config.mjs
@@ -0,0 +1 @@
+export { default } from '@rubriclab/config/postcss'
diff --git a/prisma.config.ts b/prisma.config.ts
new file mode 100644
index 0000000..8e9db6e
--- /dev/null
+++ b/prisma.config.ts
@@ -0,0 +1,9 @@
+import 'dotenv/config'
+import { defineConfig } from 'prisma/config'
+
+export default defineConfig({
+ migrations: {
+ seed: 'bun run prisma/seed.ts'
+ },
+ schema: 'prisma'
+})
diff --git a/prisma/auth.prisma b/prisma/auth.prisma
new file mode 100644
index 0000000..5919aae
--- /dev/null
+++ b/prisma/auth.prisma
@@ -0,0 +1,72 @@
+model User {
+ id String @id @default(nanoid(6))
+ email String @unique
+
+ oAuth2AuthenticationAccounts OAuth2AuthenticationAccount[]
+ oAuth2AuthorizationAccounts OAuth2AuthorizationAccount[]
+ apiKeyAuthorizationAccounts ApiKeyAuthorizationAccount[]
+
+ sessions Session[]
+
+ tasks Task[]
+}
+
+model OAuth2AuthenticationRequest {
+ token String @id
+ callbackUrl String
+ expiresAt DateTime
+}
+
+model OAuth2AuthorizationRequest {
+ token String @id
+ userId String
+ callbackUrl String
+ expiresAt DateTime
+}
+
+model MagicLinkRequest {
+ token String @id
+ email String
+ expiresAt DateTime
+}
+
+model OAuth2AuthenticationAccount {
+ userId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ provider String
+ accountId String
+ accessToken String
+ refreshToken String
+ expiresAt DateTime
+
+ @@id([userId, provider, accountId])
+}
+
+model OAuth2AuthorizationAccount {
+ userId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ provider String
+ accountId String
+ accessToken String
+ refreshToken String
+ expiresAt DateTime
+
+ @@id([userId, provider, accountId])
+}
+
+model ApiKeyAuthorizationAccount {
+ userId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ provider String
+ accountId String
+ apiKey String
+
+ @@id([userId, provider, accountId])
+}
+
+model Session {
+ key String @id @default(cuid())
+ userId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ expiresAt DateTime
+}
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
new file mode 100644
index 0000000..a6210d5
--- /dev/null
+++ b/prisma/schema.prisma
@@ -0,0 +1,18 @@
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+
+model Task {
+ id Int @id @default(autoincrement())
+ title String
+ createdAt DateTime @default(now())
+ status Boolean @default(false)
+
+ user User? @relation(fields: [userId], references: [id])
+ userId String?
+}
diff --git a/prisma/seed.ts b/prisma/seed.ts
new file mode 100644
index 0000000..374c587
--- /dev/null
+++ b/prisma/seed.ts
@@ -0,0 +1,14 @@
+#!/usr/bin/env bun
+
+import db from '~/db'
+
+async function seed() {
+ await db.task.create({
+ data: {
+ status: false,
+ title: 'Create your first task'
+ }
+ })
+}
+
+seed()
diff --git a/public/fonts/PlusJakartaSans-Bold.ttf b/public/fonts/PlusJakartaSans-Bold.ttf
new file mode 100644
index 0000000..386d3a6
Binary files /dev/null and b/public/fonts/PlusJakartaSans-Bold.ttf differ
diff --git a/src/app/(app)/ai.tsx b/src/app/(app)/ai.tsx
new file mode 100644
index 0000000..c9e187d
--- /dev/null
+++ b/src/app/(app)/ai.tsx
@@ -0,0 +1,34 @@
+'use server'
+
+import { executeTodoAgent } from '~/agents/todo'
+import env from '~/env'
+import { publish } from '~/events/server'
+
+export async function sendMessage({ userId, message }: { userId: string; message: string }) {
+ const { response } = await executeTodoAgent({
+ messages: [{ content: message, role: 'user' }],
+ onEvent: async events => {
+ switch (events.type) {
+ case 'assistant_message': {
+ await publish({
+ channel: userId,
+ eventType: events.type,
+ payload: events
+ })
+ break
+ }
+ case 'function_call': {
+ await publish({
+ channel: userId,
+ eventType: events.name,
+ payload: events
+ })
+ break
+ }
+ }
+ },
+ openAIKey: env.OPENAI_API_KEY
+ })
+
+ console.log(response)
+}
diff --git a/src/app/(app)/chat.tsx b/src/app/(app)/chat.tsx
new file mode 100644
index 0000000..cfb546c
--- /dev/null
+++ b/src/app/(app)/chat.tsx
@@ -0,0 +1,90 @@
+'use client'
+
+import { useState } from 'react'
+import type { TodoAgentResponseEvent, TodoAgentToolEvent } from '~/agents/todo'
+import { useSession } from '~/auth/client'
+import { ChatBox } from '~/components/ChatBox'
+import { AssistantMessage, ToolMessage, UserMessage } from '~/components/Message'
+
+import { useEvents } from '~/events/client'
+import { sendMessage } from './ai'
+
+type Message =
+ | TodoAgentToolEvent
+ | TodoAgentResponseEvent
+ | {
+ id: string
+ type: 'user_message'
+ message: string
+ }
+
+function MessageSwitch({ message }: { message: Message }) {
+ switch (message.type) {
+ case 'user_message': {
+ return {message.message}
+ }
+
+ case 'assistant_message': {
+ return {message.message.response}
+ }
+ case 'function_call': {
+ return (
+
+ )
+ }
+ }
+}
+
+function ChatMessages({
+ userId,
+ messages,
+ addMessage
+}: {
+ userId: string
+ messages: Message[]
+ addMessage: (message: Message) => void
+}) {
+ useEvents({
+ id: userId,
+ on: {
+ assistant_message: addMessage
+ }
+ })
+
+ return (
+
+ {messages.map(message => (
+
+ ))}
+
+ )
+}
+
+export default function Chat() {
+ const { userId } = useSession()
+ const [messages, setMessages] = useState([])
+
+ function addMessage(message: Message) {
+ setMessages(prev => [...prev, message])
+ }
+
+ function handleSubmit(message: string) {
+ addMessage({
+ id: Date.now().toString(),
+ message,
+ type: 'user_message'
+ })
+ sendMessage({ message, userId })
+ }
+
+ return (
+
+
+
+
+ )
+}
diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx
new file mode 100644
index 0000000..30354ff
--- /dev/null
+++ b/src/app/(app)/layout.tsx
@@ -0,0 +1,17 @@
+import { getSession } from '~/auth/actions'
+import { ClientAuthProvider } from '~/auth/client'
+import { Nav } from '~/components/Nav'
+
+export default async function AppLayout({ children }: { children: React.ReactNode }) {
+ return (
+ // @ts-expect-error: Auth Package Bug
+
+
+
+ )
+}
diff --git a/src/app/(app)/page.tsx b/src/app/(app)/page.tsx
new file mode 100644
index 0000000..744f3c5
--- /dev/null
+++ b/src/app/(app)/page.tsx
@@ -0,0 +1,5 @@
+import Chat from './chat'
+
+export default function Page() {
+ return
+}
diff --git a/src/app/(landing)/signin/page.tsx b/src/app/(landing)/signin/page.tsx
new file mode 100644
index 0000000..2f898e3
--- /dev/null
+++ b/src/app/(landing)/signin/page.tsx
@@ -0,0 +1,5 @@
+import { SignInWithGithubButton } from '~/components/SignIn'
+
+export default function SignInPage() {
+ return
+}
diff --git a/src/app/api/auth/[...auth]/route.ts b/src/app/api/auth/[...auth]/route.ts
new file mode 100644
index 0000000..e772cb1
--- /dev/null
+++ b/src/app/api/auth/[...auth]/route.ts
@@ -0,0 +1,3 @@
+import { routes } from '~/auth/server'
+
+export const { GET } = routes
diff --git a/src/app/api/events/route.ts b/src/app/api/events/route.ts
new file mode 100644
index 0000000..f96bd80
--- /dev/null
+++ b/src/app/api/events/route.ts
@@ -0,0 +1 @@
+export { GET, maxDuration } from '~/events/server'
diff --git a/src/app/icon.tsx b/src/app/icon.tsx
new file mode 100644
index 0000000..9e70457
--- /dev/null
+++ b/src/app/icon.tsx
@@ -0,0 +1,30 @@
+import { ImageResponse } from 'next/og'
+
+export const contentType = 'image/png'
+export const size = {
+ height: 32,
+ width: 32
+}
+
+export default async function Icon() {
+ return new ImageResponse(
+
+ R
+
,
+ {
+ ...size
+ }
+ )
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
new file mode 100644
index 0000000..bb1ec7c
--- /dev/null
+++ b/src/app/layout.tsx
@@ -0,0 +1,14 @@
+import './styles.css'
+
+export const metadata = {
+ description: 'Generated by Create Rubric App',
+ title: 'Create Rubric App'
+}
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx
new file mode 100644
index 0000000..d1e6475
--- /dev/null
+++ b/src/app/opengraph-image.tsx
@@ -0,0 +1,41 @@
+import { readFile } from 'node:fs/promises'
+import { ImageResponse } from 'next/og'
+
+export const alt = 'Create Rubric App'
+export const size = {
+ height: 630,
+ width: 1200
+}
+
+export const contentType = 'image/png'
+
+export default async function Image() {
+ const interSemiBold = await readFile('public/fonts/PlusJakartaSans-Bold.ttf')
+
+ return new ImageResponse(
+
+ R
+
,
+ {
+ ...size,
+ fonts: [
+ {
+ data: interSemiBold,
+ name: 'Inter',
+ style: 'normal',
+ weight: 400
+ }
+ ]
+ }
+ )
+}
diff --git a/src/app/styles.css b/src/app/styles.css
new file mode 100644
index 0000000..cca18ce
--- /dev/null
+++ b/src/app/styles.css
@@ -0,0 +1,3 @@
+/** biome-ignore-all lint/suspicious/noUnknownAtRules: Tailwind Grammar */
+
+@import "tailwindcss";
diff --git a/src/app/twitter-image.tsx b/src/app/twitter-image.tsx
new file mode 100644
index 0000000..90779fd
--- /dev/null
+++ b/src/app/twitter-image.tsx
@@ -0,0 +1 @@
+export { alt, contentType, default, size } from './opengraph-image'
diff --git a/src/lib/agents/todo.ts b/src/lib/agents/todo.ts
new file mode 100644
index 0000000..a416c02
--- /dev/null
+++ b/src/lib/agents/todo.ts
@@ -0,0 +1,33 @@
+import { createAgent, createResponseFormat, noTabs } from '@rubriclab/agents'
+import { z } from 'zod/v4'
+import createTodo from '~/tools/createTodo'
+import getTodoList from '~/tools/getTodoList'
+
+const responseFormat = createResponseFormat({
+ name: 'todo_agent_response_format',
+ schema: z.object({
+ response: z.string()
+ })
+})
+
+const systemPrompt = noTabs`
+ You are a todo agent.
+ The user will ask you to do CRUD operations against a TODO database.
+ You should use tools to help them.
+`
+
+const { executeAgent, eventTypes, __ToolEvent, __ResponseEvent } = createAgent({
+ model: 'gpt-4.1-mini',
+ responseFormat,
+ systemPrompt,
+ tools: {
+ createTodo,
+ getTodoList
+ }
+})
+
+export { eventTypes as todoAgentEventTypes }
+export { executeAgent as executeTodoAgent }
+
+export type TodoAgentToolEvent = typeof __ToolEvent
+export type TodoAgentResponseEvent = typeof __ResponseEvent
diff --git a/src/lib/auth/actions.ts b/src/lib/auth/actions.ts
new file mode 100644
index 0000000..aa760fb
--- /dev/null
+++ b/src/lib/auth/actions.ts
@@ -0,0 +1,5 @@
+'use server'
+
+import { actions } from './server'
+
+export const { signIn, signOut, sendMagicLink, getAuthConstants, getSession } = actions
diff --git a/src/lib/auth/client.ts b/src/lib/auth/client.ts
new file mode 100644
index 0000000..1156d65
--- /dev/null
+++ b/src/lib/auth/client.ts
@@ -0,0 +1,19 @@
+'use client'
+
+import type { Prisma } from '@prisma/client'
+import { CreateAuthContext } from '@rubriclab/auth/client'
+
+export const { ClientAuthProvider, useSession } =
+ CreateAuthContext<
+ Prisma.SessionGetPayload<{
+ include: {
+ user: {
+ include: {
+ apiKeyAuthorizationAccounts: true
+ oAuth2AuthenticationAccounts: true
+ oAuth2AuthorizationAccounts: true
+ }
+ }
+ }
+ }>
+ >()
diff --git a/src/lib/auth/server.ts b/src/lib/auth/server.ts
new file mode 100644
index 0000000..7f1e9fe
--- /dev/null
+++ b/src/lib/auth/server.ts
@@ -0,0 +1,14 @@
+import { createAuth, createGithubAuthenticationProvider, prismaAdapter } from '@rubriclab/auth'
+import db from '~/db'
+import env from '~/env'
+
+export const { routes, actions, __types } = createAuth({
+ authUrl: env.NEXT_PUBLIC_AUTH_URL,
+ databaseProvider: prismaAdapter(db),
+ oAuth2AuthenticationProviders: {
+ github: createGithubAuthenticationProvider({
+ githubClientId: env.GITHUB_CLIENT_ID,
+ githubClientSecret: env.GITHUB_CLIENT_SECRET
+ })
+ }
+})
diff --git a/src/lib/components/ChatBox.tsx b/src/lib/components/ChatBox.tsx
new file mode 100644
index 0000000..0982808
--- /dev/null
+++ b/src/lib/components/ChatBox.tsx
@@ -0,0 +1,51 @@
+'use client'
+
+import { type KeyboardEvent, useState } from 'react'
+
+export function ChatBox({
+ submit,
+ placeholder = 'Type a message...'
+}: {
+ submit: (message: string) => void
+ placeholder?: string
+}) {
+ const [message, setMessage] = useState(placeholder)
+
+ return (
+
+ )
+}
diff --git a/src/lib/components/Message.tsx b/src/lib/components/Message.tsx
new file mode 100644
index 0000000..f89b8ee
--- /dev/null
+++ b/src/lib/components/Message.tsx
@@ -0,0 +1,52 @@
+export function UserMessage({ children }: { children: React.ReactNode }) {
+ return (
+
+ )
+}
+
+export function AssistantMessage({ children }: { children: React.ReactNode }) {
+ return (
+
+ )
+}
+
+export function ToolMessage({
+ name,
+ args,
+ result
+}: {
+ name: string
+ args: React.ReactNode
+ result?: React.ReactNode
+}) {
+ return (
+
+
+
+ Tool: {name}
+
+
+
+
+ {result && (
+
+
+ Output
+
+
{result}
+
+ )}
+
+
+
+ )
+}
diff --git a/src/lib/components/Nav.tsx b/src/lib/components/Nav.tsx
new file mode 100644
index 0000000..69b7962
--- /dev/null
+++ b/src/lib/components/Nav.tsx
@@ -0,0 +1,17 @@
+'use client'
+
+import { useSession } from '~/auth/client'
+import { SignOutButton } from '~/components/SignOut'
+
+export function Nav() {
+ const { user } = useSession()
+ return (
+
+
Home
+
+
Signed in as {user.email}
+
+
+
+ )
+}
diff --git a/src/lib/components/SignIn.tsx b/src/lib/components/SignIn.tsx
new file mode 100644
index 0000000..832ef4c
--- /dev/null
+++ b/src/lib/components/SignIn.tsx
@@ -0,0 +1,11 @@
+'use client'
+
+import { signIn } from '~/auth/actions'
+
+export function SignInWithGithubButton() {
+ return (
+
+ )
+}
diff --git a/src/lib/components/SignOut.tsx b/src/lib/components/SignOut.tsx
new file mode 100644
index 0000000..4d384f1
--- /dev/null
+++ b/src/lib/components/SignOut.tsx
@@ -0,0 +1,15 @@
+'use client'
+
+import { signOut } from '~/auth/actions'
+
+export function SignOutButton() {
+ return (
+
+ )
+}
diff --git a/src/lib/db.ts b/src/lib/db.ts
new file mode 100644
index 0000000..c4e22e4
--- /dev/null
+++ b/src/lib/db.ts
@@ -0,0 +1,3 @@
+import { PrismaClient } from '@prisma/client'
+
+export default new PrismaClient()
diff --git a/src/lib/env.ts b/src/lib/env.ts
new file mode 100644
index 0000000..4df8bd8
--- /dev/null
+++ b/src/lib/env.ts
@@ -0,0 +1,19 @@
+import { createEnv } from '@t3-oss/env-nextjs'
+import z from 'zod'
+
+export default createEnv({
+ client: {
+ NEXT_PUBLIC_AUTH_URL: z.string().min(1)
+ },
+ experimental__runtimeEnv: {
+ NEXT_PUBLIC_AUTH_URL: process.env.NEXT_PUBLIC_AUTH_URL
+ },
+ server: {
+ DATABASE_URL: z.string().min(1),
+ GITHUB_CLIENT_ID: z.string().min(1),
+ GITHUB_CLIENT_SECRET: z.string().min(1),
+ NODE_ENV: z.string(),
+ OPENAI_API_KEY: z.string().min(1),
+ UPSTASH_REDIS_URL: z.string().min(1)
+ }
+})
diff --git a/src/lib/events/client.ts b/src/lib/events/client.ts
new file mode 100644
index 0000000..ede0659
--- /dev/null
+++ b/src/lib/events/client.ts
@@ -0,0 +1,7 @@
+import { createEventsClient } from '@rubriclab/events/client'
+import { eventTypes } from '~/events/types'
+
+export const { useEvents } = createEventsClient({
+ eventTypes,
+ url: '/api/events'
+})
diff --git a/src/lib/events/server.ts b/src/lib/events/server.ts
new file mode 100644
index 0000000..92d0d1b
--- /dev/null
+++ b/src/lib/events/server.ts
@@ -0,0 +1,8 @@
+import { createEventsServer } from '@rubriclab/events/server'
+import env from '~/env'
+import { eventTypes } from '~/events/types'
+
+export const { publish, GET, maxDuration } = createEventsServer({
+ eventTypes,
+ redisURL: env.UPSTASH_REDIS_URL
+})
diff --git a/src/lib/events/types.ts b/src/lib/events/types.ts
new file mode 100644
index 0000000..7508659
--- /dev/null
+++ b/src/lib/events/types.ts
@@ -0,0 +1,6 @@
+import { createEventTypes } from '@rubriclab/events'
+import { todoAgentEventTypes } from '~/agents/todo'
+
+export const eventTypes = createEventTypes({
+ ...todoAgentEventTypes
+})
diff --git a/src/lib/tools/createTodo.ts b/src/lib/tools/createTodo.ts
new file mode 100644
index 0000000..4945154
--- /dev/null
+++ b/src/lib/tools/createTodo.ts
@@ -0,0 +1,22 @@
+import { createTool } from '@rubriclab/agents'
+import z from 'zod/v4'
+import db from '~/db'
+
+export default createTool({
+ async execute({ status, title }) {
+ await db.task.create({
+ data: {
+ status,
+ title
+ }
+ })
+ return undefined
+ },
+ schema: {
+ input: z.object({
+ status: z.boolean(),
+ title: z.string()
+ }),
+ output: z.undefined()
+ }
+})
diff --git a/src/lib/tools/getTodoList.ts b/src/lib/tools/getTodoList.ts
new file mode 100644
index 0000000..7bef5f0
--- /dev/null
+++ b/src/lib/tools/getTodoList.ts
@@ -0,0 +1,31 @@
+import { createTool } from '@rubriclab/agents'
+import z from 'zod/v4'
+import db from '~/db'
+
+export default createTool({
+ async execute() {
+ return await db.task.findMany({
+ include: {
+ user: {
+ select: {
+ email: true
+ }
+ }
+ }
+ })
+ },
+ schema: {
+ input: z.object({}),
+ output: z.array(
+ z.object({
+ status: z.boolean(),
+ title: z.string(),
+ user: z
+ .object({
+ email: z.string()
+ })
+ .nullable()
+ })
+ )
+ }
+})
diff --git a/tsconfig.json b/tsconfig.json
index bfa0fea..d018413 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,29 +1,24 @@
{
"compilerOptions": {
- // Environment setup & latest features
- "lib": ["ESNext"],
- "target": "ESNext",
- "module": "Preserve",
- "moduleDetection": "force",
- "jsx": "react-jsx",
- "allowJs": true,
-
- // Bundler mode
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "noEmit": true,
-
- // Best practices
- "strict": true,
- "skipLibCheck": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedIndexedAccess": true,
- "noImplicitOverride": true,
-
- // Some stricter flags (disabled by default)
- "noUnusedLocals": false,
- "noUnusedParameters": false,
- "noPropertyAccessFromIndexSignature": false
- }
+ "baseUrl": ".",
+ "paths": {
+ "~/*": [
+ "./src/lib/*"
+ ]
+ },
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "exclude": [
+ "node_modules"
+ ],
+ "extends": "@rubriclab/config/tsconfig",
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts"
+ ]
}