create-theokit 0.4.0-beta.0 → 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 (105) hide show
  1. package/package.json +8 -4
  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/LICENSE +0 -201
  19. package/templates/api-only/.nvmrc +0 -1
  20. package/templates/api-only/README.md.tmpl +0 -78
  21. package/templates/api-only/_gitignore +0 -5
  22. package/templates/api-only/app/page.tsx +0 -3
  23. package/templates/api-only/index.html +0 -12
  24. package/templates/api-only/package.json.tmpl +0 -28
  25. package/templates/api-only/public/.gitkeep +0 -0
  26. package/templates/api-only/public/favicon.ico +0 -0
  27. package/templates/api-only/server/routes/health.ts +0 -5
  28. package/templates/api-only/server/routes/users.ts +0 -27
  29. package/templates/api-only/server/routes/webhooks/echo.ts +0 -34
  30. package/templates/api-only/theo.config.ts +0 -3
  31. package/templates/api-only/tsconfig.json +0 -15
  32. package/templates/dashboard/.nvmrc +0 -1
  33. package/templates/dashboard/README.md.tmpl +0 -76
  34. package/templates/dashboard/_gitignore +0 -5
  35. package/templates/dashboard/app/about/page.tsx +0 -3
  36. package/templates/dashboard/app/dashboard/layout.tsx +0 -10
  37. package/templates/dashboard/app/dashboard/page.tsx +0 -3
  38. package/templates/dashboard/app/layout.tsx +0 -14
  39. package/templates/dashboard/app/page.tsx +0 -8
  40. package/templates/dashboard/index.html +0 -12
  41. package/templates/dashboard/package.json.tmpl +0 -28
  42. package/templates/dashboard/public/.gitkeep +0 -0
  43. package/templates/dashboard/public/favicon.ico +0 -0
  44. package/templates/dashboard/server/crons/cleanup-conversations.ts +0 -59
  45. package/templates/dashboard/server/routes/health.ts +0 -5
  46. package/templates/dashboard/theo.config.ts +0 -3
  47. package/templates/dashboard/tsconfig.json +0 -15
  48. package/templates/default/.nvmrc +0 -1
  49. package/templates/default/index.html +0 -12
  50. package/templates/default/public/.gitkeep +0 -0
  51. package/templates/default/public/favicon.ico +0 -0
  52. package/templates/default/server/crons/cleanup-conversations.ts +0 -59
  53. package/templates/default/server/routes/chat.ts +0 -69
  54. package/templates/default/server/routes/health.ts +0 -5
  55. package/templates/default/theo.config.ts +0 -3
  56. package/templates/default/types/jobs.d.ts +0 -25
  57. package/templates/postgres/.env.example +0 -5
  58. package/templates/postgres/.nvmrc +0 -1
  59. package/templates/postgres/README.md.tmpl +0 -83
  60. package/templates/postgres/_gitignore +0 -5
  61. package/templates/postgres/app/layout.tsx +0 -14
  62. package/templates/postgres/app/page.tsx +0 -8
  63. package/templates/postgres/db/index.ts +0 -7
  64. package/templates/postgres/db/schema.ts +0 -8
  65. package/templates/postgres/drizzle.config.ts +0 -10
  66. package/templates/postgres/index.html +0 -12
  67. package/templates/postgres/package.json.tmpl +0 -36
  68. package/templates/postgres/public/.gitkeep +0 -0
  69. package/templates/postgres/public/favicon.ico +0 -0
  70. package/templates/postgres/server/context.ts +0 -5
  71. package/templates/postgres/server/jobs/log-message.ts +0 -26
  72. package/templates/postgres/server/routes/health.ts +0 -5
  73. package/templates/postgres/server/routes/users.ts +0 -22
  74. package/templates/postgres/theo.config.ts +0 -3
  75. package/templates/postgres/tsconfig.json +0 -15
  76. package/templates/saas/.env.example +0 -7
  77. package/templates/saas/.nvmrc +0 -1
  78. package/templates/saas/README.md.tmpl +0 -103
  79. package/templates/saas/_gitignore +0 -5
  80. package/templates/saas/app/layout.tsx +0 -5
  81. package/templates/saas/app/page.tsx +0 -104
  82. package/templates/saas/db/index.ts +0 -6
  83. package/templates/saas/db/schema.ts +0 -20
  84. package/templates/saas/drizzle.config.ts +0 -10
  85. package/templates/saas/index.html +0 -12
  86. package/templates/saas/package.json.tmpl +0 -38
  87. package/templates/saas/public/.gitkeep +0 -0
  88. package/templates/saas/public/favicon.ico +0 -0
  89. package/templates/saas/server/context.ts +0 -37
  90. package/templates/saas/server/routes/agent.ts +0 -49
  91. package/templates/saas/server/routes/billing/stripe-webhook.ts +0 -49
  92. package/templates/saas/server/routes/login.ts +0 -25
  93. package/templates/saas/server/routes/logout.ts +0 -10
  94. package/templates/saas/server/routes/me.ts +0 -10
  95. package/templates/saas/theo.config.ts +0 -5
  96. package/templates/saas/tsconfig.json +0 -15
  97. package/templates/services/agent-node/Dockerfile.tmpl +0 -20
  98. package/templates/services/agent-node/README.md +0 -38
  99. package/templates/services/agent-node/package.json.tmpl +0 -18
  100. package/templates/services/agent-node/src/index.ts +0 -58
  101. package/templates/services/agent-node/tsconfig.json +0 -13
  102. package/templates/services/agent-python/Dockerfile.tmpl +0 -20
  103. package/templates/services/agent-python/README.md +0 -37
  104. package/templates/services/agent-python/main.py +0 -77
  105. package/templates/services/agent-python/pyproject.toml.tmpl +0 -16
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "create-theokit",
3
- "version": "0.4.0-beta.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "description": "Scaffold a new TheoKit project",
6
6
  "license": "Apache-2.0",
