create-theokit 0.2.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/package.json +5 -1
  2. package/templates/default/.env.example +5 -0
  3. package/templates/default/README.md.tmpl +71 -57
  4. package/templates/default/_gitignore +2 -3
  5. package/templates/default/app/layout.tsx +51 -82
  6. package/templates/default/app/page.tsx +169 -271
  7. package/templates/default/app.ts +23 -0
  8. package/templates/default/package.json.tmpl +10 -23
  9. package/templates/default/server/agents/assistant.agent.ts +46 -0
  10. package/templates/default/server/controllers/tasks.controller.ts +70 -0
  11. package/templates/default/server/filters/http-error.filter.ts +20 -0
  12. package/templates/default/server/guards/auth.guard.ts +47 -0
  13. package/templates/default/server/interceptors/timing.interceptor.ts +14 -0
  14. package/templates/default/server/middleware/logger.middleware.ts +12 -0
  15. package/templates/default/server/store.ts +46 -0
  16. package/templates/default/server/toolboxes/task.tools.ts +58 -0
  17. package/templates/default/tsconfig.json +7 -7
  18. package/templates/api-only/.nvmrc +0 -1
  19. package/templates/api-only/README.md.tmpl +0 -78
  20. package/templates/api-only/_gitignore +0 -5
  21. package/templates/api-only/app/page.tsx +0 -3
  22. package/templates/api-only/index.html +0 -12
  23. package/templates/api-only/package.json.tmpl +0 -28
  24. package/templates/api-only/public/.gitkeep +0 -0
  25. package/templates/api-only/public/favicon.ico +0 -0
  26. package/templates/api-only/server/routes/health.ts +0 -5
  27. package/templates/api-only/server/routes/users.ts +0 -27
  28. package/templates/api-only/server/routes/webhooks/echo.ts +0 -34
  29. package/templates/api-only/theo.config.ts +0 -3
  30. package/templates/api-only/tsconfig.json +0 -15
  31. package/templates/dashboard/.nvmrc +0 -1
  32. package/templates/dashboard/README.md.tmpl +0 -76
  33. package/templates/dashboard/_gitignore +0 -5
  34. package/templates/dashboard/app/about/page.tsx +0 -3
  35. package/templates/dashboard/app/dashboard/layout.tsx +0 -10
  36. package/templates/dashboard/app/dashboard/page.tsx +0 -3
  37. package/templates/dashboard/app/layout.tsx +0 -14
  38. package/templates/dashboard/app/page.tsx +0 -8
  39. package/templates/dashboard/index.html +0 -12
  40. package/templates/dashboard/package.json.tmpl +0 -28
  41. package/templates/dashboard/public/.gitkeep +0 -0
  42. package/templates/dashboard/public/favicon.ico +0 -0
  43. package/templates/dashboard/server/crons/cleanup-conversations.ts +0 -59
  44. package/templates/dashboard/server/routes/health.ts +0 -5
  45. package/templates/dashboard/theo.config.ts +0 -3
  46. package/templates/dashboard/tsconfig.json +0 -15
  47. package/templates/default/.nvmrc +0 -1
  48. package/templates/default/index.html +0 -12
  49. package/templates/default/public/.gitkeep +0 -0
  50. package/templates/default/public/favicon.ico +0 -0
  51. package/templates/default/server/crons/cleanup-conversations.ts +0 -59
  52. package/templates/default/server/routes/chat.ts +0 -69
  53. package/templates/default/server/routes/health.ts +0 -5
  54. package/templates/default/theo.config.ts +0 -3
  55. package/templates/default/types/jobs.d.ts +0 -25
  56. package/templates/postgres/.env.example +0 -5
  57. package/templates/postgres/.nvmrc +0 -1
  58. package/templates/postgres/README.md.tmpl +0 -83
  59. package/templates/postgres/_gitignore +0 -5
  60. package/templates/postgres/app/layout.tsx +0 -14
  61. package/templates/postgres/app/page.tsx +0 -8
  62. package/templates/postgres/db/index.ts +0 -7
  63. package/templates/postgres/db/schema.ts +0 -8
  64. package/templates/postgres/drizzle.config.ts +0 -10
  65. package/templates/postgres/index.html +0 -12
  66. package/templates/postgres/package.json.tmpl +0 -36
  67. package/templates/postgres/public/.gitkeep +0 -0
  68. package/templates/postgres/public/favicon.ico +0 -0
  69. package/templates/postgres/server/context.ts +0 -5
  70. package/templates/postgres/server/jobs/log-message.ts +0 -26
  71. package/templates/postgres/server/routes/health.ts +0 -5
  72. package/templates/postgres/server/routes/users.ts +0 -22
  73. package/templates/postgres/theo.config.ts +0 -3
  74. package/templates/postgres/tsconfig.json +0 -15
  75. package/templates/saas/.env.example +0 -7
  76. package/templates/saas/.nvmrc +0 -1
  77. package/templates/saas/README.md.tmpl +0 -103
  78. package/templates/saas/_gitignore +0 -5
  79. package/templates/saas/app/layout.tsx +0 -5
  80. package/templates/saas/app/page.tsx +0 -104
  81. package/templates/saas/db/index.ts +0 -6
  82. package/templates/saas/db/schema.ts +0 -20
  83. package/templates/saas/drizzle.config.ts +0 -10
  84. package/templates/saas/index.html +0 -12
  85. package/templates/saas/package.json.tmpl +0 -38
  86. package/templates/saas/public/.gitkeep +0 -0
  87. package/templates/saas/public/favicon.ico +0 -0
  88. package/templates/saas/server/context.ts +0 -37
  89. package/templates/saas/server/routes/agent.ts +0 -49
  90. package/templates/saas/server/routes/billing/stripe-webhook.ts +0 -49
  91. package/templates/saas/server/routes/login.ts +0 -25
  92. package/templates/saas/server/routes/logout.ts +0 -10
  93. package/templates/saas/server/routes/me.ts +0 -10
  94. package/templates/saas/theo.config.ts +0 -5
  95. package/templates/saas/tsconfig.json +0 -15
  96. package/templates/services/agent-node/Dockerfile.tmpl +0 -20
  97. package/templates/services/agent-node/README.md +0 -38
  98. package/templates/services/agent-node/package.json.tmpl +0 -18
  99. package/templates/services/agent-node/src/index.ts +0 -58
  100. package/templates/services/agent-node/tsconfig.json +0 -13
  101. package/templates/services/agent-python/Dockerfile.tmpl +0 -20
  102. package/templates/services/agent-python/README.md +0 -37
  103. package/templates/services/agent-python/main.py +0 -77
  104. package/templates/services/agent-python/pyproject.toml.tmpl +0 -16
@@ -0,0 +1,47 @@
1
+ /**
2
+ * RolesGuard — RBAC authorization for controllers AND agents.
3
+ *
4
+ * Same guard, same pipeline, same behavior on both HTTP and AI routes.
5
+ * Uses @Roles([Role.Admin]) on class/method and @IsPublic(true) to skip.
6
+ */
7
+ import {
8
+ createDecorator, Reflector,
9
+ type CanActivate, type ExecutionContext,
10
+ } from '@theokit/http-decorators'
11
+
12
+ export enum Role {
13
+ User = 'user',
14
+ Admin = 'admin',
15
+ }
16
+
17
+ /** Declare required roles for a route or agent. */
18
+ export const Roles = createDecorator<Role[]>()
19
+
20
+ /** Mark a route as public — skips auth entirely. */
21
+ export const IsPublic = createDecorator<boolean>()
22
+
23
+ const reflector = new Reflector()
24
+
25
+ export class RolesGuard implements CanActivate {
26
+ canActivate(context: ExecutionContext): boolean {
27
+ // Public routes skip auth
28
+ const isPublic = reflector.getAllAndOverride(
29
+ IsPublic,
30
+ context.getClass(),
31
+ context.getMethodName(),
32
+ )
33
+ if (isPublic) return true
34
+
35
+ // Check required roles
36
+ const roles = reflector.getAllAndOverride(
37
+ Roles,
38
+ context.getClass(),
39
+ context.getMethodName(),
40
+ )
41
+ if (!roles) return true // no roles required
42
+
43
+ // Read role from request header (replace with JWT/session in production)
44
+ const userRole = context.getRequest().headers.get('x-role') ?? ''
45
+ return roles.some((r) => r === userRole)
46
+ }
47
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * TimingInterceptor — logs request duration.
3
+ * Applied to both controllers and agents.
4
+ */
5
+ import type { Interceptor } from '@theokit/http-decorators'
6
+
7
+ export class TimingInterceptor implements Interceptor {
8
+ async intercept(_request: Request, next: () => Promise<unknown>): Promise<unknown> {
9
+ const start = Date.now()
10
+ const result = await next()
11
+ console.log(` ${Date.now() - start}ms`)
12
+ return result
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * LoggerMiddleware — logs every incoming request.
3
+ */
4
+ import type { NestMiddleware } from '@theokit/http-decorators'
5
+
6
+ export class LoggerMiddleware implements NestMiddleware {
7
+ use(request: Request, next: () => Promise<Response | null>): Promise<Response | null> {
8
+ const url = new URL(request.url)
9
+ console.log(` ${new Date().toLocaleTimeString()} ${request.method} ${url.pathname}`)
10
+ return next()
11
+ }
12
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * In-memory data store.
3
+ * Replace with Drizzle + PostgreSQL for production.
4
+ */
5
+
6
+ export interface Task {
7
+ id: number
8
+ title: string
9
+ priority: 'low' | 'medium' | 'high'
10
+ done: boolean
11
+ createdAt: string
12
+ }
13
+
14
+ let seq = 0
15
+
16
+ const tasks: Task[] = [
17
+ { id: ++seq, title: 'Set up TheoKit project', priority: 'high', done: true, createdAt: '2026-01-01' },
18
+ { id: ++seq, title: 'Create first controller', priority: 'high', done: true, createdAt: '2026-01-02' },
19
+ { id: ++seq, title: 'Add AI agent', priority: 'medium', done: false, createdAt: '2026-01-03' },
20
+ { id: ++seq, title: 'Deploy to production', priority: 'low', done: false, createdAt: '2026-01-04' },
21
+ ]
22
+
23
+ export const taskStore = {
24
+ list: () => [...tasks],
25
+ get: (id: number) => tasks.find((t) => t.id === id),
26
+ search: (q: string) => tasks.filter((t) => t.title.toLowerCase().includes(q.toLowerCase())),
27
+ create: (data: { title: string; priority?: Task['priority'] }) => {
28
+ const task: Task = { id: ++seq, title: data.title, priority: data.priority ?? 'medium', done: false, createdAt: new Date().toISOString().split('T')[0] }
29
+ tasks.push(task)
30
+ return task
31
+ },
32
+ update: (id: number, data: Partial<Pick<Task, 'title' | 'priority' | 'done'>>) => {
33
+ const t = tasks.find((x) => x.id === id)
34
+ if (!t) return null
35
+ if (data.title !== undefined) t.title = data.title
36
+ if (data.priority !== undefined) t.priority = data.priority
37
+ if (data.done !== undefined) t.done = data.done
38
+ return t
39
+ },
40
+ remove: (id: number) => {
41
+ const idx = tasks.findIndex((t) => t.id === id)
42
+ if (idx === -1) return false
43
+ tasks.splice(idx, 1)
44
+ return true
45
+ },
46
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * TaskTools — agent toolbox for task management.
3
+ *
4
+ * These tools are called by the LLM when the agent decides
5
+ * to interact with the task data. Each @Tool method is
6
+ * compiled to a defineTool() call at startup.
7
+ */
8
+ import 'reflect-metadata'
9
+ import { z } from 'zod'
10
+ import { Toolbox, Tool, Trace, Audit } from '@theokit/agents'
11
+ import { taskStore } from '../store.js'
12
+
13
+ @Toolbox({ namespace: 'tasks' })
14
+ @Trace(true)
15
+ export class TaskTools {
16
+ @Tool({
17
+ name: 'list',
18
+ description: 'List all tasks with their status and priority',
19
+ input: z.object({}),
20
+ })
21
+ async list() {
22
+ return JSON.stringify(taskStore.list())
23
+ }
24
+
25
+ @Tool({
26
+ name: 'search',
27
+ description: 'Search tasks by keyword in title',
28
+ input: z.object({ query: z.string() }),
29
+ })
30
+ async search(input: { query: string }) {
31
+ return JSON.stringify(taskStore.search(input.query))
32
+ }
33
+
34
+ @Tool({
35
+ name: 'create',
36
+ description: 'Create a new task',
37
+ input: z.object({
38
+ title: z.string(),
39
+ priority: z.enum(['low', 'medium', 'high']).default('medium'),
40
+ }),
41
+ risk: 'medium',
42
+ })
43
+ @Audit(true)
44
+ async create(input: { title: string; priority?: 'low' | 'medium' | 'high' }) {
45
+ return JSON.stringify(taskStore.create(input))
46
+ }
47
+
48
+ @Tool({
49
+ name: 'complete',
50
+ description: 'Mark a task as done by its ID',
51
+ input: z.object({ taskId: z.number() }),
52
+ })
53
+ @Audit(true)
54
+ async complete(input: { taskId: number }) {
55
+ const task = taskStore.update(input.taskId, { done: true })
56
+ return task ? JSON.stringify(task) : 'Task not found'
57
+ }
58
+ }
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "experimentalDecorators": true,
7
+ "emitDecoratorMetadata": true,
6
8
  "strict": true,
7
- "noEmit": true,
8
9
  "esModuleInterop": true,
9
10
  "skipLibCheck": true,
10
- "jsx": "react-jsx",
11
- "isolatedModules": true,
12
- "resolveJsonModule": true
11
+ "outDir": "dist"
13
12
  },
14
- "include": ["app/**/*.ts", "app/**/*.tsx", "server/**/*.ts"]
13
+ "include": ["**/*.ts", "**/*.tsx"],
14
+ "exclude": ["node_modules", "dist"]
15
15
  }
@@ -1 +0,0 @@
1
- 22.12
@@ -1,78 +0,0 @@
1
- # {{name}}
2
-
3
- TheoKit API-only project. Backend routes with Zod validation + typed responses — no frontend bundle, no React.
4
-
5
- > 📚 **Full docs:** https://docs.theokit.dev
6
-
7
- ## Quick start
8
-
9
- ```bash
10
- # 1. Set your provider key if you wire an agent route later
11
- echo 'OPENROUTER_API_KEY=sk-or-v1-...' > .env
12
-
13
- # 2. Boot the dev server
14
- npx theokit dev
15
-
16
- # 3. Probe the health route
17
- curl http://localhost:3000/api/health
18
- ```
19
-
20
- You should see `{"status":"ok"}`. The server is now serving the routes under `server/routes/`.
21
-
22
- ## Templates
23
-
24
- - **default** — TheoUI chat composer + agent route.
25
- - **dashboard** — nested layouts + sidebar.
26
- - **api-only** (this one) — server routes without React.
27
- - **postgres** — Drizzle ORM + migrations.
28
- - **saas** — full app with auth, billing, sessions.
29
-
30
- ## What the framework auto-loads
31
-
32
- - **`.env` → `process.env`**. Edit `.env`; restart the dev server.
33
- - **`.theo/` build output cleanup** on every `theokit build`.
34
- - **Route discovery** — every `server/routes/*.ts` becomes a wired endpoint.
35
-
36
- ## Project structure
37
-
38
- ```
39
- server/
40
- ├── routes/
41
- │ ├── health.ts GET /api/health — returns {status:"ok"}
42
- │ └── users.ts CRUD /api/users — Zod-validated body
43
- theo.config.ts Framework config
44
- .env Secrets — never committed (.gitignore)
45
- ```
46
-
47
- ## Sample requests
48
-
49
- ```bash
50
- # Health check
51
- curl http://localhost:3000/api/health
52
-
53
- # Create a user (POST with JSON body)
54
- curl -X POST http://localhost:3000/api/users \
55
- -H 'Content-Type: application/json' \
56
- -d '{"name":"Alice","email":"alice@example.com"}'
57
-
58
- # List users
59
- curl http://localhost:3000/api/users
60
- ```
61
-
62
- ## Common commands
63
-
64
- | Command | What it does |
65
- |---|---|
66
- | `npx theokit dev` | Dev server with HMR + structured logs |
67
- | `npx theokit build` | Production build → `.theo/` |
68
- | `npx theokit start` | Serve the production build |
69
- | `npx theokit routes` | List all routes detected |
70
- | `npm run typecheck` | TypeScript strict check (no emit) |
71
-
72
- ## Add a new route
73
-
74
- Drop a `.ts` file in `server/routes/`. Use `defineRoute` from `theokit/server` for Zod-validated handlers, or export `GET`/`POST` directly.
75
-
76
- ## License
77
-
78
- Apply your own. The TheoKit framework is Apache-2.0.
@@ -1,5 +0,0 @@
1
- node_modules
2
- .theo
3
- dist
4
- .env
5
- .env.local
@@ -1,3 +0,0 @@
1
- export default function Page() {
2
- return <h1>Theo API Server</h1>
3
- }
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Theo App</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/@theo/entry-client"></script>
11
- </body>
12
- </html>
@@ -1,28 +0,0 @@
1
- {
2
- "name": "{{name}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "theokit dev",
8
- "build": "theokit build",
9
- "start": "theokit start",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "theokit": "^0.2.2",
14
- "react": "^19.0.0",
15
- "react-dom": "^19.0.0"
16
- },
17
- "devDependencies": {
18
- "@types/node": "^22.10.0",
19
- "typescript": "^5.7.0",
20
- "@types/react": "^19.0.0",
21
- "@types/react-dom": "^19.0.0"
22
- },
23
- "pnpm": {
24
- "onlyBuiltDependencies": [
25
- "esbuild"
26
- ]
27
- }
28
- }
File without changes
@@ -1,5 +0,0 @@
1
- import { defineRoute } from 'theokit/server'
2
-
3
- export const GET = defineRoute({
4
- handler: () => ({ ok: true }),
5
- })
@@ -1,27 +0,0 @@
1
- import { defineRoute } from 'theokit/server'
2
- import { z } from 'zod'
3
-
4
- const users = [
5
- { id: '1', name: 'Alice', email: 'alice@example.com' },
6
- { id: '2', name: 'Bob', email: 'bob@example.com' },
7
- ]
8
-
9
- export const GET = defineRoute({
10
- query: z.object({ search: z.string().optional() }),
11
- handler: ({ query }) => {
12
- if (query.search) {
13
- return users.filter((u) => u.name.toLowerCase().includes(query.search!.toLowerCase()))
14
- }
15
- return users
16
- },
17
- })
18
-
19
- export const POST = defineRoute({
20
- body: z.object({ name: z.string().min(1), email: z.string().email() }),
21
- status: 201,
22
- handler: ({ body }) => ({
23
- id: String(users.length + 1),
24
- name: body.name,
25
- email: body.email,
26
- }),
27
- })
@@ -1,34 +0,0 @@
1
- import { defineWebhook } from 'theokit/server'
2
- import { createHmac, timingSafeEqual } from 'node:crypto'
3
- import { z } from 'zod'
4
-
5
- /**
6
- * Echo webhook — demonstrates `defineWebhook` HMAC-SHA256 pattern
7
- * without depending on an external provider (Stripe, GitHub, etc.).
8
- *
9
- * Self-test:
10
- * SECRET=$(openssl rand -base64 32)
11
- * echo -n '{"message":"hi"}' | openssl dgst -sha256 -hmac "$SECRET"
12
- * curl -X POST localhost:3000/api/webhooks/echo \
13
- * -H "x-echo-signature: <hex from above>" \
14
- * -H "Content-Type: application/json" \
15
- * -d '{"message":"hi"}'
16
- */
17
- const ECHO_SECRET = process.env.ECHO_WEBHOOK_SECRET ?? ''
18
-
19
- export const POST = defineWebhook({
20
- verify: ({ rawBody, headers }) => {
21
- if (ECHO_SECRET === '') return false
22
- const sig = headers.get('x-echo-signature') ?? ''
23
- const expected = createHmac('sha256', ECHO_SECRET).update(rawBody).digest('hex')
24
- try {
25
- return timingSafeEqual(Buffer.from(sig, 'utf-8'), Buffer.from(expected, 'utf-8'))
26
- } catch {
27
- return false
28
- }
29
- },
30
- inputSchema: z.object({ message: z.string() }),
31
- handler: async ({ input }) => {
32
- return Response.json({ echoed: input.message, timestamp: new Date().toISOString() })
33
- },
34
- })
@@ -1,3 +0,0 @@
1
- import { defineConfig } from 'theokit'
2
-
3
- export default defineConfig({})
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "noEmit": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "jsx": "react-jsx",
11
- "isolatedModules": true,
12
- "resolveJsonModule": true
13
- },
14
- "include": ["app/**/*.ts", "app/**/*.tsx", "server/**/*.ts"]
15
- }
@@ -1 +0,0 @@
1
- 22.12
@@ -1,76 +0,0 @@
1
- # {{name}}
2
-
3
- TheoKit dashboard project. Build the app your agent lives in — with nested layouts and a sidebar wired from day one.
4
-
5
- > 📚 **Full docs:** https://docs.theokit.dev
6
-
7
- ## Quick start
8
-
9
- ```bash
10
- # 1. Set your provider key (OpenRouter recommended — one key, any model)
11
- echo 'OPENROUTER_API_KEY=sk-or-v1-...' > .env
12
-
13
- # 2. Boot the dev server
14
- npx theokit dev
15
- ```
16
-
17
- Open the printed URL. The default surface is a dashboard shell with sidebar nav + content area, ready to host your agent panels.
18
-
19
- ## Templates
20
-
21
- - **default** — TheoUI chat composer + agent route.
22
- - **dashboard** (this one) — nested layouts + sidebar nav.
23
- - **api-only** — server routes without React.
24
- - **postgres** — Drizzle ORM + migrations.
25
- - **saas** — full app with auth, billing, sessions.
26
-
27
- ## What the framework auto-loads
28
-
29
- - **`.env` → `process.env`**. Edit `.env`; restart the dev server.
30
- - **`.theo/` build output cleanup** on every `theokit build`.
31
- - **Tailwind + `@theokit/ui` styling** auto-configured for the TheoUI surface.
32
-
33
- ## Project structure
34
-
35
- ```
36
- app/ Frontend (file-based routing with nested layouts)
37
- ├── layout.tsx root wrapper — TheoUI provider + theme
38
- ├── page.tsx / — dashboard home
39
- ├── dashboard/
40
- │ ├── layout.tsx /dashboard/* — sidebar shell
41
- │ └── page.tsx /dashboard — primary panel
42
- server/ Backend (explicit routes)
43
- ├── routes/
44
- │ └── health.ts GET /api/health
45
- theo.config.ts Framework config
46
- tailwind.config.ts Tailwind theme tokens
47
- .env Secrets — never committed
48
- ```
49
-
50
- ## Common commands
51
-
52
- | Command | What it does |
53
- |---|---|
54
- | `npx theokit dev` | Dev server with HMR + devtools overlay |
55
- | `npx theokit build` | Production build → `.theo/` |
56
- | `npx theokit start` | Serve the production build |
57
- | `npx theokit check` | Lint for upgrade-readiness |
58
- | `npx theokit routes` | List all routes + actions detected |
59
- | `npm run typecheck` | TypeScript strict check (no emit) |
60
-
61
- ## Add a new panel
62
-
63
- ```bash
64
- mkdir -p app/dashboard/billing
65
- cat > app/dashboard/billing/page.tsx <<'EOF'
66
- export default function BillingPage() {
67
- return <h2>Billing</h2>
68
- }
69
- EOF
70
- ```
71
-
72
- The route appears at `/dashboard/billing` after HMR.
73
-
74
- ## License
75
-
76
- Apply your own. The TheoKit framework is Apache-2.0.
@@ -1,5 +0,0 @@
1
- node_modules
2
- .theo
3
- dist
4
- .env
5
- .env.local
@@ -1,3 +0,0 @@
1
- export default function AboutPage() {
2
- return <h1>About</h1>
3
- }
@@ -1,10 +0,0 @@
1
- import { Outlet } from 'react-router'
2
-
3
- export default function DashboardLayout() {
4
- return (
5
- <div>
6
- <h2>Dashboard Area</h2>
7
- <Outlet />
8
- </div>
9
- )
10
- }
@@ -1,3 +0,0 @@
1
- export default function DashboardPage() {
2
- return <h1>Dashboard</h1>
3
- }
@@ -1,14 +0,0 @@
1
- import { Outlet } from 'react-router'
2
-
3
- export default function RootLayout() {
4
- return (
5
- <div>
6
- <nav>
7
- <a href="/">Home</a> | <a href="/about">About</a> | <a href="/dashboard">Dashboard</a>
8
- </nav>
9
- <main>
10
- <Outlet />
11
- </main>
12
- </div>
13
- )
14
- }
@@ -1,8 +0,0 @@
1
- export default function HomePage() {
2
- return (
3
- <div>
4
- <h1>Welcome to Theo</h1>
5
- <p>Your fullstack TypeScript framework.</p>
6
- </div>
7
- )
8
- }
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Theo App</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/@theo/entry-client"></script>
11
- </body>
12
- </html>
@@ -1,28 +0,0 @@
1
- {
2
- "name": "{{name}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "theokit dev",
8
- "build": "theokit build",
9
- "start": "theokit start",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "theokit": "^0.2.2",
14
- "react": "^19.0.0",
15
- "react-dom": "^19.0.0"
16
- },
17
- "devDependencies": {
18
- "@types/node": "^22.10.0",
19
- "typescript": "^5.7.0",
20
- "@types/react": "^19.0.0",
21
- "@types/react-dom": "^19.0.0"
22
- },
23
- "pnpm": {
24
- "onlyBuiltDependencies": [
25
- "esbuild"
26
- ]
27
- }
28
- }
File without changes