7
+ "scripts": {
8
+ "build": "tsup"
9
+ },
7
10
  "bin": {
8
11
  "create-theokit": "./dist/cli.js"
9
12
  },
@@ -14,7 +17,8 @@
14
17
  "dependencies": {
15
18
  "cross-spawn": "^7.0.6"
16
19
  },
17
- "scripts": {
18
- "build": "tsup"
20
+ "publishConfig": {
21
+ "provenance": true,
22
+ "access": "public"
19
23
  }
20
- }
24
+ }
@@ -0,0 +1,5 @@
1
+ # LLM API key (OpenRouter, Anthropic, or OpenAI)
2
+ OPENROUTER_API_KEY=sk-or-v1-your-key-here
3
+
4
+ # Optional: override the model declared in @Agent({ model })
5
+ # LLM_MODEL=openai/gpt-4o-mini
@@ -1,75 +1,89 @@
1
1
  # {{name}}
2
2
 
3
- TheoKit project. Build the app your agent lives in routing, auth, real-time, deploy — wired.
3
+ Built with [TheoKit](https://theokit.dev)Full-Stack TypeScript for AI Agents.
4
4
 
5
- > 📚 **Full docs:** https://docs.theokit.dev
6
-
7
- ## Quick start
5
+ ## Getting Started
8
6
 
9
7
  ```bash
10
- # 1. Set your provider key (OpenRouter recommended — one key, any model)
11
- cp .env.example .env # if .env.example shipped; otherwise:
12
- echo 'OPENROUTER_API_KEY=sk-or-v1-...' > .env
13
-
14
- # 2. Boot the dev server
15
- npx theokit dev
16
- ```
17
-
18
- Open the printed URL. The default surface is a chat composer wired to `server/routes/chat.ts`. Drop in your real key in `.env` and the agent responds.
19
-
20
- ## Templates
21
-
22
- - **default** (this one) — TheoUI chat composer + agent route.
23
- - **`--bare`** — Hello Theo with no `@theokit/*` deps. Use this when you want a clean structure to grow into or when the SDK isn't on your registry yet.
24
- - **dashboard** — nested layouts + sidebar.
25
- - **api-only** — server routes without React.
26
- - **postgres** — Drizzle ORM + migrations.
27
- - **saas** — full app with auth, billing, sessions.
8
+ # Install dependencies
9
+ npm install
28
10
 
29
- ## What the framework auto-loads
11
+ # Set your LLM API key
12
+ cp .env.example .env
13
+ # Edit .env with your OpenRouter/Anthropic/OpenAI key
30
14
 
31
- - **`.env` `process.env`**. Edit `.env`; restart the dev server. Server routes read `process.env.MY_KEY` directly.
32
- - **`.theo/` build output cleanup** on every `theokit build`.
33
- - **`.theokit/agents/` LRU GC** on every `theokit dev` startup (default cap: 100 agents).
34
- - **Tailwind + `@theokit/ui` styling** auto-configured when `@theokit/ui` is in your `package.json` AND no consumer `tailwind.config.*` is present. This project ships an explicit `tailwind.config.ts` because the TheoUI v3 surface still requires it. The zero-config path lands when `@theokit/ui` ships its Vite plugin (cross-repo work, pending sign-off).
35
-
36
- For the full story of what's automatic vs deliberate, see [docs.usetheo.dev/zero-config](https://docs.usetheo.dev/zero-config) (or your local `node_modules/theokit/docs/concepts/zero-config.md`).
15
+ # Start development server
16
+ bun dev
17
+ # or: npm run dev:node
18
+ ```
37
19
 
38
- ## Project structure
20
+ ## Project Structure
39
21
 
40
22
  ```
41
- app/ Frontend (file-based routing)
42
- ├── page.tsx / — chat composer
43
- ├── layout.tsx wrapper — TheoUI provider + theme
44
- server/ Backend (explicit routes & actions)
45
- ├── routes/
46
- │ ├── chat.ts POST /api/chat — agent SSE stream
47
- │ └── health.ts GET /api/health
48
- theo.config.ts Framework config
49
- tailwind.config.ts Tailwind theme tokens (TheoUI)
50
- postcss.config.js PostCSS pipeline (Tailwind + autoprefixer)
51
- .env Secrets never committed (.gitignore)
23
+ {{name}}/
24
+ ├── app.ts # Entry point (TheoApp.create)
25
+ ├── server/
26
+ │ ├── controllers/
27
+ │ │ └── tasks.controller.ts # HTTP CRUD (@Controller)
28
+ │ ├── agents/
29
+ └── assistant.agent.ts # AI Agent (@Agent + @MainLoop)
30
+ │ ├── toolboxes/
31
+ │ │ └── task.tools.ts # Agent tools (@Toolbox + @Tool)
32
+ │ ├── guards/
33
+ │ │ └── auth.guard.ts # RBAC (@Roles + RolesGuard)
34
+ │ ├── interceptors/
35
+ │ │ └── timing.interceptor.ts # Request timing
36
+ │ ├── filters/
37
+ │ │ └── http-error.filter.ts # Error formatting
38
+ │ ├── middleware/
39
+ │ │ └── logger.middleware.ts # Request logging
40
+ │ └── store.ts # In-memory data store
41
+ └── .env.example # Environment variables
52
42
  ```
53
43
 
54
- ## Common commands
44
+ ## API Endpoints
45
+
46
+ ### HTTP Controllers
55
47
 
56
- | Command | What it does |
57
- |---|---|
58
- | `npx theokit dev` | Dev server with HMR, devtools overlay, structured logs |
59
- | `npx theokit build` | Production build `.theo/` |
60
- | `npx theokit start` | Serve the production build |
61
- | `npx theokit check` | Lint for upgrade-readiness (CSRF, CSP, zero-config migration hints) |
62
- | `npx theokit generate route foo` | Scaffold a new server route |
63
- | `npx theokit routes` | List all routes + actions detected |
48
+ | Method | Path | Auth | Description |
49
+ |--------|------|------|-------------|
50
+ | GET | /api/tasks | Public | List all tasks |
51
+ | GET | /api/tasks/search?q= | Public | Search tasks |
52
+ | GET | /api/tasks/:id | Public | Get task by ID |
53
+ | POST | /api/tasks | User | Create task |
54
+ | PUT | /api/tasks/:id | User | Update task |
55
+ | DELETE | /api/tasks/:id | Admin | Delete task |
64
56
 
65
- ## What if `npm install` fails on `@theokit/sdk`?
57
+ ### AI Agent
66
58
 
67
- The agent SDK is in soft-release while the npm publish is operator-deferred. If you hit `404 Not Found` for `@theokit/sdk`:
59
+ | Method | Path | Auth | Description |
60
+ |--------|------|------|-------------|
61
+ | POST | /api/agents/assistant/chat | User | Chat with AI (SSE stream) |
68
62
 
69
- - **Quick path**: re-scaffold with `--bare` — Hello Theo without any `@theokit/*` deps.
70
- - **Inside the TheoKit monorepo**: replace `"@theokit/sdk": "^1.0.0"` with `"workspace:*"` in `package.json`.
71
- - **Wait**: track the publish at https://github.com/usetheo/theokit-sdk.
63
+ ## Examples
64
+
65
+ ```bash
66
+ # List tasks
67
+ curl http://localhost:3000/api/tasks
68
+
69
+ # Create a task (requires user role)
70
+ curl -X POST http://localhost:3000/api/tasks \
71
+ -H "Content-Type: application/json" \
72
+ -H "x-role: user" \
73
+ -d '{"title":"New task","priority":"high"}'
74
+
75
+ # Chat with AI agent (SSE streaming)
76
+ curl -N -X POST http://localhost:3000/api/agents/assistant/chat \
77
+ -H "Content-Type: application/json" \
78
+ -H "x-role: user" \
79
+ -d '{"message":"List all tasks and mark the first one as done"}'
80
+ ```
72
81
 
73
- ## License
82
+ ## Key Concepts
74
83
 
75
- Apply your own. The TheoKit framework is Apache-2.0.
84
+ - **@Controller** HTTP routes with Zod validation
85
+ - **@Agent** — AI agent with LLM + tool calling + SSE streaming
86
+ - **@Toolbox** + **@Tool** — Functions the AI can call
87
+ - **@UseGuards** — Same auth for controllers AND agents
88
+ - **@Mixin** — Compose toolboxes into agents
89
+ - **TheoApp.create()** — Zero-wiring bootstrap (like NestFactory.create)
@@ -1,5 +1,4 @@
1
- node_modules
2
- .theo
3
- dist
1
+ node_modules/
2
+ dist/
4
3
  .env
5
4
  .env.local
@@ -1,85 +1,54 @@
1
- import '@theokit/ui/styles.css'
2
-
3
- import { Outlet } from 'react-router'
4
- import {
5
- Sidebar,
6
- TopNav,
7
- AgentProfile,
8
- ThemeSwitcher,
9
- ThemeScript,
10
- Tooltip,
11
- Badge,
12
- CostMeter,
13
- type AgentProfileDescriptor,
14
- } from '@theokit/ui'
15
- import { Bot, MessageSquare, History, Settings } from 'lucide-react'
16
-
17
- const AGENTS: AgentProfileDescriptor[] = [
18
- {
19
- id: 'theo',
20
- name: 'Theo',
21
- description: 'Mock LLM — replace at server/routes/chat.ts.',
22
- tone: 'primary',
23
- initials: 'TH',
24
- badge: 'Online',
25
- },
26
- ]
27
-
28
- export default function RootLayout() {
1
+ export default function Layout({ children }: { children: React.ReactNode }) {
29
2
  return (
30
- <>
31
- <ThemeScript />
32
- <div className="grid h-screen w-screen grid-rows-[auto_1fr] bg-background text-foreground">
33
- <TopNav className="border-border/60 border-b px-4 py-2">
34
- <TopNav.Left>
35
- <Tooltip label="TheoKit agent surface" side="bottom">
36
- <span className="inline-flex items-center gap-2">
37
- <Bot className="size-5 text-primary" aria-hidden />
38
- <span className="font-semibold text-sm tracking-tight">Theo Agent</span>
39
- <Badge variant="outline" size="sm">
40
- v0.1
41
- </Badge>
42
- </span>
43
- </Tooltip>
44
- </TopNav.Left>
45
- <TopNav.Right>
46
- <Tooltip label="Toggle theme" side="bottom" align="end">
47
- <span>
48
- <ThemeSwitcher />
49
- </span>
50
- </Tooltip>
51
- </TopNav.Right>
52
- </TopNav>
53
-
54
- <div className="grid h-full grid-cols-[260px_1fr] overflow-hidden">
55
- <Sidebar className="flex flex-col border-border/60 border-r p-3">
56
- <Sidebar.Header>
57
- <AgentProfile agents={AGENTS} activeId="theo" />
58
- </Sidebar.Header>
59
-
60
- <Sidebar.Section title="Workspace">
61
- <Sidebar.Item icon={MessageSquare} active>
62
- New conversation
63
- </Sidebar.Item>
64
- <Sidebar.Item icon={History}>History</Sidebar.Item>
65
- <Sidebar.Item icon={Settings}>Settings</Sidebar.Item>
66
- </Sidebar.Section>
67
-
68
- <Sidebar.Footer className="mt-auto">
69
- <CostMeter
70
- compact
71
- title="This session"
72
- cost={0.0023}
73
- delta={{ value: 0.0023, period: 'now' }}
74
- />
75
- </Sidebar.Footer>
76
- </Sidebar>
77
-
78
- <main className="flex h-full flex-col overflow-hidden">
79
- <Outlet />
80
- </main>
81
- </div>
82
- </div>
83
- </>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charSet="utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <title>TheoKit App</title>
8
+ <style dangerouslySetInnerHTML={{ __html: STYLES }} />
9
+ </head>
10
+ <body>{children}</body>
11
+ </html>
84
12
  )
85
13
  }
14
+
15
+ const STYLES = `
16
+ :root { --bg: #0a0a0a; --card: #141414; --border: #2a2a2a; --text: #e0e0e0; --muted: #888; --accent: #6366f1; --green: #22c55e; --red: #ef4444; --yellow: #eab308; }
17
+ * { margin: 0; padding: 0; box-sizing: border-box; }
18
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; }
19
+ #app { max-width: 1200px; margin: 0 auto; padding: 20px; }
20
+ header { margin-bottom: 24px; }
21
+ h1 { font-size: 1.6rem; } .accent { color: var(--accent); }
22
+ .subtitle { color: var(--muted); font-size: 0.85rem; margin-top: 2px; }
23
+ .role-bar { margin-top: 12px; }
24
+ .role-bar select { padding: 6px 12px; background: #1a1a1a; border: 1px solid var(--border); border-radius: 6px; color: var(--text); font-size: 0.8rem; }
25
+ .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; } @media(max-width:768px){.grid{grid-template-columns:1fr;}}
26
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 20px; }
27
+ h2 { font-size: 1rem; margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
28
+ .badge { font-size: 0.65rem; padding: 2px 8px; border-radius: 99px; background: #6366f122; color: var(--accent); }
29
+ .badge-ai { background: #eab30822; color: var(--yellow); }
30
+ table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
31
+ th { text-align: left; padding: 8px 4px; color: var(--muted); border-bottom: 1px solid var(--border); font-weight: 500; }
32
+ td { padding: 8px 4px; border-bottom: 1px solid var(--border); }
33
+ tr.done td { opacity: 0.5; text-decoration: line-through; }
34
+ .prio { font-size: 0.7rem; padding: 2px 8px; border-radius: 99px; }
35
+ .prio-high { background: #ef444422; color: var(--red); } .prio-med { background: #eab30822; color: var(--yellow); } .prio-low { background: #22c55e22; color: var(--green); }
36
+ .create-bar { display: flex; gap: 8px; margin-top: 14px; }
37
+ .create-bar input { flex: 1; padding: 8px 12px; background: #1a1a1a; border: 1px solid var(--border); border-radius: 6px; color: var(--text); font-size: 0.85rem; }
38
+ .create-bar select { padding: 8px; background: #1a1a1a; border: 1px solid var(--border); border-radius: 6px; color: var(--text); font-size: 0.8rem; }
39
+ .create-bar button { padding: 8px 16px; background: var(--accent); color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; }
40
+ .error { color: var(--red); font-size: 0.8rem; margin-top: 4px; }
41
+ .chat-box { height: 400px; overflow-y: auto; padding: 12px; background: #0d0d0d; border-radius: 8px; margin-bottom: 10px; font-size: 0.85rem; line-height: 1.6; }
42
+ .msg { margin-bottom: 10px; padding: 8px 12px; border-radius: 8px; }
43
+ .msg.user { background: #6366f118; color: var(--accent); }
44
+ .msg.agent { background: #1a1a1a; }
45
+ .msg.tool { background: #eab30810; color: var(--yellow); font-size: 0.78rem; font-family: monospace; }
46
+ .msg.system { color: var(--muted); font-size: 0.78rem; font-style: italic; }
47
+ .msg.error { color: var(--red); font-size: 0.8rem; }
48
+ .chat-bar { display: flex; gap: 8px; }
49
+ .chat-bar input { flex: 1; padding: 10px 14px; background: #1a1a1a; border: 1px solid var(--border); border-radius: 8px; color: var(--text); font-size: 0.9rem; outline: none; }
50
+ .chat-bar input:focus { border-color: var(--accent); }
51
+ .chat-bar button { padding: 10px 20px; background: var(--accent); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; }
52
+ .chat-bar button:disabled { opacity: 0.4; cursor: not-allowed; }
53
+ .cost { color: var(--muted); font-size: 0.75rem; margin-top: 6px; text-align: right; }
54
+ `